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 10namespace v8 { 11namespace 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 52enum RegisterCode { 53#define REGISTER_CODE(R) kRegCode_##R, 54 GENERAL_REGISTERS(REGISTER_CODE) 55#undef REGISTER_CODE 56 kRegAfterLast 57}; 58 59class Register : public RegisterBase<Register, kRegAfterLast> { 60 public: 61 bool is_byte_register() const { return code() <= 3; } 62 63 private: 64 friend class RegisterBase<Register, kRegAfterLast>; 65 explicit constexpr Register(int code) : RegisterBase(code) {} 66}; 67 68ASSERT_TRIVIALLY_COPYABLE(Register); 69static_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); 74GENERAL_REGISTERS(DEFINE_REGISTER) 75#undef DEFINE_REGISTER 76constexpr Register no_reg = Register::no_reg(); 77 78// Returns the number of padding slots needed for stack pointer alignment. 79constexpr int ArgumentPaddingSlots(int argument_count) { 80 // No argument padding required. 81 return 0; 82} 83 84constexpr AliasingKind kFPAliasing = AliasingKind::kOverlap; 85constexpr bool kSimdMaskRegisters = false; 86 87enum DoubleCode { 88#define REGISTER_CODE(R) kDoubleCode_##R, 89 DOUBLE_REGISTERS(REGISTER_CODE) 90#undef REGISTER_CODE 91 kDoubleAfterLast 92}; 93 94class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> { 95 friend class RegisterBase<XMMRegister, kDoubleAfterLast>; 96 explicit constexpr XMMRegister(int code) : RegisterBase(code) {} 97}; 98 99using FloatRegister = XMMRegister; 100 101using DoubleRegister = XMMRegister; 102 103using Simd128Register = XMMRegister; 104 105#define DEFINE_REGISTER(R) \ 106 constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R); 107DOUBLE_REGISTERS(DEFINE_REGISTER) 108#undef DEFINE_REGISTER 109constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); 110 111// Note that the bit values must match those used in actual instruction encoding 112constexpr int kNumRegs = 8; 113 114// Define {RegisterName} methods for the register types. 115DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS) 116DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS) 117 118// Give alias names to registers for calling conventions. 119constexpr Register kReturnRegister0 = eax; 120constexpr Register kReturnRegister1 = edx; 121constexpr Register kReturnRegister2 = edi; 122constexpr Register kJSFunctionRegister = edi; 123constexpr Register kContextRegister = esi; 124constexpr Register kAllocateSizeRegister = edx; 125constexpr Register kInterpreterAccumulatorRegister = eax; 126constexpr Register kInterpreterBytecodeOffsetRegister = edx; 127constexpr Register kInterpreterBytecodeArrayRegister = edi; 128constexpr Register kInterpreterDispatchTableRegister = esi; 129 130constexpr Register kJavaScriptCallArgCountRegister = eax; 131constexpr Register kJavaScriptCallCodeStartRegister = ecx; 132constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; 133constexpr 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. 138constexpr Register kJavaScriptCallExtraArg1Register = ecx; 139 140// The off-heap trampoline does not need a register on ia32 (it uses a 141// pc-relative call instead). 142constexpr Register kOffHeapTrampolineRegister = no_reg; 143 144constexpr Register kRuntimeCallFunctionRegister = edx; 145constexpr Register kRuntimeCallArgCountRegister = eax; 146constexpr Register kRuntimeCallArgvRegister = ecx; 147constexpr Register kWasmInstanceRegister = esi; 148constexpr Register kWasmCompileLazyFuncIndexRegister = edi; 149 150constexpr Register kRootRegister = ebx; 151 152constexpr DoubleRegister kFPReturnRegister0 = xmm1; // xmm0 isn't allocatable. 153 154} // namespace internal 155} // namespace v8 156 157#endif // V8_CODEGEN_IA32_REGISTER_IA32_H_ 158