Why is RCX not used for passing parameters to system calls, being replaced with R10? [duplicate]

X86-64 system calls use syscall instruction. This instruction saves return address to rcx, and after that it loads rip from IA32_LSTAR MSR. I.e. rcx is immediately destroyed by syscall. This is the reason why rcx had to be replaced for system call ABI. This same syscall instruction also saves rflags into r11, and then masks … Read more

Why does the x86-64 System V calling convention pass args in registers instead of just the stack?

instead of put the first 6 arguments in registers just to move them onto the stack in the function prologue? I was looking at some code that gcc generated and that’s what it always did. Then you forgot to enable optimization. gcc -O0 spills everything to memory so you can modify them with a debugger … Read more

Is garbage allowed in high bits of parameter and return value registers in x86-64 SysV ABI?

It looks like you have two questions here: Do the high bits of a return value need to be zeroed before returning? (And do the high bits of arguments need to be zeroed before calling?) What are the costs/benefits associated with this decision? The answer to the first question is no, there can be garbage … Read more

Why can a T* be passed in register, but a unique_ptr cannot?

Is this actually an ABI requirement, or maybe it’s just some pessimization in certain scenarios? One example is System V Application Binary Interface AMD64 Architecture Processor Supplement. This ABI is for 64-bit x86-compatible CPUs (Linux x86_64 architecure). It is followed on Solaris, Linux, FreeBSD, macOS, Windows Subsystem for Linux: If a C++ object has either … Read more

C++ on x86-64: when are structs/classes passed and returned in registers?

The ABI specification is defined here. A newer version is available here. I assume the reader is accustomed to the terminology of the document and that they can classify the primitive types. If the object size is larger than two eight-bytes, it is passed in memory: struct foo { unsigned long long a; unsigned long … Read more

How do C compilers implement functions that return large structures?

None; no copies are done. The address of the caller’s Data return value is actually passed as a hidden argument to the function, and the createData function simply writes into the caller’s stack frame. This is known as the named return value optimisation. Also see the c++ faq on this topic. commercial-grade C++ compilers implement … Read more

Why not store function parameters in XMM vector registers?

Most functions don’t have more than 6 integer parameters, so this is really a corner case. Passing some excess integer params in xmm registers would make the rules for where to find floating point args more complicated, for little to no benefit. Besides the fact that it probably wouldn’t make code any faster. A further … Read more

Why does gcc use movl instead of push to pass function args?

Here is what the gcc manual has to say about it: -mpush-args -mno-push-args Use PUSH operations to store outgoing parameters. This method is shorter and usually equally fast as method using SUB/MOV operations and is enabled by default. In some cases disabling it may improve performance because of improved scheduling and reduced dependencies. -maccumulate-outgoing-args If … Read more