Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: src/x64/assembler-x64.h

Issue 1287383003: Re-reland: Remove register index/code indirection (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix MIPS tests again Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/register-configuration.cc ('k') | src/x64/assembler-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 29 matching lines...) Expand all
40 #include <deque> 40 #include <deque>
41 41
42 #include "src/assembler.h" 42 #include "src/assembler.h"
43 #include "src/compiler.h" 43 #include "src/compiler.h"
44 44
45 namespace v8 { 45 namespace v8 {
46 namespace internal { 46 namespace internal {
47 47
48 // Utility functions 48 // Utility functions
49 49
50 #define GENERAL_REGISTERS(V) \
51 V(rax) \
52 V(rcx) \
53 V(rdx) \
54 V(rbx) \
55 V(rsp) \
56 V(rbp) \
57 V(rsi) \
58 V(rdi) \
59 V(r8) \
60 V(r9) \
61 V(r10) \
62 V(r11) \
63 V(r12) \
64 V(r13) \
65 V(r14) \
66 V(r15)
67
68 #define ALLOCATABLE_GENERAL_REGISTERS(V) \
69 V(rax) \
70 V(rbx) \
71 V(rdx) \
72 V(rcx) \
73 V(rsi) \
74 V(rdi) \
75 V(r8) \
76 V(r9) \
77 V(r11) \
78 V(r12) \
79 V(r14) \
80 V(r15)
81
82
50 // CPU Registers. 83 // CPU Registers.
51 // 84 //
52 // 1) We would prefer to use an enum, but enum values are assignment- 85 // 1) We would prefer to use an enum, but enum values are assignment-
53 // compatible with int, which has caused code-generation bugs. 86 // compatible with int, which has caused code-generation bugs.
54 // 87 //
55 // 2) We would prefer to use a class instead of a struct but we don't like 88 // 2) We would prefer to use a class instead of a struct but we don't like
56 // the register initialization to depend on the particular initialization 89 // the register initialization to depend on the particular initialization
57 // order (which appears to be different on OS X, Linux, and Windows for the 90 // order (which appears to be different on OS X, Linux, and Windows for the
58 // installed versions of C++ we tried). Using a struct permits C-style 91 // installed versions of C++ we tried). Using a struct permits C-style
59 // "initialization". Also, the Register objects cannot be const as this 92 // "initialization". Also, the Register objects cannot be const as this
60 // forces initialization stubs in MSVC, making us dependent on initialization 93 // forces initialization stubs in MSVC, making us dependent on initialization
61 // order. 94 // order.
62 // 95 //
63 // 3) By not using an enum, we are possibly preventing the compiler from 96 // 3) By not using an enum, we are possibly preventing the compiler from
64 // doing certain constant folds, which may significantly reduce the 97 // doing certain constant folds, which may significantly reduce the
65 // code generated for some assembly instructions (because they boil down 98 // code generated for some assembly instructions (because they boil down
66 // to a few constants). If this is a problem, we could change the code 99 // to a few constants). If this is a problem, we could change the code
67 // such that we use an enum in optimized mode, and the struct in debug 100 // such that we use an enum in optimized mode, and the struct in debug
68 // mode. This way we get the compile-time error checking in debug mode 101 // mode. This way we get the compile-time error checking in debug mode
69 // and best performance in optimized code. 102 // and best performance in optimized code.
70 // 103 //
104 struct Register {
105 enum Code {
106 #define REGISTER_CODE(R) kCode_##R,
107 GENERAL_REGISTERS(REGISTER_CODE)
108 #undef REGISTER_CODE
109 kAfterLast,
110 kCode_no_reg = -1
111 };
71 112
72 struct Register { 113 static const int kNumRegisters = Code::kAfterLast;
73 // The non-allocatable registers are: 114
74 // rsp - stack pointer 115 static Register from_code(int code) {
75 // rbp - frame pointer 116 DCHECK(code >= 0);
76 // r10 - fixed scratch register 117 DCHECK(code < kNumRegisters);
77 // r13 - root register 118 Register r = {code};
78 static const int kMaxNumAllocatableRegisters = 12; 119 return r;
79 static int NumAllocatableRegisters() {
80 return kMaxNumAllocatableRegisters;
81 } 120 }
82 static const int kNumRegisters = 16; 121 const char* ToString();
83 122 bool IsAllocatable() const;
84 static int ToAllocationIndex(Register reg) { 123 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
85 return kAllocationIndexByRegisterCode[reg.code()]; 124 bool is(Register reg) const { return reg_code == reg.reg_code; }
125 int code() const {
126 DCHECK(is_valid());
127 return reg_code;
128 }
129 int bit() const {
130 DCHECK(is_valid());
131 return 1 << reg_code;
86 } 132 }
87 133
88 static Register FromAllocationIndex(int index) { 134 bool is_byte_register() const { return reg_code <= 3; }
89 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); 135 // Return the high bit of the register code as a 0 or 1. Used often
90 Register result = { kRegisterCodeByAllocationIndex[index] }; 136 // when constructing the REX prefix byte.
137 int high_bit() const { return reg_code >> 3; }
138 // Return the 3 low bits of the register code. Used when encoding registers
139 // in modR/M, SIB, and opcode bytes.
140 int low_bits() const { return reg_code & 0x7; }
141
142 // Unfortunately we can't make this private in a struct when initializing
143 // by assignment.
144 int reg_code;
145 };
146
147
148 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
149 GENERAL_REGISTERS(DECLARE_REGISTER)
150 #undef DECLARE_REGISTER
151 const Register no_reg = {Register::kCode_no_reg};
152
153
154 #ifdef _WIN64
155 // Windows calling convention
156 const Register arg_reg_1 = {Register::kCode_rcx};
157 const Register arg_reg_2 = {Register::kCode_rdx};
158 const Register arg_reg_3 = {Register::kCode_r8};
159 const Register arg_reg_4 = {Register::kCode_r9};
160 #else
161 // AMD64 calling convention
162 const Register arg_reg_1 = {Register::kCode_rdi};
163 const Register arg_reg_2 = {Register::kCode_rsi};
164 const Register arg_reg_3 = {Register::kCode_rdx};
165 const Register arg_reg_4 = {Register::kCode_rcx};
166 #endif // _WIN64
167
168
169 #define DOUBLE_REGISTERS(V) \
170 V(xmm0) \
171 V(xmm1) \
172 V(xmm2) \
173 V(xmm3) \
174 V(xmm4) \
175 V(xmm5) \
176 V(xmm6) \
177 V(xmm7) \
178 V(xmm8) \
179 V(xmm9) \
180 V(xmm10) \
181 V(xmm11) \
182 V(xmm12) \
183 V(xmm13) \
184 V(xmm14) \
185 V(xmm15)
186
187 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
188 V(xmm1) \
189 V(xmm2) \
190 V(xmm3) \
191 V(xmm4) \
192 V(xmm5) \
193 V(xmm6) \
194 V(xmm7) \
195 V(xmm8) \
196 V(xmm9) \
197 V(xmm10) \
198 V(xmm11) \
199 V(xmm12) \
200 V(xmm13) \
201 V(xmm14) \
202 V(xmm15)
203
204
205 struct DoubleRegister {
206 enum Code {
207 #define REGISTER_CODE(R) kCode_##R,
208 DOUBLE_REGISTERS(REGISTER_CODE)
209 #undef REGISTER_CODE
210 kAfterLast,
211 kCode_no_reg = -1
212 };
213
214 static const int kMaxNumRegisters = Code::kAfterLast;
215
216 static DoubleRegister from_code(int code) {
217 DoubleRegister result = {code};
91 return result; 218 return result;
92 } 219 }
93 220
94 static const char* AllocationIndexToString(int index) { 221 const char* ToString();
95 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); 222 bool IsAllocatable() const;
96 const char* const names[] = { 223 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
97 "rax", 224 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
98 "rbx",
99 "rdx",
100 "rcx",
101 "rsi",
102 "rdi",
103 "r8",
104 "r9",
105 "r11",
106 "r12",
107 "r14",
108 "r15"
109 };
110 return names[index];
111 }
112
113 static Register from_code(int code) {
114 Register r = { code };
115 return r;
116 }
117 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
118 bool is(Register reg) const { return code_ == reg.code_; }
119 // rax, rbx, rcx and rdx are byte registers, the rest are not.
120 bool is_byte_register() const { return code_ <= 3; }
121 int code() const { 225 int code() const {
122 DCHECK(is_valid()); 226 DCHECK(is_valid());
123 return code_; 227 return reg_code;
124 }
125 int bit() const {
126 return 1 << code_;
127 } 228 }
128 229
129 // Return the high bit of the register code as a 0 or 1. Used often 230 // Return the high bit of the register code as a 0 or 1. Used often
130 // when constructing the REX prefix byte. 231 // when constructing the REX prefix byte.
131 int high_bit() const { 232 int high_bit() const { return reg_code >> 3; }
132 return code_ >> 3;
133 }
134 // Return the 3 low bits of the register code. Used when encoding registers 233 // Return the 3 low bits of the register code. Used when encoding registers
135 // in modR/M, SIB, and opcode bytes. 234 // in modR/M, SIB, and opcode bytes.
136 int low_bits() const { 235 int low_bits() const { return reg_code & 0x7; }
137 return code_ & 0x7;
138 }
139 236
140 // Unfortunately we can't make this private in a struct when initializing 237 // Unfortunately we can't make this private in a struct when initializing
141 // by assignment. 238 // by assignment.
142 int code_; 239 int reg_code;
143
144 private:
145 static const int kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters];
146 static const int kAllocationIndexByRegisterCode[kNumRegisters];
147 }; 240 };
148 241
149 const int kRegister_rax_Code = 0;
150 const int kRegister_rcx_Code = 1;
151 const int kRegister_rdx_Code = 2;
152 const int kRegister_rbx_Code = 3;
153 const int kRegister_rsp_Code = 4;
154 const int kRegister_rbp_Code = 5;
155 const int kRegister_rsi_Code = 6;
156 const int kRegister_rdi_Code = 7;
157 const int kRegister_r8_Code = 8;
158 const int kRegister_r9_Code = 9;
159 const int kRegister_r10_Code = 10;
160 const int kRegister_r11_Code = 11;
161 const int kRegister_r12_Code = 12;
162 const int kRegister_r13_Code = 13;
163 const int kRegister_r14_Code = 14;
164 const int kRegister_r15_Code = 15;
165 const int kRegister_no_reg_Code = -1;
166 242
167 const Register rax = { kRegister_rax_Code }; 243 #define DECLARE_REGISTER(R) \
168 const Register rcx = { kRegister_rcx_Code }; 244 const DoubleRegister R = {DoubleRegister::kCode_##R};
169 const Register rdx = { kRegister_rdx_Code }; 245 DOUBLE_REGISTERS(DECLARE_REGISTER)
170 const Register rbx = { kRegister_rbx_Code }; 246 #undef DECLARE_REGISTER
171 const Register rsp = { kRegister_rsp_Code }; 247 const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
172 const Register rbp = { kRegister_rbp_Code };
173 const Register rsi = { kRegister_rsi_Code };
174 const Register rdi = { kRegister_rdi_Code };
175 const Register r8 = { kRegister_r8_Code };
176 const Register r9 = { kRegister_r9_Code };
177 const Register r10 = { kRegister_r10_Code };
178 const Register r11 = { kRegister_r11_Code };
179 const Register r12 = { kRegister_r12_Code };
180 const Register r13 = { kRegister_r13_Code };
181 const Register r14 = { kRegister_r14_Code };
182 const Register r15 = { kRegister_r15_Code };
183 const Register no_reg = { kRegister_no_reg_Code };
184
185 #ifdef _WIN64
186 // Windows calling convention
187 const Register arg_reg_1 = { kRegister_rcx_Code };
188 const Register arg_reg_2 = { kRegister_rdx_Code };
189 const Register arg_reg_3 = { kRegister_r8_Code };
190 const Register arg_reg_4 = { kRegister_r9_Code };
191 #else
192 // AMD64 calling convention
193 const Register arg_reg_1 = { kRegister_rdi_Code };
194 const Register arg_reg_2 = { kRegister_rsi_Code };
195 const Register arg_reg_3 = { kRegister_rdx_Code };
196 const Register arg_reg_4 = { kRegister_rcx_Code };
197 #endif // _WIN64
198
199 struct XMMRegister {
200 static const int kMaxNumRegisters = 16;
201 static const int kMaxNumAllocatableRegisters = 15;
202 static int NumAllocatableRegisters() {
203 return kMaxNumAllocatableRegisters;
204 }
205
206 // TODO(turbofan): Proper support for float32.
207 static int NumAllocatableAliasedRegisters() {
208 return NumAllocatableRegisters();
209 }
210
211 static int ToAllocationIndex(XMMRegister reg) {
212 DCHECK(reg.code() != 0);
213 return reg.code() - 1;
214 }
215
216 static XMMRegister FromAllocationIndex(int index) {
217 DCHECK(0 <= index && index < kMaxNumAllocatableRegisters);
218 XMMRegister result = { index + 1 };
219 return result;
220 }
221
222 static const char* AllocationIndexToString(int index) {
223 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
224 const char* const names[] = {
225 "xmm1",
226 "xmm2",
227 "xmm3",
228 "xmm4",
229 "xmm5",
230 "xmm6",
231 "xmm7",
232 "xmm8",
233 "xmm9",
234 "xmm10",
235 "xmm11",
236 "xmm12",
237 "xmm13",
238 "xmm14",
239 "xmm15"
240 };
241 return names[index];
242 }
243
244 static XMMRegister from_code(int code) {
245 DCHECK(code >= 0);
246 DCHECK(code < kMaxNumRegisters);
247 XMMRegister r = { code };
248 return r;
249 }
250 bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters; }
251 bool is(XMMRegister reg) const { return code_ == reg.code_; }
252 int code() const {
253 DCHECK(is_valid());
254 return code_;
255 }
256
257 // Return the high bit of the register code as a 0 or 1. Used often
258 // when constructing the REX prefix byte.
259 int high_bit() const {
260 return code_ >> 3;
261 }
262 // Return the 3 low bits of the register code. Used when encoding registers
263 // in modR/M, SIB, and opcode bytes.
264 int low_bits() const {
265 return code_ & 0x7;
266 }
267
268 int code_;
269 };
270
271 const XMMRegister xmm0 = { 0 };
272 const XMMRegister xmm1 = { 1 };
273 const XMMRegister xmm2 = { 2 };
274 const XMMRegister xmm3 = { 3 };
275 const XMMRegister xmm4 = { 4 };
276 const XMMRegister xmm5 = { 5 };
277 const XMMRegister xmm6 = { 6 };
278 const XMMRegister xmm7 = { 7 };
279 const XMMRegister xmm8 = { 8 };
280 const XMMRegister xmm9 = { 9 };
281 const XMMRegister xmm10 = { 10 };
282 const XMMRegister xmm11 = { 11 };
283 const XMMRegister xmm12 = { 12 };
284 const XMMRegister xmm13 = { 13 };
285 const XMMRegister xmm14 = { 14 };
286 const XMMRegister xmm15 = { 15 };
287 248
288 249
289 typedef XMMRegister DoubleRegister; 250 typedef DoubleRegister XMMRegister;
290
291 251
292 enum Condition { 252 enum Condition {
293 // any value < 0 is considered no_condition 253 // any value < 0 is considered no_condition
294 no_condition = -1, 254 no_condition = -1,
295 255
296 overflow = 0, 256 overflow = 0,
297 no_overflow = 1, 257 no_overflow = 1,
298 below = 2, 258 below = 2,
299 above_equal = 3, 259 above_equal = 3,
300 equal = 4, 260 equal = 4,
(...skipping 1844 matching lines...) Expand 10 before | Expand all | Expand 10 after
2145 Assembler* assembler_; 2105 Assembler* assembler_;
2146 #ifdef DEBUG 2106 #ifdef DEBUG
2147 int space_before_; 2107 int space_before_;
2148 #endif 2108 #endif
2149 }; 2109 };
2150 2110
2151 } // namespace internal 2111 } // namespace internal
2152 } // namespace v8 2112 } // namespace v8
2153 2113
2154 #endif // V8_X64_ASSEMBLER_X64_H_ 2114 #endif // V8_X64_ASSEMBLER_X64_H_
OLDNEW
« no previous file with comments | « src/register-configuration.cc ('k') | src/x64/assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698