Skip to contentSkip to conversation

Where is it written?

DISCUSSION George Anzinger 11 participants 23 messages Nov 10, 2000 – Nov 14, 2000

lore
Share & tools
lore
#0 lore raw

I thought this would be simple, but...

Could someone point me at the info on calling conventions to be used with
x86 processors. I need this to write asm code correctly and I suspect that it is a bit more formal than the various comments I have found in the sources. Is it, perhaps an Intel doc? Or a gcc thing?

George
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#1 lore raw
Quoted 7 lines · George Anzinger

I thought this would be simple, but...

Could someone point me at the info on calling conventions to be used with
x86 processors. I need this to write asm code correctly and I suspect that it is a bit more formal than the various comments I have found in the sources. Is it, perhaps an Intel doc? Or a gcc thing?

It may be out of print by now, but the original reference for the x86 ABI, is the:

System V Application Binary Interface
Intel386 (tm) Processor Supplement

When Cygnus purchased the manual I have, many moons ago, it was published by AT&T, with a copyright date of 1991, published by Prentice Hall, with an ISBN number of 0-13-877689-X. It most recently was published by SCO (possibly even Caldera, which just bought SCO). You can get an online version from:

	http://www.sco.com/developer/devspecs/abi386-4.pdf
Signature · 8 lines
Michael Meissner, Red Hat, Inc.
PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA
Work:	  [email protected]		phone: +1 978-486-9304
Non-work: [email protected]	fax:   +1 978-692-4482
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#2 lore raw
Quoted 8 lines · Michael Meissner

It may be out of print by now, but the original reference for the x86 ABI, is the:

System V Application Binary Interface
Intel386 (tm) Processor Supplement

When Cygnus purchased the manual I have, many moons ago, it was published by AT&T, with a copyright date of 1991,

Gee that looks old. Might there be better calling conventions for the Pentium 4 or Athlon? Memory latency, vector registers, and more direct access to floating-point registers may mean we ought to change the calling conventions. One would start with the kernel of course, because it stands alone.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#3 lore raw
In reply to Michael Meissner
Quoted 8 lines · Albert D. Cahalan
Quoted 6 lines · Michael Meissner

It may be out of print by now, but the original reference for the x86 ABI, is the:

System V Application Binary Interface
Intel386 (tm) Processor Supplement

Quoted 8 lines
Quoted 2 lines

When Cygnus purchased the manual I have, many moons ago, it was published by AT&T, with a copyright date of 1991,

Gee that looks old. Might there be better calling conventions for the Pentium 4 or Athlon? Memory latency, vector registers, and more direct access to floating-point registers may mean we ought to change the calling conventions. One would start with the kernel of course, because it stands alone.

Generally with ABIs you don't want to mess with it (otherwise you can't be guaranteed that a library built by somebody else will be compatible with your code, without all sorts of bits in the e_flags field). It allows multiple compilers to be provided that all interoperate (as long as they follow the same spec).

Don't get me wrong -- in my 25 years of compiler hacking, I've never seen an ABI that I was completely happy with, including ABI's that I designed myself. ABIs by their nature are a compromise. That particular ABI was short sighted in that it wants only 32-bit alignment for doubles, instead of 64-bit alignment for instance, and also doesn't align the stack to higher alignment boundaries.

Signature · 8 lines
Michael Meissner, Red Hat, Inc.
PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA
Work:	  [email protected]		phone: +1 978-486-9304
Non-work: [email protected]	fax:   +1 978-692-4482
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#4 lore raw
In reply to Michael Meissner
Followup to:  <[email protected]>
By author:    "Albert D. Cahalan" <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 7 lines

Gee that looks old. Might there be better calling conventions for the Pentium 4 or Athlon? Memory latency, vector registers, and more direct access to floating-point registers may mean we ought to change the calling conventions. One would start with the kernel of course, because it stands alone.

The main win would be passing arguments in registers -- at least three such registers could be used (%eax, %edx, %ecx) without increasing register pressure. Doing this for nonvaradic functions probably would be a win. Similarly, floating-point arguments and SSE arguments could be passed in registers, and _Bool output (a C99 feature) could at least theoretically be returned in a flag.

-hpa

Signature · 7 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#5 lore raw
In reply to Michael Meissner
Followup to:  <[email protected]>
By author:    Michael Meissner <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 7 lines

