1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_X64_REGISTER_X64_H_
6#define V8_X64_REGISTER_X64_H_
7
8#include "src/register.h"
9#include "src/reglist.h"
10
11namespace v8 {
12namespace internal {
13
14#define GENERAL_REGISTERS(V) \
15 V(rax) \
16 V(rcx) \
17 V(rdx) \
18 V(rbx) \
19 V(rsp) \
20 V(rbp) \
21 V(rsi) \
22 V(rdi) \
23 V(r8) \
24 V(r9) \
25 V(r10) \
26 V(r11) \
27 V(r12) \
28 V(r13) \
29 V(r14) \
30 V(r15)
31
32#define ALLOCATABLE_GENERAL_REGISTERS(V) \
33 V(rax) \
34 V(rbx) \
35 V(rdx) \
36 V(rcx) \
37 V(rsi) \
38 V(rdi) \
39 V(r8) \
40 V(r9) \
41 V(r11) \
42 V(r12) \
43 V(r14) \
44 V(r15)
45
46enum RegisterCode {
47#define REGISTER_CODE(R) kRegCode_##R,
48 GENERAL_REGISTERS(REGISTER_CODE)
49#undef REGISTER_CODE
50 kRegAfterLast
51};
52
53class Register : public RegisterBase<Register, kRegAfterLast> {
54 public:
55 bool is_byte_register() const { return reg_code_ <= 3; }
56 // Return the high bit of the register code as a 0 or 1. Used often
57 // when constructing the REX prefix byte.
58 int high_bit() const { return reg_code_ >> 3; }
59 // Return the 3 low bits of the register code. Used when encoding registers
60 // in modR/M, SIB, and opcode bytes.
61 int low_bits() const { return reg_code_ & 0x7; }
62
63 private:
64 friend class RegisterBase<Register, kRegAfterLast>;
65 explicit constexpr Register(int code) : RegisterBase(code) {}
66};
67
68ASSERT_TRIVIALLY_COPYABLE(Register);
69static_assert(sizeof(Register) == sizeof(int),
70 "Register can efficiently be passed by value");
71
72#define DECLARE_REGISTER(R) \
73 constexpr Register R = Register::from_code<kRegCode_##R>();
74GENERAL_REGISTERS(DECLARE_REGISTER)
75#undef DECLARE_REGISTER
76constexpr Register no_reg = Register::no_reg();
77
78constexpr int kNumRegs = 16;
79
80constexpr RegList kJSCallerSaved =
81 Register::ListOf<rax, rcx, rdx,
82 rbx, // used as a caller-saved register in JavaScript code
83 rdi // callee function
84 >();
85
86constexpr int kNumJSCallerSaved = 5;
87
88// Number of registers for which space is reserved in safepoints.
89constexpr int kNumSafepointRegisters = 16;
90
91#ifdef _WIN64
92// Windows calling convention
93constexpr Register arg_reg_1 = rcx;
94constexpr Register arg_reg_2 = rdx;
95constexpr Register arg_reg_3 = r8;
96constexpr Register arg_reg_4 = r9;
97#else
98// AMD64 calling convention
99constexpr Register arg_reg_1 = rdi;
100constexpr Register arg_reg_2 = rsi;
101constexpr Register arg_reg_3 = rdx;
102constexpr Register arg_reg_4 = rcx;
103#endif // _WIN64
104
105#define DOUBLE_REGISTERS(V) \
106 V(xmm0) \
107 V(xmm1) \
108 V(xmm2) \
109 V(xmm3) \
110 V(xmm4) \
111 V(xmm5) \
112 V(xmm6) \
113 V(xmm7) \
114 V(xmm8) \
115 V(xmm9) \
116 V(xmm10) \
117 V(xmm11) \
118 V(xmm12) \
119 V(xmm13) \
120 V(xmm14) \
121 V(xmm15)
122
123#define FLOAT_REGISTERS DOUBLE_REGISTERS
124#define SIMD128_REGISTERS DOUBLE_REGISTERS
125
126#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
127 V(xmm0) \
128 V(xmm1) \
129 V(xmm2) \
130 V(xmm3) \
131 V(xmm4) \
132 V(xmm5) \
133 V(xmm6) \
134 V(xmm7) \
135 V(xmm8) \
136 V(xmm9) \
137 V(xmm10) \
138 V(xmm11) \
139 V(xmm12) \
140 V(xmm13) \
141 V(xmm14)
142
143constexpr bool kPadArguments = false;
144constexpr bool kSimpleFPAliasing = true;
145constexpr bool kSimdMaskRegisters = false;
146
147enum DoubleRegisterCode {
148#define REGISTER_CODE(R) kDoubleCode_##R,
149 DOUBLE_REGISTERS(REGISTER_CODE)
150#undef REGISTER_CODE
151 kDoubleAfterLast
152};
153
154class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> {
155 public:
156 // Return the high bit of the register code as a 0 or 1. Used often
157 // when constructing the REX prefix byte.
158 int high_bit() const { return reg_code_ >> 3; }
159 // Return the 3 low bits of the register code. Used when encoding registers
160 // in modR/M, SIB, and opcode bytes.
161 int low_bits() const { return reg_code_ & 0x7; }
162
163 private:
164 friend class RegisterBase<XMMRegister, kDoubleAfterLast>;
165 explicit constexpr XMMRegister(int code) : RegisterBase(code) {}
166};
167
168ASSERT_TRIVIALLY_COPYABLE(XMMRegister);
169static_assert(sizeof(XMMRegister) == sizeof(int),
170 "XMMRegister can efficiently be passed by value");
171
172typedef XMMRegister FloatRegister;
173
174typedef XMMRegister DoubleRegister;
175
176typedef XMMRegister Simd128Register;
177
178#define DECLARE_REGISTER(R) \
179 constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
180DOUBLE_REGISTERS(DECLARE_REGISTER)
181#undef DECLARE_REGISTER
182constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
183
184// Define {RegisterName} methods for the register types.
185DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
186DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS)
187
188// Give alias names to registers for calling conventions.
189constexpr Register kReturnRegister0 = rax;
190constexpr Register kReturnRegister1 = rdx;
191constexpr Register kReturnRegister2 = r8;
192constexpr Register kJSFunctionRegister = rdi;
193constexpr Register kContextRegister = rsi;
194constexpr Register kAllocateSizeRegister = rdx;
195constexpr Register kSpeculationPoisonRegister = r12;
196constexpr Register kInterpreterAccumulatorRegister = rax;
197constexpr Register kInterpreterBytecodeOffsetRegister = r9;
198constexpr Register kInterpreterBytecodeArrayRegister = r14;
199constexpr Register kInterpreterDispatchTableRegister = r15;
200
201constexpr Register kJavaScriptCallArgCountRegister = rax;
202constexpr Register kJavaScriptCallCodeStartRegister = rcx;
203constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
204constexpr Register kJavaScriptCallNewTargetRegister = rdx;
205constexpr Register kJavaScriptCallExtraArg1Register = rbx;
206
207constexpr Register kRuntimeCallFunctionRegister = rbx;
208constexpr Register kRuntimeCallArgCountRegister = rax;
209constexpr Register kRuntimeCallArgvRegister = r15;
210constexpr Register kWasmInstanceRegister = rsi;
211
212// Default scratch register used by MacroAssembler (and other code that needs
213// a spare register). The register isn't callee save, and not used by the
214// function calling convention.
215constexpr Register kScratchRegister = r10;
216constexpr XMMRegister kScratchDoubleReg = xmm15;
217constexpr Register kRootRegister = r13; // callee save
218
219constexpr Register kOffHeapTrampolineRegister = kScratchRegister;
220
221} // namespace internal
222} // namespace v8
223
224#endif // V8_X64_REGISTER_X64_H_
225