| 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 |