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 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 if (instr->InputAt(1)->IsRegister()) { \ | 273 if (instr->InputAt(1)->IsRegister()) { \ |
274 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ | 274 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ |
275 i.InputRegister##width(1)); \ | 275 i.InputRegister##width(1)); \ |
276 } else { \ | 276 } else { \ |
277 int64_t imm = i.InputOperand##width(1).immediate().value(); \ | 277 int64_t imm = i.InputOperand##width(1).immediate().value(); \ |
278 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ | 278 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ |
279 } \ | 279 } \ |
280 } while (0) | 280 } while (0) |
281 | 281 |
282 | 282 |
283 #define ASSEMBLE_BRANCH_TO(target) \ | |
284 do { \ | |
285 bool fallthrough = IsNextInAssemblyOrder(target); \ | |
286 if (!fallthrough) __ B(GetLabel(target)); \ | |
287 } while (0) | |
288 | |
289 | |
290 // Assembles an instruction after register allocation, producing machine code. | 283 // Assembles an instruction after register allocation, producing machine code. |
291 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 284 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
292 Arm64OperandConverter i(this, instr); | 285 Arm64OperandConverter i(this, instr); |
293 InstructionCode opcode = instr->opcode(); | 286 InstructionCode opcode = instr->opcode(); |
294 switch (ArchOpcodeField::decode(opcode)) { | 287 switch (ArchOpcodeField::decode(opcode)) { |
295 case kArchCallCodeObject: { | 288 case kArchCallCodeObject: { |
296 EnsureSpaceForLazyDeopt(); | 289 EnsureSpaceForLazyDeopt(); |
297 if (instr->InputAt(0)->IsImmediate()) { | 290 if (instr->InputAt(0)->IsImmediate()) { |
298 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 291 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
299 RelocInfo::CODE_TARGET); | 292 RelocInfo::CODE_TARGET); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 __ Sxtw(i.OutputRegister(), i.InputRegister32(0)); | 527 __ Sxtw(i.OutputRegister(), i.InputRegister32(0)); |
535 break; | 528 break; |
536 case kArm64Ubfx: | 529 case kArm64Ubfx: |
537 __ Ubfx(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1), | 530 __ Ubfx(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1), |
538 i.InputInt8(2)); | 531 i.InputInt8(2)); |
539 break; | 532 break; |
540 case kArm64Ubfx32: | 533 case kArm64Ubfx32: |
541 __ Ubfx(i.OutputRegister32(), i.InputRegister32(0), i.InputInt8(1), | 534 __ Ubfx(i.OutputRegister32(), i.InputRegister32(0), i.InputInt8(1), |
542 i.InputInt8(2)); | 535 i.InputInt8(2)); |
543 break; | 536 break; |
544 case kArm64Tbz: | 537 case kArm64TestAndBranch32: |
545 __ Tbz(i.InputRegister64(0), i.InputInt6(1), GetLabel(i.InputRpo(2))); | 538 case kArm64TestAndBranch: |
546 ASSEMBLE_BRANCH_TO(i.InputRpo(3)); | 539 // Pseudo instructions turned into tbz/tbnz in AssembleArchBranch. |
547 break; | 540 break; |
548 case kArm64Tbz32: | 541 case kArm64CompareAndBranch32: |
549 __ Tbz(i.InputRegister32(0), i.InputInt5(1), GetLabel(i.InputRpo(2))); | 542 // Pseudo instruction turned into cbz/cbnz in AssembleArchBranch. |
550 ASSEMBLE_BRANCH_TO(i.InputRpo(3)); | |
551 break; | |
552 case kArm64Tbnz: | |
553 __ Tbnz(i.InputRegister64(0), i.InputInt6(1), GetLabel(i.InputRpo(2))); | |
554 ASSEMBLE_BRANCH_TO(i.InputRpo(3)); | |
555 break; | |
556 case kArm64Tbnz32: | |
557 __ Tbnz(i.InputRegister32(0), i.InputInt5(1), GetLabel(i.InputRpo(2))); | |
558 ASSEMBLE_BRANCH_TO(i.InputRpo(3)); | |
559 break; | |
560 case kArm64Cbz32: | |
561 __ Cbz(i.InputRegister32(0), GetLabel(i.InputRpo(1))); | |
562 ASSEMBLE_BRANCH_TO(i.InputRpo(2)); | |
563 break; | |
564 case kArm64Cbnz32: | |
565 __ Cbnz(i.InputRegister32(0), GetLabel(i.InputRpo(1))); | |
566 ASSEMBLE_BRANCH_TO(i.InputRpo(2)); | |
567 break; | 543 break; |
568 case kArm64Claim: { | 544 case kArm64Claim: { |
569 int words = MiscField::decode(instr->opcode()); | 545 int words = MiscField::decode(instr->opcode()); |
570 __ Claim(words); | 546 __ Claim(words); |
571 break; | 547 break; |
572 } | 548 } |
573 case kArm64Poke: { | 549 case kArm64Poke: { |
574 int slot = MiscField::decode(instr->opcode()); | 550 int slot = MiscField::decode(instr->opcode()); |
575 Operand operand(slot * kPointerSize); | 551 Operand operand(slot * kPointerSize); |
576 __ Poke(i.InputRegister(0), operand); | 552 __ Poke(i.InputRegister(0), operand); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 break; | 735 break; |
760 } | 736 } |
761 } | 737 } |
762 | 738 |
763 | 739 |
764 // Assemble branches after this instruction. | 740 // Assemble branches after this instruction. |
765 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 741 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
766 Arm64OperandConverter i(this, instr); | 742 Arm64OperandConverter i(this, instr); |
767 Label* tlabel = branch->true_label; | 743 Label* tlabel = branch->true_label; |
768 Label* flabel = branch->false_label; | 744 Label* flabel = branch->false_label; |
769 switch (branch->condition) { | 745 FlagsCondition condition = branch->condition; |
770 case kUnorderedEqual: | 746 ArchOpcode opcode = instr->arch_opcode(); |
771 __ B(vs, flabel); | 747 |
772 // Fall through. | 748 if (opcode == kArm64CompareAndBranch32) { |
773 case kEqual: | 749 switch (condition) { |
774 __ B(eq, tlabel); | 750 case kEqual: |
775 break; | 751 __ Cbz(i.InputRegister32(0), tlabel); |
776 case kUnorderedNotEqual: | 752 break; |
777 __ B(vs, tlabel); | 753 case kNotEqual: |
778 // Fall through. | 754 __ Cbnz(i.InputRegister32(0), tlabel); |
779 case kNotEqual: | 755 break; |
780 __ B(ne, tlabel); | 756 default: |
781 break; | 757 UNREACHABLE(); |
782 case kSignedLessThan: | 758 } |
783 __ B(lt, tlabel); | 759 } else if (opcode == kArm64TestAndBranch32) { |
784 break; | 760 switch (condition) { |
785 case kSignedGreaterThanOrEqual: | 761 case kEqual: |
786 __ B(ge, tlabel); | 762 __ Tbz(i.InputRegister32(0), i.InputInt5(1), tlabel); |
787 break; | 763 break; |
788 case kSignedLessThanOrEqual: | 764 case kNotEqual: |
789 __ B(le, tlabel); | 765 __ Tbnz(i.InputRegister32(0), i.InputInt5(1), tlabel); |
790 break; | 766 break; |
791 case kSignedGreaterThan: | 767 default: |
792 __ B(gt, tlabel); | 768 UNREACHABLE(); |
793 break; | 769 } |
794 case kUnorderedLessThan: | 770 } else if (opcode == kArm64TestAndBranch) { |
795 __ B(vs, flabel); | 771 switch (condition) { |
796 // Fall through. | 772 case kEqual: |
797 case kUnsignedLessThan: | 773 __ Tbz(i.InputRegister64(0), i.InputInt6(1), tlabel); |
798 __ B(lo, tlabel); | 774 break; |
799 break; | 775 case kNotEqual: |
800 case kUnorderedGreaterThanOrEqual: | 776 __ Tbnz(i.InputRegister64(0), i.InputInt6(1), tlabel); |
801 __ B(vs, tlabel); | 777 break; |
802 // Fall through. | 778 default: |
803 case kUnsignedGreaterThanOrEqual: | 779 UNREACHABLE(); |
804 __ B(hs, tlabel); | 780 } |
805 break; | 781 } else { |
806 case kUnorderedLessThanOrEqual: | 782 switch (condition) { |
807 __ B(vs, flabel); | 783 case kUnorderedEqual: |
808 // Fall through. | 784 __ B(vs, flabel); |
809 case kUnsignedLessThanOrEqual: | 785 // Fall through. |
810 __ B(ls, tlabel); | 786 case kEqual: |
811 break; | 787 __ B(eq, tlabel); |
812 case kUnorderedGreaterThan: | 788 break; |
813 __ B(vs, tlabel); | 789 case kUnorderedNotEqual: |
814 // Fall through. | 790 __ B(vs, tlabel); |
815 case kUnsignedGreaterThan: | 791 // Fall through. |
816 __ B(hi, tlabel); | 792 case kNotEqual: |
817 break; | 793 __ B(ne, tlabel); |
818 case kOverflow: | 794 break; |
819 __ B(vs, tlabel); | 795 case kSignedLessThan: |
820 break; | 796 __ B(lt, tlabel); |
821 case kNotOverflow: | 797 break; |
822 __ B(vc, tlabel); | 798 case kSignedGreaterThanOrEqual: |
823 break; | 799 __ B(ge, tlabel); |
| 800 break; |
| 801 case kSignedLessThanOrEqual: |
| 802 __ B(le, tlabel); |
| 803 break; |
| 804 case kSignedGreaterThan: |
| 805 __ B(gt, tlabel); |
| 806 break; |
| 807 case kUnorderedLessThan: |
| 808 __ B(vs, flabel); |
| 809 // Fall through. |
| 810 case kUnsignedLessThan: |
| 811 __ B(lo, tlabel); |
| 812 break; |
| 813 case kUnorderedGreaterThanOrEqual: |
| 814 __ B(vs, tlabel); |
| 815 // Fall through. |
| 816 case kUnsignedGreaterThanOrEqual: |
| 817 __ B(hs, tlabel); |
| 818 break; |
| 819 case kUnorderedLessThanOrEqual: |
| 820 __ B(vs, flabel); |
| 821 // Fall through. |
| 822 case kUnsignedLessThanOrEqual: |
| 823 __ B(ls, tlabel); |
| 824 break; |
| 825 case kUnorderedGreaterThan: |
| 826 __ B(vs, tlabel); |
| 827 // Fall through. |
| 828 case kUnsignedGreaterThan: |
| 829 __ B(hi, tlabel); |
| 830 break; |
| 831 case kOverflow: |
| 832 __ B(vs, tlabel); |
| 833 break; |
| 834 case kNotOverflow: |
| 835 __ B(vc, tlabel); |
| 836 break; |
| 837 } |
824 } | 838 } |
825 if (!branch->fallthru) __ B(flabel); // no fallthru to flabel. | 839 if (!branch->fallthru) __ B(flabel); // no fallthru to flabel. |
826 } | 840 } |
827 | 841 |
828 | 842 |
829 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 843 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { |
830 if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target)); | 844 if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target)); |
831 } | 845 } |
832 | 846 |
833 | 847 |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 } | 1171 } |
1158 } | 1172 } |
1159 MarkLazyDeoptSite(); | 1173 MarkLazyDeoptSite(); |
1160 } | 1174 } |
1161 | 1175 |
1162 #undef __ | 1176 #undef __ |
1163 | 1177 |
1164 } // namespace compiler | 1178 } // namespace compiler |
1165 } // namespace internal | 1179 } // namespace internal |
1166 } // namespace v8 | 1180 } // namespace v8 |
OLD | NEW |