OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/crankshaft/x87/lithium-gap-resolver-x87.h" | 7 #include "src/crankshaft/x87/lithium-gap-resolver-x87.h" |
| 8 #include "src/register-configuration.h" |
8 | 9 |
9 #include "src/crankshaft/x87/lithium-codegen-x87.h" | 10 #include "src/crankshaft/x87/lithium-codegen-x87.h" |
10 | 11 |
11 namespace v8 { | 12 namespace v8 { |
12 namespace internal { | 13 namespace internal { |
13 | 14 |
14 LGapResolver::LGapResolver(LCodeGen* owner) | 15 LGapResolver::LGapResolver(LCodeGen* owner) |
15 : cgen_(owner), | 16 : cgen_(owner), |
16 moves_(32, owner->zone()), | 17 moves_(32, owner->zone()), |
17 source_uses_(), | 18 source_uses_(), |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 for (int i = 0; i < moves_.length(); ++i) { | 160 for (int i = 0; i < moves_.length(); ++i) { |
160 if (!moves_[i].IsEliminated() && moves_[i].source()->Equals(operand)) { | 161 if (!moves_[i].IsEliminated() && moves_[i].source()->Equals(operand)) { |
161 ++count; | 162 ++count; |
162 } | 163 } |
163 } | 164 } |
164 return count; | 165 return count; |
165 } | 166 } |
166 | 167 |
167 | 168 |
168 Register LGapResolver::GetFreeRegisterNot(Register reg) { | 169 Register LGapResolver::GetFreeRegisterNot(Register reg) { |
169 int skip_index = reg.is(no_reg) ? -1 : Register::ToAllocationIndex(reg); | 170 int skip_index = reg.is(no_reg) ? -1 : reg.code(); |
170 for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) { | 171 const RegisterConfiguration* config = |
171 if (source_uses_[i] == 0 && destination_uses_[i] > 0 && i != skip_index) { | 172 RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); |
172 return Register::FromAllocationIndex(i); | 173 for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { |
| 174 int code = config->GetAllocatableGeneralCode(i); |
| 175 if (source_uses_[code] == 0 && destination_uses_[code] > 0 && |
| 176 code != skip_index) { |
| 177 return Register::from_code(code); |
173 } | 178 } |
174 } | 179 } |
175 return no_reg; | 180 return no_reg; |
176 } | 181 } |
177 | 182 |
178 | 183 |
179 bool LGapResolver::HasBeenReset() { | 184 bool LGapResolver::HasBeenReset() { |
180 if (!moves_.is_empty()) return false; | 185 if (!moves_.is_empty()) return false; |
181 if (spilled_register_ >= 0) return false; | 186 if (spilled_register_ >= 0) return false; |
182 | 187 const RegisterConfiguration* config = |
183 for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) { | 188 RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); |
184 if (source_uses_[i] != 0) return false; | 189 for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { |
185 if (destination_uses_[i] != 0) return false; | 190 int code = config->GetAllocatableGeneralCode(i); |
| 191 if (source_uses_[code] != 0) return false; |
| 192 if (destination_uses_[code] != 0) return false; |
186 } | 193 } |
187 return true; | 194 return true; |
188 } | 195 } |
189 | 196 |
190 | 197 |
191 void LGapResolver::Verify() { | 198 void LGapResolver::Verify() { |
192 #ifdef ENABLE_SLOW_DCHECKS | 199 #ifdef ENABLE_SLOW_DCHECKS |
193 // No operand should be the destination for more than one move. | 200 // No operand should be the destination for more than one move. |
194 for (int i = 0; i < moves_.length(); ++i) { | 201 for (int i = 0; i < moves_.length(); ++i) { |
195 LOperand* destination = moves_[i].destination(); | 202 LOperand* destination = moves_[i].destination(); |
196 for (int j = i + 1; j < moves_.length(); ++j) { | 203 for (int j = i + 1; j < moves_.length(); ++j) { |
197 SLOW_DCHECK(!destination->Equals(moves_[j].destination())); | 204 SLOW_DCHECK(!destination->Equals(moves_[j].destination())); |
198 } | 205 } |
199 } | 206 } |
200 #endif | 207 #endif |
201 } | 208 } |
202 | 209 |
203 | 210 |
204 #define __ ACCESS_MASM(cgen_->masm()) | 211 #define __ ACCESS_MASM(cgen_->masm()) |
205 | 212 |
206 void LGapResolver::Finish() { | 213 void LGapResolver::Finish() { |
207 if (spilled_register_ >= 0) { | 214 if (spilled_register_ >= 0) { |
208 __ pop(Register::FromAllocationIndex(spilled_register_)); | 215 __ pop(Register::from_code(spilled_register_)); |
209 spilled_register_ = -1; | 216 spilled_register_ = -1; |
210 } | 217 } |
211 moves_.Rewind(0); | 218 moves_.Rewind(0); |
212 } | 219 } |
213 | 220 |
214 | 221 |
215 void LGapResolver::EnsureRestored(LOperand* operand) { | 222 void LGapResolver::EnsureRestored(LOperand* operand) { |
216 if (operand->IsRegister() && operand->index() == spilled_register_) { | 223 if (operand->IsRegister() && operand->index() == spilled_register_) { |
217 __ pop(Register::FromAllocationIndex(spilled_register_)); | 224 __ pop(Register::from_code(spilled_register_)); |
218 spilled_register_ = -1; | 225 spilled_register_ = -1; |
219 } | 226 } |
220 } | 227 } |
221 | 228 |
222 | 229 |
223 Register LGapResolver::EnsureTempRegister() { | 230 Register LGapResolver::EnsureTempRegister() { |
224 // 1. We may have already spilled to create a temp register. | 231 // 1. We may have already spilled to create a temp register. |
225 if (spilled_register_ >= 0) { | 232 if (spilled_register_ >= 0) { |
226 return Register::FromAllocationIndex(spilled_register_); | 233 return Register::from_code(spilled_register_); |
227 } | 234 } |
228 | 235 |
229 // 2. We may have a free register that we can use without spilling. | 236 // 2. We may have a free register that we can use without spilling. |
230 Register free = GetFreeRegisterNot(no_reg); | 237 Register free = GetFreeRegisterNot(no_reg); |
231 if (!free.is(no_reg)) return free; | 238 if (!free.is(no_reg)) return free; |
232 | 239 |
233 // 3. Prefer to spill a register that is not used in any remaining move | 240 // 3. Prefer to spill a register that is not used in any remaining move |
234 // because it will not need to be restored until the end. | 241 // because it will not need to be restored until the end. |
235 for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) { | 242 const RegisterConfiguration* config = |
236 if (source_uses_[i] == 0 && destination_uses_[i] == 0) { | 243 RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); |
237 Register scratch = Register::FromAllocationIndex(i); | 244 for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { |
| 245 int code = config->GetAllocatableGeneralCode(i); |
| 246 if (source_uses_[code] == 0 && destination_uses_[code] == 0) { |
| 247 Register scratch = Register::from_code(code); |
238 __ push(scratch); | 248 __ push(scratch); |
239 spilled_register_ = i; | 249 spilled_register_ = code; |
240 return scratch; | 250 return scratch; |
241 } | 251 } |
242 } | 252 } |
243 | 253 |
244 // 4. Use an arbitrary register. Register 0 is as arbitrary as any other. | 254 // 4. Use an arbitrary register. Register 0 is as arbitrary as any other. |
245 Register scratch = Register::FromAllocationIndex(0); | 255 spilled_register_ = config->GetAllocatableGeneralCode(0); |
| 256 Register scratch = Register::from_code(spilled_register_); |
246 __ push(scratch); | 257 __ push(scratch); |
247 spilled_register_ = 0; | |
248 return scratch; | 258 return scratch; |
249 } | 259 } |
250 | 260 |
251 | 261 |
252 void LGapResolver::EmitMove(int index) { | 262 void LGapResolver::EmitMove(int index) { |
253 LOperand* source = moves_[index].source(); | 263 LOperand* source = moves_[index].source(); |
254 LOperand* destination = moves_[index].destination(); | 264 LOperand* destination = moves_[index].destination(); |
255 EnsureRestored(source); | 265 EnsureRestored(source); |
256 EnsureRestored(destination); | 266 EnsureRestored(destination); |
257 | 267 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 source_uses_[destination->index()] = CountSourceUses(destination); | 451 source_uses_[destination->index()] = CountSourceUses(destination); |
442 } | 452 } |
443 } | 453 } |
444 | 454 |
445 #undef __ | 455 #undef __ |
446 | 456 |
447 } // namespace internal | 457 } // namespace internal |
448 } // namespace v8 | 458 } // namespace v8 |
449 | 459 |
450 #endif // V8_TARGET_ARCH_X87 | 460 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |