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

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

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