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_IA32_REGISTER_IA32_H_ 6 #define V8_CODEGEN_IA32_REGISTER_IA32_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(eax) \ 16 V(ecx) \ 17 V(edx) \ 18 V(ebx) \ 19 V(esp) \ 20 V(ebp) \ 21 V(esi) \ 22 V(edi) 23 24 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ 25 V(eax) \ 26 V(ecx) \ 27 V(edx) \ 28 V(esi) \ 29 V(edi) 30 31 #define DOUBLE_REGISTERS(V) \ 32 V(xmm0) \ 33 V(xmm1) \ 34 V(xmm2) \ 35 V(xmm3) \ 36 V(xmm4) \ 37 V(xmm5) \ 38 V(xmm6) \ 39 V(xmm7) 40 41 #define FLOAT_REGISTERS DOUBLE_REGISTERS 42 #define SIMD128_REGISTERS DOUBLE_REGISTERS 43 44 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 45 V(xmm1) \ 46 V(xmm2) \ 47 V(xmm3) \ 48 V(xmm4) \ 49 V(xmm5) \ 50 V(xmm6) \ 51 V(xmm7) 52 53 enum RegisterCode { 54 #define REGISTER_CODE(R) kRegCode_##R, 55 GENERAL_REGISTERS(REGISTER_CODE) 56 #undef REGISTER_CODE 57 kRegAfterLast 58 }; 59 60 class Register : public RegisterBase<Register, kRegAfterLast> { 61 public: is_byte_register()62 bool is_byte_register() const { return code() <= 3; } 63 64 private: 65 friend class RegisterBase<Register, kRegAfterLast>; Register(int code)66 explicit constexpr Register(int code) : RegisterBase(code) {} 67 }; 68 69 ASSERT_TRIVIALLY_COPYABLE(Register); 70 static_assert(sizeof(Register) == sizeof(int), 71 "Register can efficiently be passed by value"); 72 73 #define DEFINE_REGISTER(R) \ 74 constexpr Register R = Register::from_code(kRegCode_##R); 75 GENERAL_REGISTERS(DEFINE_REGISTER) 76 #undef DEFINE_REGISTER 77 constexpr Register no_reg = Register::no_reg(); 78 79 constexpr bool kPadArguments = false; 80 constexpr bool kSimpleFPAliasing = true; 81 constexpr bool kSimdMaskRegisters = false; 82 83 enum DoubleCode { 84 #define REGISTER_CODE(R) kDoubleCode_##R, 85 DOUBLE_REGISTERS(REGISTER_CODE) 86 #undef REGISTER_CODE 87 kDoubleAfterLast 88 }; 89 90 class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> { 91 friend class RegisterBase<XMMRegister, kDoubleAfterLast>; XMMRegister(int code)92 explicit constexpr XMMRegister(int code) : RegisterBase(code) {} 93 }; 94 95 using FloatRegister = XMMRegister; 96 97 using DoubleRegister = XMMRegister; 98 99 using Simd128Register = XMMRegister; 100 101 #define DEFINE_REGISTER(R) \ 102 constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R); 103 DOUBLE_REGISTERS(DEFINE_REGISTER) 104 #undef DEFINE_REGISTER 105 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); 106 107 // Note that the bit values must match those used in actual instruction encoding 108 constexpr int kNumRegs = 8; 109 110 // Caller-saved registers 111 constexpr RegList kJSCallerSaved = 112 Register::ListOf(eax, ecx, edx, 113 ebx, // used as caller-saved register in JavaScript code 114 edi); // callee function 115 116 constexpr int kNumJSCallerSaved = 5; 117 118 // Number of registers for which space is reserved in safepoints. 119 constexpr int kNumSafepointRegisters = 8; 120 121 // Define {RegisterName} methods for the register types. 122 DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS) 123 DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS) 124 125 // Give alias names to registers for calling conventions. 126 constexpr Register kReturnRegister0 = eax; 127 constexpr Register kReturnRegister1 = edx; 128 constexpr Register kReturnRegister2 = edi; 129 constexpr Register kJSFunctionRegister = edi; 130 constexpr Register kContextRegister = esi; 131 constexpr Register kAllocateSizeRegister = edx; 132 constexpr Register kInterpreterAccumulatorRegister = eax; 133 constexpr Register kInterpreterBytecodeOffsetRegister = edx; 134 constexpr Register kInterpreterBytecodeArrayRegister = edi; 135 constexpr Register kInterpreterDispatchTableRegister = esi; 136 137 constexpr Register kJavaScriptCallArgCountRegister = eax; 138 constexpr Register kJavaScriptCallCodeStartRegister = ecx; 139 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; 140 constexpr Register kJavaScriptCallNewTargetRegister = edx; 141 142 // The ExtraArg1Register not part of the real JS calling convention and is 143 // mostly there to simplify consistent interface descriptor definitions across 144 // platforms. Note that on ia32 it aliases kJavaScriptCallCodeStartRegister. 145 constexpr Register kJavaScriptCallExtraArg1Register = ecx; 146 147 // The off-heap trampoline does not need a register on ia32 (it uses a 148 // pc-relative call instead). 149 constexpr Register kOffHeapTrampolineRegister = no_reg; 150 151 constexpr Register kRuntimeCallFunctionRegister = edx; 152 constexpr Register kRuntimeCallArgCountRegister = eax; 153 constexpr Register kRuntimeCallArgvRegister = ecx; 154 constexpr Register kWasmInstanceRegister = esi; 155 constexpr Register kWasmCompileLazyFuncIndexRegister = edi; 156 157 constexpr Register kRootRegister = ebx; 158 159 // TODO(860429): Remove remaining poisoning infrastructure on ia32. 160 constexpr Register kSpeculationPoisonRegister = no_reg; 161 162 constexpr DoubleRegister kFPReturnRegister0 = xmm1; // xmm0 isn't allocatable. 163 164 } // namespace internal 165 } // namespace v8 166 167 #endif // V8_CODEGEN_IA32_REGISTER_IA32_H_ 168