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-base.h" 9 10 namespace v8 { 11 namespace internal { 12 13 #define GENERAL_REGISTERS(V) \ 14 V(eax) \ 15 V(ecx) \ 16 V(edx) \ 17 V(ebx) \ 18 V(esp) \ 19 V(ebp) \ 20 V(esi) \ 21 V(edi) 22 23 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ 24 V(eax) \ 25 V(ecx) \ 26 V(edx) \ 27 V(esi) \ 28 V(edi) 29 30 #define DOUBLE_REGISTERS(V) \ 31 V(xmm0) \ 32 V(xmm1) \ 33 V(xmm2) \ 34 V(xmm3) \ 35 V(xmm4) \ 36 V(xmm5) \ 37 V(xmm6) \ 38 V(xmm7) 39 40 #define FLOAT_REGISTERS DOUBLE_REGISTERS 41 #define SIMD128_REGISTERS DOUBLE_REGISTERS 42 43 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 44 V(xmm1) \ 45 V(xmm2) \ 46 V(xmm3) \ 47 V(xmm4) \ 48 V(xmm5) \ 49 V(xmm6) \ 50 V(xmm7) 51 52 enum RegisterCode { 53 #define REGISTER_CODE(R) kRegCode_##R, 54 GENERAL_REGISTERS(REGISTER_CODE) 55 #undef REGISTER_CODE 56 kRegAfterLast 57 }; 58 59 class Register : public RegisterBase<Register, kRegAfterLast> { 60 public: is_byte_register()61 bool is_byte_register() const { return code() <= 3; } 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 DEFINE_REGISTER(R) \ 73 constexpr Register R = Register::from_code(kRegCode_##R); 74 GENERAL_REGISTERS(DEFINE_REGISTER) 75 #undef DEFINE_REGISTER 76 constexpr Register no_reg = Register::no_reg(); 77 78 // Returns the number of padding slots needed for stack pointer alignment. ArgumentPaddingSlots(int argument_count)79constexpr int ArgumentPaddingSlots(int argument_count) { 80 // No argument padding required. 81 return 0; 82 } 83 84 constexpr AliasingKind kFPAliasing = AliasingKind::kOverlap; 85 constexpr bool kSimdMaskRegisters = false; 86 87 enum DoubleCode { 88 #define REGISTER_CODE(R) kDoubleCode_##R, 89 DOUBLE_REGISTERS(REGISTER_CODE) 90 #undef REGISTER_CODE 91 kDoubleAfterLast 92 }; 93 94 class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> { 95 friend class RegisterBase<XMMRegister, kDoubleAfterLast>; XMMRegister(int code)96 explicit constexpr XMMRegister(int code) : RegisterBase(code) {} 97 }; 98 99 using FloatRegister = XMMRegister; 100 101 using DoubleRegister = XMMRegister; 102 103 using Simd128Register = XMMRegister; 104 105 #define DEFINE_REGISTER(R) \ 106 constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R); 107 DOUBLE_REGISTERS(DEFINE_REGISTER) 108 #undef DEFINE_REGISTER 109 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); 110 111 // Note that the bit values must match those used in actual instruction encoding 112 constexpr int kNumRegs = 8; 113 114 // Define {RegisterName} methods for the register types. 115 DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS) 116 DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS) 117 118 // Give alias names to registers for calling conventions. 119 constexpr Register kReturnRegister0 = eax; 120 constexpr Register kReturnRegister1 = edx; 121 constexpr Register kReturnRegister2 = edi; 122 constexpr Register kJSFunctionRegister = edi; 123 constexpr Register kContextRegister = esi; 124 constexpr Register kAllocateSizeRegister = edx; 125 constexpr Register kInterpreterAccumulatorRegister = eax; 126 constexpr Register kInterpreterBytecodeOffsetRegister = edx; 127 constexpr Register kInterpreterBytecodeArrayRegister = edi; 128 constexpr Register kInterpreterDispatchTableRegister = esi; 129 130 constexpr Register kJavaScriptCallArgCountRegister = eax; 131 constexpr Register kJavaScriptCallCodeStartRegister = ecx; 132 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; 133 constexpr Register kJavaScriptCallNewTargetRegister = edx; 134 135 // The ExtraArg1Register not part of the real JS calling convention and is 136 // mostly there to simplify consistent interface descriptor definitions across 137 // platforms. Note that on ia32 it aliases kJavaScriptCallCodeStartRegister. 138 constexpr Register kJavaScriptCallExtraArg1Register = ecx; 139 140 // The off-heap trampoline does not need a register on ia32 (it uses a 141 // pc-relative call instead). 142 constexpr Register kOffHeapTrampolineRegister = no_reg; 143 144 constexpr Register kRuntimeCallFunctionRegister = edx; 145 constexpr Register kRuntimeCallArgCountRegister = eax; 146 constexpr Register kRuntimeCallArgvRegister = ecx; 147 constexpr Register kWasmInstanceRegister = esi; 148 constexpr Register kWasmCompileLazyFuncIndexRegister = edi; 149 150 constexpr Register kRootRegister = ebx; 151 152 constexpr DoubleRegister kFPReturnRegister0 = xmm1; // xmm0 isn't allocatable. 153 154 } // namespace internal 155 } // namespace v8 156 157 #endif // V8_CODEGEN_IA32_REGISTER_IA32_H_ 158