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 |