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