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

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

Issue 1410393004: X87: Re-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/crankshaft/x87/lithium-x87.cc ('k') | src/x87/code-stubs-x87.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 23 matching lines...) Expand all
34 34
35 // A light-weight IA32 Assembler. 35 // A light-weight IA32 Assembler.
36 36
37 #ifndef V8_X87_ASSEMBLER_X87_H_ 37 #ifndef V8_X87_ASSEMBLER_X87_H_
38 #define V8_X87_ASSEMBLER_X87_H_ 38 #define V8_X87_ASSEMBLER_X87_H_
39 39
40 #include <deque> 40 #include <deque>
41 41
42 #include "src/assembler.h" 42 #include "src/assembler.h"
43 #include "src/isolate.h" 43 #include "src/isolate.h"
44 #include "src/utils.h"
44 45
45 namespace v8 { 46 namespace v8 {
46 namespace internal { 47 namespace internal {
47 48
49 #define GENERAL_REGISTERS(V) \
50 V(eax) \
51 V(ecx) \
52 V(edx) \
53 V(ebx) \
54 V(esp) \
55 V(ebp) \
56 V(esi) \
57 V(edi)
58
59 #define ALLOCATABLE_GENERAL_REGISTERS(V) \
60 V(eax) \
61 V(ecx) \
62 V(edx) \
63 V(ebx) \
64 V(esi) \
65 V(edi)
66
67 #define DOUBLE_REGISTERS(V) \
68 V(stX_0) \
69 V(stX_1) \
70 V(stX_2) \
71 V(stX_3) \
72 V(stX_4) \
73 V(stX_5) \
74 V(stX_6) \
75 V(stX_7)
76
77 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
78 V(stX_0) \
79 V(stX_1) \
80 V(stX_2) \
81 V(stX_3) \
82 V(stX_4) \
83 V(stX_5)
84
48 // CPU Registers. 85 // CPU Registers.
49 // 86 //
50 // 1) We would prefer to use an enum, but enum values are assignment- 87 // 1) We would prefer to use an enum, but enum values are assignment-
51 // compatible with int, which has caused code-generation bugs. 88 // compatible with int, which has caused code-generation bugs.
52 // 89 //
53 // 2) We would prefer to use a class instead of a struct but we don't like 90 // 2) We would prefer to use a class instead of a struct but we don't like
54 // the register initialization to depend on the particular initialization 91 // the register initialization to depend on the particular initialization
55 // order (which appears to be different on OS X, Linux, and Windows for the 92 // order (which appears to be different on OS X, Linux, and Windows for the
56 // installed versions of C++ we tried). Using a struct permits C-style 93 // installed versions of C++ we tried). Using a struct permits C-style
57 // "initialization". Also, the Register objects cannot be const as this 94 // "initialization". Also, the Register objects cannot be const as this
58 // forces initialization stubs in MSVC, making us dependent on initialization 95 // forces initialization stubs in MSVC, making us dependent on initialization
59 // order. 96 // order.
60 // 97 //
61 // 3) By not using an enum, we are possibly preventing the compiler from 98 // 3) By not using an enum, we are possibly preventing the compiler from
62 // doing certain constant folds, which may significantly reduce the 99 // doing certain constant folds, which may significantly reduce the
63 // code generated for some assembly instructions (because they boil down 100 // code generated for some assembly instructions (because they boil down
64 // to a few constants). If this is a problem, we could change the code 101 // to a few constants). If this is a problem, we could change the code
65 // such that we use an enum in optimized mode, and the struct in debug 102 // such that we use an enum in optimized mode, and the struct in debug
66 // mode. This way we get the compile-time error checking in debug mode 103 // mode. This way we get the compile-time error checking in debug mode
67 // and best performance in optimized code. 104 // and best performance in optimized code.
68 // 105 //
69 struct Register { 106 struct Register {
70 static const int kMaxNumAllocatableRegisters = 6; 107 enum Code {
71 static int NumAllocatableRegisters() { 108 #define REGISTER_CODE(R) kCode_##R,
72 return kMaxNumAllocatableRegisters; 109 GENERAL_REGISTERS(REGISTER_CODE)
73 } 110 #undef REGISTER_CODE
74 static const int kNumRegisters = 8; 111 kAfterLast,
112 kCode_no_reg = -1
113 };
75 114
76 static inline const char* AllocationIndexToString(int index); 115 static const int kNumRegisters = Code::kAfterLast;
77 116
78 static Register from_code(int code) { 117 static Register from_code(int code) {
79 DCHECK(code >= 0); 118 DCHECK(code >= 0);
80 DCHECK(code < kNumRegisters); 119 DCHECK(code < kNumRegisters);
81 Register r = { code }; 120 Register r = {code};
82 return r; 121 return r;
83 } 122 }
84 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } 123 const char* ToString();
85 bool is(Register reg) const { return code_ == reg.code_; } 124 bool IsAllocatable() const;
86 // eax, ebx, ecx and edx are byte registers, the rest are not. 125 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
87 bool is_byte_register() const { return code_ <= 3; } 126 bool is(Register reg) const { return reg_code == reg.reg_code; }
88 int code() const { 127 int code() const {
89 DCHECK(is_valid()); 128 DCHECK(is_valid());
90 return code_; 129 return reg_code;
91 } 130 }
92 int bit() const { 131 int bit() const {
93 DCHECK(is_valid()); 132 DCHECK(is_valid());
94 return 1 << code_; 133 return 1 << reg_code;
95 } 134 }
96 135
136 bool is_byte_register() const { return reg_code <= 3; }
137
97 // Unfortunately we can't make this private in a struct. 138 // Unfortunately we can't make this private in a struct.
98 int code_; 139 int reg_code;
99 }; 140 };
100 141
101 const int kRegister_eax_Code = 0;
102 const int kRegister_ecx_Code = 1;
103 const int kRegister_edx_Code = 2;
104 const int kRegister_ebx_Code = 3;
105 const int kRegister_esp_Code = 4;
106 const int kRegister_ebp_Code = 5;
107 const int kRegister_esi_Code = 6;
108 const int kRegister_edi_Code = 7;
109 const int kRegister_no_reg_Code = -1;
110 142
111 const Register eax = { kRegister_eax_Code }; 143 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
112 const Register ecx = { kRegister_ecx_Code }; 144 GENERAL_REGISTERS(DECLARE_REGISTER)
113 const Register edx = { kRegister_edx_Code }; 145 #undef DECLARE_REGISTER
114 const Register ebx = { kRegister_ebx_Code }; 146 const Register no_reg = {Register::kCode_no_reg};
115 const Register esp = { kRegister_esp_Code };
116 const Register ebp = { kRegister_ebp_Code };
117 const Register esi = { kRegister_esi_Code };
118 const Register edi = { kRegister_edi_Code };
119 const Register no_reg = { kRegister_no_reg_Code };
120 147
121 148
122 inline const char* Register::AllocationIndexToString(int index) { 149 struct DoubleRegister {
123 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); 150 enum Code {
124 // This is the mapping of allocation indices to registers. 151 #define REGISTER_CODE(R) kCode_##R,
125 const char* const kNames[] = { "eax", "ecx", "edx", "ebx", "esi", "edi" }; 152 DOUBLE_REGISTERS(REGISTER_CODE)
126 return kNames[index]; 153 #undef REGISTER_CODE
127 } 154 kAfterLast,
155 kCode_no_reg = -1
156 };
128 157
158 static const int kMaxNumRegisters = Code::kAfterLast;
159 static const int kMaxNumAllocatableRegisters = 6;
129 160
130 struct X87Register { 161 static DoubleRegister from_code(int code) {
131 static const int kMaxNumAllocatableRegisters = 6; 162 DoubleRegister result = {code};
132 static const int kMaxNumRegisters = 8;
133 static int NumAllocatableRegisters() {
134 return kMaxNumAllocatableRegisters;
135 }
136
137
138 // TODO(turbofan): Proper support for float32.
139 static int NumAllocatableAliasedRegisters() {
140 return NumAllocatableRegisters();
141 }
142
143
144 static int ToAllocationIndex(X87Register reg) {
145 return reg.code_;
146 }
147
148 static const char* AllocationIndexToString(int index) {
149 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
150 const char* const names[] = {
151 "stX_0", "stX_1", "stX_2", "stX_3", "stX_4",
152 "stX_5", "stX_6", "stX_7"
153 };
154 return names[index];
155 }
156
157 static X87Register FromAllocationIndex(int index) {
158 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
159 X87Register result;
160 result.code_ = index;
161 return result; 163 return result;
162 } 164 }
163 165
164 bool is_valid() const { 166 bool IsAllocatable() const;
165 return 0 <= code_ && code_ < kMaxNumRegisters; 167 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
166 }
167 168
168 int code() const { 169 int code() const {
169 DCHECK(is_valid()); 170 DCHECK(is_valid());
170 return code_; 171 return reg_code;
171 } 172 }
172 173
173 bool is(X87Register reg) const { 174 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
174 return code_ == reg.code_;
175 }
176 175
177 int code_; 176 const char* ToString();
177
178 int reg_code;
178 }; 179 };
179 180
181 #define DECLARE_REGISTER(R) \
182 const DoubleRegister R = {DoubleRegister::kCode_##R};
183 DOUBLE_REGISTERS(DECLARE_REGISTER)
184 #undef DECLARE_REGISTER
185 const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
180 186
181 typedef X87Register DoubleRegister; 187 typedef DoubleRegister X87Register;
182
183
184 const X87Register stX_0 = { 0 };
185 const X87Register stX_1 = { 1 };
186 const X87Register stX_2 = { 2 };
187 const X87Register stX_3 = { 3 };
188 const X87Register stX_4 = { 4 };
189 const X87Register stX_5 = { 5 };
190 const X87Register stX_6 = { 6 };
191 const X87Register stX_7 = { 7 };
192
193 188
194 enum Condition { 189 enum Condition {
195 // any value < 0 is considered no_condition 190 // any value < 0 is considered no_condition
196 no_condition = -1, 191 no_condition = -1,
197 192
198 overflow = 0, 193 overflow = 0,
199 no_overflow = 1, 194 no_overflow = 1,
200 below = 2, 195 below = 2,
201 above_equal = 3, 196 above_equal = 3,
202 equal = 4, 197 equal = 4,
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 Assembler* assembler_; 1072 Assembler* assembler_;
1078 #ifdef DEBUG 1073 #ifdef DEBUG
1079 int space_before_; 1074 int space_before_;
1080 #endif 1075 #endif
1081 }; 1076 };
1082 1077
1083 } // namespace internal 1078 } // namespace internal
1084 } // namespace v8 1079 } // namespace v8
1085 1080
1086 #endif // V8_X87_ASSEMBLER_X87_H_ 1081 #endif // V8_X87_ASSEMBLER_X87_H_
OLDNEW
« no previous file with comments | « src/crankshaft/x87/lithium-x87.cc ('k') | src/x87/code-stubs-x87.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698