• 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_S390_REGISTER_S390_H_
6 #define V8_CODEGEN_S390_REGISTER_S390_H_
7 
8 #include "src/codegen/register.h"
9 #include "src/codegen/reglist.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // clang-format off
15 #define GENERAL_REGISTERS(V)                              \
16   V(r0)  V(r1)  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)  \
17   V(r8)  V(r9)  V(r10) V(fp) V(ip) V(r13) V(r14) V(sp)
18 
19 #define ALLOCATABLE_GENERAL_REGISTERS(V)                  \
20   V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)                \
21   V(r8)  V(r9)  V(r13)
22 
23 #define DOUBLE_REGISTERS(V)                               \
24   V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
25   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13) V(d14) V(d15)
26 
27 #define FLOAT_REGISTERS DOUBLE_REGISTERS
28 #define SIMD128_REGISTERS DOUBLE_REGISTERS
29 
30 #define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
31   V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)         \
32   V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d15) V(d0)
33 
34 #define C_REGISTERS(V)                                            \
35   V(cr0)  V(cr1)  V(cr2)  V(cr3)  V(cr4)  V(cr5)  V(cr6)  V(cr7)  \
36   V(cr8)  V(cr9)  V(cr10) V(cr11) V(cr12) V(cr15)
37 // clang-format on
38 
39 // Register list in load/store instructions
40 // Note that the bit values must match those used in actual instruction encoding
41 
42 // Caller-saved/arguments registers
43 const RegList kJSCallerSaved = 1 << 1 | 1 << 2 |  // r2  a1
44                                1 << 3 |           // r3  a2
45                                1 << 4 |           // r4  a3
46                                1 << 5;            // r5  a4
47 
48 const int kNumJSCallerSaved = 5;
49 
50 // Callee-saved registers preserved when switching from C to JavaScript
51 const RegList kCalleeSaved =
52     1 << 6 |   // r6 (argument passing in CEntryStub)
53                //    (HandleScope logic in MacroAssembler)
54     1 << 7 |   // r7 (argument passing in CEntryStub)
55                //    (HandleScope logic in MacroAssembler)
56     1 << 8 |   // r8 (argument passing in CEntryStub)
57                //    (HandleScope logic in MacroAssembler)
58     1 << 9 |   // r9 (HandleScope logic in MacroAssembler)
59     1 << 10 |  // r10 (Roots register in Javascript)
60     1 << 11 |  // r11 (fp in Javascript)
61     1 << 12 |  // r12 (ip in Javascript)
62     1 << 13;   // r13 (cp in Javascript)
63 // 1 << 15;   // r15 (sp in Javascript)
64 
65 const int kNumCalleeSaved = 8;
66 
67 const RegList kCallerSavedDoubles = 1 << 0 |  // d0
68                                     1 << 1 |  // d1
69                                     1 << 2 |  // d2
70                                     1 << 3 |  // d3
71                                     1 << 4 |  // d4
72                                     1 << 5 |  // d5
73                                     1 << 6 |  // d6
74                                     1 << 7;   // d7
75 
76 const int kNumCallerSavedDoubles = 8;
77 
78 const RegList kCalleeSavedDoubles = 1 << 8 |   // d8
79                                     1 << 9 |   // d9
80                                     1 << 10 |  // d10
81                                     1 << 11 |  // d11
82                                     1 << 12 |  // d12
83                                     1 << 13 |  // d12
84                                     1 << 14 |  // d12
85                                     1 << 15;   // d13
86 
87 const int kNumCalleeSavedDoubles = 8;
88 
89 // The following constants describe the stack frame linkage area as
90 // defined by the ABI.
91 
92 #if V8_TARGET_ARCH_S390X
93 // [0] Back Chain
94 // [1] Reserved for compiler use
95 // [2] GPR 2
96 // [3] GPR 3
97 // ...
98 // [15] GPR 15
99 // [16] FPR 0
100 // [17] FPR 2
101 // [18] FPR 4
102 // [19] FPR 6
103 const int kNumRequiredStackFrameSlots = 20;
104 const int kStackFrameRASlot = 14;
105 const int kStackFrameSPSlot = 15;
106 const int kStackFrameExtraParamSlot = 20;
107 #else
108 // [0] Back Chain
109 // [1] Reserved for compiler use
110 // [2] GPR 2
111 // [3] GPR 3
112 // ...
113 // [15] GPR 15
114 // [16..17] FPR 0
115 // [18..19] FPR 2
116 // [20..21] FPR 4
117 // [22..23] FPR 6
118 const int kNumRequiredStackFrameSlots = 24;
119 const int kStackFrameRASlot = 14;
120 const int kStackFrameSPSlot = 15;
121 const int kStackFrameExtraParamSlot = 24;
122 #endif
123 
124 // zLinux ABI requires caller frames to include sufficient space for
125 // callee preserved register save area.
126 #if V8_TARGET_ARCH_S390X
127 const int kCalleeRegisterSaveAreaSize = 160;
128 #elif V8_TARGET_ARCH_S390
129 const int kCalleeRegisterSaveAreaSize = 96;
130 #else
131 const int kCalleeRegisterSaveAreaSize = 0;
132 #endif
133 
134 enum RegisterCode {
135 #define REGISTER_CODE(R) kRegCode_##R,
136   GENERAL_REGISTERS(REGISTER_CODE)
137 #undef REGISTER_CODE
138       kRegAfterLast
139 };
140 
141 class Register : public RegisterBase<Register, kRegAfterLast> {
142  public:
143 #if V8_TARGET_LITTLE_ENDIAN
144   static constexpr int kMantissaOffset = 0;
145   static constexpr int kExponentOffset = 4;
146 #else
147   static constexpr int kMantissaOffset = 4;
148   static constexpr int kExponentOffset = 0;
149 #endif
150 
151  private:
152   friend class RegisterBase;
Register(int code)153   explicit constexpr Register(int code) : RegisterBase(code) {}
154 };
155 
156 ASSERT_TRIVIALLY_COPYABLE(Register);
157 static_assert(sizeof(Register) == sizeof(int),
158               "Register can efficiently be passed by value");
159 
160 #define DEFINE_REGISTER(R) \
161   constexpr Register R = Register::from_code(kRegCode_##R);
162 GENERAL_REGISTERS(DEFINE_REGISTER)
163 #undef DEFINE_REGISTER
164 constexpr Register no_reg = Register::no_reg();
165 
166 // Register aliases
167 constexpr Register kRootRegister = r10;  // Roots array pointer.
168 constexpr Register cp = r13;             // JavaScript context pointer.
169 
170 constexpr bool kPadArguments = false;
171 constexpr bool kSimpleFPAliasing = true;
172 constexpr bool kSimdMaskRegisters = false;
173 
174 enum DoubleRegisterCode {
175 #define REGISTER_CODE(R) kDoubleCode_##R,
176   DOUBLE_REGISTERS(REGISTER_CODE)
177 #undef REGISTER_CODE
178       kDoubleAfterLast
179 };
180 
181 // Double word VFP register.
182 class DoubleRegister : public RegisterBase<DoubleRegister, kDoubleAfterLast> {
183  public:
184   // A few double registers are reserved: one as a scratch register and one to
185   // hold 0.0, that does not fit in the immediate field of vmov instructions.
186   // d14: 0.0
187   // d15: scratch register.
188   static constexpr int kSizeInBytes = 8;
189 
190   // This function differs from kNumRegisters by returning the number of double
191   // registers supported by the current CPU, while kNumRegisters always returns
192   // 32.
193   inline static int SupportedRegisterCount();
194 
195  private:
196   friend class RegisterBase;
197 
DoubleRegister(int code)198   explicit constexpr DoubleRegister(int code) : RegisterBase(code) {}
199 };
200 
201 ASSERT_TRIVIALLY_COPYABLE(DoubleRegister);
202 static_assert(sizeof(DoubleRegister) == sizeof(int),
203               "DoubleRegister can efficiently be passed by value");
204 
205 using FloatRegister = DoubleRegister;
206 
207 // TODO(john.yan) Define SIMD registers.
208 using Simd128Register = DoubleRegister;
209 
210 #define DEFINE_REGISTER(R) \
211   constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
212 DOUBLE_REGISTERS(DEFINE_REGISTER)
213 #undef DEFINE_REGISTER
214 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
215 
216 constexpr DoubleRegister kDoubleRegZero = d14;
217 constexpr DoubleRegister kScratchDoubleReg = d13;
218 
219 Register ToRegister(int num);
220 
221 enum CRegisterCode {
222 #define REGISTER_CODE(R) kCCode_##R,
223   C_REGISTERS(REGISTER_CODE)
224 #undef REGISTER_CODE
225       kCAfterLast
226 };
227 
228 // Coprocessor register
229 class CRegister : public RegisterBase<CRegister, kCAfterLast> {
230   friend class RegisterBase;
CRegister(int code)231   explicit constexpr CRegister(int code) : RegisterBase(code) {}
232 };
233 
234 constexpr CRegister no_creg = CRegister::no_reg();
235 #define DECLARE_C_REGISTER(R) \
236   constexpr CRegister R = CRegister::from_code(kCCode_##R);
237 C_REGISTERS(DECLARE_C_REGISTER)
238 #undef DECLARE_C_REGISTER
239 
240 // Define {RegisterName} methods for the register types.
241 DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
242 DEFINE_REGISTER_NAMES(DoubleRegister, DOUBLE_REGISTERS)
243 
244 // Give alias names to registers for calling conventions.
245 constexpr Register kReturnRegister0 = r2;
246 constexpr Register kReturnRegister1 = r3;
247 constexpr Register kReturnRegister2 = r4;
248 constexpr Register kJSFunctionRegister = r3;
249 constexpr Register kContextRegister = r13;
250 constexpr Register kAllocateSizeRegister = r3;
251 constexpr Register kSpeculationPoisonRegister = r9;
252 constexpr Register kInterpreterAccumulatorRegister = r2;
253 constexpr Register kInterpreterBytecodeOffsetRegister = r6;
254 constexpr Register kInterpreterBytecodeArrayRegister = r7;
255 constexpr Register kInterpreterDispatchTableRegister = r8;
256 
257 constexpr Register kJavaScriptCallArgCountRegister = r2;
258 constexpr Register kJavaScriptCallCodeStartRegister = r4;
259 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
260 constexpr Register kJavaScriptCallNewTargetRegister = r5;
261 constexpr Register kJavaScriptCallExtraArg1Register = r4;
262 
263 constexpr Register kOffHeapTrampolineRegister = ip;
264 constexpr Register kRuntimeCallFunctionRegister = r3;
265 constexpr Register kRuntimeCallArgCountRegister = r2;
266 constexpr Register kRuntimeCallArgvRegister = r4;
267 constexpr Register kWasmInstanceRegister = r6;
268 constexpr Register kWasmCompileLazyFuncIndexRegister = r7;
269 
270 constexpr DoubleRegister kFPReturnRegister0 = d0;
271 
272 }  // namespace internal
273 }  // namespace v8
274 
275 #endif  // V8_CODEGEN_S390_REGISTER_S390_H_
276