Stephen Sprunk said:
Doesn't x86-64 pass the first N arguments (technically, first N integer
and first M floating arguments) to non-variadic functions in registers
and leave an empty space in the stack frame in case the callee needs to
spill them?
this differs between the Win64 and SysV calling conventions (Win64 used
respectively on Windows x64, SysV used on Linux x86-64 and OSX and others).
in Win64, 32 bytes are provided as a spill area, and only 4 arguments are
passed in registers.
in SysV, there is no provided spill area (which personally I think was a bad
design idea, since then the callee needs to provide space to spill into, but
oh well...). SysV may pass 6 integer/pointer and 8 floating-point arguments
(in a disjoint manner), and technically literal passed structs may be
unpacked and passed in registers, but I don't bother with this in my
compiler.
Nope; AMD specified that 32-bit operations are sign-extended for exactly
this reason. (16-bit operations, though, are zero-extended; Intel
messed up when creating the i386.)
I wish it were sign extended...
I checked this recently, and it said these were zero-extended.
I considered making it sign extension (in my interpreter) in contrast to the
Intel docs, but figured that it is possible that compilers might depend on
this zero-extension.
then again, I am only likely to use pre-existing compilers for 32-bit x86,
and my compiler for 64-bit x86, so this may be a justifiable infraction...
... unless the locals are never spilled, perhaps?
only Win64 provides for spills, and the space is 32 bytes regardless of the
size or types of arguments.
SysV does not itself provide for spills, and even then, the stack spots are
likely to remain 64 bits (since 64-bit stack spots are still used for < 64
bit arguments).
hence, stack layout is typically different than struct layout...