| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
| 6 #include "src/compiler/code-generator-impl.h" | 6 #include "src/compiler/code-generator-impl.h" |
| 7 #include "src/compiler/gap-resolver.h" | 7 #include "src/compiler/gap-resolver.h" |
| 8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
| 9 #include "src/mips/macro-assembler-mips.h" | 9 #include "src/mips/macro-assembler-mips.h" |
| 10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 case Constant::kRpoNumber: | 73 case Constant::kRpoNumber: |
| 74 UNREACHABLE(); // TODO(titzer): RPO immediates on mips? | 74 UNREACHABLE(); // TODO(titzer): RPO immediates on mips? |
| 75 break; | 75 break; |
| 76 } | 76 } |
| 77 UNREACHABLE(); | 77 UNREACHABLE(); |
| 78 return Operand(zero_reg); | 78 return Operand(zero_reg); |
| 79 } | 79 } |
| 80 | 80 |
| 81 Operand InputOperand(size_t index) { | 81 Operand InputOperand(size_t index) { |
| 82 InstructionOperand* op = instr_->InputAt(index); | 82 InstructionOperand* op = instr_->InputAt(index); |
| 83 if (op->IsRegister()) { | 83 if (op->GeneratesRegister()) { |
| 84 return Operand(ToRegister(op)); | 84 return Operand(ToRegister(op)); |
| 85 } | 85 } |
| 86 return InputImmediate(index); | 86 return InputImmediate(index); |
| 87 } | 87 } |
| 88 | 88 |
| 89 MemOperand MemoryOperand(size_t* first_index) { | 89 MemOperand MemoryOperand(size_t* first_index) { |
| 90 const size_t index = *first_index; | 90 const size_t index = *first_index; |
| 91 switch (AddressingModeField::decode(instr_->opcode())) { | 91 switch (AddressingModeField::decode(instr_->opcode())) { |
| 92 case kMode_None: | 92 case kMode_None: |
| 93 break; | 93 break; |
| 94 case kMode_MRI: | 94 case kMode_MRI: |
| 95 *first_index += 2; | 95 *first_index += 2; |
| 96 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); | 96 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); |
| 97 case kMode_MRR: | 97 case kMode_MRR: |
| 98 // TODO(plind): r6 address mode, to be implemented ... | 98 // TODO(plind): r6 address mode, to be implemented ... |
| 99 UNREACHABLE(); | 99 UNREACHABLE(); |
| 100 } | 100 } |
| 101 UNREACHABLE(); | 101 UNREACHABLE(); |
| 102 return MemOperand(no_reg); | 102 return MemOperand(no_reg); |
| 103 } | 103 } |
| 104 | 104 |
| 105 MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); } | 105 MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); } |
| 106 | 106 |
| 107 MemOperand ToMemOperand(InstructionOperand* op) const { | 107 MemOperand ToMemOperand(InstructionOperand* op) const { |
| 108 DCHECK(op != NULL); | 108 DCHECK(op != NULL); |
| 109 DCHECK(!op->IsRegister()); | 109 DCHECK(!op->GeneratesRegister()); |
| 110 DCHECK(!op->IsDoubleRegister()); | 110 DCHECK(!op->IsDoubleRegister()); |
| 111 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 111 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); |
| 112 // The linkage computes where all spill slots are located. | 112 // The linkage computes where all spill slots are located. |
| 113 FrameOffset offset = linkage()->GetFrameOffset( | 113 FrameOffset offset = linkage()->GetFrameOffset( |
| 114 AllocatedOperand::cast(op)->index(), frame(), 0); | 114 AllocatedOperand::cast(op)->index(), frame(), 0); |
| 115 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); | 115 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); |
| 116 } | 116 } |
| 117 }; | 117 }; |
| 118 | 118 |
| 119 | 119 |
| 120 static inline bool HasRegisterInput(Instruction* instr, size_t index) { | 120 static inline bool HasRegisterInput(Instruction* instr, size_t index) { |
| 121 return instr->InputAt(index)->IsRegister(); | 121 return instr->InputAt(index)->GeneratesRegister(); |
| 122 } | 122 } |
| 123 | 123 |
| 124 | 124 |
| 125 namespace { | 125 namespace { |
| 126 | 126 |
| 127 class OutOfLineLoadSingle final : public OutOfLineCode { | 127 class OutOfLineLoadSingle final : public OutOfLineCode { |
| 128 public: | 128 public: |
| 129 OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result) | 129 OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result) |
| 130 : OutOfLineCode(gen), result_(result) {} | 130 : OutOfLineCode(gen), result_(result) {} |
| 131 | 131 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 return kNoFPUCondition; | 297 return kNoFPUCondition; |
| 298 } | 298 } |
| 299 | 299 |
| 300 } // namespace | 300 } // namespace |
| 301 | 301 |
| 302 | 302 |
| 303 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ | 303 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ |
| 304 do { \ | 304 do { \ |
| 305 auto result = i.Output##width##Register(); \ | 305 auto result = i.Output##width##Register(); \ |
| 306 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ | 306 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ |
| 307 if (instr->InputAt(0)->IsRegister()) { \ | 307 if (instr->InputAt(0)->GeneratesRegister()) { \ |
| 308 auto offset = i.InputRegister(0); \ | 308 auto offset = i.InputRegister(0); \ |
| 309 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ | 309 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ |
| 310 __ Daddu(at, i.InputRegister(2), offset); \ | 310 __ Daddu(at, i.InputRegister(2), offset); \ |
| 311 __ asm_instr(result, MemOperand(at, 0)); \ | 311 __ asm_instr(result, MemOperand(at, 0)); \ |
| 312 } else { \ | 312 } else { \ |
| 313 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 313 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
| 314 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ | 314 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ |
| 315 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ | 315 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ |
| 316 } \ | 316 } \ |
| 317 __ bind(ool->exit()); \ | 317 __ bind(ool->exit()); \ |
| 318 } while (0) | 318 } while (0) |
| 319 | 319 |
| 320 | 320 |
| 321 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ | 321 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
| 322 do { \ | 322 do { \ |
| 323 auto result = i.OutputRegister(); \ | 323 auto result = i.OutputRegister(); \ |
| 324 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ | 324 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
| 325 if (instr->InputAt(0)->IsRegister()) { \ | 325 if (instr->InputAt(0)->GeneratesRegister()) { \ |
| 326 auto offset = i.InputRegister(0); \ | 326 auto offset = i.InputRegister(0); \ |
| 327 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ | 327 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ |
| 328 __ Daddu(at, i.InputRegister(2), offset); \ | 328 __ Daddu(at, i.InputRegister(2), offset); \ |
| 329 __ asm_instr(result, MemOperand(at, 0)); \ | 329 __ asm_instr(result, MemOperand(at, 0)); \ |
| 330 } else { \ | 330 } else { \ |
| 331 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 331 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
| 332 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ | 332 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ |
| 333 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ | 333 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ |
| 334 } \ | 334 } \ |
| 335 __ bind(ool->exit()); \ | 335 __ bind(ool->exit()); \ |
| 336 } while (0) | 336 } while (0) |
| 337 | 337 |
| 338 | 338 |
| 339 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ | 339 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ |
| 340 do { \ | 340 do { \ |
| 341 Label done; \ | 341 Label done; \ |
| 342 if (instr->InputAt(0)->IsRegister()) { \ | 342 if (instr->InputAt(0)->GeneratesRegister()) { \ |
| 343 auto offset = i.InputRegister(0); \ | 343 auto offset = i.InputRegister(0); \ |
| 344 auto value = i.Input##width##Register(2); \ | 344 auto value = i.Input##width##Register(2); \ |
| 345 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ | 345 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ |
| 346 __ Daddu(at, i.InputRegister(3), offset); \ | 346 __ Daddu(at, i.InputRegister(3), offset); \ |
| 347 __ asm_instr(value, MemOperand(at, 0)); \ | 347 __ asm_instr(value, MemOperand(at, 0)); \ |
| 348 } else { \ | 348 } else { \ |
| 349 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 349 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
| 350 auto value = i.Input##width##Register(2); \ | 350 auto value = i.Input##width##Register(2); \ |
| 351 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 351 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
| 352 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 352 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
| 353 } \ | 353 } \ |
| 354 __ bind(&done); \ | 354 __ bind(&done); \ |
| 355 } while (0) | 355 } while (0) |
| 356 | 356 |
| 357 | 357 |
| 358 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 358 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
| 359 do { \ | 359 do { \ |
| 360 Label done; \ | 360 Label done; \ |
| 361 if (instr->InputAt(0)->IsRegister()) { \ | 361 if (instr->InputAt(0)->GeneratesRegister()) { \ |
| 362 auto offset = i.InputRegister(0); \ | 362 auto offset = i.InputRegister(0); \ |
| 363 auto value = i.InputRegister(2); \ | 363 auto value = i.InputRegister(2); \ |
| 364 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ | 364 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ |
| 365 __ Daddu(at, i.InputRegister(3), offset); \ | 365 __ Daddu(at, i.InputRegister(3), offset); \ |
| 366 __ asm_instr(value, MemOperand(at, 0)); \ | 366 __ asm_instr(value, MemOperand(at, 0)); \ |
| 367 } else { \ | 367 } else { \ |
| 368 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 368 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
| 369 auto value = i.InputRegister(2); \ | 369 auto value = i.InputRegister(2); \ |
| 370 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 370 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
| 371 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 371 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 case kMips64Or: | 561 case kMips64Or: |
| 562 __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 562 __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 563 break; | 563 break; |
| 564 case kMips64Xor: | 564 case kMips64Xor: |
| 565 __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 565 __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 566 break; | 566 break; |
| 567 case kMips64Clz: | 567 case kMips64Clz: |
| 568 __ Clz(i.OutputRegister(), i.InputRegister(0)); | 568 __ Clz(i.OutputRegister(), i.InputRegister(0)); |
| 569 break; | 569 break; |
| 570 case kMips64Shl: | 570 case kMips64Shl: |
| 571 if (instr->InputAt(1)->IsRegister()) { | 571 if (instr->InputAt(1)->GeneratesRegister()) { |
| 572 __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 572 __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
| 573 } else { | 573 } else { |
| 574 int64_t imm = i.InputOperand(1).immediate(); | 574 int64_t imm = i.InputOperand(1).immediate(); |
| 575 __ sll(i.OutputRegister(), i.InputRegister(0), | 575 __ sll(i.OutputRegister(), i.InputRegister(0), |
| 576 static_cast<uint16_t>(imm)); | 576 static_cast<uint16_t>(imm)); |
| 577 } | 577 } |
| 578 break; | 578 break; |
| 579 case kMips64Shr: | 579 case kMips64Shr: |
| 580 if (instr->InputAt(1)->IsRegister()) { | 580 if (instr->InputAt(1)->GeneratesRegister()) { |
| 581 __ srlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 581 __ srlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
| 582 } else { | 582 } else { |
| 583 int64_t imm = i.InputOperand(1).immediate(); | 583 int64_t imm = i.InputOperand(1).immediate(); |
| 584 __ srl(i.OutputRegister(), i.InputRegister(0), | 584 __ srl(i.OutputRegister(), i.InputRegister(0), |
| 585 static_cast<uint16_t>(imm)); | 585 static_cast<uint16_t>(imm)); |
| 586 } | 586 } |
| 587 break; | 587 break; |
| 588 case kMips64Sar: | 588 case kMips64Sar: |
| 589 if (instr->InputAt(1)->IsRegister()) { | 589 if (instr->InputAt(1)->GeneratesRegister()) { |
| 590 __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 590 __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
| 591 } else { | 591 } else { |
| 592 int64_t imm = i.InputOperand(1).immediate(); | 592 int64_t imm = i.InputOperand(1).immediate(); |
| 593 __ sra(i.OutputRegister(), i.InputRegister(0), | 593 __ sra(i.OutputRegister(), i.InputRegister(0), |
| 594 static_cast<uint16_t>(imm)); | 594 static_cast<uint16_t>(imm)); |
| 595 } | 595 } |
| 596 break; | 596 break; |
| 597 case kMips64Ext: | 597 case kMips64Ext: |
| 598 __ Ext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1), | 598 __ Ext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1), |
| 599 i.InputInt8(2)); | 599 i.InputInt8(2)); |
| 600 break; | 600 break; |
| 601 case kMips64Dext: | 601 case kMips64Dext: |
| 602 __ Dext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1), | 602 __ Dext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1), |
| 603 i.InputInt8(2)); | 603 i.InputInt8(2)); |
| 604 break; | 604 break; |
| 605 case kMips64Dshl: | 605 case kMips64Dshl: |
| 606 if (instr->InputAt(1)->IsRegister()) { | 606 if (instr->InputAt(1)->GeneratesRegister()) { |
| 607 __ dsllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 607 __ dsllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
| 608 } else { | 608 } else { |
| 609 int64_t imm = i.InputOperand(1).immediate(); | 609 int64_t imm = i.InputOperand(1).immediate(); |
| 610 if (imm < 32) { | 610 if (imm < 32) { |
| 611 __ dsll(i.OutputRegister(), i.InputRegister(0), | 611 __ dsll(i.OutputRegister(), i.InputRegister(0), |
| 612 static_cast<uint16_t>(imm)); | 612 static_cast<uint16_t>(imm)); |
| 613 } else { | 613 } else { |
| 614 __ dsll32(i.OutputRegister(), i.InputRegister(0), | 614 __ dsll32(i.OutputRegister(), i.InputRegister(0), |
| 615 static_cast<uint16_t>(imm - 32)); | 615 static_cast<uint16_t>(imm - 32)); |
| 616 } | 616 } |
| 617 } | 617 } |
| 618 break; | 618 break; |
| 619 case kMips64Dshr: | 619 case kMips64Dshr: |
| 620 if (instr->InputAt(1)->IsRegister()) { | 620 if (instr->InputAt(1)->GeneratesRegister()) { |
| 621 __ dsrlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 621 __ dsrlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
| 622 } else { | 622 } else { |
| 623 int64_t imm = i.InputOperand(1).immediate(); | 623 int64_t imm = i.InputOperand(1).immediate(); |
| 624 if (imm < 32) { | 624 if (imm < 32) { |
| 625 __ dsrl(i.OutputRegister(), i.InputRegister(0), | 625 __ dsrl(i.OutputRegister(), i.InputRegister(0), |
| 626 static_cast<uint16_t>(imm)); | 626 static_cast<uint16_t>(imm)); |
| 627 } else { | 627 } else { |
| 628 __ dsrl32(i.OutputRegister(), i.InputRegister(0), | 628 __ dsrl32(i.OutputRegister(), i.InputRegister(0), |
| 629 static_cast<uint16_t>(imm - 32)); | 629 static_cast<uint16_t>(imm - 32)); |
| 630 } | 630 } |
| 631 } | 631 } |
| 632 break; | 632 break; |
| 633 case kMips64Dsar: | 633 case kMips64Dsar: |
| 634 if (instr->InputAt(1)->IsRegister()) { | 634 if (instr->InputAt(1)->GeneratesRegister()) { |
| 635 __ dsrav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 635 __ dsrav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
| 636 } else { | 636 } else { |
| 637 int64_t imm = i.InputOperand(1).immediate(); | 637 int64_t imm = i.InputOperand(1).immediate(); |
| 638 if (imm < 32) { | 638 if (imm < 32) { |
| 639 __ dsra(i.OutputRegister(), i.InputRegister(0), imm); | 639 __ dsra(i.OutputRegister(), i.InputRegister(0), imm); |
| 640 } else { | 640 } else { |
| 641 __ dsra32(i.OutputRegister(), i.InputRegister(0), imm - 32); | 641 __ dsra32(i.OutputRegister(), i.InputRegister(0), imm - 32); |
| 642 } | 642 } |
| 643 } | 643 } |
| 644 break; | 644 break; |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 __ Ret(); | 1243 __ Ret(); |
| 1244 } | 1244 } |
| 1245 } | 1245 } |
| 1246 | 1246 |
| 1247 | 1247 |
| 1248 void CodeGenerator::AssembleMove(InstructionOperand* source, | 1248 void CodeGenerator::AssembleMove(InstructionOperand* source, |
| 1249 InstructionOperand* destination) { | 1249 InstructionOperand* destination) { |
| 1250 MipsOperandConverter g(this, NULL); | 1250 MipsOperandConverter g(this, NULL); |
| 1251 // Dispatch on the source and destination operand kinds. Not all | 1251 // Dispatch on the source and destination operand kinds. Not all |
| 1252 // combinations are possible. | 1252 // combinations are possible. |
| 1253 if (source->IsRegister()) { | 1253 if (source->GeneratesRegister()) { |
| 1254 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 1254 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot()); |
| 1255 Register src = g.ToRegister(source); | 1255 Register src = g.ToRegister(source); |
| 1256 if (destination->IsRegister()) { | 1256 if (destination->GeneratesRegister()) { |
| 1257 __ mov(g.ToRegister(destination), src); | 1257 __ mov(g.ToRegister(destination), src); |
| 1258 } else { | 1258 } else { |
| 1259 __ sd(src, g.ToMemOperand(destination)); | 1259 __ sd(src, g.ToMemOperand(destination)); |
| 1260 } | 1260 } |
| 1261 } else if (source->IsStackSlot()) { | 1261 } else if (source->IsStackSlot()) { |
| 1262 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 1262 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot()); |
| 1263 MemOperand src = g.ToMemOperand(source); | 1263 MemOperand src = g.ToMemOperand(source); |
| 1264 if (destination->IsRegister()) { | 1264 if (destination->GeneratesRegister()) { |
| 1265 __ ld(g.ToRegister(destination), src); | 1265 __ ld(g.ToRegister(destination), src); |
| 1266 } else { | 1266 } else { |
| 1267 Register temp = kScratchReg; | 1267 Register temp = kScratchReg; |
| 1268 __ ld(temp, src); | 1268 __ ld(temp, src); |
| 1269 __ sd(temp, g.ToMemOperand(destination)); | 1269 __ sd(temp, g.ToMemOperand(destination)); |
| 1270 } | 1270 } |
| 1271 } else if (source->IsConstant()) { | 1271 } else if (source->IsConstant()) { |
| 1272 Constant src = g.ToConstant(source); | 1272 Constant src = g.ToConstant(source); |
| 1273 if (destination->IsRegister() || destination->IsStackSlot()) { | 1273 if (destination->GeneratesRegister() || destination->IsStackSlot()) { |
| 1274 Register dst = | 1274 Register dst = destination->GeneratesRegister() |
| 1275 destination->IsRegister() ? g.ToRegister(destination) : kScratchReg; | 1275 ? g.ToRegister(destination) |
| 1276 : kScratchReg; |
| 1276 switch (src.type()) { | 1277 switch (src.type()) { |
| 1277 case Constant::kInt32: | 1278 case Constant::kInt32: |
| 1278 __ li(dst, Operand(src.ToInt32())); | 1279 __ li(dst, Operand(src.ToInt32())); |
| 1279 break; | 1280 break; |
| 1280 case Constant::kFloat32: | 1281 case Constant::kFloat32: |
| 1281 __ li(dst, isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); | 1282 __ li(dst, isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); |
| 1282 break; | 1283 break; |
| 1283 case Constant::kInt64: | 1284 case Constant::kInt64: |
| 1284 __ li(dst, Operand(src.ToInt64())); | 1285 __ li(dst, Operand(src.ToInt64())); |
| 1285 break; | 1286 break; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1349 UNREACHABLE(); | 1350 UNREACHABLE(); |
| 1350 } | 1351 } |
| 1351 } | 1352 } |
| 1352 | 1353 |
| 1353 | 1354 |
| 1354 void CodeGenerator::AssembleSwap(InstructionOperand* source, | 1355 void CodeGenerator::AssembleSwap(InstructionOperand* source, |
| 1355 InstructionOperand* destination) { | 1356 InstructionOperand* destination) { |
| 1356 MipsOperandConverter g(this, NULL); | 1357 MipsOperandConverter g(this, NULL); |
| 1357 // Dispatch on the source and destination operand kinds. Not all | 1358 // Dispatch on the source and destination operand kinds. Not all |
| 1358 // combinations are possible. | 1359 // combinations are possible. |
| 1359 if (source->IsRegister()) { | 1360 if (source->GeneratesRegister()) { |
| 1360 // Register-register. | 1361 // Register-register. |
| 1361 Register temp = kScratchReg; | 1362 Register temp = kScratchReg; |
| 1362 Register src = g.ToRegister(source); | 1363 Register src = g.ToRegister(source); |
| 1363 if (destination->IsRegister()) { | 1364 if (destination->GeneratesRegister()) { |
| 1364 Register dst = g.ToRegister(destination); | 1365 Register dst = g.ToRegister(destination); |
| 1365 __ Move(temp, src); | 1366 __ Move(temp, src); |
| 1366 __ Move(src, dst); | 1367 __ Move(src, dst); |
| 1367 __ Move(dst, temp); | 1368 __ Move(dst, temp); |
| 1368 } else { | 1369 } else { |
| 1369 DCHECK(destination->IsStackSlot()); | 1370 DCHECK(destination->IsStackSlot()); |
| 1370 MemOperand dst = g.ToMemOperand(destination); | 1371 MemOperand dst = g.ToMemOperand(destination); |
| 1371 __ mov(temp, src); | 1372 __ mov(temp, src); |
| 1372 __ ld(src, dst); | 1373 __ ld(src, dst); |
| 1373 __ sd(temp, dst); | 1374 __ sd(temp, dst); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 } | 1450 } |
| 1450 } | 1451 } |
| 1451 } | 1452 } |
| 1452 } | 1453 } |
| 1453 | 1454 |
| 1454 #undef __ | 1455 #undef __ |
| 1455 | 1456 |
| 1456 } // namespace compiler | 1457 } // namespace compiler |
| 1457 } // namespace internal | 1458 } // namespace internal |
| 1458 } // namespace v8 | 1459 } // namespace v8 |
| OLD | NEW |