| 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 | 6 |
| 7 #include "src/arm64/macro-assembler-arm64.h" | 7 #include "src/arm64/macro-assembler-arm64.h" |
| 8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
| 9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 } else { \ | 122 } else { \ |
| 123 int64_t imm = i.InputOperand##width(1).immediate().value(); \ | 123 int64_t imm = i.InputOperand##width(1).immediate().value(); \ |
| 124 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ | 124 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ |
| 125 } \ | 125 } \ |
| 126 } while (0); | 126 } while (0); |
| 127 | 127 |
| 128 | 128 |
| 129 // Assembles an instruction after register allocation, producing machine code. | 129 // Assembles an instruction after register allocation, producing machine code. |
| 130 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 130 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 131 Arm64OperandConverter i(this, instr); | 131 Arm64OperandConverter i(this, instr); |
| 132 | 132 InstructionCode opcode = instr->opcode(); |
| 133 switch (ArchOpcodeField::decode(instr->opcode())) { | 133 switch (ArchOpcodeField::decode(opcode)) { |
| 134 case kArchJmp: | 134 case kArchJmp: |
| 135 __ B(code_->GetLabel(i.InputBlock(0))); | 135 __ B(code_->GetLabel(i.InputBlock(0))); |
| 136 break; | 136 break; |
| 137 case kArchNop: | 137 case kArchNop: |
| 138 // don't emit code for nops. | 138 // don't emit code for nops. |
| 139 break; | 139 break; |
| 140 case kArchRet: | 140 case kArchRet: |
| 141 AssembleReturn(); | 141 AssembleReturn(); |
| 142 break; | 142 break; |
| 143 case kArchDeoptimize: { | 143 case kArchDeoptimize: { |
| 144 int deoptimization_id = MiscField::decode(instr->opcode()); | 144 int deoptimization_id = MiscField::decode(instr->opcode()); |
| 145 BuildTranslation(instr, deoptimization_id); | 145 BuildTranslation(instr, deoptimization_id); |
| 146 | 146 |
| 147 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 147 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
| 148 isolate(), deoptimization_id, Deoptimizer::LAZY); | 148 isolate(), deoptimization_id, Deoptimizer::LAZY); |
| 149 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 149 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
| 150 break; | 150 break; |
| 151 } | 151 } |
| 152 case kArm64Add: | 152 case kArm64Add: |
| 153 __ Add(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 153 __ Add(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 154 break; | 154 break; |
| 155 case kArm64Add32: | 155 case kArm64Add32: |
| 156 __ Add(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1)); | 156 if (FlagsModeField::decode(opcode) != kFlags_none) { |
| 157 __ Adds(i.OutputRegister32(), i.InputRegister32(0), |
| 158 i.InputOperand32(1)); |
| 159 } else { |
| 160 __ Add(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1)); |
| 161 } |
| 157 break; | 162 break; |
| 158 case kArm64And: | 163 case kArm64And: |
| 159 __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 164 __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
| 160 break; | 165 break; |
| 161 case kArm64And32: | 166 case kArm64And32: |
| 162 __ And(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1)); | 167 __ And(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1)); |
| 163 break; | 168 break; |
| 164 case kArm64Mul: | 169 case kArm64Mul: |
| 165 __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 170 __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
| 166 break; | 171 break; |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 // Fall through. | 505 // Fall through. |
| 501 case kUnsignedLessThanOrEqual: | 506 case kUnsignedLessThanOrEqual: |
| 502 __ B(ls, tlabel); | 507 __ B(ls, tlabel); |
| 503 break; | 508 break; |
| 504 case kUnorderedGreaterThan: | 509 case kUnorderedGreaterThan: |
| 505 __ B(vs, tlabel); | 510 __ B(vs, tlabel); |
| 506 // Fall through. | 511 // Fall through. |
| 507 case kUnsignedGreaterThan: | 512 case kUnsignedGreaterThan: |
| 508 __ B(hi, tlabel); | 513 __ B(hi, tlabel); |
| 509 break; | 514 break; |
| 515 case kOverflow: |
| 516 __ B(vs, tlabel); |
| 517 break; |
| 518 case kNotOverflow: |
| 519 __ B(vc, tlabel); |
| 520 break; |
| 510 } | 521 } |
| 511 if (!fallthru) __ B(flabel); // no fallthru to flabel. | 522 if (!fallthru) __ B(flabel); // no fallthru to flabel. |
| 512 __ Bind(&done); | 523 __ Bind(&done); |
| 513 } | 524 } |
| 514 | 525 |
| 515 | 526 |
| 516 // Assemble boolean materializations after this instruction. | 527 // Assemble boolean materializations after this instruction. |
| 517 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 528 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
| 518 FlagsCondition condition) { | 529 FlagsCondition condition) { |
| 519 Arm64OperandConverter i(this, instr); | 530 Arm64OperandConverter i(this, instr); |
| 520 Label done; | 531 Label done; |
| 521 | 532 |
| 522 // Materialize a full 64-bit 1 or 0 value. | 533 // Materialize a full 64-bit 1 or 0 value. The result register is always the |
| 534 // last output of the instruction. |
| 523 Label check; | 535 Label check; |
| 524 Register reg = i.OutputRegister(); | 536 ASSERT_NE(0, instr->OutputCount()); |
| 537 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
| 525 Condition cc = nv; | 538 Condition cc = nv; |
| 526 switch (condition) { | 539 switch (condition) { |
| 527 case kUnorderedEqual: | 540 case kUnorderedEqual: |
| 528 __ B(vc, &check); | 541 __ B(vc, &check); |
| 529 __ Mov(reg, 0); | 542 __ Mov(reg, 0); |
| 530 __ B(&done); | 543 __ B(&done); |
| 531 // Fall through. | 544 // Fall through. |
| 532 case kEqual: | 545 case kEqual: |
| 533 cc = eq; | 546 cc = eq; |
| 534 break; | 547 break; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 cc = ls; | 590 cc = ls; |
| 578 break; | 591 break; |
| 579 case kUnorderedGreaterThan: | 592 case kUnorderedGreaterThan: |
| 580 __ B(vc, &check); | 593 __ B(vc, &check); |
| 581 __ Mov(reg, 1); | 594 __ Mov(reg, 1); |
| 582 __ B(&done); | 595 __ B(&done); |
| 583 // Fall through. | 596 // Fall through. |
| 584 case kUnsignedGreaterThan: | 597 case kUnsignedGreaterThan: |
| 585 cc = hi; | 598 cc = hi; |
| 586 break; | 599 break; |
| 600 case kOverflow: |
| 601 cc = vs; |
| 602 break; |
| 603 case kNotOverflow: |
| 604 cc = vc; |
| 605 break; |
| 587 } | 606 } |
| 588 __ bind(&check); | 607 __ bind(&check); |
| 589 __ Cset(reg, cc); | 608 __ Cset(reg, cc); |
| 590 __ B(&done); | 609 __ B(&done); |
| 591 __ Bind(&done); | 610 __ Bind(&done); |
| 592 } | 611 } |
| 593 | 612 |
| 594 | 613 |
| 595 // TODO(dcarney): increase stack slots in frame once before first use. | 614 // TODO(dcarney): increase stack slots in frame once before first use. |
| 596 static int AlignedStackSlots(int stack_slots) { | 615 static int AlignedStackSlots(int stack_slots) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 v8::internal::Instruction* instr = | 841 v8::internal::Instruction* instr = |
| 823 reinterpret_cast<v8::internal::Instruction*>(instr_address); | 842 reinterpret_cast<v8::internal::Instruction*>(instr_address); |
| 824 return instr->IsMovz() && instr->Rd() == xzr.code() && instr->SixtyFourBits(); | 843 return instr->IsMovz() && instr->Rd() == xzr.code() && instr->SixtyFourBits(); |
| 825 } | 844 } |
| 826 | 845 |
| 827 #endif // DEBUG | 846 #endif // DEBUG |
| 828 | 847 |
| 829 } // namespace compiler | 848 } // namespace compiler |
| 830 } // namespace internal | 849 } // namespace internal |
| 831 } // namespace v8 | 850 } // namespace v8 |
| OLD | NEW |