// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_CODEGEN_IA32_REGISTER_IA32_H_ #define V8_CODEGEN_IA32_REGISTER_IA32_H_ #include "src/codegen/register.h" #include "src/codegen/reglist.h" namespace v8 { namespace internal { #define GENERAL_REGISTERS(V) \ V(eax) \ V(ecx) \ V(edx) \ V(ebx) \ V(esp) \ V(ebp) \ V(esi) \ V(edi) #define ALLOCATABLE_GENERAL_REGISTERS(V) \ V(eax) \ V(ecx) \ V(edx) \ V(esi) \ V(edi) #define DOUBLE_REGISTERS(V) \ V(xmm0) \ V(xmm1) \ V(xmm2) \ V(xmm3) \ V(xmm4) \ V(xmm5) \ V(xmm6) \ V(xmm7) #define FLOAT_REGISTERS DOUBLE_REGISTERS #define SIMD128_REGISTERS DOUBLE_REGISTERS #define ALLOCATABLE_DOUBLE_REGISTERS(V) \ V(xmm1) \ V(xmm2) \ V(xmm3) \ V(xmm4) \ V(xmm5) \ V(xmm6) \ V(xmm7) enum RegisterCode { #define REGISTER_CODE(R) kRegCode_##R, GENERAL_REGISTERS(REGISTER_CODE) #undef REGISTER_CODE kRegAfterLast }; class Register : public RegisterBase { public: bool is_byte_register() const { return reg_code_ <= 3; } private: friend class RegisterBase; explicit constexpr Register(int code) : RegisterBase(code) {} }; ASSERT_TRIVIALLY_COPYABLE(Register); static_assert(sizeof(Register) == sizeof(int), "Register can efficiently be passed by value"); #define DEFINE_REGISTER(R) \ constexpr Register R = Register::from_code(); GENERAL_REGISTERS(DEFINE_REGISTER) #undef DEFINE_REGISTER constexpr Register no_reg = Register::no_reg(); constexpr bool kPadArguments = false; constexpr bool kSimpleFPAliasing = true; constexpr bool kSimdMaskRegisters = false; enum DoubleCode { #define REGISTER_CODE(R) kDoubleCode_##R, DOUBLE_REGISTERS(REGISTER_CODE) #undef REGISTER_CODE kDoubleAfterLast }; class XMMRegister : public RegisterBase { friend class RegisterBase; explicit constexpr XMMRegister(int code) : RegisterBase(code) {} }; using FloatRegister = XMMRegister; using DoubleRegister = XMMRegister; using Simd128Register = XMMRegister; #define DEFINE_REGISTER(R) \ constexpr DoubleRegister R = DoubleRegister::from_code(); DOUBLE_REGISTERS(DEFINE_REGISTER) #undef DEFINE_REGISTER constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); // Note that the bit values must match those used in actual instruction encoding constexpr int kNumRegs = 8; // Caller-saved registers constexpr RegList kJSCallerSaved = Register::ListOf(); constexpr int kNumJSCallerSaved = 5; // Number of registers for which space is reserved in safepoints. constexpr int kNumSafepointRegisters = 8; // Define {RegisterName} methods for the register types. DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS) DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS) // Give alias names to registers for calling conventions. constexpr Register kReturnRegister0 = eax; constexpr Register kReturnRegister1 = edx; constexpr Register kReturnRegister2 = edi; constexpr Register kJSFunctionRegister = edi; constexpr Register kContextRegister = esi; constexpr Register kAllocateSizeRegister = edx; constexpr Register kInterpreterAccumulatorRegister = eax; constexpr Register kInterpreterBytecodeOffsetRegister = edx; constexpr Register kInterpreterBytecodeArrayRegister = edi; constexpr Register kInterpreterDispatchTableRegister = esi; constexpr Register kJavaScriptCallArgCountRegister = eax; constexpr Register kJavaScriptCallCodeStartRegister = ecx; constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; constexpr Register kJavaScriptCallNewTargetRegister = edx; // The ExtraArg1Register not part of the real JS calling convention and is // mostly there to simplify consistent interface descriptor definitions across // platforms. Note that on ia32 it aliases kJavaScriptCallCodeStartRegister. constexpr Register kJavaScriptCallExtraArg1Register = ecx; // The off-heap trampoline does not need a register on ia32 (it uses a // pc-relative call instead). constexpr Register kOffHeapTrampolineRegister = no_reg; constexpr Register kRuntimeCallFunctionRegister = edx; constexpr Register kRuntimeCallArgCountRegister = eax; constexpr Register kRuntimeCallArgvRegister = ecx; constexpr Register kWasmInstanceRegister = esi; constexpr Register kWasmCompileLazyFuncIndexRegister = edi; constexpr Register kRootRegister = ebx; // TODO(860429): Remove remaining poisoning infrastructure on ia32. constexpr Register kSpeculationPoisonRegister = no_reg; } // namespace internal } // namespace v8 #endif // V8_CODEGEN_IA32_REGISTER_IA32_H_