Generally with ABIs you don't want to mess with it (otherwise you can't be guaranteed that a library built by somebody else will be compatible with your code, without all sorts of bits in the e_flags field). It allows multiple compilers to be provided that all interoperate (as long as they follow the same spec).

Quoted 6 lines

Don't get me wrong -- in my 25 years of compiler hacking, I've never seen an ABI that I was completely happy with, including ABI's that I designed myself. ABIs by their nature are a compromise. That particular ABI was short sighted in that it wants only 32-bit alignment for doubles, instead of 64-bit alignment for instance, and also doesn't align the stack to higher alignment boundaries.

We can mess with the ABI, but it requires a wholescale rev of the entire system. We have had such revs before -- each major rev of libc is one -- but they are incredibly painful. However, if we find ourselves in a situation where there are enough reasons to introduce libc.so.7 then perhaps looking at some revs to the ABI might be in order -- passing arguments in registers and aligning the stack to 64 bits probably would be the main items.

-hpa

Signature · 7 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#6 lore raw
Quoted 2 lines · H. Peter Anvin

We can mess with the ABI, but it requires a wholescale rev of the entire system.

AFAICT, there is nothing stopping us from redoing the kernel ABI to pass the first few parameters between kernel functions in registers. As long as the syscall interface is unchanged, that ABI change will only break binary modules (care_factor == 0). The ABI type would need to be added to the symbol version prefix, trivial.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#7 lore raw
In reply to H. Peter Anvin
Followup to:  <[email protected]>
By author:    Keith Owens <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 12 lines
Quoted 2 lines · H. Peter Anvin

We can mess with the ABI, but it requires a wholescale rev of the entire system.

AFAICT, there is nothing stopping us from redoing the kernel ABI to pass the first few parameters between kernel functions in registers. As long as the syscall interface is unchanged, that ABI change will only break binary modules (care_factor == 0). The ABI type would need to be added to the symbol version prefix, trivial.

Yes, the kernel is very different; however, the big win for an ABI change is in user space.

AFAIK, I think Linus tried this once, but ran into bugs in gcc. We might very well try again in 2.5.

-hpa

Signature · 7 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#8 lore raw
In reply to H. Peter Anvin
Quoted 10 lines · Keith Owens
Quoted 2 lines · H. Peter Anvin

We can mess with the ABI, but it requires a wholescale rev of the entire system.

AFAICT, there is nothing stopping us from redoing the kernel ABI to pass the first few parameters between kernel functions in registers. As long as the syscall interface is unchanged, that ABI change will only break binary modules (care_factor == 0). The ABI type would need to be added to the symbol version prefix, trivial.

Other than the minor little fact that -mregparm=n exposes several latent compiler bugs, that since it is not part of the ABI, it isn't on anybody's radar screen as needing to be fixed. This is of course the downside of free software, that volunteers tend to have their own ideas of what to work on.

Also note, that for -mregpar=n, it is important that variable argument functions be declared properly in all callers, since they need to use the standard calling sequence.

Signature · 8 lines
Michael Meissner, Red Hat, Inc.
PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA
Work:	  [email protected]		phone: +1 978-486-9304
Non-work: [email protected]	fax:   +1 978-692-4482
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#9 lore raw
In reply to H. Peter Anvin
Quoted 3 lines · Michael Meissner

Other than the minor little fact that -mregparm=n exposes several latent compiler bugs, that since it is not part of the ABI, it isn't on anybody's radar screen as needing to be fixed. This is of course the downside of free

mregparm bug is supposed to been fixed in 2.95 by Bernd Schmit.

Andrea
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#10 lore raw
In reply to H. Peter Anvin
Quoted 2 lines · H. Peter Anvin

AFAIK, I think Linus tried this once, but ran into bugs in gcc. We might very well try again in 2.5.

You'll definitely have to use a compiler later than gcc 2.95, since there were in fact major bugs in this area. I'd be interested in hearing bug reports from someone trying with current cvs sources.

r~
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#11 lore raw
In reply to Michael Meissner
Quoted 2 lines · Michael Meissner

Don't get me wrong -- in my 25 years of compiler hacking, I've never seen an ABI that I was completely happy with, [..]

Ok, but I've seen only one that I'm completly unhappy with. Can you think at one case where it's better to push the parameter on the stack instead of passing them through the callee clobbered ebx/eax/edx? Saving the pushes makes a relevant performance difference (that's why we have FASTCALL in kernel to use the sane calling convention even with the <2.95 gcc in fast paths).

