Store num args instead of offset in prologue and func entry SrcKeys
[hiphop-php.git] / hphp / runtime / vm / jit / abi-x64.cpp
blob198cecf161c27d504955c0fb03b8073108184022
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/abi-x64.h"
19 #include "hphp/runtime/vm/jit/types.h"
20 #include "hphp/runtime/vm/jit/abi.h"
22 namespace HPHP::jit::x64 {
24 ///////////////////////////////////////////////////////////////////////////////
26 namespace {
28 ///////////////////////////////////////////////////////////////////////////////
30 const RegSet kGPRegs =
31 reg::rax | reg::rbx | reg::rcx | reg::rdx |
32 reg::rdi | reg::rsi | reg::rsp | reg::rbp |
33 reg::r8 | reg::r9 | reg::r10 | reg::r11 |
34 reg::r12 | reg::r13 | reg::r14 | reg::r15;
36 #ifdef _MSC_VER
37 const RegSet kGPCallerSaved =
38 reg::rax | reg::rcx | reg::rdx |
39 reg::r8 | reg::r9 | reg::r10 | reg::r11;
41 const RegSet kGPCalleeSaved =
42 reg::rbx | reg::rsi | reg::rdi | reg::r13 | reg::r14 | reg::r15;
43 #else
44 const RegSet kGPCallerSaved =
45 reg::rax | reg::rcx | reg::rdx | reg::rsi | reg::rdi |
46 reg::r8 | reg::r9 | reg::r10 | reg::r11;
48 const RegSet kGPCalleeSaved =
49 reg::rbx | reg::r12 | reg::r13 | reg::r14 | reg::r15;
50 #endif
52 const RegSet kGPReserved = x64::rsp() | x64::rvmfp() | x64::rvmtl();
53 const RegSet kGPUnreserved = kGPRegs - kGPReserved;
55 const RegSet kXMMRegs =
56 reg::xmm0 | reg::xmm1 | reg::xmm2 | reg::xmm3 |
57 reg::xmm4 | reg::xmm5 | reg::xmm6 | reg::xmm7 |
58 reg::xmm8 | reg::xmm9 | reg::xmm10 | reg::xmm11 |
59 reg::xmm12 | reg::xmm13 | reg::xmm14 | reg::xmm15;
61 const RegSet kXMMCallerSaved = kXMMRegs;
62 const RegSet kXMMCalleeSaved;
64 const RegSet kXMMReserved;
65 const RegSet kXMMUnreserved = kXMMRegs - kXMMReserved;
67 const RegSet kCallerSaved = kGPCallerSaved | kXMMCallerSaved;
68 const RegSet kCalleeSaved = kGPCalleeSaved | kXMMCalleeSaved;
70 const RegSet kSF = RegSet(RegSF{0});
72 ///////////////////////////////////////////////////////////////////////////////
75 * Registers that can safely be used within a prologue.
77 const RegSet kPrologueRegs = kXMMCallerSaved | kGPUnreserved;
80 * Registers that can safely be used for scratch purposes in-between traces.
82 const RegSet kScratchCrossTraceRegs = kPrologueRegs - reg::r15;
85 * Helper code ABI registers.
87 const RegSet kGPHelperRegs = reg::r10 | reg::r11;
88 const RegSet kXMMHelperRegs = reg::xmm5 | reg::xmm6 | reg::xmm7;
90 ///////////////////////////////////////////////////////////////////////////////
92 const Abi trace_abi {
93 kGPUnreserved,
94 kGPReserved,
95 kXMMUnreserved,
96 kXMMReserved,
97 kCalleeSaved,
98 kSF
101 const Abi prologue_abi {
102 trace_abi.gp() & kPrologueRegs,
103 trace_abi.gp() - kPrologueRegs,
104 trace_abi.simd() & kPrologueRegs,
105 trace_abi.simd() - kPrologueRegs,
106 trace_abi.calleeSaved & kPrologueRegs,
107 trace_abi.sf
110 const Abi cross_trace_abi {
111 trace_abi.gp() & kScratchCrossTraceRegs,
112 trace_abi.gp() - kScratchCrossTraceRegs,
113 trace_abi.simd() & kScratchCrossTraceRegs,
114 trace_abi.simd() - kScratchCrossTraceRegs,
115 trace_abi.calleeSaved & kScratchCrossTraceRegs,
116 trace_abi.sf
119 const Abi helper_abi {
120 kGPHelperRegs,
121 trace_abi.gp() - kGPHelperRegs,
122 kXMMHelperRegs,
123 trace_abi.simd() - kXMMHelperRegs,
124 trace_abi.calleeSaved,
125 trace_abi.sf
128 ///////////////////////////////////////////////////////////////////////////////
130 // x64 INTEGER class argument registers.
131 constexpr PhysReg gp_args[] = {
132 #ifdef _MSC_VER
133 reg::rcx, reg::rdx, reg::r8, reg::r9
134 #else
135 reg::rdi, reg::rsi, reg::rdx, reg::rcx, reg::r8, reg::r9
136 #endif
139 // x64 SSE class argument registers.
140 constexpr PhysReg simd_args[] = {
141 #ifdef _MSC_VER
142 reg::xmm0, reg::xmm1, reg::xmm2, reg::xmm3,
143 #else
144 reg::xmm0, reg::xmm1, reg::xmm2, reg::xmm3,
145 reg::xmm4, reg::xmm5, reg::xmm6, reg::xmm7,
146 #endif
149 constexpr PhysReg svcreq_args[] = {
150 reg::rsi, reg::rdx
153 ///////////////////////////////////////////////////////////////////////////////
157 ///////////////////////////////////////////////////////////////////////////////
159 const Abi& abi(CodeKind kind) {
160 switch (kind) {
161 case CodeKind::Trace:
162 return trace_abi;
163 case CodeKind::Prologue:
164 return prologue_abi;
165 case CodeKind::CrossTrace:
166 return cross_trace_abi;
167 case CodeKind::Helper:
168 return helper_abi;
170 not_reached();
173 ///////////////////////////////////////////////////////////////////////////////
175 PhysReg rret(size_t i) {
176 assertx(i < 2);
177 return i == 0 ? reg::rax : reg::rdx;
179 PhysReg rret_simd(size_t i) {
180 assertx(i == 0);
181 return reg::xmm0;
185 PhysReg rarg(size_t i) {
186 assertx(i < num_arg_regs());
187 return gp_args[i];
189 PhysReg rarg_simd(size_t i) {
190 assertx(i < num_arg_regs_simd());
191 return simd_args[i];
193 PhysReg rarg_ind_ret(size_t i) {
194 assertx(i < num_arg_regs_ind_ret());
195 return PhysReg();
198 size_t num_arg_regs() {
199 return sizeof(gp_args) / sizeof(PhysReg);
201 size_t num_arg_regs_simd() {
202 return sizeof(simd_args) / sizeof(PhysReg);
204 size_t num_arg_regs_ind_ret() {
205 return 0;
208 RegSet arg_regs(size_t n) {
209 return jit::arg_regs(n);
211 RegSet arg_regs_simd(size_t n) {
212 return jit::arg_regs_simd(n);
214 RegSet arg_regs_ind_ret(size_t n) {
215 return jit::arg_regs_ind_ret(n);
218 PhysReg r_svcreq_sf() {
219 return abi().sf.choose();
221 PhysReg r_svcreq_arg(size_t i) {
222 return svcreq_args[i];
225 ///////////////////////////////////////////////////////////////////////////////