5 #include "src/compiler/backend/instruction-scheduler.h" 11 bool InstructionScheduler::SchedulerSupported() {
return true; }
13 int InstructionScheduler::GetTargetInstructionFlags(
14 const Instruction* instr)
const {
15 switch (instr->arch_opcode()) {
23 case kMips64AssertEqual:
24 case kMips64BitcastDL:
25 case kMips64BitcastLD:
26 case kMips64ByteSwap32:
27 case kMips64ByteSwap64:
73 case kMips64F32x4AddHoriz:
75 case kMips64F32x4ExtractLane:
83 case kMips64F32x4RecipApprox:
84 case kMips64F32x4RecipSqrtApprox:
85 case kMips64F32x4ReplaceLane:
86 case kMips64F32x4SConvertI32x4:
87 case kMips64F32x4Splat:
89 case kMips64F32x4UConvertI32x4:
90 case kMips64Float32Max:
91 case kMips64Float32Min:
92 case kMips64Float32RoundDown:
93 case kMips64Float32RoundTiesEven:
94 case kMips64Float32RoundTruncate:
95 case kMips64Float32RoundUp:
96 case kMips64Float64ExtractLowWord32:
97 case kMips64Float64ExtractHighWord32:
98 case kMips64Float64InsertLowWord32:
99 case kMips64Float64InsertHighWord32:
100 case kMips64Float64Max:
101 case kMips64Float64Min:
102 case kMips64Float64RoundDown:
103 case kMips64Float64RoundTiesEven:
104 case kMips64Float64RoundTruncate:
105 case kMips64Float64RoundUp:
106 case kMips64Float64SilenceNaN:
109 case kMips64I16x8Add:
110 case kMips64I16x8AddHoriz:
111 case kMips64I16x8AddSaturateS:
112 case kMips64I16x8AddSaturateU:
114 case kMips64I16x8ExtractLane:
115 case kMips64I16x8GeS:
116 case kMips64I16x8GeU:
117 case kMips64I16x8GtS:
118 case kMips64I16x8GtU:
119 case kMips64I16x8MaxS:
120 case kMips64I16x8MaxU:
121 case kMips64I16x8MinS:
122 case kMips64I16x8MinU:
123 case kMips64I16x8Mul:
125 case kMips64I16x8Neg:
126 case kMips64I16x8ReplaceLane:
127 case kMips64I8x16SConvertI16x8:
128 case kMips64I16x8SConvertI32x4:
129 case kMips64I16x8SConvertI8x16High:
130 case kMips64I16x8SConvertI8x16Low:
131 case kMips64I16x8Shl:
132 case kMips64I16x8ShrS:
133 case kMips64I16x8ShrU:
134 case kMips64I16x8Splat:
135 case kMips64I16x8Sub:
136 case kMips64I16x8SubSaturateS:
137 case kMips64I16x8SubSaturateU:
138 case kMips64I8x16UConvertI16x8:
139 case kMips64I16x8UConvertI32x4:
140 case kMips64I16x8UConvertI8x16High:
141 case kMips64I16x8UConvertI8x16Low:
142 case kMips64I32x4Add:
143 case kMips64I32x4AddHoriz:
145 case kMips64I32x4ExtractLane:
146 case kMips64I32x4GeS:
147 case kMips64I32x4GeU:
148 case kMips64I32x4GtS:
149 case kMips64I32x4GtU:
150 case kMips64I32x4MaxS:
151 case kMips64I32x4MaxU:
152 case kMips64I32x4MinS:
153 case kMips64I32x4MinU:
154 case kMips64I32x4Mul:
156 case kMips64I32x4Neg:
157 case kMips64I32x4ReplaceLane:
158 case kMips64I32x4SConvertF32x4:
159 case kMips64I32x4SConvertI16x8High:
160 case kMips64I32x4SConvertI16x8Low:
161 case kMips64I32x4Shl:
162 case kMips64I32x4ShrS:
163 case kMips64I32x4ShrU:
164 case kMips64I32x4Splat:
165 case kMips64I32x4Sub:
166 case kMips64I32x4UConvertF32x4:
167 case kMips64I32x4UConvertI16x8High:
168 case kMips64I32x4UConvertI16x8Low:
169 case kMips64I8x16Add:
170 case kMips64I8x16AddSaturateS:
171 case kMips64I8x16AddSaturateU:
173 case kMips64I8x16ExtractLane:
174 case kMips64I8x16GeS:
175 case kMips64I8x16GeU:
176 case kMips64I8x16GtS:
177 case kMips64I8x16GtU:
178 case kMips64I8x16MaxS:
179 case kMips64I8x16MaxU:
180 case kMips64I8x16MinS:
181 case kMips64I8x16MinU:
182 case kMips64I8x16Mul:
184 case kMips64I8x16Neg:
185 case kMips64I8x16ReplaceLane:
186 case kMips64I8x16Shl:
187 case kMips64I8x16ShrS:
188 case kMips64I8x16ShrU:
189 case kMips64I8x16Splat:
190 case kMips64I8x16Sub:
191 case kMips64I8x16SubSaturateS:
192 case kMips64I8x16SubSaturateU:
220 case kMips64S128Select:
222 case kMips64S128Zero:
223 case kMips64S16x8InterleaveEven:
224 case kMips64S16x8InterleaveOdd:
225 case kMips64S16x8InterleaveLeft:
226 case kMips64S16x8InterleaveRight:
227 case kMips64S16x8PackEven:
228 case kMips64S16x8PackOdd:
229 case kMips64S16x2Reverse:
230 case kMips64S16x4Reverse:
231 case kMips64S1x16AllTrue:
232 case kMips64S1x16AnyTrue:
233 case kMips64S1x4AllTrue:
234 case kMips64S1x4AnyTrue:
235 case kMips64S1x8AllTrue:
236 case kMips64S1x8AnyTrue:
237 case kMips64S32x4InterleaveEven:
238 case kMips64S32x4InterleaveOdd:
239 case kMips64S32x4InterleaveLeft:
240 case kMips64S32x4InterleaveRight:
241 case kMips64S32x4PackEven:
242 case kMips64S32x4PackOdd:
243 case kMips64S32x4Shuffle:
244 case kMips64S8x16Concat:
245 case kMips64S8x16InterleaveEven:
246 case kMips64S8x16InterleaveOdd:
247 case kMips64S8x16InterleaveLeft:
248 case kMips64S8x16InterleaveRight:
249 case kMips64S8x16PackEven:
250 case kMips64S8x16PackOdd:
251 case kMips64S8x2Reverse:
252 case kMips64S8x4Reverse:
253 case kMips64S8x8Reverse:
254 case kMips64S8x16Shuffle:
267 case kMips64TruncUlD:
268 case kMips64TruncUlS:
269 case kMips64TruncUwD:
270 case kMips64TruncUwS:
276 return kNoOpcodeFlags;
296 case kMips64Word64AtomicLoadUint8:
297 case kMips64Word64AtomicLoadUint16:
298 case kMips64Word64AtomicLoadUint32:
299 case kMips64Word64AtomicLoadUint64:
301 return kIsLoadOperation;
311 case kMips64StackClaim:
312 case kMips64StoreToStackSlot:
320 case kMips64Word64AtomicStoreWord8:
321 case kMips64Word64AtomicStoreWord16:
322 case kMips64Word64AtomicStoreWord32:
323 case kMips64Word64AtomicStoreWord64:
324 case kMips64Word64AtomicAddUint8:
325 case kMips64Word64AtomicAddUint16:
326 case kMips64Word64AtomicAddUint32:
327 case kMips64Word64AtomicAddUint64:
328 case kMips64Word64AtomicSubUint8:
329 case kMips64Word64AtomicSubUint16:
330 case kMips64Word64AtomicSubUint32:
331 case kMips64Word64AtomicSubUint64:
332 case kMips64Word64AtomicAndUint8:
333 case kMips64Word64AtomicAndUint16:
334 case kMips64Word64AtomicAndUint32:
335 case kMips64Word64AtomicAndUint64:
336 case kMips64Word64AtomicOrUint8:
337 case kMips64Word64AtomicOrUint16:
338 case kMips64Word64AtomicOrUint32:
339 case kMips64Word64AtomicOrUint64:
340 case kMips64Word64AtomicXorUint8:
341 case kMips64Word64AtomicXorUint16:
342 case kMips64Word64AtomicXorUint32:
343 case kMips64Word64AtomicXorUint64:
344 case kMips64Word64AtomicExchangeUint8:
345 case kMips64Word64AtomicExchangeUint16:
346 case kMips64Word64AtomicExchangeUint32:
347 case kMips64Word64AtomicExchangeUint64:
348 case kMips64Word64AtomicCompareExchangeUint8:
349 case kMips64Word64AtomicCompareExchangeUint16:
350 case kMips64Word64AtomicCompareExchangeUint32:
351 case kMips64Word64AtomicCompareExchangeUint64:
352 return kHasSideEffect;
354 #define CASE(Name) case k##Name: 355 COMMON_ARCH_OPCODE_LIST(CASE)
493 int DadduLatency(
bool is_operand_register =
true) {
494 if (is_operand_register) {
501 int DsubuLatency(
bool is_operand_register =
true) {
502 return DadduLatency(is_operand_register);
505 int AndLatency(
bool is_operand_register =
true) {
506 return DadduLatency(is_operand_register);
509 int OrLatency(
bool is_operand_register =
true) {
510 return DadduLatency(is_operand_register);
513 int NorLatency(
bool is_operand_register =
true) {
514 if (is_operand_register) {
521 int XorLatency(
bool is_operand_register =
true) {
522 return DadduLatency(is_operand_register);
525 int MulLatency(
bool is_operand_register =
true) {
526 if (is_operand_register) {
529 return Latency::MUL + 1;
533 int DmulLatency(
bool is_operand_register =
true) {
535 if (kArchVariant >= kMips64r6) {
536 latency = Latency::DMUL;
538 latency = Latency::DMULT + Latency::MFLO;
540 if (!is_operand_register) {
546 int MulhLatency(
bool is_operand_register =
true) {
548 if (kArchVariant >= kMips64r6) {
549 latency = Latency::MUH;
551 latency = Latency::MULT + Latency::MFHI;
553 if (!is_operand_register) {
559 int MulhuLatency(
bool is_operand_register =
true) {
561 if (kArchVariant >= kMips64r6) {
562 latency = Latency::MUH;
564 latency = Latency::MULTU + Latency::MFHI;
566 if (!is_operand_register) {
572 int DMulhLatency(
bool is_operand_register =
true) {
574 if (kArchVariant >= kMips64r6) {
575 latency = Latency::DMUH;
577 latency = Latency::DMULT + Latency::MFHI;
579 if (!is_operand_register) {
585 int DivLatency(
bool is_operand_register =
true) {
586 if (is_operand_register) {
589 return Latency::DIV + 1;
593 int DivuLatency(
bool is_operand_register =
true) {
594 if (is_operand_register) {
595 return Latency::DIVU;
597 return Latency::DIVU + 1;
601 int DdivLatency(
bool is_operand_register =
true) {
603 if (kArchVariant >= kMips64r6) {
604 latency = Latency::DDIV;
606 latency = Latency::DDIV + Latency::MFLO;
608 if (!is_operand_register) {
614 int DdivuLatency(
bool is_operand_register =
true) {
616 if (kArchVariant >= kMips64r6) {
617 latency = Latency::DDIVU;
619 latency = Latency::DDIVU + Latency::MFLO;
621 if (!is_operand_register) {
627 int ModLatency(
bool is_operand_register =
true) {
629 if (kArchVariant >= kMips64r6) {
632 latency = Latency::DIV + Latency::MFHI;
634 if (!is_operand_register) {
640 int ModuLatency(
bool is_operand_register =
true) {
642 if (kArchVariant >= kMips64r6) {
645 latency = Latency::DIVU + Latency::MFHI;
647 if (!is_operand_register) {
653 int DmodLatency(
bool is_operand_register =
true) {
655 if (kArchVariant >= kMips64r6) {
658 latency = Latency::DDIV + Latency::MFHI;
660 if (!is_operand_register) {
666 int DmoduLatency(
bool is_operand_register =
true) {
668 if (kArchVariant >= kMips64r6) {
671 latency = Latency::DDIV + Latency::MFHI;
673 if (!is_operand_register) {
680 if (kArchVariant >= kMips64r6) {
681 return Latency::BRANCH + 1;
688 if (kArchVariant >= kMips64r6) {
689 return Latency::BRANCH + 1;
697 return DadduLatency() + 1;
702 return DadduLatency(
false) + Latency::BRANCH + 5;
707 return 1 + DadduLatency() + Latency::BRANCH + 2;
710 int SmiUntagLatency() {
return 1; }
712 int PrepareForTailCallLatency() {
714 return 2 * (DlsaLatency() + DadduLatency(
false)) + 2 + Latency::BRANCH +
715 Latency::BRANCH + 2 * DsubuLatency(
false) + 2 + Latency::BRANCH + 1;
718 int AssemblePopArgumentsAdoptFrameLatency() {
719 return 1 + Latency::BRANCH + 1 + SmiUntagLatency() +
720 PrepareForTailCallLatency();
723 int AssertLatency() {
return 1; }
725 int PrepareCallCFunctionLatency() {
726 int frame_alignment = TurboAssembler::ActivationFrameAlignment();
727 if (frame_alignment > kPointerSize) {
728 return 1 + DsubuLatency(
false) + AndLatency(
false) + 1;
730 return DsubuLatency(
false);
734 int AdjustBaseAndOffsetLatency() {
738 int AlignedMemoryLatency() {
return AdjustBaseAndOffsetLatency() + 1; }
741 if (kArchVariant >= kMips64r6) {
742 return AlignedMemoryLatency();
744 return AdjustBaseAndOffsetLatency() + 2 * AlignedMemoryLatency() + 2;
749 if (kArchVariant >= kMips64r6) {
750 return AlignedMemoryLatency();
753 return AdjustBaseAndOffsetLatency() + 3;
758 if (kArchVariant >= kMips64r6) {
759 return AlignedMemoryLatency();
761 return UlwLatency() + 1;
766 if (kArchVariant >= kMips64r6) {
767 return AlignedMemoryLatency();
770 return AdjustBaseAndOffsetLatency() + 3;
775 if (kArchVariant >= kMips64r6) {
776 return AlignedMemoryLatency();
778 return UlwLatency() + Latency::MTC1;
783 if (kArchVariant >= kMips64r6) {
784 return AlignedMemoryLatency();
786 return UldLatency() + Latency::DMTC1;
791 if (kArchVariant >= kMips64r6) {
792 return AlignedMemoryLatency();
795 return AdjustBaseAndOffsetLatency() + 2 + 2 * AlignedMemoryLatency();
800 if (kArchVariant >= kMips64r6) {
801 return AlignedMemoryLatency();
803 return AdjustBaseAndOffsetLatency() + 2;
808 if (kArchVariant >= kMips64r6) {
809 return AlignedMemoryLatency();
811 return AdjustBaseAndOffsetLatency() + 2;
816 if (kArchVariant >= kMips64r6) {
817 return AlignedMemoryLatency();
819 return Latency::MFC1 + UswLatency();
824 if (kArchVariant >= kMips64r6) {
825 return AlignedMemoryLatency();
827 return Latency::DMFC1 + UsdLatency();
831 int Lwc1Latency() {
return AdjustBaseAndOffsetLatency() + Latency::LWC1; }
833 int Swc1Latency() {
return AdjustBaseAndOffsetLatency() + Latency::SWC1; }
835 int Sdc1Latency() {
return AdjustBaseAndOffsetLatency() + Latency::SDC1; }
837 int Ldc1Latency() {
return AdjustBaseAndOffsetLatency() + Latency::LDC1; }
839 int MultiPushLatency() {
840 int latency = DsubuLatency(
false);
841 for (int16_t
i = kNumRegisters - 1;
i >= 0;
i--) {
847 int MultiPushFPULatency() {
848 int latency = DsubuLatency(
false);
849 for (int16_t
i = kNumRegisters - 1;
i >= 0;
i--) {
850 latency += Sdc1Latency();
855 int PushCallerSavedLatency(SaveFPRegsMode fp_mode) {
856 int latency = MultiPushLatency();
857 if (fp_mode == kSaveFPRegs) {
858 latency += MultiPushFPULatency();
863 int MultiPopLatency() {
864 int latency = DadduLatency(
false);
865 for (int16_t
i = 0;
i < kNumRegisters;
i++) {
871 int MultiPopFPULatency() {
872 int latency = DadduLatency(
false);
873 for (int16_t
i = 0;
i < kNumRegisters;
i++) {
874 latency += Ldc1Latency();
879 int PopCallerSavedLatency(SaveFPRegsMode fp_mode) {
880 int latency = MultiPopLatency();
881 if (fp_mode == kSaveFPRegs) {
882 latency += MultiPopFPULatency();
887 int CallCFunctionHelperLatency() {
889 int latency = AndLatency(
false) + Latency::BRANCH + 2 + CallLatency();
890 if (base::OS::ActivationFrameAlignment() > kPointerSize) {
893 latency += DadduLatency(
false);
898 int CallCFunctionLatency() {
return 1 + CallCFunctionHelperLatency(); }
900 int AssembleArchJumpLatency() {
902 return Latency::BRANCH;
905 int AssembleArchLookupSwitchLatency(
const Instruction* instr) {
907 for (
size_t index = 2; index < instr->InputCount(); index += 2) {
908 latency += 1 + Latency::BRANCH;
910 return latency + AssembleArchJumpLatency();
913 int GenerateSwitchTableLatency() {
915 if (kArchVariant >= kMips64r6) {
916 latency = DlsaLatency() + 2;
924 int AssembleArchTableSwitchLatency() {
925 return Latency::BRANCH + GenerateSwitchTableLatency();
928 int DropAndRetLatency() {
930 return DadduLatency(
false) + JumpLatency();
933 int AssemblerReturnLatency() {
935 return DadduLatency(
false) + MultiPopLatency() + MultiPopFPULatency() +
936 Latency::BRANCH + DadduLatency() + 1 + DropAndRetLatency();
939 int TryInlineTruncateDoubleToILatency() {
940 return 2 + Latency::TRUNC_W_D + Latency::MFC1 + 2 + AndLatency(
false) +
944 int CallStubDelayedLatency() {
return 1 + CallLatency(); }
946 int TruncateDoubleToIDelayedLatency() {
948 return TryInlineTruncateDoubleToILatency() + 1 + DsubuLatency(
false) +
949 Sdc1Latency() + CallStubDelayedLatency() + DadduLatency(
false) + 1;
952 int CheckPageFlagLatency() {
953 return AndLatency(
false) + AlignedMemoryLatency() + AndLatency(
false) +
957 int SltuLatency(
bool is_operand_register =
true) {
958 if (is_operand_register) {
965 int BranchShortHelperR6Latency() {
969 int BranchShortHelperLatency() {
970 return SltuLatency() + 2;
973 int BranchShortLatency(BranchDelaySlot bdslot = PROTECT) {
974 if (kArchVariant >= kMips64r6 && bdslot == PROTECT) {
975 return BranchShortHelperR6Latency();
977 return BranchShortHelperLatency();
981 int MoveLatency() {
return 1; }
983 int MovToFloatParametersLatency() {
return 2 * MoveLatency(); }
985 int MovFromFloatResultLatency() {
return MoveLatency(); }
987 int DaddOverflowLatency() {
992 int DsubOverflowLatency() {
997 int MulOverflowLatency() {
999 return MulLatency() + MulhLatency() + 2;
1002 int DclzLatency() {
return 1; }
1005 if (kArchVariant >= kMips64r6) {
1006 return 3 + DclzLatency();
1008 return DadduLatency(
false) + XorLatency() + AndLatency() + DclzLatency() +
1014 if (kArchVariant >= kMips64r6) {
1017 return DadduLatency(
false) + XorLatency() + AndLatency() + 1 +
1022 int PopcntLatency() {
1023 return 2 + AndLatency() + DsubuLatency() + 1 + AndLatency() + 1 +
1024 AndLatency() + DadduLatency() + 1 + DadduLatency() + 1 + AndLatency() +
1025 1 + MulLatency() + 1;
1028 int DpopcntLatency() {
1029 return 2 + AndLatency() + DsubuLatency() + 1 + AndLatency() + 1 +
1030 AndLatency() + DadduLatency() + 1 + DadduLatency() + 1 + AndLatency() +
1031 1 + DmulLatency() + 1;
1034 int CompareFLatency() {
return Latency::C_cond_S; }
1036 int CompareF32Latency() {
return CompareFLatency(); }
1038 int CompareF64Latency() {
return CompareFLatency(); }
1040 int CompareIsNanFLatency() {
return CompareFLatency(); }
1042 int CompareIsNanF32Latency() {
return CompareIsNanFLatency(); }
1044 int CompareIsNanF64Latency() {
return CompareIsNanFLatency(); }
1047 if (kArchVariant >= kMips64r6) {
1048 return Latency::NEG_S;
1051 return CompareIsNanF32Latency() + 2 * Latency::BRANCH + Latency::NEG_S +
1052 Latency::MFC1 + 1 + XorLatency() + Latency::MTC1;
1057 if (kArchVariant >= kMips64r6) {
1058 return Latency::NEG_D;
1061 return CompareIsNanF64Latency() + 2 * Latency::BRANCH + Latency::NEG_D +
1062 Latency::DMFC1 + 1 + XorLatency() + Latency::DMTC1;
1066 int Float64RoundLatency() {
1067 if (kArchVariant >= kMips64r6) {
1068 return Latency::RINT_D + 4;
1071 return Latency::DMFC1 + 1 + Latency::BRANCH + Latency::MOV_D + 4 +
1072 Latency::DMFC1 + Latency::BRANCH + Latency::CVT_D_L + 2 +
1077 int Float32RoundLatency() {
1078 if (kArchVariant >= kMips64r6) {
1079 return Latency::RINT_S + 4;
1082 return Latency::MFC1 + 1 + Latency::BRANCH + Latency::MOV_S + 4 +
1083 Latency::MFC1 + Latency::BRANCH + Latency::CVT_S_W + 2 +
1088 int Float32MaxLatency() {
1090 int latency = CompareIsNanF32Latency() + Latency::BRANCH;
1091 if (kArchVariant >= kMips64r6) {
1092 return latency + Latency::MAX_S;
1094 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1095 Latency::MFC1 + 1 + Latency::MOV_S;
1099 int Float64MaxLatency() {
1101 int latency = CompareIsNanF64Latency() + Latency::BRANCH;
1102 if (kArchVariant >= kMips64r6) {
1103 return latency + Latency::MAX_D;
1105 return latency + 5 * Latency::BRANCH + 2 * CompareF64Latency() +
1106 Latency::DMFC1 + Latency::MOV_D;
1110 int Float32MinLatency() {
1112 int latency = CompareIsNanF32Latency() + Latency::BRANCH;
1113 if (kArchVariant >= kMips64r6) {
1114 return latency + Latency::MIN_S;
1116 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1117 Latency::MFC1 + 1 + Latency::MOV_S;
1121 int Float64MinLatency() {
1123 int latency = CompareIsNanF64Latency() + Latency::BRANCH;
1124 if (kArchVariant >= kMips64r6) {
1125 return latency + Latency::MIN_D;
1127 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1128 Latency::DMFC1 + Latency::MOV_D;
1132 int TruncLSLatency(
bool load_status) {
1133 int latency = Latency::TRUNC_L_S + Latency::DMFC1;
1135 latency += SltuLatency() + 7;
1140 int TruncLDLatency(
bool load_status) {
1141 int latency = Latency::TRUNC_L_D + Latency::DMFC1;
1143 latency += SltuLatency() + 7;
1148 int TruncUlSLatency() {
1150 return 2 * CompareF32Latency() + CompareIsNanF32Latency() +
1151 4 * Latency::BRANCH + Latency::SUB_S + 2 * Latency::TRUNC_L_S +
1152 3 * Latency::DMFC1 + OrLatency() + Latency::MTC1 + Latency::MOV_S +
1156 int TruncUlDLatency() {
1158 return 2 * CompareF64Latency() + CompareIsNanF64Latency() +
1159 4 * Latency::BRANCH + Latency::SUB_D + 2 * Latency::TRUNC_L_D +
1160 3 * Latency::DMFC1 + OrLatency() + Latency::DMTC1 + Latency::MOV_D +
1164 int PushLatency() {
return DadduLatency() + AlignedMemoryLatency(); }
1166 int ByteSwapSignedLatency() {
return 2; }
1168 int LlLatency(
int offset) {
1169 bool is_one_instruction =
1170 (kArchVariant == kMips64r6) ? is_int9(offset) : is_int16(offset);
1171 if (is_one_instruction) {
1178 int ExtractBitsLatency(
bool sign_extend,
int size) {
1194 int InsertBitsLatency() {
return 2 + DsubuLatency(
false) + 2; }
1196 int ScLatency(
int offset) {
1197 bool is_one_instruction =
1198 (kArchVariant == kMips64r6) ? is_int9(offset) : is_int16(offset);
1199 if (is_one_instruction) {
1206 int Word32AtomicExchangeLatency(
bool sign_extend,
int size) {
1207 return DadduLatency(
false) + 1 + DsubuLatency() + 2 + LlLatency(0) +
1208 ExtractBitsLatency(sign_extend, size) + InsertBitsLatency() +
1209 ScLatency(0) + BranchShortLatency() + 1;
1212 int Word32AtomicCompareExchangeLatency(
bool sign_extend,
int size) {
1213 return 2 + DsubuLatency() + 2 + LlLatency(0) +
1214 ExtractBitsLatency(sign_extend, size) + InsertBitsLatency() +
1215 ScLatency(0) + BranchShortLatency() + 1;
1218 int InstructionScheduler::GetInstructionLatency(
const Instruction* instr) {
1221 switch (instr->arch_opcode()) {
1222 case kArchCallCodeObject:
1223 case kArchCallWasmFunction:
1224 return CallLatency();
1225 case kArchTailCallCodeObjectFromJSFunction:
1226 case kArchTailCallCodeObject: {
1228 if (instr->arch_opcode() == kArchTailCallCodeObjectFromJSFunction) {
1229 latency = AssemblePopArgumentsAdoptFrameLatency();
1231 return latency + JumpLatency();
1233 case kArchTailCallWasm:
1234 case kArchTailCallAddress:
1235 return JumpLatency();
1236 case kArchCallJSFunction: {
1238 if (FLAG_debug_code) {
1239 latency = 1 + AssertLatency();
1241 return latency + 1 + DadduLatency(
false) + CallLatency();
1243 case kArchPrepareCallCFunction:
1244 return PrepareCallCFunctionLatency();
1245 case kArchSaveCallerRegisters: {
1247 static_cast<SaveFPRegsMode
>(MiscField::decode(instr->opcode()));
1248 return PushCallerSavedLatency(fp_mode);
1250 case kArchRestoreCallerRegisters: {
1252 static_cast<SaveFPRegsMode
>(MiscField::decode(instr->opcode()));
1253 return PopCallerSavedLatency(fp_mode);
1255 case kArchPrepareTailCall:
1257 case kArchCallCFunction:
1258 return CallCFunctionLatency();
1260 return AssembleArchJumpLatency();
1261 case kArchLookupSwitch:
1262 return AssembleArchLookupSwitchLatency(instr);
1263 case kArchTableSwitch:
1264 return AssembleArchTableSwitchLatency();
1265 case kArchDebugAbort:
1266 return CallLatency() + 1;
1267 case kArchDebugBreak:
1271 case kArchThrowTerminator:
1272 case kArchDeoptimize:
1275 return AssemblerReturnLatency();
1276 case kArchStackPointer:
1277 case kArchFramePointer:
1279 case kArchParentFramePointer:
1281 return AlignedMemoryLatency();
1282 case kArchTruncateDoubleToI:
1283 return TruncateDoubleToIDelayedLatency();
1284 case kArchStoreWithWriteBarrier:
1285 return DadduLatency() + 1 + CheckPageFlagLatency();
1286 case kArchStackSlot:
1288 return DadduLatency(
false) + AndLatency(
false) + AssertLatency() +
1289 DadduLatency(
false) + AndLatency(
false) + BranchShortLatency() +
1290 1 + DsubuLatency() + DadduLatency();
1291 case kArchWordPoisonOnSpeculation:
1292 return AndLatency();
1293 case kIeee754Float64Acos:
1294 case kIeee754Float64Acosh:
1295 case kIeee754Float64Asin:
1296 case kIeee754Float64Asinh:
1297 case kIeee754Float64Atan:
1298 case kIeee754Float64Atanh:
1299 case kIeee754Float64Atan2:
1300 case kIeee754Float64Cos:
1301 case kIeee754Float64Cosh:
1302 case kIeee754Float64Cbrt:
1303 case kIeee754Float64Exp:
1304 case kIeee754Float64Expm1:
1305 case kIeee754Float64Log:
1306 case kIeee754Float64Log1p:
1307 case kIeee754Float64Log10:
1308 case kIeee754Float64Log2:
1309 case kIeee754Float64Pow:
1310 case kIeee754Float64Sin:
1311 case kIeee754Float64Sinh:
1312 case kIeee754Float64Tan:
1313 case kIeee754Float64Tanh:
1314 return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1315 CallCFunctionLatency() + MovFromFloatResultLatency();
1318 return DadduLatency(instr->InputAt(1)->IsRegister());
1319 case kMips64DaddOvf:
1320 return DaddOverflowLatency();
1323 return DsubuLatency(instr->InputAt(1)->IsRegister());
1324 case kMips64DsubOvf:
1325 return DsubOverflowLatency();
1327 return MulLatency();
1329 return MulOverflowLatency();
1330 case kMips64MulHigh:
1331 return MulhLatency();
1332 case kMips64MulHighU:
1333 return MulhuLatency();
1334 case kMips64DMulHigh:
1335 return DMulhLatency();
1337 int latency = DivLatency(instr->InputAt(1)->IsRegister());
1338 if (kArchVariant >= kMips64r6) {
1341 return latency + MovzLatency();
1345 int latency = DivuLatency(instr->InputAt(1)->IsRegister());
1346 if (kArchVariant >= kMips64r6) {
1349 return latency + MovzLatency();
1353 return ModLatency();
1355 return ModuLatency();
1357 return DmulLatency();
1359 int latency = DdivLatency();
1360 if (kArchVariant >= kMips64r6) {
1363 return latency + MovzLatency();
1366 case kMips64DdivU: {
1367 int latency = DdivuLatency();
1368 if (kArchVariant >= kMips64r6) {
1371 return latency + MovzLatency();
1375 return DmodLatency();
1377 return DmoduLatency();
1380 return DlsaLatency();
1382 return AndLatency(instr->InputAt(1)->IsRegister());
1383 case kMips64And32: {
1384 bool is_operand_register = instr->InputAt(1)->IsRegister();
1385 int latency = AndLatency(is_operand_register);
1386 if (is_operand_register) {
1393 return OrLatency(instr->InputAt(1)->IsRegister());
1395 bool is_operand_register = instr->InputAt(1)->IsRegister();
1396 int latency = OrLatency(is_operand_register);
1397 if (is_operand_register) {
1404 return NorLatency(instr->InputAt(1)->IsRegister());
1405 case kMips64Nor32: {
1406 bool is_operand_register = instr->InputAt(1)->IsRegister();
1407 int latency = NorLatency(is_operand_register);
1408 if (is_operand_register) {
1415 return XorLatency(instr->InputAt(1)->IsRegister());
1416 case kMips64Xor32: {
1417 bool is_operand_register = instr->InputAt(1)->IsRegister();
1418 int latency = XorLatency(is_operand_register);
1419 if (is_operand_register) {
1427 return DclzLatency();
1429 return CtzLatency();
1431 return DctzLatency();
1433 return PopcntLatency();
1434 case kMips64Dpopcnt:
1435 return DpopcntLatency();
1452 return AndLatency(instr->InputAt(1)->IsRegister());
1456 return MoveLatency() + CompareF32Latency();
1458 return Latency::ADD_S;
1460 return Latency::SUB_S;
1462 return Latency::MUL_S;
1464 return Latency::DIV_S;
1466 return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1467 CallCFunctionLatency() + MovFromFloatResultLatency();
1469 return Latency::ABS_S;
1471 return NegdLatency();
1473 return Latency::SQRT_S;
1475 return Latency::MAX_S;
1477 return Latency::MIN_S;
1479 return MoveLatency() + CompareF64Latency();
1481 return Latency::ADD_D;
1483 return Latency::SUB_D;
1485 return Latency::MUL_D;
1487 return Latency::DIV_D;
1489 return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1490 CallCFunctionLatency() + MovFromFloatResultLatency();
1492 return Latency::ABS_D;
1494 return NegdLatency();
1496 return Latency::SQRT_D;
1498 return Latency::MAX_D;
1500 return Latency::MIN_D;
1501 case kMips64Float64RoundDown:
1502 case kMips64Float64RoundTruncate:
1503 case kMips64Float64RoundUp:
1504 case kMips64Float64RoundTiesEven:
1505 return Float64RoundLatency();
1506 case kMips64Float32RoundDown:
1507 case kMips64Float32RoundTruncate:
1508 case kMips64Float32RoundUp:
1509 case kMips64Float32RoundTiesEven:
1510 return Float32RoundLatency();
1511 case kMips64Float32Max:
1512 return Float32MaxLatency();
1513 case kMips64Float64Max:
1514 return Float64MaxLatency();
1515 case kMips64Float32Min:
1516 return Float32MinLatency();
1517 case kMips64Float64Min:
1518 return Float64MinLatency();
1519 case kMips64Float64SilenceNaN:
1520 return Latency::SUB_D;
1522 return Latency::CVT_S_D;
1524 return Latency::CVT_D_S;
1526 return Latency::MTC1 + Latency::CVT_D_W;
1528 return Latency::MTC1 + Latency::CVT_S_W;
1530 return 1 + Latency::DMTC1 + Latency::CVT_S_L;
1532 return Latency::DMTC1 + Latency::CVT_S_L;
1534 return Latency::DMTC1 + Latency::CVT_D_L;
1536 return 1 + Latency::DMTC1 + Latency::CVT_D_L;
1538 return 2 * Latency::BRANCH + 3 + 2 * Latency::DMTC1 +
1539 2 * Latency::CVT_D_L + Latency::ADD_D;
1541 return 2 * Latency::BRANCH + 3 + 2 * Latency::DMTC1 +
1542 2 * Latency::CVT_S_L + Latency::ADD_S;
1543 case kMips64FloorWD:
1544 return Latency::FLOOR_W_D + Latency::MFC1;
1546 return Latency::CEIL_W_D + Latency::MFC1;
1547 case kMips64RoundWD:
1548 return Latency::ROUND_W_D + Latency::MFC1;
1549 case kMips64TruncWD:
1550 return Latency::TRUNC_W_D + Latency::MFC1;
1551 case kMips64FloorWS:
1552 return Latency::FLOOR_W_S + Latency::MFC1;
1554 return Latency::CEIL_W_S + Latency::MFC1;
1555 case kMips64RoundWS:
1556 return Latency::ROUND_W_S + Latency::MFC1;
1557 case kMips64TruncWS:
1558 return Latency::TRUNC_W_S + Latency::MFC1 + 2 + MovnLatency();
1559 case kMips64TruncLS:
1560 return TruncLSLatency(instr->OutputCount() > 1);
1561 case kMips64TruncLD:
1562 return TruncLDLatency(instr->OutputCount() > 1);
1563 case kMips64TruncUwD:
1565 return CompareF64Latency() + 2 * Latency::BRANCH +
1566 2 * Latency::TRUNC_W_D + Latency::SUB_D + OrLatency() +
1567 Latency::MTC1 + Latency::MFC1 + Latency::MTHC1 + 1;
1568 case kMips64TruncUwS:
1570 return CompareF32Latency() + 2 * Latency::BRANCH +
1571 2 * Latency::TRUNC_W_S + Latency::SUB_S + OrLatency() +
1572 Latency::MTC1 + 2 * Latency::MFC1 + 2 + MovzLatency();
1573 case kMips64TruncUlS:
1574 return TruncUlSLatency();
1575 case kMips64TruncUlD:
1576 return TruncUlDLatency();
1577 case kMips64BitcastDL:
1578 return Latency::DMFC1;
1579 case kMips64BitcastLD:
1580 return Latency::DMTC1;
1581 case kMips64Float64ExtractLowWord32:
1582 return Latency::MFC1;
1583 case kMips64Float64InsertLowWord32:
1584 return Latency::MFHC1 + Latency::MTC1 + Latency::MTHC1;
1585 case kMips64Float64ExtractHighWord32:
1586 return Latency::MFHC1;
1587 case kMips64Float64InsertHighWord32:
1588 return Latency::MTHC1;
1603 return AlignedMemoryLatency();
1605 return Lwc1Latency();
1607 return Ldc1Latency();
1609 return Swc1Latency();
1611 return Sdc1Latency();
1614 return UlhuLatency();
1616 return UlwuLatency();
1618 return UlwLatency();
1620 return UldLatency();
1622 return Ulwc1Latency();
1624 return Uldc1Latency();
1626 return UshLatency();
1628 return UswLatency();
1630 return UsdLatency();
1632 return Uswc1Latency();
1634 return Usdc1Latency();
1637 if (instr->InputAt(0)->IsFPRegister()) {
1638 latency = Sdc1Latency() + DsubuLatency(
false);
1640 latency = PushLatency();
1646 if (instr->OutputAt(0)->IsFPRegister()) {
1647 auto op = LocationOperand::cast(instr->OutputAt(0));
1648 switch (op->representation()) {
1649 case MachineRepresentation::kFloat64:
1650 latency = Ldc1Latency();
1652 case MachineRepresentation::kFloat32:
1653 latency = Latency::LWC1;
1659 latency = AlignedMemoryLatency();
1663 case kMips64StackClaim:
1664 return DsubuLatency(
false);
1665 case kMips64StoreToStackSlot: {
1667 if (instr->InputAt(0)->IsFPRegister()) {
1668 if (instr->InputAt(0)->IsSimd128Register()) {
1671 latency = Sdc1Latency();
1674 latency = AlignedMemoryLatency();
1678 case kMips64ByteSwap64:
1679 return ByteSwapSignedLatency();
1680 case kMips64ByteSwap32:
1681 return ByteSwapSignedLatency();
1682 case kWord32AtomicLoadInt8:
1683 case kWord32AtomicLoadUint8:
1684 case kWord32AtomicLoadInt16:
1685 case kWord32AtomicLoadUint16:
1686 case kWord32AtomicLoadWord32:
1688 case kWord32AtomicStoreWord8:
1689 case kWord32AtomicStoreWord16:
1690 case kWord32AtomicStoreWord32:
1692 case kWord32AtomicExchangeInt8:
1693 return Word32AtomicExchangeLatency(
true, 8);
1694 case kWord32AtomicExchangeUint8:
1695 return Word32AtomicExchangeLatency(
false, 8);
1696 case kWord32AtomicExchangeInt16:
1697 return Word32AtomicExchangeLatency(
true, 16);
1698 case kWord32AtomicExchangeUint16:
1699 return Word32AtomicExchangeLatency(
false, 16);
1700 case kWord32AtomicExchangeWord32:
1701 return 2 + LlLatency(0) + 1 + ScLatency(0) + BranchShortLatency() + 1;
1702 case kWord32AtomicCompareExchangeInt8:
1703 return Word32AtomicCompareExchangeLatency(
true, 8);
1704 case kWord32AtomicCompareExchangeUint8:
1705 return Word32AtomicCompareExchangeLatency(
false, 8);
1706 case kWord32AtomicCompareExchangeInt16:
1707 return Word32AtomicCompareExchangeLatency(
true, 16);
1708 case kWord32AtomicCompareExchangeUint16:
1709 return Word32AtomicCompareExchangeLatency(
false, 16);
1710 case kWord32AtomicCompareExchangeWord32:
1711 return 3 + LlLatency(0) + BranchShortLatency() + 1 + ScLatency(0) +
1712 BranchShortLatency() + 1;
1713 case kMips64AssertEqual:
1714 return AssertLatency();