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_X64_REGISTER_X64_H_ 6 #define V8_CODEGEN_X64_REGISTER_X64_H_ 7 8 #include "src/codegen/register.h" 9 #include "src/codegen/reglist.h" 10 11 namespace v8 { 12 namespace internal { 13 14 #define GENERAL_REGISTERS(V) \ 15 V(rax) \ 16 V(rcx) \ 17 V(rdx) \ 18 V(rbx) \ 19 V(rsp) \ 20 V(rbp) \ 21 V(rsi) \ 22 V(rdi) \ 23 V(r8) \ 24 V(r9) \ 25 V(r10) \ 26 V(r11) \ 27 V(r12) \ 28 V(r13) \ 29 V(r14) \ 30 V(r15) 31 32 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ 33 V(rax) \ 34 V(rbx) \ 35 V(rdx) \ 36 V(rcx) \ 37 V(rsi) \ 38 V(rdi) \ 39 V(r8) \ 40 V(r9) \ 41 V(r11) \ 42 V(r12) \ 43 V(r14) \ 44 V(r15) 45 46 enum RegisterCode { 47 #define REGISTER_CODE(R) kRegCode_##R, 48 GENERAL_REGISTERS(REGISTER_CODE) 49 #undef REGISTER_CODE 50 kRegAfterLast 51 }; 52 53 class Register : public RegisterBase<Register, kRegAfterLast> { 54 public: is_byte_register()55 bool is_byte_register() const { return code() <= 3; } 56 // Return the high bit of the register code as a 0 or 1. Used often 57 // when constructing the REX prefix byte. high_bit()58 int high_bit() const { return code() >> 3; } 59 // Return the 3 low bits of the register code. Used when encoding registers 60 // in modR/M, SIB, and opcode bytes. low_bits()61 int low_bits() const { return code() & 0x7; } 62 63 private: 64 friend class RegisterBase<Register, kRegAfterLast>; Register(int code)65 explicit constexpr Register(int code) : RegisterBase(code) {} 66 }; 67 68 ASSERT_TRIVIALLY_COPYABLE(Register); 69 static_assert(sizeof(Register) == sizeof(int), 70 "Register can efficiently be passed by value"); 71 72 #define DECLARE_REGISTER(R) \ 73 constexpr Register R = Register::from_code(kRegCode_##R); 74 GENERAL_REGISTERS(DECLARE_REGISTER) 75 #undef DECLARE_REGISTER 76 constexpr Register no_reg = Register::no_reg(); 77 78 constexpr int kNumRegs = 16; 79 80 constexpr RegList kJSCallerSaved = 81 Register::ListOf(rax, rcx, rdx, 82 rbx, // used as a caller-saved register in JavaScript code 83 rdi); // callee function 84 85 constexpr int kNumJSCallerSaved = 5; 86 87 // Number of registers for which space is reserved in safepoints. 88 constexpr int kNumSafepointRegisters = 16; 89 90 #ifdef V8_TARGET_OS_WIN 91 // Windows calling convention 92 constexpr Register arg_reg_1 = rcx; 93 constexpr Register arg_reg_2 = rdx; 94 constexpr Register arg_reg_3 = r8; 95 constexpr Register arg_reg_4 = r9; 96 #else 97 // AMD64 calling convention 98 constexpr Register arg_reg_1 = rdi; 99 constexpr Register arg_reg_2 = rsi; 100 constexpr Register arg_reg_3 = rdx; 101 constexpr Register arg_reg_4 = rcx; 102 #endif // V8_TARGET_OS_WIN 103 104 #define DOUBLE_REGISTERS(V) \ 105 V(xmm0) \ 106 V(xmm1) \ 107 V(xmm2) \ 108 V(xmm3) \ 109 V(xmm4) \ 110 V(xmm5) \ 111 V(xmm6) \ 112 V(xmm7) \ 113 V(xmm8) \ 114 V(xmm9) \ 115 V(xmm10) \ 116 V(xmm11) \ 117 V(xmm12) \ 118 V(xmm13) \ 119 V(xmm14) \ 120 V(xmm15) 121 122 #define FLOAT_REGISTERS DOUBLE_REGISTERS 123 #define SIMD128_REGISTERS DOUBLE_REGISTERS 124 125 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 126 V(xmm0) \ 127 V(xmm1) \ 128 V(xmm2) \ 129 V(xmm3) \ 130 V(xmm4) \ 131 V(xmm5) \ 132 V(xmm6) \ 133 V(xmm7) \ 134 V(xmm8) \ 135 V(xmm9) \ 136 V(xmm10) \ 137 V(xmm11) \ 138 V(xmm12) \ 139 V(xmm13) \ 140 V(xmm14) 141 142 constexpr bool kPadArguments = false; 143 constexpr bool kSimpleFPAliasing = true; 144 constexpr bool kSimdMaskRegisters = false; 145 146 enum DoubleRegisterCode { 147 #define REGISTER_CODE(R) kDoubleCode_##R, 148 DOUBLE_REGISTERS(REGISTER_CODE) 149 #undef REGISTER_CODE 150 kDoubleAfterLast 151 }; 152 153 class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> { 154 public: 155 // Return the high bit of the register code as a 0 or 1. Used often 156 // when constructing the REX prefix byte. high_bit()157 int high_bit() const { return code() >> 3; } 158 // Return the 3 low bits of the register code. Used when encoding registers 159 // in modR/M, SIB, and opcode bytes. low_bits()160 int low_bits() const { return code() & 0x7; } 161 162 private: 163 friend class RegisterBase<XMMRegister, kDoubleAfterLast>; XMMRegister(int code)164 explicit constexpr XMMRegister(int code) : RegisterBase(code) {} 165 }; 166 167 ASSERT_TRIVIALLY_COPYABLE(XMMRegister); 168 static_assert(sizeof(XMMRegister) == sizeof(int), 169 "XMMRegister can efficiently be passed by value"); 170 171 using FloatRegister = XMMRegister; 172 173 using DoubleRegister = XMMRegister; 174 175 using Simd128Register = XMMRegister; 176 177 #define DECLARE_REGISTER(R) \ 178 constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R); 179 DOUBLE_REGISTERS(DECLARE_REGISTER) 180 #undef DECLARE_REGISTER 181 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); 182 183 // Define {RegisterName} methods for the register types. 184 DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS) 185 DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS) 186 187 // Give alias names to registers for calling conventions. 188 constexpr Register kReturnRegister0 = rax; 189 constexpr Register kReturnRegister1 = rdx; 190 constexpr Register kReturnRegister2 = r8; 191 constexpr Register kJSFunctionRegister = rdi; 192 constexpr Register kContextRegister = rsi; 193 constexpr Register kAllocateSizeRegister = rdx; 194 constexpr Register kSpeculationPoisonRegister = r12; 195 constexpr Register kInterpreterAccumulatorRegister = rax; 196 constexpr Register kInterpreterBytecodeOffsetRegister = r9; 197 constexpr Register kInterpreterBytecodeArrayRegister = r14; 198 constexpr Register kInterpreterDispatchTableRegister = r15; 199 200 constexpr Register kJavaScriptCallArgCountRegister = rax; 201 constexpr Register kJavaScriptCallCodeStartRegister = rcx; 202 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; 203 constexpr Register kJavaScriptCallNewTargetRegister = rdx; 204 constexpr Register kJavaScriptCallExtraArg1Register = rbx; 205 206 constexpr Register kRuntimeCallFunctionRegister = rbx; 207 constexpr Register kRuntimeCallArgCountRegister = rax; 208 constexpr Register kRuntimeCallArgvRegister = r15; 209 constexpr Register kWasmInstanceRegister = rsi; 210 211 // Default scratch register used by MacroAssembler (and other code that needs 212 // a spare register). The register isn't callee save, and not used by the 213 // function calling convention. 214 constexpr Register kScratchRegister = r10; 215 constexpr XMMRegister kScratchDoubleReg = xmm15; 216 constexpr Register kRootRegister = r13; // callee save 217 218 constexpr Register kOffHeapTrampolineRegister = kScratchRegister; 219 220 constexpr DoubleRegister kFPReturnRegister0 = xmm0; 221 222 } // namespace internal 223 } // namespace v8 224 225 #endif // V8_CODEGEN_X64_REGISTER_X64_H_ 226