| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 | 149 |
| 150 // This move is no longer blocked. | 150 // This move is no longer blocked. |
| 151 EmitMove(index); | 151 EmitMove(index); |
| 152 } | 152 } |
| 153 | 153 |
| 154 | 154 |
| 155 void LGapResolver::Verify() { | 155 void LGapResolver::Verify() { |
| 156 TODO_UNIMPLEMENTED("LGapResolver::Verify"); | 156 TODO_UNIMPLEMENTED("LGapResolver::Verify"); |
| 157 } | 157 } |
| 158 | 158 |
| 159 |
| 159 void LGapResolver::BreakCycle(int index) { | 160 void LGapResolver::BreakCycle(int index) { |
| 160 ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source())); | 161 ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source())); |
| 161 ASSERT(!in_cycle_); | 162 ASSERT(!in_cycle_); |
| 162 | 163 |
| 163 // We use a register which is not allocatable by crankshaft to break the cycle | 164 // We use a register which is not allocatable by crankshaft to break the cycle |
| 164 // to be sure it doesn't interfere with the moves we are resolving. | 165 // to be sure it doesn't interfere with the moves we are resolving. |
| 165 ASSERT(!kSavedValue.IsAllocatable()); | 166 ASSERT(!kSavedValue.IsAllocatable()); |
| 166 need_to_restore_root_ = true; | 167 need_to_restore_root_ = true; |
| 167 | 168 |
| 168 // We save in a register the source of that move and we remember its | 169 // We save in a register the source of that move and we remember its |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 // combinations are possible. | 227 // combinations are possible. |
| 227 | 228 |
| 228 if (source->IsRegister()) { | 229 if (source->IsRegister()) { |
| 229 Register source_register = cgen_->ToRegister(source); | 230 Register source_register = cgen_->ToRegister(source); |
| 230 if (destination->IsRegister()) { | 231 if (destination->IsRegister()) { |
| 231 __ Mov(cgen_->ToRegister(destination), source_register); | 232 __ Mov(cgen_->ToRegister(destination), source_register); |
| 232 } else { | 233 } else { |
| 233 ASSERT(destination->IsStackSlot()); | 234 ASSERT(destination->IsStackSlot()); |
| 234 __ Str(source_register, cgen_->ToMemOperand(destination)); | 235 __ Str(source_register, cgen_->ToMemOperand(destination)); |
| 235 } | 236 } |
| 237 |
| 236 } else if (source->IsStackSlot()) { | 238 } else if (source->IsStackSlot()) { |
| 237 MemOperand source_operand = cgen_->ToMemOperand(source); | 239 MemOperand source_operand = cgen_->ToMemOperand(source); |
| 238 if (destination->IsRegister()) { | 240 if (destination->IsRegister()) { |
| 239 __ Ldr(cgen_->ToRegister(destination), source_operand); | 241 __ Ldr(cgen_->ToRegister(destination), source_operand); |
| 240 } else { | 242 } else { |
| 241 ASSERT(destination->IsStackSlot()); | 243 ASSERT(destination->IsStackSlot()); |
| 242 EmitStackSlotMove(index); | 244 EmitStackSlotMove(index); |
| 243 } | 245 } |
| 246 |
| 244 } else if (source->IsConstantOperand()) { | 247 } else if (source->IsConstantOperand()) { |
| 245 LConstantOperand* constant_source = LConstantOperand::cast(source); | 248 LConstantOperand* constant_source = LConstantOperand::cast(source); |
| 246 if (destination->IsRegister()) { | 249 if (destination->IsRegister()) { |
| 247 Register dst = cgen_->ToRegister(destination); | 250 Register dst = cgen_->ToRegister(destination); |
| 248 if (cgen_->IsSmi(constant_source)) { | 251 if (cgen_->IsSmi(constant_source)) { |
| 249 __ Mov(dst, Operand(cgen_->ToSmi(constant_source))); | 252 __ Mov(dst, Operand(cgen_->ToSmi(constant_source))); |
| 250 } else if (cgen_->IsInteger32Constant(constant_source)) { | 253 } else if (cgen_->IsInteger32Constant(constant_source)) { |
| 251 __ Mov(dst, cgen_->ToInteger32(constant_source)); | 254 __ Mov(dst, cgen_->ToInteger32(constant_source)); |
| 252 } else { | 255 } else { |
| 253 __ LoadObject(dst, cgen_->ToHandle(constant_source)); | 256 __ LoadObject(dst, cgen_->ToHandle(constant_source)); |
| 254 } | 257 } |
| 258 } else if (source->IsDoubleRegister()) { |
| 259 DoubleRegister result = cgen_->ToDoubleRegister(destination); |
| 260 __ Fmov(result, cgen_->ToDouble(constant_source)); |
| 255 } else { | 261 } else { |
| 256 ASSERT(destination->IsStackSlot()); | 262 ASSERT(destination->IsStackSlot()); |
| 257 ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone. | 263 ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone. |
| 258 need_to_restore_root_ = true; | 264 need_to_restore_root_ = true; |
| 259 if (cgen_->IsSmi(constant_source)) { | 265 if (cgen_->IsSmi(constant_source)) { |
| 260 __ Mov(kSavedValue, Operand(cgen_->ToSmi(constant_source))); | 266 __ Mov(kSavedValue, Operand(cgen_->ToSmi(constant_source))); |
| 261 } else if (cgen_->IsInteger32Constant(constant_source)) { | 267 } else if (cgen_->IsInteger32Constant(constant_source)) { |
| 262 __ Mov(kSavedValue, cgen_->ToInteger32(constant_source)); | 268 __ Mov(kSavedValue, cgen_->ToInteger32(constant_source)); |
| 263 } else { | 269 } else { |
| 264 __ LoadObject(kSavedValue, cgen_->ToHandle(constant_source)); | 270 __ LoadObject(kSavedValue, cgen_->ToHandle(constant_source)); |
| 265 } | 271 } |
| 266 __ Str(kSavedValue, cgen_->ToMemOperand(destination)); | 272 __ Str(kSavedValue, cgen_->ToMemOperand(destination)); |
| 267 } | 273 } |
| 274 |
| 268 } else if (source->IsDoubleRegister()) { | 275 } else if (source->IsDoubleRegister()) { |
| 269 DoubleRegister src = cgen_->ToDoubleRegister(source); | 276 DoubleRegister src = cgen_->ToDoubleRegister(source); |
| 270 if (destination->IsDoubleRegister()) { | 277 if (destination->IsDoubleRegister()) { |
| 271 __ Fmov(cgen_->ToDoubleRegister(destination), src); | 278 __ Fmov(cgen_->ToDoubleRegister(destination), src); |
| 272 } else { | 279 } else { |
| 273 ASSERT(destination->IsDoubleStackSlot()); | 280 ASSERT(destination->IsDoubleStackSlot()); |
| 274 __ Str(src, cgen_->ToMemOperand(destination)); | 281 __ Str(src, cgen_->ToMemOperand(destination)); |
| 275 } | 282 } |
| 283 |
| 276 } else if (source->IsDoubleStackSlot()) { | 284 } else if (source->IsDoubleStackSlot()) { |
| 277 MemOperand src = cgen_->ToMemOperand(source); | 285 MemOperand src = cgen_->ToMemOperand(source); |
| 278 if (destination->IsDoubleRegister()) { | 286 if (destination->IsDoubleRegister()) { |
| 279 __ Ldr(cgen_->ToDoubleRegister(destination), src); | 287 __ Ldr(cgen_->ToDoubleRegister(destination), src); |
| 280 } else { | 288 } else { |
| 281 // TODO(all): double stack slot to double stack slot move. | 289 // TODO(all): double stack slot to double stack slot move. |
| 282 UNIMPLEMENTED(); | 290 UNIMPLEMENTED(); |
| 283 } | 291 } |
| 292 |
| 284 } else { | 293 } else { |
| 285 UNREACHABLE(); | 294 UNREACHABLE(); |
| 286 } | 295 } |
| 287 | 296 |
| 288 // The move has been emitted, we can eliminate it. | 297 // The move has been emitted, we can eliminate it. |
| 289 moves_[index].Eliminate(); | 298 moves_[index].Eliminate(); |
| 290 } | 299 } |
| 291 | 300 |
| 292 | 301 |
| 293 void LGapResolver::EmitStackSlotMove(int index) { | 302 void LGapResolver::EmitStackSlotMove(int index) { |
| 294 // We need a temp register to perform a stack slot to stack slot move, and | 303 // We need a temp register to perform a stack slot to stack slot move, and |
| 295 // the register must not be involved in breaking cycles. | 304 // the register must not be involved in breaking cycles. |
| 296 | 305 |
| 297 // Use the Crankshaft double scratch register as the temporary. | 306 // Use the Crankshaft double scratch register as the temporary. |
| 298 DoubleRegister temp = crankshaft_fp_scratch; | 307 DoubleRegister temp = crankshaft_fp_scratch; |
| 299 | 308 |
| 300 LOperand* src = moves_[index].source(); | 309 LOperand* src = moves_[index].source(); |
| 301 LOperand* dst = moves_[index].destination(); | 310 LOperand* dst = moves_[index].destination(); |
| 302 | 311 |
| 303 ASSERT(src->IsStackSlot()); | 312 ASSERT(src->IsStackSlot()); |
| 304 ASSERT(dst->IsStackSlot()); | 313 ASSERT(dst->IsStackSlot()); |
| 305 __ Ldr(temp, cgen_->ToMemOperand(src)); | 314 __ Ldr(temp, cgen_->ToMemOperand(src)); |
| 306 __ Str(temp, cgen_->ToMemOperand(dst)); | 315 __ Str(temp, cgen_->ToMemOperand(dst)); |
| 307 } | 316 } |
| 308 | 317 |
| 309 } } // namespace v8::internal | 318 } } // namespace v8::internal |
| OLD | NEW |