Switch-related cleanup
[hiphop-php.git] / hphp / runtime / vm / jit / abi-x64.h
blob5f9bf9a10091605f4a27ef967292376513f2e94c
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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
19 * tracelets.
21 * Most changes here will likely require corresponding changes in
22 * __enterTCHelper and other parts of mc-generator.cpp and the IR
23 * translator.
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
40 * traces.
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;
62 * scratch register
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
114 * the interpreter.
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
145 * the callee.
147 const RegSet kCrossCallRegs = kCrossTraceRegs;
150 * Registers that can safely be used for scratch purposes in-between
151 * traces.
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
155 * modifying them.
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) {
172 RegSet regs;
173 for (int i = 0; i < n; i++) {
174 regs.add(argNumToRegName[i]);
176 return regs;
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,
212 .sf = kSF,
213 .canSpill = true,
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,
222 .sf = abi.sf,
223 .canSpill = false
226 //////////////////////////////////////////////////////////////////////
230 #endif