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 // Returns the number of padding slots needed for stack pointer alignment.
ArgumentPaddingSlots(int argument_count)80 constexpr int ArgumentPaddingSlots(int argument_count) {
81   // No argument padding required.
82   return 0;
83 }
84 
85 constexpr bool kSimpleFPAliasing = true;
86 constexpr bool kSimdMaskRegisters = false;
87 
88 enum DoubleCode {
89 #define REGISTER_CODE(R) kDoubleCode_##R,
90   DOUBLE_REGISTERS(REGISTER_CODE)
91 #undef REGISTER_CODE
92       kDoubleAfterLast
93 };
94 
95 class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> {
96   friend class RegisterBase<XMMRegister, kDoubleAfterLast>;
XMMRegister(int code)97   explicit constexpr XMMRegister(int code) : RegisterBase(code) {}
98 };
99 
100 using FloatRegister = XMMRegister;
101 
102 using DoubleRegister = XMMRegister;
103 
104 using Simd128Register = XMMRegister;
105 
106 #define DEFINE_REGISTER(R) \
107   constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
108 DOUBLE_REGISTERS(DEFINE_REGISTER)
109 #undef DEFINE_REGISTER
110 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
111 
112 // Note that the bit values must match those used in actual instruction encoding
113 constexpr int kNumRegs = 8;
114 
115 // Caller-saved registers
116 constexpr RegList kJSCallerSaved =
117     Register::ListOf(eax, ecx, edx,
118                      ebx,   // used as caller-saved register in JavaScript code
119                      edi);  // callee function
120 
121 constexpr int kNumJSCallerSaved = 5;
122 
123 // Number of registers for which space is reserved in safepoints.
124 constexpr int kNumSafepointRegisters = 8;
125 
126 // Define {RegisterName} methods for the register types.
127 DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
128 DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS)
129 
130 // Give alias names to registers for calling conventions.
131 constexpr Register kReturnRegister0 = eax;
132 constexpr Register kReturnRegister1 = edx;
133 constexpr Register kReturnRegister2 = edi;
134 constexpr Register kJSFunctionRegister = edi;
135 constexpr Register kContextRegister = esi;
136 constexpr Register kAllocateSizeRegister = edx;
137 constexpr Register kInterpreterAccumulatorRegister = eax;
138 constexpr Register kInterpreterBytecodeOffsetRegister = edx;
139 constexpr Register kInterpreterBytecodeArrayRegister = edi;
140 constexpr Register kInterpreterDispatchTableRegister = esi;
141 
142 constexpr Register kJavaScriptCallArgCountRegister = eax;
143 constexpr Register kJavaScriptCallCodeStartRegister = ecx;
144 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
145 constexpr Register kJavaScriptCallNewTargetRegister = edx;
146 
147 // The ExtraArg1Register not part of the real JS calling convention and is
148 // mostly there to simplify consistent interface descriptor definitions across
149 // platforms. Note that on ia32 it aliases kJavaScriptCallCodeStartRegister.
150 constexpr Register kJavaScriptCallExtraArg1Register = ecx;
151 
152 // The off-heap trampoline does not need a register on ia32 (it uses a
153 // pc-relative call instead).
154 constexpr Register kOffHeapTrampolineRegister = no_reg;
155 
156 constexpr Register kRuntimeCallFunctionRegister = edx;
157 constexpr Register kRuntimeCallArgCountRegister = eax;
158 constexpr Register kRuntimeCallArgvRegister = ecx;
159 constexpr Register kWasmInstanceRegister = esi;
160 constexpr Register kWasmCompileLazyFuncIndexRegister = edi;
161 
162 constexpr Register kRootRegister = ebx;
163 
164 constexpr DoubleRegister kFPReturnRegister0 = xmm1;  // xmm0 isn't allocatable.
165 
166 }  // namespace internal
167 }  // namespace v8
168 
169 #endif  // V8_CODEGEN_IA32_REGISTER_IA32_H_
170