v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
register-x64.h
Go to the documentation of this file.
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
9
10namespace v8 {
11namespace internal {
12
13#define GENERAL_REGISTERS(V) \
14 V(rax) \
15 V(rcx) \
16 V(rdx) \
17 V(rbx) \
18 V(rsp) \
19 V(rbp) \
20 V(rsi) \
21 V(rdi) \
22 V(r8) \
23 V(r9) \
24 V(r10) \
25 V(r11) \
26 V(r12) \
27 V(r13) \
28 V(r14) \
29 V(r15)
30
31#define ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \
32 V(rax) \
33 V(rbx) \
34 V(rdx) \
35 V(rcx) \
36 V(rsi) \
37 V(rdi) \
38 V(r8) \
39 V(r9) \
40 V(r11) \
41 V(r12) \
42 V(r15)
43
44#ifdef V8_COMPRESS_POINTERS
45#define MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V)
46#else
47#define MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V) V(r14)
48#endif
49
50#define ALLOCATABLE_GENERAL_REGISTERS(V) \
51 ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \
52 MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V)
53
55#define REGISTER_CODE(R) kRegCode_##R,
57#undef REGISTER_CODE
59};
60
61class Register : public RegisterBase<Register, kRegAfterLast> {
62 public:
63 constexpr bool is_byte_register() const { return code() <= 3; }
64 // Return the high bit of the register code as a 0 or 1. Used often
65 // when constructing the REX prefix byte.
66 constexpr int high_bit() const { return code() >> 3; }
67 // Return the 3 low bits of the register code. Used when encoding registers
68 // in modR/M, SIB, and opcode bytes.
69 constexpr int low_bits() const { return code() & 0x7; }
70
71 private:
72 friend class RegisterBase<Register, kRegAfterLast>;
73 explicit constexpr Register(int code) : RegisterBase(code) {}
74};
75
76// Register that store tagged value. Tagged value is in compressed form when
77// pointer compression is enabled.
79 public:
81 Register reg() { return reg_; }
82
83 private:
85};
86
88static_assert(sizeof(Register) <= sizeof(int),
89 "Register can efficiently be passed by value");
90
91// Assign |source| value to |no_reg| and return the |source|'s previous value.
92template <typename RegT>
93inline RegT ReassignRegister(RegT& source) {
94 RegT result = source;
95 source = RegT::no_reg();
96 return result;
97}
98
99#define DECLARE_REGISTER(R) \
100 constexpr Register R = Register::from_code(kRegCode_##R);
102#undef DECLARE_REGISTER
103constexpr Register no_reg = Register::no_reg();
104
105constexpr int kNumRegs = 16;
106
107#ifdef V8_TARGET_OS_WIN
108// Windows calling convention
109constexpr Register kCArgRegs[] = {rcx, rdx, r8, r9};
110
111// The Windows 64 ABI always reserves spill slots on the stack for the four
112// register arguments even if the function takes fewer than four arguments.
113// These stack slots are sometimes called 'home space', sometimes 'shadow
114// store' in Microsoft documentation, see
115// https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention.
116constexpr int kWindowsHomeStackSlots = 4;
117#else
118// AMD64 calling convention
119constexpr Register kCArgRegs[] = {rdi, rsi, rdx, rcx, r8, r9};
120#endif // V8_TARGET_OS_WIN
121
123
124#define DOUBLE_REGISTERS(V) \
125 V(xmm0) \
126 V(xmm1) \
127 V(xmm2) \
128 V(xmm3) \
129 V(xmm4) \
130 V(xmm5) \
131 V(xmm6) \
132 V(xmm7) \
133 V(xmm8) \
134 V(xmm9) \
135 V(xmm10) \
136 V(xmm11) \
137 V(xmm12) \
138 V(xmm13) \
139 V(xmm14) \
140 V(xmm15)
141
142#define FLOAT_REGISTERS DOUBLE_REGISTERS
143#define SIMD128_REGISTERS DOUBLE_REGISTERS
144
145#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
146 V(xmm0) \
147 V(xmm1) \
148 V(xmm2) \
149 V(xmm3) \
150 V(xmm4) \
151 V(xmm5) \
152 V(xmm6) \
153 V(xmm7) \
154 V(xmm8) \
155 V(xmm9) \
156 V(xmm10) \
157 V(xmm11) \
158 V(xmm12) \
159 V(xmm13) \
160 V(xmm14)
161
162#define YMM_REGISTERS(V) \
163 V(ymm0) \
164 V(ymm1) \
165 V(ymm2) \
166 V(ymm3) \
167 V(ymm4) \
168 V(ymm5) \
169 V(ymm6) \
170 V(ymm7) \
171 V(ymm8) \
172 V(ymm9) \
173 V(ymm10) \
174 V(ymm11) \
175 V(ymm12) \
176 V(ymm13) \
177 V(ymm14) \
178 V(ymm15)
179
180// Returns the number of padding slots needed for stack pointer alignment.
181constexpr int ArgumentPaddingSlots(int argument_count) {
182 // No argument padding required.
183 return 0;
184}
185
187constexpr bool kSimdMaskRegisters = false;
188
190#define REGISTER_CODE(R) kDoubleCode_##R,
192#undef REGISTER_CODE
194};
195
197#define REGISTER_CODE(R) kYMMCode_##R,
199#undef REGISTER_CODE
202static_assert(static_cast<int>(kDoubleAfterLast) ==
203 static_cast<int>(kYMMAfterLast),
204 "The number of XMM register codes must match the number of YMM "
205 "register codes");
206
207class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> {
208 public:
209 // Return the high bit of the register code as a 0 or 1. Used often
210 // when constructing the REX prefix byte.
211 int high_bit() const { return code() >> 3; }
212 // Return the 3 low bits of the register code. Used when encoding registers
213 // in modR/M, SIB, and opcode bytes.
214 int low_bits() const { return code() & 0x7; }
215
216 protected:
218 explicit constexpr XMMRegister(int code) : RegisterBase(code) {}
219};
220
222static_assert(sizeof(XMMRegister) <= sizeof(int),
223 "XMMRegister can efficiently be passed by value");
224
225class YMMRegister : public XMMRegister {
226 public:
227 static constexpr YMMRegister from_code(int code) {
228 V8_ASSUME(code >= 0 && code < XMMRegister::kNumRegisters);
229 return YMMRegister(code);
230 }
231
232 static constexpr YMMRegister from_xmm(XMMRegister xmm) {
233 return YMMRegister(xmm.code());
234 }
235
236 private:
237 friend class XMMRegister;
238 explicit constexpr YMMRegister(int code) : XMMRegister(code) {}
239};
240
242static_assert(sizeof(YMMRegister) <= sizeof(int),
243 "YMMRegister can efficiently be passed by value");
244
246
248
250
252
253#define DECLARE_REGISTER(R) \
254 constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
256#undef DECLARE_REGISTER
258
259#define DECLARE_REGISTER(R) \
260 constexpr YMMRegister R = YMMRegister::from_code(kYMMCode_##R);
262#undef DECLARE_REGISTER
263
264// Define {RegisterName} methods for the register types.
268
269// Give alias names to registers for calling conventions.
270constexpr Register kStackPointerRegister = rsp;
271constexpr Register kReturnRegister0 = rax;
272constexpr Register kReturnRegister1 = rdx;
273constexpr Register kReturnRegister2 = r8;
274constexpr Register kJSFunctionRegister = rdi;
275constexpr Register kContextRegister = rsi;
276constexpr Register kAllocateSizeRegister = rdx;
281
288
291constexpr Register kRuntimeCallArgvRegister = r15;
292constexpr Register kWasmImplicitArgRegister = rsi;
294
295// Default scratch register used by MacroAssembler (and other code that needs
296// a spare register). The register isn't callee save, and not used by the
297// function calling convention.
299constexpr XMMRegister kScratchDoubleReg = xmm15;
301constexpr Register kRootRegister = r13; // callee save
302#ifdef V8_COMPRESS_POINTERS
303constexpr Register kPtrComprCageBaseRegister = r14; // callee save
304#else
306#endif
307
308constexpr DoubleRegister kFPReturnRegister0 = xmm0;
309
310} // namespace internal
311} // namespace v8
312
313#endif // V8_CODEGEN_X64_REGISTER_X64_H_
constexpr int low_bits() const
constexpr int high_bit() const
constexpr Register(int code)
constexpr bool is_byte_register() const
static constexpr Register no_reg()
constexpr XMMRegister(int code)
constexpr YMMRegister(int code)
static constexpr YMMRegister from_code(int code)
static constexpr YMMRegister from_xmm(XMMRegister xmm)
ZoneVector< RpoNumber > & result
InstructionOperand source
constexpr Register no_reg
constexpr Register kRootRegister
constexpr AliasingKind kFPAliasing
constexpr Register kRuntimeCallFunctionRegister
constexpr DoubleRegister kScratchDoubleReg
constexpr int kNumRegs
constexpr Register kRuntimeCallArgvRegister
constexpr Register kJavaScriptCallTargetRegister
constexpr DwVfpRegister no_dreg
constexpr Register kJavaScriptCallArgCountRegister
constexpr Register kInterpreterAccumulatorRegister
static const int kRegisterPassedArguments
constexpr DoubleRegister kFPReturnRegister0
constexpr Register kReturnRegister1
constexpr Register kReturnRegister0
constexpr Register kScratchRegister
constexpr Register kWasmImplicitArgRegister
constexpr Register kContextRegister
constexpr Register kRuntimeCallArgCountRegister
constexpr Register kInterpreterDispatchTableRegister
constexpr Register kAllocateSizeRegister
constexpr Register kWasmTrapHandlerFaultAddressRegister
constexpr Register kJavaScriptCallExtraArg1Register
constexpr Register kJavaScriptCallCodeStartRegister
constexpr Register kPtrComprCageBaseRegister
constexpr Register kReturnRegister2
Register ReassignRegister(Register &source)
constexpr Register kStackPointerRegister
constexpr int ArgumentPaddingSlots(int argument_count)
constexpr Register kCArgRegs[]
constexpr bool kSimdMaskRegisters
constexpr Register kJavaScriptCallDispatchHandleRegister
constexpr Register kInterpreterBytecodeOffsetRegister
constexpr Register kJavaScriptCallNewTargetRegister
constexpr Register kJSFunctionRegister
constexpr Register kInterpreterBytecodeArrayRegister
constexpr YMMRegister kScratchSimd256Reg
#define GENERAL_REGISTERS(V)
#define REGISTER_CODE(R)
#define DECLARE_REGISTER(R)
#define DOUBLE_REGISTERS(V)
#define DEFINE_REGISTER_NAMES(RegType, LIST)
#define YMM_REGISTERS(V)
#define ASSERT_TRIVIALLY_COPYABLE(T)
Definition macros.h:267
#define arraysize(array)
Definition macros.h:67
#define V8_ASSUME
Definition v8config.h:533