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/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 public: | 193 public: |
194 OutOfLineLoadInteger(CodeGenerator* gen, Register result) | 194 OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
195 : OutOfLineCode(gen), result_(result) {} | 195 : OutOfLineCode(gen), result_(result) {} |
196 | 196 |
197 void Generate() FINAL { __ mov(result_, Operand::Zero()); } | 197 void Generate() FINAL { __ mov(result_, Operand::Zero()); } |
198 | 198 |
199 private: | 199 private: |
200 Register const result_; | 200 Register const result_; |
201 }; | 201 }; |
202 | 202 |
| 203 |
| 204 Condition FlagsConditionToCondition(FlagsCondition condition) { |
| 205 switch (condition) { |
| 206 case kEqual: |
| 207 return eq; |
| 208 case kNotEqual: |
| 209 return ne; |
| 210 case kSignedLessThan: |
| 211 return lt; |
| 212 case kSignedGreaterThanOrEqual: |
| 213 return ge; |
| 214 case kSignedLessThanOrEqual: |
| 215 return le; |
| 216 case kSignedGreaterThan: |
| 217 return gt; |
| 218 case kUnsignedLessThan: |
| 219 return lo; |
| 220 case kUnsignedGreaterThanOrEqual: |
| 221 return hs; |
| 222 case kUnsignedLessThanOrEqual: |
| 223 return ls; |
| 224 case kUnsignedGreaterThan: |
| 225 return hi; |
| 226 case kOverflow: |
| 227 return vs; |
| 228 case kNotOverflow: |
| 229 return vc; |
| 230 case kUnorderedEqual: |
| 231 case kUnorderedNotEqual: |
| 232 break; |
| 233 } |
| 234 UNREACHABLE(); |
| 235 return kNoCondition; |
| 236 } |
| 237 |
203 } // namespace | 238 } // namespace |
204 | 239 |
205 | 240 |
206 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ | 241 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ |
207 do { \ | 242 do { \ |
208 auto result = i.OutputFloat##width##Register(); \ | 243 auto result = i.OutputFloat##width##Register(); \ |
209 auto offset = i.InputRegister(0); \ | 244 auto offset = i.InputRegister(0); \ |
210 if (instr->InputAt(1)->IsRegister()) { \ | 245 if (instr->InputAt(1)->IsRegister()) { \ |
211 __ cmp(offset, i.InputRegister(1)); \ | 246 __ cmp(offset, i.InputRegister(1)); \ |
212 } else { \ | 247 } else { \ |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 break; | 714 break; |
680 } | 715 } |
681 } | 716 } |
682 | 717 |
683 | 718 |
684 // Assembles branches after an instruction. | 719 // Assembles branches after an instruction. |
685 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 720 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
686 ArmOperandConverter i(this, instr); | 721 ArmOperandConverter i(this, instr); |
687 Label* tlabel = branch->true_label; | 722 Label* tlabel = branch->true_label; |
688 Label* flabel = branch->false_label; | 723 Label* flabel = branch->false_label; |
689 switch (branch->condition) { | 724 Condition cc = FlagsConditionToCondition(branch->condition); |
690 case kUnorderedEqual: | 725 __ b(cc, tlabel); |
691 // The "eq" condition will not catch the unordered case. | |
692 // The jump/fall through to false label will be used if the comparison | |
693 // was unordered. | |
694 case kEqual: | |
695 __ b(eq, tlabel); | |
696 break; | |
697 case kUnorderedNotEqual: | |
698 // Unordered or not equal can be tested with "ne" condtion. | |
699 // See ARMv7 manual A8.3 - Conditional execution. | |
700 case kNotEqual: | |
701 __ b(ne, tlabel); | |
702 break; | |
703 case kSignedLessThan: | |
704 __ b(lt, tlabel); | |
705 break; | |
706 case kSignedGreaterThanOrEqual: | |
707 __ b(ge, tlabel); | |
708 break; | |
709 case kSignedLessThanOrEqual: | |
710 __ b(le, tlabel); | |
711 break; | |
712 case kSignedGreaterThan: | |
713 __ b(gt, tlabel); | |
714 break; | |
715 case kUnorderedLessThan: | |
716 // The "lo" condition will not catch the unordered case. | |
717 // The jump/fall through to false label will be used if the comparison | |
718 // was unordered. | |
719 case kUnsignedLessThan: | |
720 __ b(lo, tlabel); | |
721 break; | |
722 case kUnorderedGreaterThanOrEqual: | |
723 // Unordered, greater than or equal can be tested with "hs" condtion. | |
724 // See ARMv7 manual A8.3 - Conditional execution. | |
725 case kUnsignedGreaterThanOrEqual: | |
726 __ b(hs, tlabel); | |
727 break; | |
728 case kUnorderedLessThanOrEqual: | |
729 // The "ls" condition will not catch the unordered case. | |
730 // The jump/fall through to false label will be used if the comparison | |
731 // was unordered. | |
732 case kUnsignedLessThanOrEqual: | |
733 __ b(ls, tlabel); | |
734 break; | |
735 case kUnorderedGreaterThan: | |
736 // Unordered or greater than can be tested with "hi" condtion. | |
737 // See ARMv7 manual A8.3 - Conditional execution. | |
738 case kUnsignedGreaterThan: | |
739 __ b(hi, tlabel); | |
740 break; | |
741 case kOverflow: | |
742 __ b(vs, tlabel); | |
743 break; | |
744 case kNotOverflow: | |
745 __ b(vc, tlabel); | |
746 break; | |
747 } | |
748 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. | 726 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. |
749 } | 727 } |
750 | 728 |
751 | 729 |
752 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 730 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { |
753 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); | 731 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); |
754 } | 732 } |
755 | 733 |
756 | 734 |
757 // Assembles boolean materializations after an instruction. | 735 // Assembles boolean materializations after an instruction. |
758 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 736 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
759 FlagsCondition condition) { | 737 FlagsCondition condition) { |
760 ArmOperandConverter i(this, instr); | 738 ArmOperandConverter i(this, instr); |
761 Label done; | |
762 | 739 |
763 // Materialize a full 32-bit 1 or 0 value. The result register is always the | 740 // Materialize a full 32-bit 1 or 0 value. The result register is always the |
764 // last output of the instruction. | 741 // last output of the instruction. |
765 Label check; | |
766 DCHECK_NE(0, instr->OutputCount()); | 742 DCHECK_NE(0, instr->OutputCount()); |
767 Register reg = i.OutputRegister(instr->OutputCount() - 1); | 743 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
768 Condition cc = kNoCondition; | 744 Condition cc = FlagsConditionToCondition(condition); |
769 switch (condition) { | |
770 case kUnorderedEqual: | |
771 __ b(vc, &check); | |
772 __ mov(reg, Operand(0)); | |
773 __ b(&done); | |
774 // Fall through. | |
775 case kEqual: | |
776 cc = eq; | |
777 break; | |
778 case kUnorderedNotEqual: | |
779 __ b(vc, &check); | |
780 __ mov(reg, Operand(1)); | |
781 __ b(&done); | |
782 // Fall through. | |
783 case kNotEqual: | |
784 cc = ne; | |
785 break; | |
786 case kSignedLessThan: | |
787 cc = lt; | |
788 break; | |
789 case kSignedGreaterThanOrEqual: | |
790 cc = ge; | |
791 break; | |
792 case kSignedLessThanOrEqual: | |
793 cc = le; | |
794 break; | |
795 case kSignedGreaterThan: | |
796 cc = gt; | |
797 break; | |
798 case kUnorderedLessThan: | |
799 __ b(vc, &check); | |
800 __ mov(reg, Operand(0)); | |
801 __ b(&done); | |
802 // Fall through. | |
803 case kUnsignedLessThan: | |
804 cc = lo; | |
805 break; | |
806 case kUnorderedGreaterThanOrEqual: | |
807 __ b(vc, &check); | |
808 __ mov(reg, Operand(1)); | |
809 __ b(&done); | |
810 // Fall through. | |
811 case kUnsignedGreaterThanOrEqual: | |
812 cc = hs; | |
813 break; | |
814 case kUnorderedLessThanOrEqual: | |
815 __ b(vc, &check); | |
816 __ mov(reg, Operand(0)); | |
817 __ b(&done); | |
818 // Fall through. | |
819 case kUnsignedLessThanOrEqual: | |
820 cc = ls; | |
821 break; | |
822 case kUnorderedGreaterThan: | |
823 __ b(vc, &check); | |
824 __ mov(reg, Operand(1)); | |
825 __ b(&done); | |
826 // Fall through. | |
827 case kUnsignedGreaterThan: | |
828 cc = hi; | |
829 break; | |
830 case kOverflow: | |
831 cc = vs; | |
832 break; | |
833 case kNotOverflow: | |
834 cc = vc; | |
835 break; | |
836 } | |
837 __ bind(&check); | |
838 __ mov(reg, Operand(0)); | 745 __ mov(reg, Operand(0)); |
839 __ mov(reg, Operand(1), LeaveCC, cc); | 746 __ mov(reg, Operand(1), LeaveCC, cc); |
840 __ bind(&done); | |
841 } | 747 } |
842 | 748 |
843 | 749 |
844 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 750 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
845 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 751 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
846 isolate(), deoptimization_id, Deoptimizer::LAZY); | 752 isolate(), deoptimization_id, Deoptimizer::LAZY); |
847 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 753 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
848 } | 754 } |
849 | 755 |
850 | 756 |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 } | 1029 } |
1124 } | 1030 } |
1125 MarkLazyDeoptSite(); | 1031 MarkLazyDeoptSite(); |
1126 } | 1032 } |
1127 | 1033 |
1128 #undef __ | 1034 #undef __ |
1129 | 1035 |
1130 } // namespace compiler | 1036 } // namespace compiler |
1131 } // namespace internal | 1037 } // namespace internal |
1132 } // namespace v8 | 1038 } // namespace v8 |
OLD | NEW |