5 #include "src/compiler/backend/code-generator.h" 6 #include "src/compiler/backend/instruction-scheduler.h" 12 bool InstructionScheduler::SchedulerSupported() {
return true; }
14 int InstructionScheduler::GetTargetInstructionFlags(
15 const Instruction* instr)
const {
16 switch (instr->arch_opcode()) {
46 case kMipsF32x4AddHoriz:
48 case kMipsF32x4ExtractLane:
56 case kMipsF32x4RecipApprox:
57 case kMipsF32x4RecipSqrtApprox:
58 case kMipsF32x4ReplaceLane:
59 case kMipsF32x4SConvertI32x4:
62 case kMipsF32x4UConvertI32x4:
65 case kMipsFloat32RoundDown:
66 case kMipsFloat32RoundTiesEven:
67 case kMipsFloat32RoundTruncate:
68 case kMipsFloat32RoundUp:
69 case kMipsFloat64ExtractHighWord32:
70 case kMipsFloat64ExtractLowWord32:
71 case kMipsFloat64InsertHighWord32:
72 case kMipsFloat64InsertLowWord32:
75 case kMipsFloat64RoundDown:
76 case kMipsFloat64RoundTiesEven:
77 case kMipsFloat64RoundTruncate:
78 case kMipsFloat64RoundUp:
79 case kMipsFloat64SilenceNaN:
83 case kMipsI16x8AddHoriz:
84 case kMipsI16x8AddSaturateS:
85 case kMipsI16x8AddSaturateU:
87 case kMipsI16x8ExtractLane:
99 case kMipsI16x8ReplaceLane:
100 case kMipsI16x8SConvertI32x4:
101 case kMipsI16x8SConvertI8x16High:
102 case kMipsI16x8SConvertI8x16Low:
106 case kMipsI16x8Splat:
108 case kMipsI16x8SubSaturateS:
109 case kMipsI16x8SubSaturateU:
110 case kMipsI16x8UConvertI32x4:
111 case kMipsI16x8UConvertI8x16High:
112 case kMipsI16x8UConvertI8x16Low:
114 case kMipsI32x4AddHoriz:
116 case kMipsI32x4ExtractLane:
128 case kMipsI32x4ReplaceLane:
129 case kMipsI32x4SConvertF32x4:
130 case kMipsI32x4SConvertI16x8High:
131 case kMipsI32x4SConvertI16x8Low:
135 case kMipsI32x4Splat:
137 case kMipsI32x4UConvertF32x4:
138 case kMipsI32x4UConvertI16x8High:
139 case kMipsI32x4UConvertI16x8Low:
141 case kMipsI8x16AddSaturateS:
142 case kMipsI8x16AddSaturateU:
144 case kMipsI8x16ExtractLane:
156 case kMipsI8x16ReplaceLane:
157 case kMipsI8x16SConvertI16x8:
161 case kMipsI8x16Splat:
163 case kMipsI8x16SubSaturateS:
164 case kMipsI8x16SubSaturateU:
165 case kMipsI8x16UConvertI16x8:
197 case kMipsS128Select:
200 case kMipsS16x2Reverse:
201 case kMipsS16x4Reverse:
202 case kMipsS16x8InterleaveEven:
203 case kMipsS16x8InterleaveLeft:
204 case kMipsS16x8InterleaveOdd:
205 case kMipsS16x8InterleaveRight:
206 case kMipsS16x8PackEven:
207 case kMipsS16x8PackOdd:
208 case kMipsS1x16AllTrue:
209 case kMipsS1x16AnyTrue:
210 case kMipsS1x4AllTrue:
211 case kMipsS1x4AnyTrue:
212 case kMipsS1x8AllTrue:
213 case kMipsS1x8AnyTrue:
214 case kMipsS32x4InterleaveEven:
215 case kMipsS32x4InterleaveLeft:
216 case kMipsS32x4InterleaveOdd:
217 case kMipsS32x4InterleaveRight:
218 case kMipsS32x4PackEven:
219 case kMipsS32x4PackOdd:
220 case kMipsS32x4Shuffle:
221 case kMipsS8x16Concat:
222 case kMipsS8x16InterleaveEven:
223 case kMipsS8x16InterleaveLeft:
224 case kMipsS8x16InterleaveOdd:
225 case kMipsS8x16InterleaveRight:
226 case kMipsS8x16PackEven:
227 case kMipsS8x16PackOdd:
228 case kMipsS8x16Shuffle:
229 case kMipsS8x2Reverse:
230 case kMipsS8x4Reverse:
231 case kMipsS8x8Reverse:
253 return kNoOpcodeFlags;
269 case kMipsWord32AtomicPairLoad:
270 return kIsLoadOperation;
279 case kMipsStackClaim:
280 case kMipsStoreToStackSlot:
287 case kMipsWord32AtomicPairStore:
288 case kMipsWord32AtomicPairAdd:
289 case kMipsWord32AtomicPairSub:
290 case kMipsWord32AtomicPairAnd:
291 case kMipsWord32AtomicPairOr:
292 case kMipsWord32AtomicPairXor:
293 case kMipsWord32AtomicPairExchange:
294 case kMipsWord32AtomicPairCompareExchange:
295 return kHasSideEffect;
297 #define CASE(Name) case k##Name: 298 COMMON_ARCH_OPCODE_LIST(CASE)
439 if (IsMipsArchVariant(kLoongson)) {
440 return (6 + 2 * Latency::BRANCH);
446 int RorLatency(
bool is_operand_register =
true) {
447 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
450 if (is_operand_register) {
458 int AdduLatency(
bool is_operand_register =
true) {
459 if (is_operand_register) {
466 int XorLatency(
bool is_operand_register =
true) {
467 return AdduLatency(is_operand_register);
470 int AndLatency(
bool is_operand_register =
true) {
471 return AdduLatency(is_operand_register);
474 int OrLatency(
bool is_operand_register =
true) {
475 return AdduLatency(is_operand_register);
478 int SubuLatency(
bool is_operand_register =
true) {
479 return AdduLatency(is_operand_register);
482 int MulLatency(
bool is_operand_register =
true) {
483 if (is_operand_register) {
484 if (IsMipsArchVariant(kLoongson)) {
485 return Latency::MULT + 1;
487 return Latency::MUL + 1;
490 if (IsMipsArchVariant(kLoongson)) {
491 return Latency::MULT + 2;
493 return Latency::MUL + 2;
498 int NorLatency(
bool is_operand_register =
true) {
499 if (is_operand_register) {
507 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
510 return SubuLatency(
false) + 7;
514 int ShlPairLatency(
bool is_operand_register =
true) {
515 if (is_operand_register) {
517 AndLatency(
false) + NorLatency() + OrLatency() + AndLatency(
false) + 4;
518 if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) {
519 return latency + Latency::BRANCH + 2;
528 int ShrPairLatency(
bool is_operand_register =
true,
uint32_t shift = 0) {
529 if (is_operand_register) {
531 AndLatency(
false) + NorLatency() + OrLatency() + AndLatency(
false) + 4;
532 if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) {
533 return latency + Latency::BRANCH + 2;
539 return (InsLatency() + 2 > OrLatency() + 3) ? InsLatency() + 2
544 int SarPairLatency(
bool is_operand_register =
true,
uint32_t shift = 0) {
545 if (is_operand_register) {
546 return AndLatency(
false) + NorLatency() + OrLatency() + AndLatency(
false) +
549 shift = shift & 0x3F;
552 }
else if (shift < 32) {
553 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
554 return InsLatency() + 2;
556 return OrLatency() + 3;
558 }
else if (shift == 32) {
567 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
577 return AdduLatency() + 1;
580 int SltLatency(
bool is_operand_register =
true) {
581 if (is_operand_register) {
588 int SltuLatency(
bool is_operand_register =
true) {
589 return SltLatency(is_operand_register);
592 int AddPairLatency() {
return 3 * AdduLatency() + SltLatency(); }
594 int SubPairLatency() {
return SltuLatency() + 3 * SubuLatency(); }
596 int MuluLatency(
bool is_operand_register =
true) {
598 if (!is_operand_register) latency++;
599 if (!IsMipsArchVariant(kMips32r6)) {
600 return latency + Latency::MULTU + 2;
602 return latency + Latency::MULU + Latency::MUHU;
606 int MulPairLatency() {
607 return MuluLatency() + 2 * MulLatency() + 2 * AdduLatency();
611 if (IsMipsArchVariant(kMips32r2)) {
612 return Latency::MADD_D;
614 return Latency::MUL_D + Latency::ADD_D;
619 if (IsMipsArchVariant(kMips32r2)) {
620 return Latency::MADD_D;
622 return Latency::MUL_D + Latency::ADD_D;
627 if (IsMipsArchVariant(kMips32r2)) {
628 return Latency::MSUB_S;
630 return Latency::MUL_S + Latency::SUB_S;
635 if (IsMipsArchVariant(kMips32r2)) {
636 return Latency::MSUB_D;
638 return Latency::MUL_D + Latency::SUB_D;
644 return Latency::MFC1;
652 return Latency::MTC1;
658 int MoveLatency(
bool is_double_register =
true) {
659 if (!is_double_register) {
660 return Latency::MTC1 + 1;
662 return Mthc1Latency() + 1;
666 int Float64RoundLatency() {
667 if (IsMipsArchVariant(kMips32r6)) {
668 return Latency::RINT_D + 4;
671 return Mfhc1Latency() + ExtLatency() + Latency::BRANCH + Latency::MOV_D +
672 4 + MoveLatency() + 1 + Latency::BRANCH + Latency::CVT_D_L;
676 int Float32RoundLatency() {
677 if (IsMipsArchVariant(kMips32r6)) {
678 return Latency::RINT_S + 4;
681 return Latency::MFC1 + ExtLatency() + Latency::BRANCH + Latency::MOV_S + 4 +
682 Latency::MFC1 + Latency::BRANCH + Latency::CVT_S_W;
686 int CvtDUwLatency() {
688 return Latency::MTC1 + Mthc1Latency() + Latency::CVT_D_L;
690 return Latency::BRANCH + Latency::MTC1 + 1 + Latency::MTC1 +
691 Mthc1Latency() + Latency::CVT_D_W + Latency::BRANCH +
692 Latency::ADD_D + Latency::CVT_D_W;
696 int CvtSUwLatency() {
return CvtDUwLatency() + Latency::CVT_S_D; }
698 int Floor_w_dLatency() {
699 if (IsMipsArchVariant(kLoongson)) {
700 return Mfhc1Latency() + Latency::FLOOR_W_D + Mthc1Latency();
702 return Latency::FLOOR_W_D;
706 int FloorWDLatency() {
return Floor_w_dLatency() + Latency::MFC1; }
708 int Ceil_w_dLatency() {
709 if (IsMipsArchVariant(kLoongson)) {
710 return Mfhc1Latency() + Latency::CEIL_W_D + Mthc1Latency();
712 return Latency::CEIL_W_D;
716 int CeilWDLatency() {
return Ceil_w_dLatency() + Latency::MFC1; }
718 int Round_w_dLatency() {
719 if (IsMipsArchVariant(kLoongson)) {
720 return Mfhc1Latency() + Latency::ROUND_W_D + Mthc1Latency();
722 return Latency::ROUND_W_D;
726 int RoundWDLatency() {
return Round_w_dLatency() + Latency::MFC1; }
728 int Trunc_w_dLatency() {
729 if (IsMipsArchVariant(kLoongson)) {
730 return Mfhc1Latency() + Latency::TRUNC_W_D + Mthc1Latency();
732 return Latency::TRUNC_W_D;
737 if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) {
738 return Latency::BRANCH + 1;
744 int Trunc_uw_dLatency() {
745 return 1 + Latency::MTC1 + Mthc1Latency() + Latency::BRANCH + Latency::SUB_D +
746 Latency::TRUNC_W_D + Latency::MFC1 + OrLatency(
false) +
747 Latency::BRANCH + Latency::TRUNC_W_D + Latency::MFC1;
750 int Trunc_uw_sLatency() {
751 return 1 + Latency::MTC1 + Latency::BRANCH + Latency::SUB_S +
752 Latency::TRUNC_W_S + Latency::MFC1 + OrLatency(
false) +
753 Latency::TRUNC_W_S + Latency::MFC1;
757 if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) {
758 return Latency::BRANCH + 1;
764 int FmoveLowLatency() {
766 return Latency::MTC1;
768 return Latency::MFHC1 + Latency::MTC1 + Latency::MTHC1;
773 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
781 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
789 if (IsMipsArchVariant(kMips32r6)) {
797 if (IsMipsArchVariant(kMips32r6)) {
804 int AdjustBaseAndOffsetLatency() {
809 if (IsMipsArchVariant(kMips32r6)) {
812 return AdjustBaseAndOffsetLatency() + 4;
817 if (IsMipsArchVariant(kMips32r6)) {
820 return AdjustBaseAndOffsetLatency() + 3;
825 if (IsMipsArchVariant(kMips32r6)) {
828 return AdjustBaseAndOffsetLatency() + 2;
833 if (IsMipsArchVariant(kMips32r6)) {
834 return Latency::LWC1;
836 return UlwLatency() + Latency::MTC1;
841 if (IsMipsArchVariant(kMips32r6)) {
842 return Latency::SWC1;
844 return Latency::MFC1 + UswLatency();
849 int latency = AdjustBaseAndOffsetLatency() + Latency::LWC1;
851 return latency + Latency::LWC1;
853 return latency + 1 + Mthc1Latency();
858 if (IsMipsArchVariant(kMips32r6)) {
859 return Ldc1Latency();
861 return 2 * UlwLatency() + Latency::MTC1 + Mthc1Latency();
866 int latency = AdjustBaseAndOffsetLatency() + Latency::SWC1;
868 return latency + Latency::SWC1;
870 return latency + Mfhc1Latency() + 1;
875 if (IsMipsArchVariant(kMips32r6)) {
876 return Sdc1Latency();
878 return Latency::MFC1 + 2 * UswLatency() + Mfhc1Latency();
882 int PushRegisterLatency() {
return AdduLatency(
false) + 1; }
884 int ByteSwapSignedLatency() {
886 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
888 }
else if (IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kLoongson)) {
893 int LlLatency(
int offset) {
894 bool is_one_instruction =
895 IsMipsArchVariant(kMips32r6) ? is_int9(offset) : is_int16(offset);
896 if (is_one_instruction) {
903 int ExtractBitsLatency(
int size,
bool sign_extend) {
904 int latency = 1 + ExtLatency();
907 return latency + SebLatency();
911 }
else if (size == 16) {
913 return latency + SehLatency();
922 int NegLatency() {
return 1; }
924 int InsertBitsLatency() {
925 return RorLatency() + InsLatency() + SubuLatency(
false) + NegLatency() +
929 int ScLatency(
int offset) {
930 bool is_one_instruction =
931 IsMipsArchVariant(kMips32r6) ? is_int9(offset) : is_int16(offset);
932 if (is_one_instruction) {
939 int BranchShortHelperR6Latency() {
943 int BranchShortHelperLatency() {
944 return SltLatency() + 2;
947 int BranchShortLatency(BranchDelaySlot bdslot = PROTECT) {
948 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) {
949 return BranchShortHelperR6Latency();
951 return BranchShortHelperLatency();
955 int Word32AtomicExchangeLatency(
bool sign_extend,
int size) {
956 return AdduLatency() + 1 + SubuLatency() + 2 + LlLatency(0) +
957 ExtractBitsLatency(size, sign_extend) + InsertBitsLatency() +
958 ScLatency(0) + BranchShortLatency() + 1;
961 int Word32AtomicCompareExchangeLatency(
bool sign_extend,
int size) {
962 return AdduLatency() + 1 + SubuLatency() + 2 + LlLatency(0) +
963 ExtractBitsLatency(size, sign_extend) + BranchShortLatency() + 1;
966 int AddOverflowLatency() {
970 int SubOverflowLatency() {
974 int MulhLatency(
bool is_operand_register =
true) {
975 if (is_operand_register) {
976 if (!IsMipsArchVariant(kMips32r6)) {
977 return Latency::MULT + Latency::MFHI;
982 if (!IsMipsArchVariant(kMips32r6)) {
983 return 1 + Latency::MULT + Latency::MFHI;
985 return 1 + Latency::MUH;
990 int MulhuLatency(
bool is_operand_register =
true) {
991 if (is_operand_register) {
992 if (!IsMipsArchVariant(kMips32r6)) {
993 return Latency::MULTU + Latency::MFHI;
995 return Latency::MUHU;
998 if (!IsMipsArchVariant(kMips32r6)) {
999 return 1 + Latency::MULTU + Latency::MFHI;
1001 return 1 + Latency::MUHU;
1006 int MulOverflowLatency() {
1007 return MulLatency() + 4;
1010 int ModLatency(
bool is_operand_register =
true) {
1011 if (is_operand_register) {
1012 if (!IsMipsArchVariant(kMips32r6)) {
1013 return Latency::DIV + Latency::MFHI;
1018 if (!IsMipsArchVariant(kMips32r6)) {
1019 return 1 + Latency::DIV + Latency::MFHI;
1026 int ModuLatency(
bool is_operand_register =
true) {
1027 return ModLatency(is_operand_register);
1030 int DivLatency(
bool is_operand_register =
true) {
1031 if (is_operand_register) {
1032 if (!IsMipsArchVariant(kMips32r6)) {
1033 return Latency::DIV + Latency::MFLO;
1035 return Latency::DIV;
1038 if (!IsMipsArchVariant(kMips32r6)) {
1039 return 1 + Latency::DIV + Latency::MFLO;
1041 return 1 + Latency::DIV;
1046 int DivuLatency(
bool is_operand_register =
true) {
1047 if (is_operand_register) {
1048 if (!IsMipsArchVariant(kMips32r6)) {
1049 return Latency::DIVU + Latency::MFLO;
1051 return Latency::DIVU;
1054 if (!IsMipsArchVariant(kMips32r6)) {
1055 return 1 + Latency::DIVU + Latency::MFLO;
1057 return 1 + Latency::DIVU;
1063 if (IsMipsArchVariant(kMips32r6)) {
1064 return RorLatency(
false) + 2 + ClzLatency();
1066 return AdduLatency(
false) + XorLatency() + AndLatency() + ClzLatency() + 1 +
1071 int PopcntLatency() {
1072 return 4 * AndLatency() + SubuLatency() + 2 * AdduLatency() + MulLatency() +
1076 int CompareFLatency() {
return Latency::C_cond_S; }
1078 int CompareIsNanFLatency() {
return CompareFLatency(); }
1080 int CompareIsNanF32Latency() {
return CompareIsNanFLatency(); }
1082 int Neg_sLatency() {
1083 if (IsMipsArchVariant(kMips32r6)) {
1084 return Latency::NEG_S;
1087 return CompareIsNanF32Latency() + 2 * Latency::BRANCH + Latency::NEG_S +
1088 Latency::MFC1 + 1 + XorLatency() + Latency::MTC1;
1092 int CompareIsNanF64Latency() {
return CompareIsNanFLatency(); }
1094 int Neg_dLatency() {
1095 if (IsMipsArchVariant(kMips32r6)) {
1096 return Latency::NEG_D;
1099 return CompareIsNanF64Latency() + 2 * Latency::BRANCH + Latency::NEG_D +
1100 Mfhc1Latency() + 1 + XorLatency() + Mthc1Latency();
1104 int CompareF32Latency() {
return CompareFLatency(); }
1106 int Move_sLatency() {
1107 return Latency::MOV_S;
1110 int Float32MaxLatency() {
1112 int latency = CompareIsNanF32Latency() + Latency::BRANCH;
1113 if (IsMipsArchVariant(kMips32r6)) {
1114 return latency + Latency::MAX_S;
1116 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1117 Latency::MFC1 + Move_sLatency();
1121 int CompareF64Latency() {
return CompareF32Latency(); }
1123 int Move_dLatency() {
1124 return Latency::MOV_D;
1127 int Float64MaxLatency() {
1129 int latency = CompareIsNanF64Latency() + Latency::BRANCH;
1130 if (IsMipsArchVariant(kMips32r6)) {
1131 return latency + Latency::MAX_D;
1133 return latency + 5 * Latency::BRANCH + 2 * CompareF64Latency() +
1134 Latency::MFHC1 + 2 * Move_dLatency();
1138 int PrepareCallCFunctionLatency() {
1139 int frame_alignment = TurboAssembler::ActivationFrameAlignment();
1140 if (frame_alignment > kPointerSize) {
1141 return 1 + SubuLatency(
false) + AndLatency(
false) + 1;
1143 return SubuLatency(
false);
1147 int MovToFloatParametersLatency() {
return 2 * MoveLatency(); }
1151 return AdduLatency(
false) + Latency::BRANCH + 3;
1154 int CallCFunctionHelperLatency() {
1156 int latency = AndLatency(
false) + Latency::BRANCH + 2 + CallLatency();
1157 if (base::OS::ActivationFrameAlignment() > kPointerSize) {
1160 latency += AdduLatency(
false);
1165 int CallCFunctionLatency() {
return 1 + CallCFunctionHelperLatency(); }
1167 int MovFromFloatResultLatency() {
return MoveLatency(); }
1169 int Float32MinLatency() {
1171 return CompareIsNanF32Latency() + Latency::BRANCH +
1172 2 * (CompareF32Latency() + Latency::BRANCH) + Latency::MFC1 +
1173 2 * Latency::BRANCH + Move_sLatency();
1176 int Float64MinLatency() {
1178 return CompareIsNanF64Latency() + Latency::BRANCH +
1179 2 * (CompareF64Latency() + Latency::BRANCH) + Mfhc1Latency() +
1180 2 * Latency::BRANCH + Move_dLatency();
1183 int SmiUntagLatency() {
return 1; }
1185 int PrepareForTailCallLatency() {
1187 return 2 * (LsaLatency() + AdduLatency(
false)) + 2 + Latency::BRANCH +
1188 Latency::BRANCH + 2 * SubuLatency(
false) + 2 + Latency::BRANCH + 1;
1191 int AssemblePopArgumentsAdaptorFrameLatency() {
1192 return 1 + Latency::BRANCH + 1 + SmiUntagLatency() +
1193 PrepareForTailCallLatency();
1198 return 1 + AdduLatency(
false) + Latency::BRANCH + 2;
1201 int AssertLatency() {
return 1; }
1203 int MultiPushLatency() {
1204 int latency = SubuLatency(
false);
1205 for (int16_t
i = kNumRegisters - 1;
i >= 0;
i--) {
1211 int MultiPushFPULatency() {
1212 int latency = SubuLatency(
false);
1213 for (int16_t
i = kNumRegisters - 1;
i >= 0;
i--) {
1214 latency += Sdc1Latency();
1219 int PushCallerSavedLatency(SaveFPRegsMode fp_mode) {
1220 int latency = MultiPushLatency();
1221 if (fp_mode == kSaveFPRegs) {
1222 latency += MultiPushFPULatency();
1227 int MultiPopFPULatency() {
1229 for (int16_t
i = 0;
i < kNumRegisters;
i++) {
1230 latency += Ldc1Latency();
1235 int MultiPopLatency() {
1237 for (int16_t
i = 0;
i < kNumRegisters;
i++) {
1243 int PopCallerSavedLatency(SaveFPRegsMode fp_mode) {
1245 if (fp_mode == kSaveFPRegs) {
1246 latency += MultiPopFPULatency();
1248 return latency + MultiPopLatency();
1251 int AssembleArchJumpLatency() {
1253 return Latency::BRANCH;
1256 int AssembleArchLookupSwitchLatency(
int cases) {
1257 return cases * (1 + Latency::BRANCH) + AssembleArchJumpLatency();
1260 int AssembleArchBinarySearchSwitchLatency(
int cases) {
1261 if (cases < CodeGenerator::kBinarySearchSwitchMinimalCases) {
1262 return AssembleArchLookupSwitchLatency(cases);
1264 return 1 + Latency::BRANCH + AssembleArchBinarySearchSwitchLatency(cases / 2);
1267 int GenerateSwitchTableLatency() {
1269 if (kArchVariant >= kMips32r6) {
1270 latency = LsaLatency() + 2;
1278 int AssembleArchTableSwitchLatency() {
1279 return Latency::BRANCH + GenerateSwitchTableLatency();
1282 int AssembleReturnLatency() {
1284 return AdduLatency(
false) + MultiPopLatency() + MultiPopFPULatency() +
1285 Latency::BRANCH + 1 + AdduLatency() + 8;
1288 int TryInlineTruncateDoubleToILatency() {
1289 return 2 + Latency::TRUNC_W_D + Latency::MFC1 + 2 + AndLatency(
false) +
1293 int CallStubDelayedLatency() {
return 1 + CallLatency(); }
1295 int TruncateDoubleToIDelayedLatency() {
1297 return TryInlineTruncateDoubleToILatency() + 1 + SubuLatency(
false) +
1298 Sdc1Latency() + CallStubDelayedLatency() + AdduLatency(
false) + 1;
1301 int CheckPageFlagLatency() {
1302 return 2 * AndLatency(
false) + 1 + Latency::BRANCH;
1305 int InstructionScheduler::GetInstructionLatency(
const Instruction* instr) {
1308 switch (instr->arch_opcode()) {
1309 case kArchCallCodeObject:
1310 case kArchCallWasmFunction:
1311 return CallLatency();
1312 case kArchTailCallCodeObjectFromJSFunction:
1313 case kArchTailCallCodeObject: {
1315 if (instr->arch_opcode() == kArchTailCallCodeObjectFromJSFunction) {
1316 latency = AssemblePopArgumentsAdaptorFrameLatency();
1318 return latency + JumpLatency();
1320 case kArchTailCallWasm:
1321 case kArchTailCallAddress:
1322 return JumpLatency();
1323 case kArchCallJSFunction: {
1325 if (FLAG_debug_code) {
1326 latency = 1 + AssertLatency();
1328 return latency + 1 + AdduLatency(
false) + CallLatency();
1330 case kArchPrepareCallCFunction:
1331 return PrepareCallCFunctionLatency();
1332 case kArchSaveCallerRegisters: {
1334 static_cast<SaveFPRegsMode
>(MiscField::decode(instr->opcode()));
1335 return PushCallerSavedLatency(fp_mode);
1337 case kArchRestoreCallerRegisters: {
1339 static_cast<SaveFPRegsMode
>(MiscField::decode(instr->opcode()));
1340 return PopCallerSavedLatency(fp_mode);
1342 case kArchPrepareTailCall:
1344 case kArchCallCFunction:
1345 return CallCFunctionLatency();
1347 return AssembleArchJumpLatency();
1348 case kArchBinarySearchSwitch:
1349 return AssembleArchBinarySearchSwitchLatency((instr->InputCount() - 2) /
1351 case kArchLookupSwitch:
1352 return AssembleArchLookupSwitchLatency((instr->InputCount() - 2) / 2);
1353 case kArchTableSwitch:
1354 return AssembleArchTableSwitchLatency();
1355 case kArchDebugAbort:
1356 return CallLatency() + 1;
1358 case kArchDeoptimize:
1361 return AssembleReturnLatency();
1362 case kArchTruncateDoubleToI:
1363 return TruncateDoubleToIDelayedLatency();
1364 case kArchStoreWithWriteBarrier:
1365 return AdduLatency() + 1 + CheckPageFlagLatency();
1366 case kArchStackSlot: {
1368 return AdduLatency(
false) + AndLatency(
false) + AssertLatency() +
1369 AdduLatency(
false) + AndLatency(
false) + BranchShortLatency() + 1 +
1370 SubuLatency() + AdduLatency();
1372 case kArchWordPoisonOnSpeculation:
1373 return AndLatency();
1374 case kIeee754Float64Acos:
1375 case kIeee754Float64Acosh:
1376 case kIeee754Float64Asin:
1377 case kIeee754Float64Asinh:
1378 case kIeee754Float64Atan:
1379 case kIeee754Float64Atanh:
1380 case kIeee754Float64Atan2:
1381 case kIeee754Float64Cos:
1382 case kIeee754Float64Cosh:
1383 case kIeee754Float64Cbrt:
1384 case kIeee754Float64Exp:
1385 case kIeee754Float64Expm1:
1386 case kIeee754Float64Log:
1387 case kIeee754Float64Log1p:
1388 case kIeee754Float64Log10:
1389 case kIeee754Float64Log2:
1390 case kIeee754Float64Pow:
1391 case kIeee754Float64Sin:
1392 case kIeee754Float64Sinh:
1393 case kIeee754Float64Tan:
1394 case kIeee754Float64Tanh:
1395 return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1396 CallCFunctionLatency() + MovFromFloatResultLatency();
1398 return AdduLatency(instr->InputAt(1)->IsRegister());
1400 return AndLatency(instr->InputAt(1)->IsRegister());
1402 return OrLatency(instr->InputAt(1)->IsRegister());
1404 return XorLatency(instr->InputAt(1)->IsRegister());
1406 return SubuLatency(instr->InputAt(1)->IsRegister());
1408 return NorLatency(instr->InputAt(1)->IsRegister());
1410 return AddOverflowLatency();
1412 return SubOverflowLatency();
1414 return MulLatency(
false);
1416 return MulhLatency(instr->InputAt(1)->IsRegister());
1418 return MulhuLatency(instr->InputAt(1)->IsRegister());
1420 return MulOverflowLatency();
1422 return ModLatency(instr->InputAt(1)->IsRegister());
1424 return ModuLatency(instr->InputAt(1)->IsRegister());
1426 int latency = DivLatency(instr->InputAt(1)->IsRegister());
1427 if (IsMipsArchVariant(kMips32r6)) {
1430 return latency + MovzLatency();
1434 int latency = DivuLatency(instr->InputAt(1)->IsRegister());
1435 if (IsMipsArchVariant(kMips32r6)) {
1438 return latency + MovzLatency();
1442 return ClzLatency();
1444 return CtzLatency();
1446 return PopcntLatency();
1447 case kMipsShlPair: {
1448 if (instr->InputAt(2)->IsRegister()) {
1449 return ShlPairLatency();
1451 return ShlPairLatency(
false);
1454 case kMipsShrPair: {
1455 if (instr->InputAt(2)->IsRegister()) {
1456 return ShrPairLatency();
1463 case kMipsSarPair: {
1464 if (instr->InputAt(2)->IsRegister()) {
1465 return SarPairLatency();
1467 return SarPairLatency(
false);
1471 return ExtLatency();
1473 return InsLatency();
1475 return RorLatency(instr->InputAt(1)->IsRegister());
1477 return LsaLatency();
1480 return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1481 CallCFunctionLatency() + MovFromFloatResultLatency();
1483 return AddPairLatency();
1485 return SubPairLatency();
1487 return MulPairLatency();
1489 return MaddSLatency();
1491 return MaddDLatency();
1493 return MsubSLatency();
1495 return MsubDLatency();
1497 return Neg_sLatency();
1499 return Neg_dLatency();
1500 case kMipsFloat64RoundDown:
1501 case kMipsFloat64RoundTruncate:
1502 case kMipsFloat64RoundUp:
1503 case kMipsFloat64RoundTiesEven:
1504 return Float64RoundLatency();
1505 case kMipsFloat32RoundDown:
1506 case kMipsFloat32RoundTruncate:
1507 case kMipsFloat32RoundUp:
1508 case kMipsFloat32RoundTiesEven:
1509 return Float32RoundLatency();
1510 case kMipsFloat32Max:
1511 return Float32MaxLatency();
1512 case kMipsFloat64Max:
1513 return Float64MaxLatency();
1514 case kMipsFloat32Min:
1515 return Float32MinLatency();
1516 case kMipsFloat64Min:
1517 return Float64MinLatency();
1519 return CvtSUwLatency();
1521 return CvtDUwLatency();
1523 return FloorWDLatency();
1525 return CeilWDLatency();
1527 return RoundWDLatency();
1529 return Trunc_w_dLatency() + Latency::MFC1;
1531 return Latency::TRUNC_W_S + Latency::MFC1 + AdduLatency(
false) +
1532 SltLatency() + MovnLatency();
1534 return Trunc_uw_dLatency();
1536 return Trunc_uw_sLatency() + AdduLatency(
false) + MovzLatency();
1537 case kMipsFloat64ExtractLowWord32:
1538 return Latency::MFC1;
1539 case kMipsFloat64ExtractHighWord32:
1540 return Mfhc1Latency();
1541 case kMipsFloat64InsertLowWord32: {
1543 return Latency::MTC1;
1545 return Latency::MFHC1 + Latency::MTC1 + Latency::MTHC1;
1548 case kMipsFloat64InsertHighWord32:
1549 return Mthc1Latency();
1550 case kMipsFloat64SilenceNaN:
1551 return Latency::SUB_D;
1553 return SebLatency();
1555 return SehLatency();
1557 return UlhuLatency();
1559 return UlhLatency();
1561 return UshLatency();
1563 return UlwLatency();
1565 return UswLatency();
1567 return Ulwc1Latency();
1569 return MoveLatency(
false) + Latency::SWC1;
1571 return MoveLatency(
false) + Uswc1Latency();
1573 return Ldc1Latency();
1575 return Uldc1Latency();
1577 return MoveLatency(
false) + Sdc1Latency();
1579 return MoveLatency(
false) + Usdc1Latency();
1581 if (instr->InputAt(0)->IsFPRegister()) {
1582 auto op = LocationOperand::cast(instr->InputAt(0));
1583 switch (op->representation()) {
1584 case MachineRepresentation::kFloat32:
1585 return Latency::SWC1 + SubuLatency(
false);
1587 case MachineRepresentation::kFloat64:
1588 return Sdc1Latency() + SubuLatency(
false);
1596 return PushRegisterLatency();
1601 if (instr->OutputAt(0)->IsFPRegister()) {
1602 auto op = LocationOperand::cast(instr->OutputAt(0));
1603 if (op->representation() == MachineRepresentation::kFloat64) {
1604 return Ldc1Latency();
1606 return Latency::LWC1;
1613 case kMipsStackClaim:
1614 return SubuLatency(
false);
1615 case kMipsStoreToStackSlot: {
1616 if (instr->InputAt(0)->IsFPRegister()) {
1617 auto op = LocationOperand::cast(instr->InputAt(0));
1618 if (op->representation() == MachineRepresentation::kFloat64) {
1619 return Sdc1Latency();
1620 }
else if (op->representation() == MachineRepresentation::kFloat32) {
1621 return Latency::SWC1;
1630 case kMipsByteSwap32:
1631 return ByteSwapSignedLatency();
1632 case kWord32AtomicLoadInt8:
1633 case kWord32AtomicLoadUint8:
1634 case kWord32AtomicLoadInt16:
1635 case kWord32AtomicLoadUint16:
1636 case kWord32AtomicLoadWord32:
1638 case kWord32AtomicStoreWord8:
1639 case kWord32AtomicStoreWord16:
1640 case kWord32AtomicStoreWord32:
1642 case kWord32AtomicExchangeInt8:
1643 return Word32AtomicExchangeLatency(
true, 8);
1644 case kWord32AtomicExchangeUint8:
1645 return Word32AtomicExchangeLatency(
false, 8);
1646 case kWord32AtomicExchangeInt16:
1647 return Word32AtomicExchangeLatency(
true, 16);
1648 case kWord32AtomicExchangeUint16:
1649 return Word32AtomicExchangeLatency(
false, 16);
1650 case kWord32AtomicExchangeWord32: {
1651 return 1 + AdduLatency() + Ldc1Latency() + 1 + ScLatency(0) +
1652 BranchShortLatency() + 1;
1654 case kWord32AtomicCompareExchangeInt8:
1655 return Word32AtomicCompareExchangeLatency(
true, 8);
1656 case kWord32AtomicCompareExchangeUint8:
1657 return Word32AtomicCompareExchangeLatency(
false, 8);
1658 case kWord32AtomicCompareExchangeInt16:
1659 return Word32AtomicCompareExchangeLatency(
true, 16);
1660 case kWord32AtomicCompareExchangeUint16:
1661 return Word32AtomicCompareExchangeLatency(
false, 16);
1662 case kWord32AtomicCompareExchangeWord32:
1663 return AdduLatency() + 1 + LlLatency(0) + BranchShortLatency() + 1;
1665 return AndLatency(instr->InputAt(1)->IsRegister());
1667 return MoveLatency() + CompareF32Latency();
1669 return MoveLatency() + CompareF64Latency();
1671 case kArchThrowTerminator:
1674 case kArchDebugBreak:
1675 case kArchStackPointer:
1676 case kArchFramePointer:
1677 case kArchParentFramePointer:
1697 return Latency::ADD_S;
1699 return Latency::SUB_S;
1701 return Latency::MUL_S;
1703 return Latency::ABS_S;
1705 return Latency::ADD_D;
1707 return Latency::SUB_D;
1709 return Latency::ABS_D;
1711 return Latency::CVT_S_D;
1713 return Latency::CVT_D_S;
1715 return Latency::MUL_D;
1717 return Latency::FLOOR_W_S;
1719 return Latency::CEIL_W_S;
1721 return Latency::ROUND_W_S;
1723 return Latency::CVT_D_W;
1725 return Latency::CVT_S_W;
1727 return Latency::DIV_S;
1729 return Latency::SQRT_S;
1731 return Latency::DIV_D;
1733 return Latency::SQRT_D;