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