• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CODEGEN_X64_REGISTER_X64_H_
6 #define V8_CODEGEN_X64_REGISTER_X64_H_
7 
8 #include "src/codegen/register.h"
9 #include "src/codegen/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:
is_byte_register()55   bool is_byte_register() const { return 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.
high_bit()58   int high_bit() const { return code() >> 3; }
59   // Return the 3 low bits of the register code.  Used when encoding registers
60   // in modR/M, SIB, and opcode bytes.
low_bits()61   int low_bits() const { return code() & 0x7; }
62 
63  private:
64   friend class RegisterBase<Register, kRegAfterLast>;
Register(int code)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 constexpr int kNumJSCallerSaved = 5;
86 
87 // Number of registers for which space is reserved in safepoints.
88 constexpr int kNumSafepointRegisters = 16;
89 
90 #ifdef V8_TARGET_OS_WIN
91 // Windows calling convention
92 constexpr Register arg_reg_1 = rcx;
93 constexpr Register arg_reg_2 = rdx;
94 constexpr Register arg_reg_3 = r8;
95 constexpr Register arg_reg_4 = r9;
96 #else
97 // AMD64 calling convention
98 constexpr Register arg_reg_1 = rdi;
99 constexpr Register arg_reg_2 = rsi;
100 constexpr Register arg_reg_3 = rdx;
101 constexpr Register arg_reg_4 = rcx;
102 #endif  // V8_TARGET_OS_WIN
103 
104 #define DOUBLE_REGISTERS(V) \
105   V(xmm0)                   \
106   V(xmm1)                   \
107   V(xmm2)                   \
108   V(xmm3)                   \
109   V(xmm4)                   \
110   V(xmm5)                   \
111   V(xmm6)                   \
112   V(xmm7)                   \
113   V(xmm8)                   \
114   V(xmm9)                   \
115   V(xmm10)                  \
116   V(xmm11)                  \
117   V(xmm12)                  \
118   V(xmm13)                  \
119   V(xmm14)                  \
120   V(xmm15)
121 
122 #define FLOAT_REGISTERS DOUBLE_REGISTERS
123 #define SIMD128_REGISTERS DOUBLE_REGISTERS
124 
125 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
126   V(xmm0)                               \
127   V(xmm1)                               \
128   V(xmm2)                               \
129   V(xmm3)                               \
130   V(xmm4)                               \
131   V(xmm5)                               \
132   V(xmm6)                               \
133   V(xmm7)                               \
134   V(xmm8)                               \
135   V(xmm9)                               \
136   V(xmm10)                              \
137   V(xmm11)                              \
138   V(xmm12)                              \
139   V(xmm13)                              \
140   V(xmm14)
141 
142 constexpr bool kPadArguments = false;
143 constexpr bool kSimpleFPAliasing = true;
144 constexpr bool kSimdMaskRegisters = false;
145 
146 enum DoubleRegisterCode {
147 #define REGISTER_CODE(R) kDoubleCode_##R,
148   DOUBLE_REGISTERS(REGISTER_CODE)
149 #undef REGISTER_CODE
150       kDoubleAfterLast
151 };
152 
153 class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> {
154  public:
155   // Return the high bit of the register code as a 0 or 1.  Used often
156   // when constructing the REX prefix byte.
high_bit()157   int high_bit() const { return code() >> 3; }
158   // Return the 3 low bits of the register code.  Used when encoding registers
159   // in modR/M, SIB, and opcode bytes.
low_bits()160   int low_bits() const { return code() & 0x7; }
161 
162  private:
163   friend class RegisterBase<XMMRegister, kDoubleAfterLast>;
XMMRegister(int code)164   explicit constexpr XMMRegister(int code) : RegisterBase(code) {}
165 };
166 
167 ASSERT_TRIVIALLY_COPYABLE(XMMRegister);
168 static_assert(sizeof(XMMRegister) == sizeof(int),
169               "XMMRegister can efficiently be passed by value");
170 
171 using FloatRegister = XMMRegister;
172 
173 using DoubleRegister = XMMRegister;
174 
175 using Simd128Register = XMMRegister;
176 
177 #define DECLARE_REGISTER(R) \
178   constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
179 DOUBLE_REGISTERS(DECLARE_REGISTER)
180 #undef DECLARE_REGISTER
181 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
182 
183 // Define {RegisterName} methods for the register types.
184 DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
185 DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS)
186 
187 // Give alias names to registers for calling conventions.
188 constexpr Register kReturnRegister0 = rax;
189 constexpr Register kReturnRegister1 = rdx;
190 constexpr Register kReturnRegister2 = r8;
191 constexpr Register kJSFunctionRegister = rdi;
192 constexpr Register kContextRegister = rsi;
193 constexpr Register kAllocateSizeRegister = rdx;
194 constexpr Register kSpeculationPoisonRegister = r12;
195 constexpr Register kInterpreterAccumulatorRegister = rax;
196 constexpr Register kInterpreterBytecodeOffsetRegister = r9;
197 constexpr Register kInterpreterBytecodeArrayRegister = r14;
198 constexpr Register kInterpreterDispatchTableRegister = r15;
199 
200 constexpr Register kJavaScriptCallArgCountRegister = rax;
201 constexpr Register kJavaScriptCallCodeStartRegister = rcx;
202 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
203 constexpr Register kJavaScriptCallNewTargetRegister = rdx;
204 constexpr Register kJavaScriptCallExtraArg1Register = rbx;
205 
206 constexpr Register kRuntimeCallFunctionRegister = rbx;
207 constexpr Register kRuntimeCallArgCountRegister = rax;
208 constexpr Register kRuntimeCallArgvRegister = r15;
209 constexpr Register kWasmInstanceRegister = rsi;
210 
211 // Default scratch register used by MacroAssembler (and other code that needs
212 // a spare register). The register isn't callee save, and not used by the
213 // function calling convention.
214 constexpr Register kScratchRegister = r10;
215 constexpr XMMRegister kScratchDoubleReg = xmm15;
216 constexpr Register kRootRegister = r13;  // callee save
217 
218 constexpr Register kOffHeapTrampolineRegister = kScratchRegister;
219 
220 constexpr DoubleRegister kFPReturnRegister0 = xmm0;
221 
222 }  // namespace internal
223 }  // namespace v8
224 
225 #endif  // V8_CODEGEN_X64_REGISTER_X64_H_
226