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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 public: | 209 public: |
210 OutOfLineLoadZero(CodeGenerator* gen, Register result) | 210 OutOfLineLoadZero(CodeGenerator* gen, Register result) |
211 : OutOfLineCode(gen), result_(result) {} | 211 : OutOfLineCode(gen), result_(result) {} |
212 | 212 |
213 void Generate() FINAL { __ Mov(result_, 0); } | 213 void Generate() FINAL { __ Mov(result_, 0); } |
214 | 214 |
215 private: | 215 private: |
216 Register const result_; | 216 Register const result_; |
217 }; | 217 }; |
218 | 218 |
| 219 |
| 220 Condition FlagsConditionToCondition(FlagsCondition condition) { |
| 221 switch (condition) { |
| 222 case kEqual: |
| 223 return eq; |
| 224 case kNotEqual: |
| 225 return ne; |
| 226 case kSignedLessThan: |
| 227 return lt; |
| 228 case kSignedGreaterThanOrEqual: |
| 229 return ge; |
| 230 case kSignedLessThanOrEqual: |
| 231 return le; |
| 232 case kSignedGreaterThan: |
| 233 return gt; |
| 234 case kUnsignedLessThan: |
| 235 return lo; |
| 236 case kUnsignedGreaterThanOrEqual: |
| 237 return hs; |
| 238 case kUnsignedLessThanOrEqual: |
| 239 return ls; |
| 240 case kUnsignedGreaterThan: |
| 241 return hi; |
| 242 case kOverflow: |
| 243 return vs; |
| 244 case kNotOverflow: |
| 245 return vc; |
| 246 case kUnorderedEqual: |
| 247 case kUnorderedNotEqual: |
| 248 break; |
| 249 } |
| 250 UNREACHABLE(); |
| 251 return nv; |
| 252 } |
| 253 |
219 } // namespace | 254 } // namespace |
220 | 255 |
221 | 256 |
222 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ | 257 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ |
223 do { \ | 258 do { \ |
224 auto result = i.OutputFloat##width##Register(); \ | 259 auto result = i.OutputFloat##width##Register(); \ |
225 auto buffer = i.InputRegister(0); \ | 260 auto buffer = i.InputRegister(0); \ |
226 auto offset = i.InputRegister32(1); \ | 261 auto offset = i.InputRegister32(1); \ |
227 auto length = i.InputOperand32(2); \ | 262 auto length = i.InputOperand32(2); \ |
228 __ Cmp(offset, length); \ | 263 __ Cmp(offset, length); \ |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 case kEqual: | 814 case kEqual: |
780 __ Tbz(i.InputRegister64(0), i.InputInt6(1), tlabel); | 815 __ Tbz(i.InputRegister64(0), i.InputInt6(1), tlabel); |
781 break; | 816 break; |
782 case kNotEqual: | 817 case kNotEqual: |
783 __ Tbnz(i.InputRegister64(0), i.InputInt6(1), tlabel); | 818 __ Tbnz(i.InputRegister64(0), i.InputInt6(1), tlabel); |
784 break; | 819 break; |
785 default: | 820 default: |
786 UNREACHABLE(); | 821 UNREACHABLE(); |
787 } | 822 } |
788 } else { | 823 } else { |
789 switch (condition) { | 824 Condition cc = FlagsConditionToCondition(condition); |
790 case kUnorderedEqual: | 825 __ B(cc, tlabel); |
791 // The "eq" condition will not catch the unordered case. | |
792 // The jump/fall through to false label will be used if the comparison | |
793 // was unordered. | |
794 case kEqual: | |
795 __ B(eq, tlabel); | |
796 break; | |
797 case kUnorderedNotEqual: | |
798 // Unordered or not equal can be tested with "ne" condtion. | |
799 // See ARMv8 manual C1.2.3 - Condition Code. | |
800 case kNotEqual: | |
801 __ B(ne, tlabel); | |
802 break; | |
803 case kSignedLessThan: | |
804 __ B(lt, tlabel); | |
805 break; | |
806 case kSignedGreaterThanOrEqual: | |
807 __ B(ge, tlabel); | |
808 break; | |
809 case kSignedLessThanOrEqual: | |
810 __ B(le, tlabel); | |
811 break; | |
812 case kSignedGreaterThan: | |
813 __ B(gt, tlabel); | |
814 break; | |
815 case kUnorderedLessThan: | |
816 // The "lo" condition will not catch the unordered case. | |
817 // The jump/fall through to false label will be used if the comparison | |
818 // was unordered. | |
819 case kUnsignedLessThan: | |
820 __ B(lo, tlabel); | |
821 break; | |
822 case kUnorderedGreaterThanOrEqual: | |
823 // Unordered, greater than or equal can be tested with "hs" condtion. | |
824 // See ARMv8 manual C1.2.3 - Condition Code. | |
825 case kUnsignedGreaterThanOrEqual: | |
826 __ B(hs, tlabel); | |
827 break; | |
828 case kUnorderedLessThanOrEqual: | |
829 // The "ls" condition will not catch the unordered case. | |
830 // The jump/fall through to false label will be used if the comparison | |
831 // was unordered. | |
832 case kUnsignedLessThanOrEqual: | |
833 __ B(ls, tlabel); | |
834 break; | |
835 case kUnorderedGreaterThan: | |
836 // Unordered or greater than can be tested with "hi" condtion. | |
837 // See ARMv8 manual C1.2.3 - Condition Code. | |
838 case kUnsignedGreaterThan: | |
839 __ B(hi, tlabel); | |
840 break; | |
841 case kOverflow: | |
842 __ B(vs, tlabel); | |
843 break; | |
844 case kNotOverflow: | |
845 __ B(vc, tlabel); | |
846 break; | |
847 } | |
848 } | 826 } |
849 if (!branch->fallthru) __ B(flabel); // no fallthru to flabel. | 827 if (!branch->fallthru) __ B(flabel); // no fallthru to flabel. |
850 } | 828 } |
851 | 829 |
852 | 830 |
853 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 831 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { |
854 if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target)); | 832 if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target)); |
855 } | 833 } |
856 | 834 |
857 | 835 |
858 // Assemble boolean materializations after this instruction. | 836 // Assemble boolean materializations after this instruction. |
859 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 837 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
860 FlagsCondition condition) { | 838 FlagsCondition condition) { |
861 Arm64OperandConverter i(this, instr); | 839 Arm64OperandConverter i(this, instr); |
862 Label done; | |
863 | 840 |
864 // Materialize a full 64-bit 1 or 0 value. The result register is always the | 841 // Materialize a full 64-bit 1 or 0 value. The result register is always the |
865 // last output of the instruction. | 842 // last output of the instruction. |
866 Label check; | |
867 DCHECK_NE(0, instr->OutputCount()); | 843 DCHECK_NE(0, instr->OutputCount()); |
868 Register reg = i.OutputRegister(instr->OutputCount() - 1); | 844 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
869 Condition cc = nv; | 845 Condition cc = FlagsConditionToCondition(condition); |
870 switch (condition) { | |
871 case kUnorderedEqual: | |
872 __ B(vc, &check); | |
873 __ Mov(reg, 0); | |
874 __ B(&done); | |
875 // Fall through. | |
876 case kEqual: | |
877 cc = eq; | |
878 break; | |
879 case kUnorderedNotEqual: | |
880 __ B(vc, &check); | |
881 __ Mov(reg, 1); | |
882 __ B(&done); | |
883 // Fall through. | |
884 case kNotEqual: | |
885 cc = ne; | |
886 break; | |
887 case kSignedLessThan: | |
888 cc = lt; | |
889 break; | |
890 case kSignedGreaterThanOrEqual: | |
891 cc = ge; | |
892 break; | |
893 case kSignedLessThanOrEqual: | |
894 cc = le; | |
895 break; | |
896 case kSignedGreaterThan: | |
897 cc = gt; | |
898 break; | |
899 case kUnorderedLessThan: | |
900 __ B(vc, &check); | |
901 __ Mov(reg, 0); | |
902 __ B(&done); | |
903 // Fall through. | |
904 case kUnsignedLessThan: | |
905 cc = lo; | |
906 break; | |
907 case kUnorderedGreaterThanOrEqual: | |
908 __ B(vc, &check); | |
909 __ Mov(reg, 1); | |
910 __ B(&done); | |
911 // Fall through. | |
912 case kUnsignedGreaterThanOrEqual: | |
913 cc = hs; | |
914 break; | |
915 case kUnorderedLessThanOrEqual: | |
916 __ B(vc, &check); | |
917 __ Mov(reg, 0); | |
918 __ B(&done); | |
919 // Fall through. | |
920 case kUnsignedLessThanOrEqual: | |
921 cc = ls; | |
922 break; | |
923 case kUnorderedGreaterThan: | |
924 __ B(vc, &check); | |
925 __ Mov(reg, 1); | |
926 __ B(&done); | |
927 // Fall through. | |
928 case kUnsignedGreaterThan: | |
929 cc = hi; | |
930 break; | |
931 case kOverflow: | |
932 cc = vs; | |
933 break; | |
934 case kNotOverflow: | |
935 cc = vc; | |
936 break; | |
937 } | |
938 __ Bind(&check); | |
939 __ Cset(reg, cc); | 846 __ Cset(reg, cc); |
940 __ Bind(&done); | |
941 } | 847 } |
942 | 848 |
943 | 849 |
944 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 850 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
945 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 851 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
946 isolate(), deoptimization_id, Deoptimizer::LAZY); | 852 isolate(), deoptimization_id, Deoptimizer::LAZY); |
947 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 853 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
948 } | 854 } |
949 | 855 |
950 | 856 |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 } | 1104 } |
1199 } | 1105 } |
1200 MarkLazyDeoptSite(); | 1106 MarkLazyDeoptSite(); |
1201 } | 1107 } |
1202 | 1108 |
1203 #undef __ | 1109 #undef __ |
1204 | 1110 |
1205 } // namespace compiler | 1111 } // namespace compiler |
1206 } // namespace internal | 1112 } // namespace internal |
1207 } // namespace v8 | 1113 } // namespace v8 |
OLD | NEW |