2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
18 * Enumerations and constants defining the binary interface between
21 * Most changes here will likely require corresponding changes in
22 * __enterTCHelper and other parts of mc-generator.cpp and the IR
26 #ifndef incl_HPHP_VM_RUNTIME_TRANSLATOR_ABI_X64_H_
27 #define incl_HPHP_VM_RUNTIME_TRANSLATOR_ABI_X64_H_
29 #include "hphp/util/asm-x64.h"
30 #include "hphp/runtime/vm/jit/abi.h"
31 #include "hphp/runtime/vm/jit/phys-reg.h"
33 namespace HPHP
{ namespace jit
{ namespace x64
{
35 //////////////////////////////////////////////////////////////////////
37 * Principal reserved registers.
39 * These registers have special purposes both during and between
44 * Frame pointer. When mid-trace, points to the ActRec for the
45 * function currently executing.
47 constexpr PhysReg rVmFp
= reg::rbp
;
50 * Stack pointer. When mid-trace, points to the top of the eval stack
51 * (lowest valid address) at the start of the current tracelet.
53 constexpr PhysReg rVmSp
= reg::rbx
;
56 * RDS base pointer. Always points to the base of the RDS block for
57 * the current request.
59 constexpr PhysReg rVmTl
= reg::r12
;
64 constexpr Reg64 rAsm
= reg::r10
;
66 //////////////////////////////////////////////////////////////////////
68 * Registers used during a tracelet for program locations.
70 * These are partitioned into caller-saved and callee-saved regs
71 * according to the x64 C abi. These are all the registers that the
72 * translator manages via its RegMap.
75 const RegSet kGPCallerSaved
=
76 reg::rax
| reg::rcx
| reg::rdx
| reg::rsi
| reg::rdi
|
77 reg::r8
| reg::r9
| reg::r10
| reg::r11
;
79 const RegSet kGPCalleeSaved
=
80 reg::rbx
| reg::r13
| reg::r14
| reg::r15
;
82 const RegSet kGPUnreserved
= kGPCallerSaved
| kGPCalleeSaved
;
84 const RegSet kGPReserved
= reg::rsp
| rVmFp
| rVmTl
;
86 const RegSet kGPRegs
= kGPUnreserved
| kGPReserved
;
88 const RegSet kXMMCallerSaved
=
89 reg::xmm0
| reg::xmm1
| reg::xmm2
| reg::xmm3
|
90 reg::xmm4
| reg::xmm5
| reg::xmm6
| reg::xmm7
|
91 reg::xmm8
| reg::xmm9
| reg::xmm10
| reg::xmm11
|
92 reg::xmm12
| reg::xmm13
| reg::xmm14
| reg::xmm15
;
94 const RegSet kXMMCalleeSaved
;
96 const RegSet kXMMUnreserved
= kXMMCallerSaved
| kXMMCalleeSaved
;
98 const RegSet kXMMReserved
;
100 const RegSet kXMMRegs
= kXMMUnreserved
| kXMMReserved
;
102 const RegSet kCallerSaved
= kGPCallerSaved
| kXMMCallerSaved
;
104 const RegSet kCalleeSaved
= kGPCalleeSaved
| kXMMCalleeSaved
;
106 const RegSet kSF
= RegSet(RegSF
{0});
108 //////////////////////////////////////////////////////////////////////
110 * Registers reserved for cross-tracelet ABI purposes.
112 * These registers should not be used for scratch purposes between
113 * tracelets, and have to be specially handled if we are returning to
118 * Registers that are live between tracelets, in two flavors, depending whether
119 * we are between tracelets in a resumed function.
121 const RegSet kCrossTraceRegs
= rVmFp
| rVmTl
;
122 const RegSet kCrossTraceRegsResumed
= kCrossTraceRegs
| rVmSp
;
125 * Registers live on entry to the fcallArrayHelper.
127 * TODO(#2288359): we don't want this to include rVmSp eventually.
129 const RegSet kCrossTraceRegsFCallArray
= kCrossTraceRegs
| rVmSp
;
132 * Registers live on entry to an interpOneCFHelper.
134 const RegSet kCrossTraceRegsInterpOneCF
= kCrossTraceRegs
| rVmSp
| rAsm
;
137 * Registers that are live after a PHP function return.
139 * TODO(#2288359): we don't want this to include rVmSp eventually.
141 const RegSet kCrossTraceRegsReturn
= kCrossTraceRegs
| rVmSp
;
144 * Registers that are live during a PHP function call, between the caller and
147 const RegSet kCrossCallRegs
= kCrossTraceRegs
;
150 * Registers that can safely be used for scratch purposes in-between
153 * Note: there are portions of the func prologue code that will hit
154 * assertions if you remove rax, rdx, or rcx from this set without
157 const RegSet kScratchCrossTraceRegs
= kXMMCallerSaved
|
158 (kGPUnreserved
- (kCrossTraceRegs
| kCrossTraceRegsResumed
));
160 //////////////////////////////////////////////////////////////////////
162 * Calling convention registers for service requests or calling C++.
165 // x64 INTEGER class argument registers.
166 const PhysReg argNumToRegName
[] = {
167 reg::rdi
, reg::rsi
, reg::rdx
, reg::rcx
, reg::r8
, reg::r9
169 const int kNumRegisterArgs
= sizeof(argNumToRegName
) / sizeof(PhysReg
);
171 inline RegSet
argSet(int n
) {
173 for (int i
= 0; i
< n
; i
++) {
174 regs
.add(argNumToRegName
[i
]);
179 // x64 SSE class argument registers.
180 const PhysReg argNumToSIMDRegName
[] = {
181 reg::xmm0
, reg::xmm1
, reg::xmm2
, reg::xmm3
,
182 reg::xmm4
, reg::xmm5
, reg::xmm6
, reg::xmm7
,
184 const int kNumSIMDRegisterArgs
= sizeof(argNumToSIMDRegName
) / sizeof(PhysReg
);
187 * JIT'd code "reverse calls" the enterTC routine by returning to it,
188 * with a service request number and arguments.
190 constexpr PhysReg serviceReqArgRegs
[] = {
191 // rdi: contains request number
192 reg::rsi
, reg::rdx
, reg::rcx
, reg::r8
194 constexpr int kNumServiceReqArgRegs
=
195 sizeof(serviceReqArgRegs
) / sizeof(PhysReg
);
198 * Some data structures are accessed often enough from translated code
199 * that we have shortcuts for getting offsets into them.
201 #define TVOFF(nm) int(offsetof(TypedValue, nm))
202 #define AROFF(nm) int(offsetof(ActRec, nm))
203 #define AFWHOFF(nm) int(offsetof(c_AsyncFunctionWaitHandle, nm))
204 #define CONTOFF(nm) int(offsetof(c_Generator, nm))
206 UNUSED
const Abi abi
{
207 .gpUnreserved
= kGPUnreserved
,
208 .gpReserved
= kGPReserved
,
209 .simdUnreserved
= kXMMUnreserved
,
210 .simdReserved
= kXMMReserved
,
211 .calleeSaved
= kCalleeSaved
,
216 UNUSED
const Abi cross_trace_abi
{
217 .gpUnreserved
= abi
.gp() & kScratchCrossTraceRegs
,
218 .gpReserved
= abi
.gp() - kScratchCrossTraceRegs
,
219 .simdUnreserved
= abi
.simd() & kScratchCrossTraceRegs
,
220 .simdReserved
= abi
.simd() - kScratchCrossTraceRegs
,
221 .calleeSaved
= abi
.calleeSaved
& kScratchCrossTraceRegs
,
226 //////////////////////////////////////////////////////////////////////