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 10namespace v8 { 11namespace 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 52const int kNumRequiredStackFrameSlots = 20; 53const int kStackFrameRASlot = 14; 54const int kStackFrameSPSlot = 15; 55const 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 67const int kNumRequiredStackFrameSlots = 24; 68const int kStackFrameRASlot = 14; 69const int kStackFrameSPSlot = 15; 70const 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 76const int kCalleeRegisterSaveAreaSize = 160; 77#elif V8_TARGET_ARCH_S390 78const int kCalleeRegisterSaveAreaSize = 96; 79#else 80const int kCalleeRegisterSaveAreaSize = 0; 81#endif 82 83enum RegisterCode { 84#define REGISTER_CODE(R) kRegCode_##R, 85 GENERAL_REGISTERS(REGISTER_CODE) 86#undef REGISTER_CODE 87 kRegAfterLast 88}; 89 90class 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; 102 explicit constexpr Register(int code) : RegisterBase(code) {} 103}; 104 105ASSERT_TRIVIALLY_COPYABLE(Register); 106static_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); 111GENERAL_REGISTERS(DEFINE_REGISTER) 112#undef DEFINE_REGISTER 113constexpr Register no_reg = Register::no_reg(); 114 115// Register aliases 116constexpr Register kRootRegister = r10; // Roots array pointer. 117constexpr Register cp = r13; // JavaScript context pointer. 118 119// Returns the number of padding slots needed for stack pointer alignment. 120constexpr int ArgumentPaddingSlots(int argument_count) { 121 // No argument padding required. 122 return 0; 123} 124 125constexpr AliasingKind kFPAliasing = AliasingKind::kOverlap; 126constexpr bool kSimdMaskRegisters = false; 127 128enum 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. 136class 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 152 explicit constexpr DoubleRegister(int code) : RegisterBase(code) {} 153}; 154 155ASSERT_TRIVIALLY_COPYABLE(DoubleRegister); 156static_assert(sizeof(DoubleRegister) <= sizeof(int), 157 "DoubleRegister can efficiently be passed by value"); 158 159using FloatRegister = DoubleRegister; 160 161// TODO(john.yan) Define SIMD registers. 162using Simd128Register = DoubleRegister; 163 164#define DEFINE_REGISTER(R) \ 165 constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R); 166DOUBLE_REGISTERS(DEFINE_REGISTER) 167#undef DEFINE_REGISTER 168constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); 169 170constexpr DoubleRegister kDoubleRegZero = d14; 171constexpr DoubleRegister kScratchDoubleReg = d13; 172 173Register ToRegister(int num); 174 175enum CRegisterCode { 176#define REGISTER_CODE(R) kCCode_##R, 177 C_REGISTERS(REGISTER_CODE) 178#undef REGISTER_CODE 179 kCAfterLast 180}; 181 182// Coprocessor register 183class CRegister : public RegisterBase<CRegister, kCAfterLast> { 184 friend class RegisterBase; 185 explicit constexpr CRegister(int code) : RegisterBase(code) {} 186}; 187 188constexpr CRegister no_creg = CRegister::no_reg(); 189#define DECLARE_C_REGISTER(R) \ 190 constexpr CRegister R = CRegister::from_code(kCCode_##R); 191C_REGISTERS(DECLARE_C_REGISTER) 192#undef DECLARE_C_REGISTER 193 194// Define {RegisterName} methods for the register types. 195DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS) 196DEFINE_REGISTER_NAMES(DoubleRegister, DOUBLE_REGISTERS) 197 198// Give alias names to registers for calling conventions. 199constexpr Register kReturnRegister0 = r2; 200constexpr Register kReturnRegister1 = r3; 201constexpr Register kReturnRegister2 = r4; 202constexpr Register kJSFunctionRegister = r3; 203constexpr Register kContextRegister = r13; 204constexpr Register kAllocateSizeRegister = r3; 205constexpr Register kInterpreterAccumulatorRegister = r2; 206constexpr Register kInterpreterBytecodeOffsetRegister = r6; 207constexpr Register kInterpreterBytecodeArrayRegister = r7; 208constexpr Register kInterpreterDispatchTableRegister = r8; 209 210constexpr Register kJavaScriptCallArgCountRegister = r2; 211constexpr Register kJavaScriptCallCodeStartRegister = r4; 212constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; 213constexpr Register kJavaScriptCallNewTargetRegister = r5; 214constexpr Register kJavaScriptCallExtraArg1Register = r4; 215 216constexpr Register kOffHeapTrampolineRegister = ip; 217constexpr Register kRuntimeCallFunctionRegister = r3; 218constexpr Register kRuntimeCallArgCountRegister = r2; 219constexpr Register kRuntimeCallArgvRegister = r4; 220constexpr Register kWasmInstanceRegister = r6; 221constexpr Register kWasmCompileLazyFuncIndexRegister = r7; 222 223constexpr DoubleRegister kFPReturnRegister0 = d0; 224 225} // namespace internal 226} // namespace v8 227 228#endif // V8_CODEGEN_S390_REGISTER_S390_H_ 229