HHVM calling convention, hhvmcc, is used by HHVM JIT for calling
functions in translated cache. We currently support LLVM back end to
generate code for X86-64 and may support other architectures in the
future.
In HHVM calling convention any GP register could be used to pass and
return values, with the exception of R12 which is reserved for
thread-local area and is callee-saved. Other than R12, we always
pass RBX and RBP as args, which are our virtual machine's stack pointer
and frame pointer respectively.
When we enter translation cache via hhvmcc function, we expect
the stack to be aligned at 16 bytes, i.e. skewed by 8 bytes as opposed
to standard ABI alignment. This affects stack object alignment and stack
adjustments for calls.
The second calling convention, hhvm_ccc, is used to call C++ helpers from
HHVM's translation cache. It is almost identical to standard C calling
convention with an exception that we pass our virtual machine's frame pointer
in RBP as the first argument to a function, and then use standard
registers/stack (RDI, RSI, etc.) for the rest of the arguments.
This sentence isn't clear to me. Is this analogous to anyreg where the register allocator can put arguments in any register and the runtime has to parse the stack map to figure out where they are? Or are there defined argument and return registers? If the later, I'd just emit this sentence.