v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
register-ppc.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_PPC_REGISTER_PPC_H_
6#define V8_CODEGEN_PPC_REGISTER_PPC_H_
7
9
10namespace v8 {
11namespace internal {
12
13// clang-format off
14#define GENERAL_REGISTERS(V) \
15 V(r0) V(sp) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \
16 V(r8) V(r9) V(r10) V(r11) V(ip) V(r13) V(r14) V(r15) \
17 V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \
18 V(r24) V(r25) V(r26) V(r27) V(r28) V(r29) V(r30) V(fp)
19
20#define ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \
21 V(r3) V(r4) V(r5) V(r6) V(r7) \
22 V(r8) V(r9) V(r10) V(r14) V(r15) \
23 V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \
24 V(r24) V(r25) V(r26) V(r30)
25
26#if V8_EMBEDDED_CONSTANT_POOL_BOOL
27#define MAYBE_ALLOCATEABLE_CONSTANT_POOL_REGISTER(V)
28#else
29#define MAYBE_ALLOCATEABLE_CONSTANT_POOL_REGISTER(V) V(r28)
30#endif
31
32#ifdef V8_COMPRESS_POINTERS
33#define MAYBE_ALLOCATABLE_CAGE_REGISTERS(V)
34#else
35#define MAYBE_ALLOCATABLE_CAGE_REGISTERS(V) V(r27)
36#endif
37
38#define ALLOCATABLE_GENERAL_REGISTERS(V) \
39 ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \
40 MAYBE_ALLOCATEABLE_CONSTANT_POOL_REGISTER(V) \
41 MAYBE_ALLOCATABLE_CAGE_REGISTERS(V)
42
43#define LOW_DOUBLE_REGISTERS(V) \
44 V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
45 V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15)
46
47#define NON_LOW_DOUBLE_REGISTERS(V) \
48 V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
49 V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
50
51#define DOUBLE_REGISTERS(V) \
52 LOW_DOUBLE_REGISTERS(V) NON_LOW_DOUBLE_REGISTERS(V)
53
54#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
55 V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
56 V(d8) V(d9) V(d10) V(d11) V(d12) V(d15) \
57 V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
58 V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
59
60#define FLOAT_REGISTERS DOUBLE_REGISTERS
61#define SIMD128_REGISTERS(V) \
62 V(v0) V(v1) V(v2) V(v3) V(v4) V(v5) V(v6) V(v7) \
63 V(v8) V(v9) V(v10) V(v11) V(v12) V(v13) V(v14) V(v15) \
64 V(v16) V(v17) V(v18) V(v19) V(v20) V(v21) V(v22) V(v23) \
65 V(v24) V(v25) V(v26) V(v27) V(v28) V(v29) V(v30) V(v31)
66
67#define ALLOCATABLE_SIMD128_REGISTERS(V) \
68 V(v0) V(v1) V(v2) V(v3) V(v4) V(v5) V(v6) V(v7) \
69 V(v8) V(v9) V(v10) V(v11) V(v12) \
70 V(v16) V(v17) V(v18) V(v19) V(v20) V(v21) V(v22) V(v23) \
71 V(v24) V(v25) V(v26) V(v27) V(v28) V(v29) V(v30) V(v31)
72
73#define C_REGISTERS(V) \
74 V(cr0) V(cr1) V(cr2) V(cr3) V(cr4) V(cr5) V(cr6) V(cr7) \
75 V(cr8) V(cr9) V(cr10) V(cr11) V(cr12) V(cr15)
76// clang-format on
77
78// The following constants describe the stack frame linkage area as
79// defined by the ABI. Note that kNumRequiredStackFrameSlots must
80// satisfy alignment requirements (rounding up if required).
81#if V8_TARGET_ARCH_PPC64 && \
82 (V8_TARGET_LITTLE_ENDIAN || \
83 (defined(_CALL_ELF) && _CALL_ELF == 2)) // ELFv2 ABI
84// [0] back chain
85// [1] condition register save area
86// [2] link register save area
87// [3] TOC save area
88// [4] Parameter1 save area
89// ...
90// [11] Parameter8 save area
91// [12] Parameter9 slot (if necessary)
92// ...
93const int kNumRequiredStackFrameSlots = 12;
94const int kStackFrameLRSlot = 2;
95const int kStackFrameExtraParamSlot = 12;
96#else // AIX
97// [0] back chain
98// [1] condition register save area
99// [2] link register save area
100// [3] reserved for compiler
101// [4] reserved by binder
102// [5] TOC save area
103// [6] Parameter1 save area
104// ...
105// [13] Parameter8 save area
106// [14] Parameter9 slot (if necessary)
107// ...
109const int kStackFrameLRSlot = 2;
111#endif
112
114#define REGISTER_CODE(R) kRegCode_##R,
116#undef REGISTER_CODE
118};
119
120class Register : public RegisterBase<Register, kRegAfterLast> {
121 public:
122#if V8_TARGET_LITTLE_ENDIAN
123 static constexpr int kMantissaOffset = 0;
124 static constexpr int kExponentOffset = 4;
125#else
126 static constexpr int kMantissaOffset = 4;
127 static constexpr int kExponentOffset = 0;
128#endif
129
130 private:
131 friend class RegisterBase;
132 explicit constexpr Register(int code) : RegisterBase(code) {}
133};
134
136static_assert(sizeof(Register) <= sizeof(int),
137 "Register can efficiently be passed by value");
138
139// Assign |source| value to |no_reg| and return the |source|'s previous value.
140inline Register ReassignRegister(Register& source) {
141 Register result = source;
142 source = Register::no_reg();
143 return result;
144}
145
146#define DEFINE_REGISTER(R) \
147 constexpr Register R = Register::from_code(kRegCode_##R);
149#undef DEFINE_REGISTER
150constexpr Register no_reg = Register::no_reg();
151
152// Aliases
153constexpr Register kConstantPoolRegister = r28; // Constant pool.
154constexpr Register kRootRegister = r29; // Roots array pointer.
155constexpr Register cp = r30; // JavaScript context pointer.
156#ifdef V8_COMPRESS_POINTERS
157constexpr Register kPtrComprCageBaseRegister = r27; // callee save
158#else
160#endif
161
162// PPC64 calling convention
163constexpr Register kCArgRegs[] = {r3, r4, r5, r6, r7, r8, r9, r10};
165
166// Returns the number of padding slots needed for stack pointer alignment.
167constexpr int ArgumentPaddingSlots(int argument_count) {
168 // No argument padding required.
169 return 0;
170}
171
173constexpr bool kSimdMaskRegisters = false;
174
175// | | 0
176// | | 1
177// | | 2
178// | | ...
179// | | 31
180// VSX |
181// | | 32
182// | | 33
183// | VMX | 34
184// | | ...
185// | | 63
186//
187// VSX registers (0 to 63) can be used by VSX vector instructions, which are
188// mainly focused on Floating Point arithmetic. They do have few Integer
189// Instructions such as logical operations, merge and select. The main Simd
190// integer instructions such as add/sub/mul/ extract_lane/replace_lane,
191// comparisons etc. are only available with VMX instructions and can only access
192// the VMX set of vector registers (which is a subset of VSX registers). So to
193// assure access to all Simd instructions in V8 and avoid moving data between
194// registers, we are only using the upper 32 registers (VMX set) for Simd
195// operations and only use the lower set for scalar (non simd) floating point
196// operations which makes our Simd register set separate from Floating Point
197// ones.
199#define REGISTER_CODE(R) kSimd128Code_##R,
201#undef REGISTER_CODE
203};
204
205// Simd128 register.
207 : public RegisterBase<Simd128Register, kSimd128AfterLast> {
208 friend class RegisterBase;
209
210 public:
211 explicit constexpr Simd128Register(int code) : RegisterBase(code) {}
212};
214static_assert(sizeof(Simd128Register) <= sizeof(int),
215 "Simd128Register can efficiently be passed by value");
216
218#define REGISTER_CODE(R) kDoubleCode_##R,
220#undef REGISTER_CODE
222};
223
224// Double word FP register.
225class DoubleRegister : public RegisterBase<DoubleRegister, kDoubleAfterLast> {
226 public:
227 // A few double registers are reserved: one as a scratch register and one to
228 // hold 0.0, that does not fit in the immediate field of vmov instructions.
229 // d14: 0.0
230 // d15: scratch register.
231 static constexpr int kSizeInBytes = 8;
232
233 // This function differs from kNumRegisters by returning the number of double
234 // registers supported by the current CPU, while kNumRegisters always returns
235 // 32.
236 inline static int SupportedRegisterCount();
237
238 // On PPC Simdi128 registers are separate from Double registers.
239 // More details can be found here: https://crrev.com/c/2718472 . This is a
240 // helper function to cast a Double to a Simdi128 register.
242 int reg_code = code();
243 V8_ASSUME(reg_code >= 0 && reg_code < kSimd128AfterLast);
244 return Simd128Register(reg_code);
245 }
246
247 private:
248 friend class RegisterBase;
249 explicit constexpr DoubleRegister(int code) : RegisterBase(code) {}
250};
251
253static_assert(sizeof(DoubleRegister) <= sizeof(int),
254 "DoubleRegister can efficiently be passed by value");
255
257
258#define DECLARE_SIMD128_REGISTER(R) \
259 constexpr Simd128Register R = Simd128Register::from_code(kSimd128Code_##R);
261#undef DECLARE_SIMD128_REGISTER
263
264#define DEFINE_REGISTER(R) \
265 constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
267#undef DEFINE_REGISTER
269
272constexpr DoubleRegister kDoubleRegZero = d14;
273constexpr DoubleRegister kScratchDoubleReg = d13;
274constexpr Simd128Register kSimd128RegZero = v14;
277
278Register ToRegister(int num);
279
281#define REGISTER_CODE(R) kCCode_##R,
283#undef REGISTER_CODE
285};
286
287// Coprocessor register
288class CRegister : public RegisterBase<CRegister, kCAfterLast> {
289 friend class RegisterBase;
290 explicit constexpr CRegister(int code) : RegisterBase(code) {}
291};
292
293constexpr CRegister no_creg = CRegister::no_reg();
294#define DECLARE_C_REGISTER(R) \
295 constexpr CRegister R = CRegister::from_code(kCCode_##R);
297#undef DECLARE_C_REGISTER
298
299// Define {RegisterName} methods for the register types.
303
304// Give alias names to registers for calling conventions.
305constexpr Register kReturnRegister0 = r3;
306constexpr Register kReturnRegister1 = r4;
307constexpr Register kReturnRegister2 = r5;
308constexpr Register kJSFunctionRegister = r4;
309constexpr Register kContextRegister = r30;
310constexpr Register kAllocateSizeRegister = r4;
311constexpr Register kInterpreterAccumulatorRegister = r3;
312constexpr Register kInterpreterBytecodeOffsetRegister = r15;
313constexpr Register kInterpreterBytecodeArrayRegister = r16;
314constexpr Register kInterpreterDispatchTableRegister = r17;
315
316constexpr Register kJavaScriptCallArgCountRegister = r3;
317constexpr Register kJavaScriptCallCodeStartRegister = r5;
319constexpr Register kJavaScriptCallNewTargetRegister = r6;
320constexpr Register kJavaScriptCallExtraArg1Register = r5;
321// DispatchHandle is only needed for the sandbox which is not available on
322// ppc64.
324
325constexpr Register kRuntimeCallFunctionRegister = r4;
326constexpr Register kRuntimeCallArgCountRegister = r3;
327constexpr Register kRuntimeCallArgvRegister = r5;
328constexpr Register kWasmImplicitArgRegister = r10;
329constexpr Register kWasmCompileLazyFuncIndexRegister = r15;
330
332
333} // namespace internal
334} // namespace v8
335
336#endif // V8_CODEGEN_PPC_REGISTER_PPC_H_
constexpr CRegister(int code)
constexpr DoubleRegister(int code)
static constexpr int kSizeInBytes
Simd128Register toSimd() const
static constexpr int kMantissaOffset
friend class RegisterBase
constexpr Register(int code)
static constexpr int kExponentOffset
static constexpr Register no_reg()
constexpr Simd128Register(int code)
ZoneVector< RpoNumber > & result
InstructionOperand source
constexpr Register no_reg
constexpr Register kRootRegister
const int kStackFrameLRSlot
constexpr AliasingKind kFPAliasing
constexpr Register kRuntimeCallFunctionRegister
const int kNumRequiredStackFrameSlots
DwVfpRegister DoubleRegister
constexpr Simd128Register kSimd128RegZero
constexpr DoubleRegister kScratchDoubleReg
constexpr Register kRuntimeCallArgvRegister
constexpr Simd128Register kScratchSimd128Reg
constexpr Register kJavaScriptCallTargetRegister
const int kStackFrameExtraParamSlot
constexpr DwVfpRegister no_dreg
constexpr LowDwVfpRegister kLastCalleeSavedDoubleReg
constexpr Register kJavaScriptCallArgCountRegister
constexpr Register kInterpreterAccumulatorRegister
static const int kRegisterPassedArguments
constexpr Register kConstantPoolRegister
QwNeonRegister Simd128Register
constexpr DoubleRegister kFPReturnRegister0
constexpr Register kReturnRegister1
constexpr Register kReturnRegister0
constexpr Register kWasmImplicitArgRegister
constexpr Register kContextRegister
constexpr Register kRuntimeCallArgCountRegister
constexpr Register kInterpreterDispatchTableRegister
constexpr Register kAllocateSizeRegister
constexpr LowDwVfpRegister kDoubleRegZero
constexpr Register kJavaScriptCallExtraArg1Register
Register ToRegister(int num)
constexpr Register kJavaScriptCallCodeStartRegister
constexpr Register kPtrComprCageBaseRegister
constexpr Register kReturnRegister2
Register ReassignRegister(Register &source)
constexpr CRegister no_creg
constexpr Register kWasmCompileLazyFuncIndexRegister
constexpr LowDwVfpRegister kFirstCalleeSavedDoubleReg
constexpr int ArgumentPaddingSlots(int argument_count)
constexpr Register cp
constexpr Register kCArgRegs[]
constexpr bool kSimdMaskRegisters
constexpr Register kJavaScriptCallDispatchHandleRegister
constexpr Simd128Register kScratchSimd128Reg2
const Simd128Register no_simdreg
constexpr Register kInterpreterBytecodeOffsetRegister
constexpr Register kJavaScriptCallNewTargetRegister
constexpr Register kJSFunctionRegister
constexpr Register kInterpreterBytecodeArrayRegister
#define DEFINE_REGISTER(register_class, name,...)
#define GENERAL_REGISTERS(V)
#define SIMD128_REGISTERS(V)
#define C_REGISTERS(V)
#define REGISTER_CODE(R)
#define DECLARE_C_REGISTER(R)
#define DOUBLE_REGISTERS(V)
#define DECLARE_SIMD128_REGISTER(R)
#define DEFINE_REGISTER_NAMES(RegType, LIST)
#define ASSERT_TRIVIALLY_COPYABLE(T)
Definition macros.h:267
#define arraysize(array)
Definition macros.h:67
#define V8_ASSUME
Definition v8config.h:533