Andrea
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#12 lore raw
In reply to Michael Meissner

[Andrea Arcangeli]

Quoted 3 lines

Can you think at one case where it's better to push the parameter on the stack instead of passing them through the callee clobbered ebx/eax/edx?

Well it's safer if you are lazy about prototyping varargs functions. But of course by doing that you're treading on thin ice anyway, in terms of type promotion and portability. So I guess it's much better to say "varargs functions MUST be prototyped" and use the registers.

I'd say go for it -- set up a mailing list and flesh out a better x86 ABI. (Yes, this is the ubiquitous "someone besides me should..." suggestion, I'm afraid I would look pretty foolish trying to help design such.) One issue: ideally you want to use 64-bit regs on AMD Hammer for long longs, but then you leave out all legacy x68s. :(

AIUI gcc can cope OK with multiple ABIs to be chosen at runtime, am I right? IRIX, HP-UX and AIX all have both 32-bit and 64-bit ABIs.

Peter
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#13 lore raw
In reply to Michael Meissner
Followup to:  <[email protected]>
By author:    Peter Samuelson <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 11 lines

[Andrea Arcangeli]

Quoted 3 lines

Can you think at one case where it's better to push the parameter on the stack instead of passing them through the callee clobbered ebx/eax/edx?

Well it's safer if you are lazy about prototyping varargs functions. But of course by doing that you're treading on thin ice anyway, in terms of type promotion and portability. So I guess it's much better to say "varargs functions MUST be prototyped" and use the registers.

It definitely is now. At the time the original x86 ABI was created, a lot of C code was still K&R, and thus prototypes didn't exist...

Quoted 4 lines

AIUI gcc can cope OK with multiple ABIs to be chosen at runtime, am I right? IRIX, HP-UX and AIX all have both 32-bit and 64-bit ABIs.

I don't think we want to introduce a new ABI in user space at this time. If we ever have to major-rev the ABI (libc.so.7), then we should consider this.

-hpa

Signature · 7 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#14 lore raw
In reply to Michael Meissner

[Peter Anvin]

Quoted 2 lines

At the time the original x86 ABI was created, a lot of C code was still K&R, and thus prototypes didn't exist...

True enough. That does explain a lot. But what about the Alpha? From reading gcc source awhile back I seem to remember that most if not all parameters are passed in registers. How does *that* work with varargs and no prototypes? Or does it?

Quoted 3 lines

I don't think we want to introduce a new ABI in user space at this time. If we ever have to major-rev the ABI (libc.so.7), then we should consider this.

Ah, but kernel-side? My point was that if gcc (and binutils) is flexible enough to let you pick an ABI at runtime, perhaps a RISCoid ABI for x86 could coexist with the SysV one, to be used initially for self-contained code like the kernel. (And later, a possible transition in userspace.)

Peter
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#15 lore raw
In reply to Michael Meissner
Quoted 10 lines · Peter Samuelson

[Peter Anvin]

Quoted 2 lines

At the time the original x86 ABI was created, a lot of C code was still K&R, and thus prototypes didn't exist...

True enough. That does explain a lot. But what about the Alpha? From reading gcc source awhile back I seem to remember that most if not all parameters are passed in registers. How does *that* work with varargs and no prototypes? Or does it?

It doesn't, but the Alpha is a *much* more recent ABI... the x86 ABI really dates back to the 16-bit 8086-series CPUs.

Quoted 9 lines
Quoted 3 lines

I don't think we want to introduce a new ABI in user space at this time. If we ever have to major-rev the ABI (libc.so.7), then we should consider this.

Ah, but kernel-side? My point was that if gcc (and binutils) is flexible enough to let you pick an ABI at runtime, perhaps a RISCoid ABI for x86 could coexist with the SysV one, to be used initially for self-contained code like the kernel. (And later, a possible transition in userspace.)

We tried once; at that point the register-based ABI support in gcc was too buggy to be useful. We might try again in 2.5 since we now have increased the minimum gcc version for kernel compiles. Binutils needs no change.

-hpa

Signature · 7 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#16 lore raw
In reply to Michael Meissner

[H. Peter Anvin <[email protected]>]

Quoted 2 lines

but the Alpha is a *much* more recent ABI... the x86 ABI really dates back to the 16-bit 8086-series CPUs.

Oh, right. Xenix. I'd forgotten.

Quoted 2 lines

We might try again in 2.5 since we now have increased the minimum gcc version for kernel compiles. Binutils needs no change.

You mean trivial changes to understand the ELF magic number for a riscoid-ABI x86 object. (You wouldn't lie to the linker and call them SysV objects, now, would you?) Also gdb and libbfd need to know about stack frames. Admittedly none of this is strictly necessary just to link and boot a kernel.

Peter
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#17 lore raw
Quoted 5 lines · Peter Samuelson

You mean trivial changes to understand the ELF magic number for a riscoid-ABI x86 object. (You wouldn't lie to the linker and call them SysV objects, now, would you?) Also gdb and libbfd need to know about stack frames. Admittedly none of this is strictly necessary just to link and boot a kernel.

Any ABI change needs to be externalised for modules. Otherwise symbol versions will not detect that the kernel was compiled with -mregparm=3 but the module was compiled with parameters on stack. Good thing this is 2.5 material.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#18 lore raw
In reply to Michael Meissner
Quoted 5 lines · H. Peter Anvin

We tried once; at that point the register-based ABI support in gcc was too buggy to be useful. We might try again in 2.5 since we now have increased the minimum gcc version for kernel compiles. Binutils needs no change.

As far as I know egcs 1.1 still has fastcall bugs, they were only fixed in 2.95 (which unfortunately has other bugs). So to use it the minimum compiler would need to be bumped again.

-Andi

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#19 lore raw
In reply to Michael Meissner
Quoted 2 lines · Peter Samuelson

I'd say go for it -- set up a mailing list and flesh out a better x86 ABI. [..]

I think it doesn't worth to break binary compatilibity at this late stage.

Quoted 2 lines

design such.) One issue: ideally you want to use 64-bit regs on AMD Hammer for long longs, but then you leave out all legacy x68s. :(

We can't in compatibilty mode because the rex regs are available _only_ in 64bit mode and even assuming the hardware would support that I would not recommend that since as you said that binary would not run anymore on any other x86 so causing pain. Recompiling a program with native x86-64 gcc 64bit (that uses the 64bit ABI) is the right way to go in that case (64bit mode uses 1 64bit register for long long as all other 64bit architectures of course).

Quoted 2 lines

AIUI gcc can cope OK with multiple ABIs to be chosen at runtime, am I right? IRIX, HP-UX and AIX all have both 32-bit and 64-bit ABIs.

Yes as in other systems, 32bit mode and 64bit mode needs different ABI and they will coexist in the same system.

Andrea
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#20 lore raw
In reply to Michael Meissner
Quoted 4 lines

Well it's safer if you are lazy about prototyping varargs functions. But of course by doing that you're treading on thin ice anyway, in terms of type promotion and portability. So I guess it's much better to say "varargs functions MUST be prototyped" and use the registers.

make -Wmissing-prototypes mandatory :-)

Olaf
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#21 lore raw
In reply to Michael Meissner
Followup to:  <[email protected]>
By author:    Andrea Arcangeli <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 6 lines

I think it doesn't worth to break binary compatilibity at this late stage.

Quoted 2 lines

design such.) One issue: ideally you want to use 64-bit regs on AMD Hammer for long longs, but then you leave out all legacy x68s. :(

Quoted 7 lines

We can't in compatibilty mode because the rex regs are available _only_ in 64bit mode and even assuming the hardware would support that I would not recommend that since as you said that binary would not run anymore on any other x86 so causing pain. Recompiling a program with native x86-64 gcc 64bit (that uses the 64bit ABI) is the right way to go in that case (64bit mode uses 1 64bit register for long long as all other 64bit architectures of course).

Well, you *could* run REX32, but REX32 is not x86 (x86 code doesn't run in REX32 mode, and REX32 code doesn't run on an x86.)

-hpa

Signature · 7 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#22 lore raw
In reply to George Anzinger
Followup to:  <[email protected]>
By author:    George Anzinger <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 9 lines

I thought this would be simple, but...

Could someone point me at the info on calling conventions to be used with x86 processors. I need this to write asm code correctly and I suspect that it is a bit more formal than the various comments I have found in the sources. Is it, perhaps an Intel doc? Or a gcc thing?

http://www.sco.com/developer/devspecs/abi386-4.pdf

-hpa

Signature · 7 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/