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

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

Issue 1287383003: Re-reland: Remove register index/code indirection (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Updated to ToT Created 5 years, 3 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
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 24 matching lines...) Expand all
35 // A light-weight IA32 Assembler. 35 // A light-weight IA32 Assembler.
36 36
37 #ifndef V8_IA32_ASSEMBLER_IA32_H_ 37 #ifndef V8_IA32_ASSEMBLER_IA32_H_
38 #define V8_IA32_ASSEMBLER_IA32_H_ 38 #define V8_IA32_ASSEMBLER_IA32_H_
39 39
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 #include "src/isolate.h" 44 #include "src/isolate.h"
45 #include "src/utils.h"
45 46
46 namespace v8 { 47 namespace v8 {
47 namespace internal { 48 namespace internal {
48 49
50 #define GENERAL_REGISTERS(V) \
51 V(eax) \
52 V(ecx) \
53 V(edx) \
54 V(ebx) \
55 V(esp) \
56 V(ebp) \
57 V(esi) \
58 V(edi)
59
60 #define ALLOCATABLE_GENERAL_REGISTERS(V) \
61 V(eax) \
62 V(ecx) \
63 V(edx) \
64 V(ebx) \
65 V(esi) \
66 V(edi)
67
68 #define DOUBLE_REGISTERS(V) \
69 V(xmm0) \
70 V(xmm1) \
71 V(xmm2) \
72 V(xmm3) \
73 V(xmm4) \
74 V(xmm5) \
75 V(xmm6) \
76 V(xmm7)
77
78 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
79 V(xmm1) \
80 V(xmm2) \
81 V(xmm3) \
82 V(xmm4) \
83 V(xmm5) \
84 V(xmm6) \
85 V(xmm7)
86
49 // CPU Registers. 87 // CPU Registers.
50 // 88 //
51 // 1) We would prefer to use an enum, but enum values are assignment- 89 // 1) We would prefer to use an enum, but enum values are assignment-
52 // compatible with int, which has caused code-generation bugs. 90 // compatible with int, which has caused code-generation bugs.
53 // 91 //
54 // 2) We would prefer to use a class instead of a struct but we don't like 92 // 2) We would prefer to use a class instead of a struct but we don't like
55 // the register initialization to depend on the particular initialization 93 // the register initialization to depend on the particular initialization
56 // order (which appears to be different on OS X, Linux, and Windows for the 94 // order (which appears to be different on OS X, Linux, and Windows for the
57 // installed versions of C++ we tried). Using a struct permits C-style 95 // installed versions of C++ we tried). Using a struct permits C-style
58 // "initialization". Also, the Register objects cannot be const as this 96 // "initialization". Also, the Register objects cannot be const as this
59 // forces initialization stubs in MSVC, making us dependent on initialization 97 // forces initialization stubs in MSVC, making us dependent on initialization
60 // order. 98 // order.
61 // 99 //
62 // 3) By not using an enum, we are possibly preventing the compiler from 100 // 3) By not using an enum, we are possibly preventing the compiler from
63 // doing certain constant folds, which may significantly reduce the 101 // doing certain constant folds, which may significantly reduce the
64 // code generated for some assembly instructions (because they boil down 102 // code generated for some assembly instructions (because they boil down
65 // to a few constants). If this is a problem, we could change the code 103 // to a few constants). If this is a problem, we could change the code
66 // such that we use an enum in optimized mode, and the struct in debug 104 // such that we use an enum in optimized mode, and the struct in debug
67 // mode. This way we get the compile-time error checking in debug mode 105 // mode. This way we get the compile-time error checking in debug mode
68 // and best performance in optimized code. 106 // and best performance in optimized code.
69 // 107 //
70 struct Register { 108 struct Register {
71 static const int kMaxNumAllocatableRegisters = 6; 109 enum Code {
72 static int NumAllocatableRegisters() { 110 #define REGISTER_CODE(R) kCode_##R,
73 return kMaxNumAllocatableRegisters; 111 GENERAL_REGISTERS(REGISTER_CODE)
74 } 112 #undef REGISTER_CODE
75 static const int kNumRegisters = 8; 113 kAfterLast,
114 kCode_no_reg = -1
115 };
76 116
77 static inline const char* AllocationIndexToString(int index); 117 static const int kNumRegisters = Code::kAfterLast;
78
79 static inline int ToAllocationIndex(Register reg);
80
81 static inline Register FromAllocationIndex(int index);
82 118
83 static Register from_code(int code) { 119 static Register from_code(int code) {
84 DCHECK(code >= 0); 120 DCHECK(code >= 0);
85 DCHECK(code < kNumRegisters); 121 DCHECK(code < kNumRegisters);
86 Register r = { code }; 122 Register r = {code};
87 return r; 123 return r;
88 } 124 }
89 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 125 const char* ToString();
90 bool is(Register reg) const { return code_ == reg.code_; } 126 bool IsAllocatable() const;
91 // eax, ebx, ecx and edx are byte registers, the rest are not. 127 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
92 bool is_byte_register() const { return code_ <= 3; } 128 bool is(Register reg) const { return reg_code == reg.reg_code; }
93 int code() const { 129 int code() const {
94 DCHECK(is_valid()); 130 DCHECK(is_valid());
95 return code_; 131 return reg_code;
96 } 132 }
97 int bit() const { 133 int bit() const {
98 DCHECK(is_valid()); 134 DCHECK(is_valid());
99 return 1 << code_; 135 return 1 << reg_code;
100 } 136 }
101 137
138 bool is_byte_register() const { return reg_code <= 3; }
139
102 // Unfortunately we can't make this private in a struct. 140 // Unfortunately we can't make this private in a struct.
103 int code_; 141 int reg_code;
104 }; 142 };
105 143
106 const int kRegister_eax_Code = 0;
107 const int kRegister_ecx_Code = 1;
108 const int kRegister_edx_Code = 2;
109 const int kRegister_ebx_Code = 3;
110 const int kRegister_esp_Code = 4;
111 const int kRegister_ebp_Code = 5;
112 const int kRegister_esi_Code = 6;
113 const int kRegister_edi_Code = 7;
114 const int kRegister_no_reg_Code = -1;
115 144
116 const Register eax = { kRegister_eax_Code }; 145 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
117 const Register ecx = { kRegister_ecx_Code }; 146 GENERAL_REGISTERS(DECLARE_REGISTER)
118 const Register edx = { kRegister_edx_Code }; 147 #undef DECLARE_REGISTER
119 const Register ebx = { kRegister_ebx_Code }; 148 const Register no_reg = {Register::kCode_no_reg};
120 const Register esp = { kRegister_esp_Code };
121 const Register ebp = { kRegister_ebp_Code };
122 const Register esi = { kRegister_esi_Code };
123 const Register edi = { kRegister_edi_Code };
124 const Register no_reg = { kRegister_no_reg_Code };
125 149
126 150
127 inline const char* Register::AllocationIndexToString(int index) { 151 struct DoubleRegister {
128 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); 152 enum Code {
129 // This is the mapping of allocation indices to registers. 153 #define REGISTER_CODE(R) kCode_##R,
130 const char* const kNames[] = { "eax", "ecx", "edx", "ebx", "esi", "edi" }; 154 DOUBLE_REGISTERS(REGISTER_CODE)
131 return kNames[index]; 155 #undef REGISTER_CODE
132 } 156 kAfterLast,
157 kCode_no_reg = -1
158 };
133 159
160 static const int kMaxNumRegisters = Code::kAfterLast;
134 161
135 inline int Register::ToAllocationIndex(Register reg) { 162 static DoubleRegister from_code(int code) {
136 DCHECK(reg.is_valid() && !reg.is(esp) && !reg.is(ebp)); 163 DoubleRegister result = {code};
137 return (reg.code() >= 6) ? reg.code() - 2 : reg.code();
138 }
139
140
141 inline Register Register::FromAllocationIndex(int index) {
142 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
143 return (index >= 4) ? from_code(index + 2) : from_code(index);
144 }
145
146
147 struct XMMRegister {
148 static const int kMaxNumAllocatableRegisters = 7;
149 static const int kMaxNumRegisters = 8;
150 static int NumAllocatableRegisters() {
151 return kMaxNumAllocatableRegisters;
152 }
153
154 // TODO(turbofan): Proper support for float32.
155 static int NumAllocatableAliasedRegisters() {
156 return NumAllocatableRegisters();
157 }
158
159 static int ToAllocationIndex(XMMRegister reg) {
160 DCHECK(reg.code() != 0);
161 return reg.code() - 1;
162 }
163
164 static XMMRegister FromAllocationIndex(int index) {
165 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
166 return from_code(index + 1);
167 }
168
169 static XMMRegister from_code(int code) {
170 XMMRegister result = { code };
171 return result; 164 return result;
172 } 165 }
173 166
174 bool is_valid() const { 167 bool IsAllocatable() const;
175 return 0 <= code_ && code_ < kMaxNumRegisters; 168 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
176 }
177 169
178 int code() const { 170 int code() const {
179 DCHECK(is_valid()); 171 DCHECK(is_valid());
180 return code_; 172 return reg_code;
181 } 173 }
182 174
183 bool is(XMMRegister reg) const { return code_ == reg.code_; } 175 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
184 176
185 static const char* AllocationIndexToString(int index) { 177 const char* ToString();
186 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
187 const char* const names[] = {
188 "xmm1",
189 "xmm2",
190 "xmm3",
191 "xmm4",
192 "xmm5",
193 "xmm6",
194 "xmm7"
195 };
196 return names[index];
197 }
198 178
199 int code_; 179 int reg_code;
200 }; 180 };
201 181
182 #define DECLARE_REGISTER(R) \
183 const DoubleRegister R = {DoubleRegister::kCode_##R};
184 DOUBLE_REGISTERS(DECLARE_REGISTER)
185 #undef DECLARE_REGISTER
186 const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
202 187
203 typedef XMMRegister DoubleRegister; 188 typedef DoubleRegister XMMRegister;
204
205
206 const XMMRegister xmm0 = { 0 };
207 const XMMRegister xmm1 = { 1 };
208 const XMMRegister xmm2 = { 2 };
209 const XMMRegister xmm3 = { 3 };
210 const XMMRegister xmm4 = { 4 };
211 const XMMRegister xmm5 = { 5 };
212 const XMMRegister xmm6 = { 6 };
213 const XMMRegister xmm7 = { 7 };
214 const XMMRegister no_xmm_reg = { -1 };
215
216 189
217 enum Condition { 190 enum Condition {
218 // any value < 0 is considered no_condition 191 // any value < 0 is considered no_condition
219 no_condition = -1, 192 no_condition = -1,
220 193
221 overflow = 0, 194 overflow = 0,
222 no_overflow = 1, 195 no_overflow = 1,
223 below = 2, 196 below = 2,
224 above_equal = 3, 197 above_equal = 3,
225 equal = 4, 198 equal = 4,
(...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 private: 1564 private:
1592 Assembler* assembler_; 1565 Assembler* assembler_;
1593 #ifdef DEBUG 1566 #ifdef DEBUG
1594 int space_before_; 1567 int space_before_;
1595 #endif 1568 #endif
1596 }; 1569 };
1597 1570
1598 } } // namespace v8::internal 1571 } } // namespace v8::internal
1599 1572
1600 #endif // V8_IA32_ASSEMBLER_IA32_H_ 1573 #endif // V8_IA32_ASSEMBLER_IA32_H_
OLDNEW
« src/arm/deoptimizer-arm.cc ('K') | « src/hydrogen.cc ('k') | src/ia32/code-stubs-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698