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

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