Line data Source code
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 :
11 : namespace v8 {
12 : namespace 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 :
46 : enum RegisterCode {
47 : #define REGISTER_CODE(R) kRegCode_##R,
48 : GENERAL_REGISTERS(REGISTER_CODE)
49 : #undef REGISTER_CODE
50 : kRegAfterLast
51 : };
52 :
53 : class Register : public RegisterBase<Register, kRegAfterLast> {
54 : public:
55 1294940 : 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 296352018 : 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 301593702 : 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 :
68 : ASSERT_TRIVIALLY_COPYABLE(Register);
69 : static_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>();
74 : GENERAL_REGISTERS(DECLARE_REGISTER)
75 : #undef DECLARE_REGISTER
76 : constexpr Register no_reg = Register::no_reg();
77 :
78 : constexpr int kNumRegs = 16;
79 :
80 : constexpr 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 :
86 : constexpr int kNumJSCallerSaved = 5;
87 :
88 : // Number of registers for which space is reserved in safepoints.
89 : constexpr int kNumSafepointRegisters = 16;
90 :
91 : #ifdef _WIN64
92 : // Windows calling convention
93 : constexpr Register arg_reg_1 = rcx;
94 : constexpr Register arg_reg_2 = rdx;
95 : constexpr Register arg_reg_3 = r8;
96 : constexpr Register arg_reg_4 = r9;
97 : #else
98 : // AMD64 calling convention
99 : constexpr Register arg_reg_1 = rdi;
100 : constexpr Register arg_reg_2 = rsi;
101 : constexpr Register arg_reg_3 = rdx;
102 : constexpr 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 :
143 : constexpr bool kPadArguments = false;
144 : constexpr bool kSimpleFPAliasing = true;
145 : constexpr bool kSimdMaskRegisters = false;
146 :
147 : enum DoubleRegisterCode {
148 : #define REGISTER_CODE(R) kDoubleCode_##R,
149 : DOUBLE_REGISTERS(REGISTER_CODE)
150 : #undef REGISTER_CODE
151 : kDoubleAfterLast
152 : };
153 :
154 : class 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 9726607 : 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 5734514 : 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 :
168 : ASSERT_TRIVIALLY_COPYABLE(XMMRegister);
169 : static_assert(sizeof(XMMRegister) == sizeof(int),
170 : "XMMRegister can efficiently be passed by value");
171 :
172 : typedef XMMRegister FloatRegister;
173 :
174 : typedef XMMRegister DoubleRegister;
175 :
176 : typedef XMMRegister Simd128Register;
177 :
178 : #define DECLARE_REGISTER(R) \
179 : constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
180 : DOUBLE_REGISTERS(DECLARE_REGISTER)
181 : #undef DECLARE_REGISTER
182 : constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
183 :
184 : // Define {RegisterName} methods for the register types.
185 2289 : DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
186 45 : DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS)
187 :
188 : // Give alias names to registers for calling conventions.
189 : constexpr Register kReturnRegister0 = rax;
190 : constexpr Register kReturnRegister1 = rdx;
191 : constexpr Register kReturnRegister2 = r8;
192 : constexpr Register kJSFunctionRegister = rdi;
193 : constexpr Register kContextRegister = rsi;
194 : constexpr Register kAllocateSizeRegister = rdx;
195 : constexpr Register kSpeculationPoisonRegister = r12;
196 : constexpr Register kInterpreterAccumulatorRegister = rax;
197 : constexpr Register kInterpreterBytecodeOffsetRegister = r9;
198 : constexpr Register kInterpreterBytecodeArrayRegister = r14;
199 : constexpr Register kInterpreterDispatchTableRegister = r15;
200 :
201 : constexpr Register kJavaScriptCallArgCountRegister = rax;
202 : constexpr Register kJavaScriptCallCodeStartRegister = rcx;
203 : constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
204 : constexpr Register kJavaScriptCallNewTargetRegister = rdx;
205 : constexpr Register kJavaScriptCallExtraArg1Register = rbx;
206 :
207 : constexpr Register kRuntimeCallFunctionRegister = rbx;
208 : constexpr Register kRuntimeCallArgCountRegister = rax;
209 : constexpr Register kRuntimeCallArgvRegister = r15;
210 : constexpr 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.
215 : constexpr Register kScratchRegister = r10;
216 : constexpr XMMRegister kScratchDoubleReg = xmm15;
217 : constexpr Register kRootRegister = r13; // callee save
218 :
219 : constexpr Register kOffHeapTrampolineRegister = kScratchRegister;
220 :
221 : } // namespace internal
222 : } // namespace v8
223 :
224 : #endif // V8_X64_REGISTER_X64_H_
|