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