2 +----------------------------------------------------------------------+
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 ///////////////////////////////////////////////////////////////////////////////
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
;
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
;
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
;
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 ///////////////////////////////////////////////////////////////////////////////
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
,
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
,
119 const Abi helper_abi
{
121 trace_abi
.gp() - kGPHelperRegs
,
123 trace_abi
.simd() - kXMMHelperRegs
,
124 trace_abi
.calleeSaved
,
128 ///////////////////////////////////////////////////////////////////////////////
130 // x64 INTEGER class argument registers.
131 constexpr PhysReg gp_args
[] = {
133 reg::rcx
, reg::rdx
, reg::r8
, reg::r9
135 reg::rdi
, reg::rsi
, reg::rdx
, reg::rcx
, reg::r8
, reg::r9
139 // x64 SSE class argument registers.
140 constexpr PhysReg simd_args
[] = {
142 reg::xmm0
, reg::xmm1
, reg::xmm2
, reg::xmm3
,
144 reg::xmm0
, reg::xmm1
, reg::xmm2
, reg::xmm3
,
145 reg::xmm4
, reg::xmm5
, reg::xmm6
, reg::xmm7
,
149 constexpr PhysReg svcreq_args
[] = {
153 ///////////////////////////////////////////////////////////////////////////////
157 ///////////////////////////////////////////////////////////////////////////////
159 const Abi
& abi(CodeKind kind
) {
161 case CodeKind::Trace
:
163 case CodeKind::Prologue
:
165 case CodeKind::CrossTrace
:
166 return cross_trace_abi
;
167 case CodeKind::Helper
:
173 ///////////////////////////////////////////////////////////////////////////////
175 PhysReg
rret(size_t i
) {
177 return i
== 0 ? reg::rax
: reg::rdx
;
179 PhysReg
rret_simd(size_t i
) {
185 PhysReg
rarg(size_t i
) {
186 assertx(i
< num_arg_regs());
189 PhysReg
rarg_simd(size_t i
) {
190 assertx(i
< num_arg_regs_simd());
193 PhysReg
rarg_ind_ret(size_t i
) {
194 assertx(i
< num_arg_regs_ind_ret());
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() {
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 ///////////////////////////////////////////////////////////////////////////////