1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/compiler/backend/code-generator.h"
6 #include "src/compiler/backend/instruction-scheduler.h"
7 
8 namespace v8 {
9 namespace internal {
10 namespace compiler {
11 
SchedulerSupported()12 bool InstructionScheduler::SchedulerSupported() { return true; }
13 
GetTargetInstructionFlags( const Instruction* instr) const14 int InstructionScheduler::GetTargetInstructionFlags(
15     const Instruction* instr) const {
16   switch (instr->arch_opcode()) {
17     case kMipsAbsD:
18     case kMipsAbsS:
19     case kMipsAdd:
20     case kMipsAddD:
21     case kMipsAddOvf:
22     case kMipsAddPair:
23     case kMipsAddS:
24     case kMipsAnd:
25     case kMipsByteSwap32:
26     case kMipsCeilWD:
27     case kMipsCeilWS:
28     case kMipsClz:
29     case kMipsCmp:
30     case kMipsCmpD:
31     case kMipsCmpS:
32     case kMipsCtz:
33     case kMipsCvtDS:
34     case kMipsCvtDUw:
35     case kMipsCvtDW:
36     case kMipsCvtSD:
37     case kMipsCvtSUw:
38     case kMipsCvtSW:
39     case kMipsDiv:
40     case kMipsDivD:
41     case kMipsDivS:
42     case kMipsDivU:
43     case kMipsExt:
44     case kMipsF64x2Abs:
45     case kMipsF64x2Neg:
46     case kMipsF64x2Sqrt:
47     case kMipsF64x2Add:
48     case kMipsF64x2Sub:
49     case kMipsF64x2Mul:
50     case kMipsF64x2Div:
51     case kMipsF64x2Min:
52     case kMipsF64x2Max:
53     case kMipsF64x2Eq:
54     case kMipsF64x2Ne:
55     case kMipsF64x2Lt:
56     case kMipsF64x2Le:
57     case kMipsF64x2Splat:
58     case kMipsF64x2ExtractLane:
59     case kMipsF64x2ReplaceLane:
60     case kMipsF64x2Pmin:
61     case kMipsF64x2Pmax:
62     case kMipsF64x2Ceil:
63     case kMipsF64x2Floor:
64     case kMipsF64x2Trunc:
65     case kMipsF64x2NearestInt:
66     case kMipsF64x2ConvertLowI32x4S:
67     case kMipsF64x2ConvertLowI32x4U:
68     case kMipsF64x2PromoteLowF32x4:
69     case kMipsI64x2Add:
70     case kMipsI64x2Sub:
71     case kMipsI64x2Mul:
72     case kMipsI64x2Neg:
73     case kMipsI64x2Shl:
74     case kMipsI64x2ShrS:
75     case kMipsI64x2ShrU:
76     case kMipsI64x2BitMask:
77     case kMipsI64x2Eq:
78     case kMipsI64x2Ne:
79     case kMipsI64x2GtS:
80     case kMipsI64x2GeS:
81     case kMipsI64x2Abs:
82     case kMipsI64x2SConvertI32x4Low:
83     case kMipsI64x2SConvertI32x4High:
84     case kMipsI64x2UConvertI32x4Low:
85     case kMipsI64x2UConvertI32x4High:
86     case kMipsI64x2ExtMulLowI32x4S:
87     case kMipsI64x2ExtMulHighI32x4S:
88     case kMipsI64x2ExtMulLowI32x4U:
89     case kMipsI64x2ExtMulHighI32x4U:
90     case kMipsF32x4Abs:
91     case kMipsF32x4Add:
92     case kMipsF32x4Eq:
93     case kMipsF32x4ExtractLane:
94     case kMipsF32x4Le:
95     case kMipsF32x4Lt:
96     case kMipsF32x4Max:
97     case kMipsF32x4Min:
98     case kMipsF32x4Mul:
99     case kMipsF32x4Div:
100     case kMipsF32x4Ne:
101     case kMipsF32x4Neg:
102     case kMipsF32x4Sqrt:
103     case kMipsF32x4RecipApprox:
104     case kMipsF32x4RecipSqrtApprox:
105     case kMipsF32x4ReplaceLane:
106     case kMipsF32x4SConvertI32x4:
107     case kMipsF32x4Splat:
108     case kMipsF32x4Sub:
109     case kMipsF32x4UConvertI32x4:
110     case kMipsF32x4Pmin:
111     case kMipsF32x4Pmax:
112     case kMipsF32x4Ceil:
113     case kMipsF32x4Floor:
114     case kMipsF32x4Trunc:
115     case kMipsF32x4NearestInt:
116     case kMipsF32x4DemoteF64x2Zero:
117     case kMipsFloat32Max:
118     case kMipsFloat32Min:
119     case kMipsFloat32RoundDown:
120     case kMipsFloat32RoundTiesEven:
121     case kMipsFloat32RoundTruncate:
122     case kMipsFloat32RoundUp:
123     case kMipsFloat64ExtractHighWord32:
124     case kMipsFloat64ExtractLowWord32:
125     case kMipsFloat64InsertHighWord32:
126     case kMipsFloat64InsertLowWord32:
127     case kMipsFloat64Max:
128     case kMipsFloat64Min:
129     case kMipsFloat64RoundDown:
130     case kMipsFloat64RoundTiesEven:
131     case kMipsFloat64RoundTruncate:
132     case kMipsFloat64RoundUp:
133     case kMipsFloat64SilenceNaN:
134     case kMipsFloorWD:
135     case kMipsFloorWS:
136     case kMipsI16x8Add:
137     case kMipsI16x8AddSatS:
138     case kMipsI16x8AddSatU:
139     case kMipsI16x8Eq:
140     case kMipsI16x8ExtractLaneU:
141     case kMipsI16x8ExtractLaneS:
142     case kMipsI16x8GeS:
143     case kMipsI16x8GeU:
144     case kMipsI16x8RoundingAverageU:
145     case kMipsI16x8GtS:
146     case kMipsI16x8GtU:
147     case kMipsI16x8MaxS:
148     case kMipsI16x8MaxU:
149     case kMipsI16x8MinS:
150     case kMipsI16x8MinU:
151     case kMipsI16x8Mul:
152     case kMipsI16x8Ne:
153     case kMipsI16x8Neg:
154     case kMipsI16x8ReplaceLane:
155     case kMipsI16x8SConvertI32x4:
156     case kMipsI16x8SConvertI8x16High:
157     case kMipsI16x8SConvertI8x16Low:
158     case kMipsI16x8Shl:
159     case kMipsI16x8ShrS:
160     case kMipsI16x8ShrU:
161     case kMipsI16x8Splat:
162     case kMipsI16x8Sub:
163     case kMipsI16x8SubSatS:
164     case kMipsI16x8SubSatU:
165     case kMipsI16x8UConvertI32x4:
166     case kMipsI16x8UConvertI8x16High:
167     case kMipsI16x8UConvertI8x16Low:
168     case kMipsI16x8Abs:
169     case kMipsI16x8BitMask:
170     case kMipsI16x8Q15MulRSatS:
171     case kMipsI16x8ExtMulLowI8x16S:
172     case kMipsI16x8ExtMulHighI8x16S:
173     case kMipsI16x8ExtMulLowI8x16U:
174     case kMipsI16x8ExtMulHighI8x16U:
175     case kMipsI16x8ExtAddPairwiseI8x16S:
176     case kMipsI16x8ExtAddPairwiseI8x16U:
177     case kMipsI32x4ExtAddPairwiseI16x8S:
178     case kMipsI32x4ExtAddPairwiseI16x8U:
179     case kMipsI32x4Add:
180     case kMipsI32x4Eq:
181     case kMipsI32x4ExtractLane:
182     case kMipsI32x4GeS:
183     case kMipsI32x4GeU:
184     case kMipsI32x4GtS:
185     case kMipsI32x4GtU:
186     case kMipsI32x4MaxS:
187     case kMipsI32x4MaxU:
188     case kMipsI32x4MinS:
189     case kMipsI32x4MinU:
190     case kMipsI32x4Mul:
191     case kMipsI32x4Ne:
192     case kMipsI32x4Neg:
193     case kMipsI32x4ReplaceLane:
194     case kMipsI32x4SConvertF32x4:
195     case kMipsI32x4SConvertI16x8High:
196     case kMipsI32x4SConvertI16x8Low:
197     case kMipsI32x4Shl:
198     case kMipsI32x4ShrS:
199     case kMipsI32x4ShrU:
200     case kMipsI32x4Splat:
201     case kMipsI32x4Sub:
202     case kMipsI32x4UConvertF32x4:
203     case kMipsI32x4UConvertI16x8High:
204     case kMipsI32x4UConvertI16x8Low:
205     case kMipsI32x4Abs:
206     case kMipsI32x4BitMask:
207     case kMipsI32x4DotI16x8S:
208     case kMipsI32x4ExtMulLowI16x8S:
209     case kMipsI32x4ExtMulHighI16x8S:
210     case kMipsI32x4ExtMulLowI16x8U:
211     case kMipsI32x4ExtMulHighI16x8U:
212     case kMipsI32x4TruncSatF64x2SZero:
213     case kMipsI32x4TruncSatF64x2UZero:
214     case kMipsI8x16Add:
215     case kMipsI8x16AddSatS:
216     case kMipsI8x16AddSatU:
217     case kMipsI8x16Eq:
218     case kMipsI8x16ExtractLaneU:
219     case kMipsI8x16ExtractLaneS:
220     case kMipsI8x16GeS:
221     case kMipsI8x16GeU:
222     case kMipsI8x16RoundingAverageU:
223     case kMipsI8x16GtS:
224     case kMipsI8x16GtU:
225     case kMipsI8x16MaxS:
226     case kMipsI8x16MaxU:
227     case kMipsI8x16MinS:
228     case kMipsI8x16MinU:
229     case kMipsI8x16Ne:
230     case kMipsI8x16Neg:
231     case kMipsI8x16ReplaceLane:
232     case kMipsI8x16SConvertI16x8:
233     case kMipsI8x16Shl:
234     case kMipsI8x16ShrS:
235     case kMipsI8x16ShrU:
236     case kMipsI8x16Splat:
237     case kMipsI8x16Sub:
238     case kMipsI8x16SubSatS:
239     case kMipsI8x16SubSatU:
240     case kMipsI8x16UConvertI16x8:
241     case kMipsI8x16Abs:
242     case kMipsI8x16Popcnt:
243     case kMipsI8x16BitMask:
244     case kMipsIns:
245     case kMipsLsa:
246     case kMipsMaddD:
247     case kMipsMaddS:
248     case kMipsMaxD:
249     case kMipsMaxS:
250     case kMipsMinD:
251     case kMipsMinS:
252     case kMipsMod:
253     case kMipsModU:
254     case kMipsMov:
255     case kMipsMsubD:
256     case kMipsMsubS:
257     case kMipsMul:
258     case kMipsMulD:
259     case kMipsMulHigh:
260     case kMipsMulHighU:
261     case kMipsMulOvf:
262     case kMipsMulPair:
263     case kMipsMulS:
264     case kMipsNegD:
265     case kMipsNegS:
266     case kMipsNor:
267     case kMipsOr:
268     case kMipsPopcnt:
269     case kMipsRor:
270     case kMipsRoundWD:
271     case kMipsRoundWS:
272     case kMipsS128And:
273     case kMipsS128Not:
274     case kMipsS128Or:
275     case kMipsS128Select:
276     case kMipsS128Xor:
277     case kMipsS128Zero:
278     case kMipsS128AndNot:
279     case kMipsS16x2Reverse:
280     case kMipsS16x4Reverse:
281     case kMipsS16x8InterleaveEven:
282     case kMipsS16x8InterleaveLeft:
283     case kMipsS16x8InterleaveOdd:
284     case kMipsS16x8InterleaveRight:
285     case kMipsS16x8PackEven:
286     case kMipsS16x8PackOdd:
287     case kMipsI64x2AllTrue:
288     case kMipsI32x4AllTrue:
289     case kMipsI16x8AllTrue:
290     case kMipsI8x16AllTrue:
291     case kMipsV128AnyTrue:
292     case kMipsS32x4InterleaveEven:
293     case kMipsS32x4InterleaveLeft:
294     case kMipsS32x4InterleaveOdd:
295     case kMipsS32x4InterleaveRight:
296     case kMipsS32x4PackEven:
297     case kMipsS32x4PackOdd:
298     case kMipsS32x4Shuffle:
299     case kMipsS8x16Concat:
300     case kMipsS8x16InterleaveEven:
301     case kMipsS8x16InterleaveLeft:
302     case kMipsS8x16InterleaveOdd:
303     case kMipsS8x16InterleaveRight:
304     case kMipsS8x16PackEven:
305     case kMipsS8x16PackOdd:
306     case kMipsI8x16Shuffle:
307     case kMipsI8x16Swizzle:
308     case kMipsS8x2Reverse:
309     case kMipsS8x4Reverse:
310     case kMipsS8x8Reverse:
311     case kMipsSar:
312     case kMipsSarPair:
313     case kMipsSeb:
314     case kMipsSeh:
315     case kMipsShl:
316     case kMipsShlPair:
317     case kMipsShr:
318     case kMipsShrPair:
319     case kMipsSqrtD:
320     case kMipsSqrtS:
321     case kMipsSub:
322     case kMipsSubD:
323     case kMipsSubOvf:
324     case kMipsSubPair:
325     case kMipsSubS:
326     case kMipsTruncUwD:
327     case kMipsTruncUwS:
328     case kMipsTruncWD:
329     case kMipsTruncWS:
330     case kMipsTst:
331     case kMipsXor:
332       return kNoOpcodeFlags;
333 
334     case kMipsLb:
335     case kMipsLbu:
336     case kMipsLdc1:
337     case kMipsLh:
338     case kMipsLhu:
339     case kMipsLw:
340     case kMipsLwc1:
341     case kMipsMsaLd:
342     case kMipsPeek:
343     case kMipsUldc1:
344     case kMipsUlh:
345     case kMipsUlhu:
346     case kMipsUlw:
347     case kMipsUlwc1:
348     case kMipsS128Load8Splat:
349     case kMipsS128Load16Splat:
350     case kMipsS128Load32Splat:
351     case kMipsS128Load64Splat:
352     case kMipsS128Load8x8S:
353     case kMipsS128Load8x8U:
354     case kMipsS128Load16x4S:
355     case kMipsS128Load16x4U:
356     case kMipsS128Load32x2S:
357     case kMipsS128Load32x2U:
358     case kMipsWord32AtomicPairLoad:
359       return kIsLoadOperation;
360 
361     case kMipsModD:
362     case kMipsMsaSt:
363     case kMipsPush:
364     case kMipsSb:
365     case kMipsSdc1:
366     case kMipsSh:
367     case kMipsStackClaim:
368     case kMipsStoreToStackSlot:
369     case kMipsSw:
370     case kMipsSwc1:
371     case kMipsUsdc1:
372     case kMipsUsh:
373     case kMipsUsw:
374     case kMipsUswc1:
375     case kMipsSync:
376     case kMipsWord32AtomicPairStore:
377     case kMipsWord32AtomicPairAdd:
378     case kMipsWord32AtomicPairSub:
379     case kMipsWord32AtomicPairAnd:
380     case kMipsWord32AtomicPairOr:
381     case kMipsWord32AtomicPairXor:
382     case kMipsWord32AtomicPairExchange:
383     case kMipsWord32AtomicPairCompareExchange:
384       return kHasSideEffect;
385 
386 #define CASE(Name) case k##Name:
387       COMMON_ARCH_OPCODE_LIST(CASE)
388 #undef CASE
389       // Already covered in architecture independent code.
390       UNREACHABLE();
391   }
392 
393   UNREACHABLE();
394 }
395 
396 enum Latency {
397   BRANCH = 4,  // Estimated max.
398   RINT_S = 4,  // Estimated.
399   RINT_D = 4,  // Estimated.
400 
401   MULT = 4,
402   MULTU = 4,
403   MADD = 4,
404   MADDU = 4,
405   MSUB = 4,
406   MSUBU = 4,
407 
408   MUL = 7,
409   MULU = 7,
410   MUH = 7,
411   MUHU = 7,
412 
413   DIV = 50,  // Min:11 Max:50
414   DIVU = 50,
415 
416   ABS_S = 4,
417   ABS_D = 4,
418   NEG_S = 4,
419   NEG_D = 4,
420   ADD_S = 4,
421   ADD_D = 4,
422   SUB_S = 4,
423   SUB_D = 4,
424   MAX_S = 4,  // Estimated.
425   MAX_D = 4,  // Estimated.
426   C_cond_S = 4,
427   C_cond_D = 4,
428   MUL_S = 4,
429 
430   MADD_S = 4,
431   MSUB_S = 4,
432   NMADD_S = 4,
433   NMSUB_S = 4,
434 
435   CABS_cond_S = 4,
436   CABS_cond_D = 4,
437 
438   CVT_D_S = 4,
439   CVT_PS_PW = 4,
440 
441   CVT_S_W = 4,
442   CVT_S_L = 4,
443   CVT_D_W = 4,
444   CVT_D_L = 4,
445 
446   CVT_S_D = 4,
447 
448   CVT_W_S = 4,
449   CVT_W_D = 4,
450   CVT_L_S = 4,
451   CVT_L_D = 4,
452 
453   CEIL_W_S = 4,
454   CEIL_W_D = 4,
455   CEIL_L_S = 4,
456   CEIL_L_D = 4,
457 
458   FLOOR_W_S = 4,
459   FLOOR_W_D = 4,
460   FLOOR_L_S = 4,
461   FLOOR_L_D = 4,
462 
463   ROUND_W_S = 4,
464   ROUND_W_D = 4,
465   ROUND_L_S = 4,
466   ROUND_L_D = 4,
467 
468   TRUNC_W_S = 4,
469   TRUNC_W_D = 4,
470   TRUNC_L_S = 4,
471   TRUNC_L_D = 4,
472 
473   MOV_S = 4,
474   MOV_D = 4,
475 
476   MOVF_S = 4,
477   MOVF_D = 4,
478 
479   MOVN_S = 4,
480   MOVN_D = 4,
481 
482   MOVT_S = 4,
483   MOVT_D = 4,
484 
485   MOVZ_S = 4,
486   MOVZ_D = 4,
487 
488   MUL_D = 5,
489   MADD_D = 5,
490   MSUB_D = 5,
491   NMADD_D = 5,
492   NMSUB_D = 5,
493 
494   RECIP_S = 13,
495   RECIP_D = 26,
496 
497   RSQRT_S = 17,
498   RSQRT_D = 36,
499 
500   DIV_S = 17,
501   SQRT_S = 17,
502 
503   DIV_D = 32,
504   SQRT_D = 32,
505 
506   MTC1 = 4,
507   MTHC1 = 4,
508   DMTC1 = 4,
509   LWC1 = 4,
510   LDC1 = 4,
511   LDXC1 = 4,
512   LUXC1 = 4,
513   LWXC1 = 4,
514 
515   MFC1 = 1,
516   MFHC1 = 1,
517   MFHI = 1,
518   MFLO = 1,
519   DMFC1 = 1,
520   SWC1 = 1,
521   SDC1 = 1,
522   SDXC1 = 1,
523   SUXC1 = 1,
524   SWXC1 = 1,
525 };
526 
ClzLatency()527 int ClzLatency() {
528   if (IsMipsArchVariant(kLoongson)) {
529     return (6 + 2 * Latency::BRANCH);
530   } else {
531     return 1;
532   }
533 }
534 
RorLatency(bool is_operand_register = true)535 int RorLatency(bool is_operand_register = true) {
536   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
537     return 1;
538   } else {
539     if (is_operand_register) {
540       return 4;
541     } else {
542       return 3;  // Estimated max.
543     }
544   }
545 }
546 
AdduLatency(bool is_operand_register = true)547 int AdduLatency(bool is_operand_register = true) {
548   if (is_operand_register) {
549     return 1;
550   } else {
551     return 2;  // Estimated max.
552   }
553 }
554 
XorLatency(bool is_operand_register = true)555 int XorLatency(bool is_operand_register = true) {
556   return AdduLatency(is_operand_register);
557 }
558 
AndLatency(bool is_operand_register = true)559 int AndLatency(bool is_operand_register = true) {
560   return AdduLatency(is_operand_register);
561 }
562 
OrLatency(bool is_operand_register = true)563 int OrLatency(bool is_operand_register = true) {
564   return AdduLatency(is_operand_register);
565 }
566 
SubuLatency(bool is_operand_register = true)567 int SubuLatency(bool is_operand_register = true) {
568   return AdduLatency(is_operand_register);
569 }
570 
MulLatency(bool is_operand_register = true)571 int MulLatency(bool is_operand_register = true) {
572   if (is_operand_register) {
573     if (IsMipsArchVariant(kLoongson)) {
574       return Latency::MULT + 1;
575     } else {
576       return Latency::MUL + 1;
577     }
578   } else {
579     if (IsMipsArchVariant(kLoongson)) {
580       return Latency::MULT + 2;
581     } else {
582       return Latency::MUL + 2;
583     }
584   }
585 }
586 
NorLatency(bool is_operand_register = true)587 int NorLatency(bool is_operand_register = true) {
588   if (is_operand_register) {
589     return 1;
590   } else {
591     return 2;
592   }
593 }
594 
InsLatency()595 int InsLatency() {
596   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
597     return 1;
598   } else {
599     return SubuLatency(false) + 7;
600   }
601 }
602 
ShlPairLatency(bool is_operand_register = true)603 int ShlPairLatency(bool is_operand_register = true) {
604   if (is_operand_register) {
605     int latency =
606         AndLatency(false) + NorLatency() + OrLatency() + AndLatency(false) + 4;
607     if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) {
608       return latency + Latency::BRANCH + 2;
609     } else {
610       return latency + 2;
611     }
612   } else {
613     return 2;
614   }
615 }
616 
ShrPairLatency(bool is_operand_register = true, uint32_t shift = 0)617 int ShrPairLatency(bool is_operand_register = true, uint32_t shift = 0) {
618   if (is_operand_register) {
619     int latency =
620         AndLatency(false) + NorLatency() + OrLatency() + AndLatency(false) + 4;
621     if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) {
622       return latency + Latency::BRANCH + 2;
623     } else {
624       return latency + 2;
625     }
626   } else {
627     // Estimated max.
628     return (InsLatency() + 2 > OrLatency() + 3) ? InsLatency() + 2
629                                                 : OrLatency() + 3;
630   }
631 }
632 
SarPairLatency(bool is_operand_register = true, uint32_t shift = 0)633 int SarPairLatency(bool is_operand_register = true, uint32_t shift = 0) {
634   if (is_operand_register) {
635     return AndLatency(false) + NorLatency() + OrLatency() + AndLatency(false) +
636            Latency::BRANCH + 6;
637   } else {
638     shift = shift & 0x3F;
639     if (shift == 0) {
640       return 2;
641     } else if (shift < 32) {
642       if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
643         return InsLatency() + 2;
644       } else {
645         return OrLatency() + 3;
646       }
647     } else if (shift == 32) {
648       return 2;
649     } else {
650       return 2;
651     }
652   }
653 }
654 
ExtLatency()655 int ExtLatency() {
656   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
657     return 1;
658   } else {
659     // Estimated max.
660     return 2;
661   }
662 }
663 
LsaLatency()664 int LsaLatency() {
665   // Estimated max.
666   return AdduLatency() + 1;
667 }
668 
SltLatency(bool is_operand_register = true)669 int SltLatency(bool is_operand_register = true) {
670   if (is_operand_register) {
671     return 1;
672   } else {
673     return 2;  // Estimated max.
674   }
675 }
676 
SltuLatency(bool is_operand_register = true)677 int SltuLatency(bool is_operand_register = true) {
678   return SltLatency(is_operand_register);
679 }
680 
AddPairLatency()681 int AddPairLatency() { return 3 * AdduLatency() + SltLatency(); }
682 
SubPairLatency()683 int SubPairLatency() { return SltuLatency() + 3 * SubuLatency(); }
684 
MuluLatency(bool is_operand_register = true)685 int MuluLatency(bool is_operand_register = true) {
686   int latency = 0;
687   if (!is_operand_register) latency++;
688   if (!IsMipsArchVariant(kMips32r6)) {
689     return latency + Latency::MULTU + 2;
690   } else {
691     return latency + Latency::MULU + Latency::MUHU;
692   }
693 }
694 
MulPairLatency()695 int MulPairLatency() {
696   return MuluLatency() + 2 * MulLatency() + 2 * AdduLatency();
697 }
698 
MaddSLatency()699 int MaddSLatency() {
700   if (IsMipsArchVariant(kMips32r2)) {
701     return Latency::MADD_D;
702   } else {
703     return Latency::MUL_D + Latency::ADD_D;
704   }
705 }
706 
MaddDLatency()707 int MaddDLatency() {
708   if (IsMipsArchVariant(kMips32r2)) {
709     return Latency::MADD_D;
710   } else {
711     return Latency::MUL_D + Latency::ADD_D;
712   }
713 }
714 
MsubSLatency()715 int MsubSLatency() {
716   if (IsMipsArchVariant(kMips32r2)) {
717     return Latency::MSUB_S;
718   } else {
719     return Latency::MUL_S + Latency::SUB_S;
720   }
721 }
722 
MsubDLatency()723 int MsubDLatency() {
724   if (IsMipsArchVariant(kMips32r2)) {
725     return Latency::MSUB_D;
726   } else {
727     return Latency::MUL_D + Latency::SUB_D;
728   }
729 }
730 
Mfhc1Latency()731 int Mfhc1Latency() {
732   if (IsFp32Mode()) {
733     return Latency::MFC1;
734   } else {
735     return 1;
736   }
737 }
738 
Mthc1Latency()739 int Mthc1Latency() {
740   if (IsFp32Mode()) {
741     return Latency::MTC1;
742   } else {
743     return 1;
744   }
745 }
746 
MoveLatency(bool is_double_register = true)747 int MoveLatency(bool is_double_register = true) {
748   if (!is_double_register) {
749     return Latency::MTC1 + 1;
750   } else {
751     return Mthc1Latency() + 1;  // Estimated.
752   }
753 }
754 
Float64RoundLatency()755 int Float64RoundLatency() {
756   if (IsMipsArchVariant(kMips32r6)) {
757     return Latency::RINT_D + 4;
758   } else {
759     // For ceil_l_d, floor_l_d, round_l_d, trunc_l_d latency is 4.
760     return Mfhc1Latency() + ExtLatency() + Latency::BRANCH + Latency::MOV_D +
761            4 + MoveLatency() + 1 + Latency::BRANCH + Latency::CVT_D_L;
762   }
763 }
764 
Float32RoundLatency()765 int Float32RoundLatency() {
766   if (IsMipsArchVariant(kMips32r6)) {
767     return Latency::RINT_S + 4;
768   } else {
769     // For ceil_w_s, floor_w_s, round_w_s, trunc_w_s latency is 4.
770     return Latency::MFC1 + ExtLatency() + Latency::BRANCH + Latency::MOV_S + 4 +
771            Latency::MFC1 + Latency::BRANCH + Latency::CVT_S_W;
772   }
773 }
774 
CvtDUwLatency()775 int CvtDUwLatency() {
776   if (IsFp64Mode()) {
777     return Latency::MTC1 + Mthc1Latency() + Latency::CVT_D_L;
778   } else {
779     return Latency::BRANCH + Latency::MTC1 + 1 + Latency::MTC1 +
780            Mthc1Latency() + Latency::CVT_D_W + Latency::BRANCH +
781            Latency::ADD_D + Latency::CVT_D_W;
782   }
783 }
784 
CvtSUwLatency()785 int CvtSUwLatency() { return CvtDUwLatency() + Latency::CVT_S_D; }
786 
Floor_w_dLatency()787 int Floor_w_dLatency() {
788   if (IsMipsArchVariant(kLoongson)) {
789     return Mfhc1Latency() + Latency::FLOOR_W_D + Mthc1Latency();
790   } else {
791     return Latency::FLOOR_W_D;
792   }
793 }
794 
FloorWDLatency()795 int FloorWDLatency() { return Floor_w_dLatency() + Latency::MFC1; }
796 
Ceil_w_dLatency()797 int Ceil_w_dLatency() {
798   if (IsMipsArchVariant(kLoongson)) {
799     return Mfhc1Latency() + Latency::CEIL_W_D + Mthc1Latency();
800   } else {
801     return Latency::CEIL_W_D;
802   }
803 }
804 
CeilWDLatency()805 int CeilWDLatency() { return Ceil_w_dLatency() + Latency::MFC1; }
806 
Round_w_dLatency()807 int Round_w_dLatency() {
808   if (IsMipsArchVariant(kLoongson)) {
809     return Mfhc1Latency() + Latency::ROUND_W_D + Mthc1Latency();
810   } else {
811     return Latency::ROUND_W_D;
812   }
813 }
814 
RoundWDLatency()815 int RoundWDLatency() { return Round_w_dLatency() + Latency::MFC1; }
816 
Trunc_w_dLatency()817 int Trunc_w_dLatency() {
818   if (IsMipsArchVariant(kLoongson)) {
819     return Mfhc1Latency() + Latency::TRUNC_W_D + Mthc1Latency();
820   } else {
821     return Latency::TRUNC_W_D;
822   }
823 }
824 
MovnLatency()825 int MovnLatency() {
826   if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) {
827     return Latency::BRANCH + 1;
828   } else {
829     return 1;
830   }
831 }
832 
Trunc_uw_dLatency()833 int Trunc_uw_dLatency() {
834   return 1 + Latency::MTC1 + Mthc1Latency() + Latency::BRANCH + Latency::SUB_D +
835          Latency::TRUNC_W_D + Latency::MFC1 + OrLatency(false) +
836          Latency::BRANCH + Latency::TRUNC_W_D + Latency::MFC1;
837 }
838 
Trunc_uw_sLatency()839 int Trunc_uw_sLatency() {
840   return 1 + Latency::MTC1 + Latency::BRANCH + Latency::SUB_S +
841          Latency::TRUNC_W_S + Latency::MFC1 + OrLatency(false) +
842          Latency::TRUNC_W_S + Latency::MFC1;
843 }
844 
MovzLatency()845 int MovzLatency() {
846   if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) {
847     return Latency::BRANCH + 1;
848   } else {
849     return 1;
850   }
851 }
852 
FmoveLowLatency()853 int FmoveLowLatency() {
854   if (IsFp32Mode()) {
855     return Latency::MTC1;
856   } else {
857     return Latency::MFHC1 + Latency::MTC1 + Latency::MTHC1;
858   }
859 }
860 
SebLatency()861 int SebLatency() {
862   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
863     return 1;
864   } else {
865     return 2;
866   }
867 }
868 
SehLatency()869 int SehLatency() {
870   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
871     return 1;
872   } else {
873     return 2;
874   }
875 }
876 
UlhuLatency()877 int UlhuLatency() {
878   if (IsMipsArchVariant(kMips32r6)) {
879     return 1;
880   } else {
881     return 4;
882   }
883 }
884 
UlhLatency()885 int UlhLatency() {
886   if (IsMipsArchVariant(kMips32r6)) {
887     return 1;
888   } else {
889     return 4;
890   }
891 }
892 
AdjustBaseAndOffsetLatency()893 int AdjustBaseAndOffsetLatency() {
894   return 3;  // Estimated max.
895 }
896 
UshLatency()897 int UshLatency() {
898   if (IsMipsArchVariant(kMips32r6)) {
899     return 1;
900   } else {
901     return AdjustBaseAndOffsetLatency() + 4;  // Estimated max.
902   }
903 }
904 
UlwLatency()905 int UlwLatency() {
906   if (IsMipsArchVariant(kMips32r6)) {
907     return 1;
908   } else {
909     return AdjustBaseAndOffsetLatency() + 3;  // Estimated max.
910   }
911 }
912 
UswLatency()913 int UswLatency() {
914   if (IsMipsArchVariant(kMips32r6)) {
915     return 1;
916   } else {
917     return AdjustBaseAndOffsetLatency() + 2;
918   }
919 }
920 
Ulwc1Latency()921 int Ulwc1Latency() {
922   if (IsMipsArchVariant(kMips32r6)) {
923     return Latency::LWC1;
924   } else {
925     return UlwLatency() + Latency::MTC1;
926   }
927 }
928 
Uswc1Latency()929 int Uswc1Latency() {
930   if (IsMipsArchVariant(kMips32r6)) {
931     return Latency::SWC1;
932   } else {
933     return Latency::MFC1 + UswLatency();
934   }
935 }
936 
Ldc1Latency()937 int Ldc1Latency() {
938   int latency = AdjustBaseAndOffsetLatency() + Latency::LWC1;
939   if (IsFp32Mode()) {
940     return latency + Latency::LWC1;
941   } else {
942     return latency + 1 + Mthc1Latency();
943   }
944 }
945 
Uldc1Latency()946 int Uldc1Latency() {
947   if (IsMipsArchVariant(kMips32r6)) {
948     return Ldc1Latency();
949   } else {
950     return 2 * UlwLatency() + Latency::MTC1 + Mthc1Latency();
951   }
952 }
953 
Sdc1Latency()954 int Sdc1Latency() {
955   int latency = AdjustBaseAndOffsetLatency() + Latency::SWC1;
956   if (IsFp32Mode()) {
957     return latency + Latency::SWC1;
958   } else {
959     return latency + Mfhc1Latency() + 1;
960   }
961 }
962 
Usdc1Latency()963 int Usdc1Latency() {
964   if (IsMipsArchVariant(kMips32r6)) {
965     return Sdc1Latency();
966   } else {
967     return Latency::MFC1 + 2 * UswLatency() + Mfhc1Latency();
968   }
969 }
970 
PushRegisterLatency()971 int PushRegisterLatency() { return AdduLatency(false) + 1; }
972 
ByteSwapSignedLatency()973 int ByteSwapSignedLatency() {
974   // operand_size == 4
975   if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
976     return 2;
977   } else if (IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kLoongson)) {
978     return 10;
979   }
980 }
981 
LlLatency(int offset)982 int LlLatency(int offset) {
983   bool is_one_instruction =
984       IsMipsArchVariant(kMips32r6) ? is_int9(offset) : is_int16(offset);
985   if (is_one_instruction) {
986     return 1;
987   } else {
988     return 3;
989   }
990 }
991 
ExtractBitsLatency(int size, bool sign_extend)992 int ExtractBitsLatency(int size, bool sign_extend) {
993   int latency = 1 + ExtLatency();
994   if (size == 8) {
995     if (sign_extend) {
996       return latency + SebLatency();
997     } else {
998       return 0;
999     }
1000   } else if (size == 16) {
1001     if (sign_extend) {
1002       return latency + SehLatency();
1003     } else {
1004       return 0;
1005     }
1006   } else {
1007     UNREACHABLE();
1008   }
1009 }
1010 
NegLatency()1011 int NegLatency() { return 1; }
1012 
InsertBitsLatency()1013 int InsertBitsLatency() {
1014   return RorLatency() + InsLatency() + SubuLatency(false) + NegLatency() +
1015          RorLatency();
1016 }
1017 
ScLatency(int offset)1018 int ScLatency(int offset) {
1019   bool is_one_instruction =
1020       IsMipsArchVariant(kMips32r6) ? is_int9(offset) : is_int16(offset);
1021   if (is_one_instruction) {
1022     return 1;
1023   } else {
1024     return 3;
1025   }
1026 }
1027 
BranchShortHelperR6Latency()1028 int BranchShortHelperR6Latency() {
1029   return 2;  // Estimated max.
1030 }
1031 
BranchShortHelperLatency()1032 int BranchShortHelperLatency() {
1033   return SltLatency() + 2;  // Estimated max.
1034 }
1035 
BranchShortLatency(BranchDelaySlot bdslot = PROTECT)1036 int BranchShortLatency(BranchDelaySlot bdslot = PROTECT) {
1037   if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) {
1038     return BranchShortHelperR6Latency();
1039   } else {
1040     return BranchShortHelperLatency();
1041   }
1042 }
1043 
Word32AtomicExchangeLatency(bool sign_extend, int size)1044 int Word32AtomicExchangeLatency(bool sign_extend, int size) {
1045   return AdduLatency() + 1 + SubuLatency() + 2 + LlLatency(0) +
1046          ExtractBitsLatency(size, sign_extend) + InsertBitsLatency() +
1047          ScLatency(0) + BranchShortLatency() + 1;
1048 }
1049 
Word32AtomicCompareExchangeLatency(bool sign_extend, int size)1050 int Word32AtomicCompareExchangeLatency(bool sign_extend, int size) {
1051   return AdduLatency() + 1 + SubuLatency() + 2 + LlLatency(0) +
1052          ExtractBitsLatency(size, sign_extend) + BranchShortLatency() + 1;
1053 }
1054 
AddOverflowLatency()1055 int AddOverflowLatency() {
1056   return 6;  // Estimated max.
1057 }
1058 
SubOverflowLatency()1059 int SubOverflowLatency() {
1060   return 6;  // Estimated max.
1061 }
1062 
MulhLatency(bool is_operand_register = true)1063 int MulhLatency(bool is_operand_register = true) {
1064   if (is_operand_register) {
1065     if (!IsMipsArchVariant(kMips32r6)) {
1066       return Latency::MULT + Latency::MFHI;
1067     } else {
1068       return Latency::MUH;
1069     }
1070   } else {
1071     if (!IsMipsArchVariant(kMips32r6)) {
1072       return 1 + Latency::MULT + Latency::MFHI;
1073     } else {
1074       return 1 + Latency::MUH;
1075     }
1076   }
1077 }
1078 
MulhuLatency(bool is_operand_register = true)1079 int MulhuLatency(bool is_operand_register = true) {
1080   if (is_operand_register) {
1081     if (!IsMipsArchVariant(kMips32r6)) {
1082       return Latency::MULTU + Latency::MFHI;
1083     } else {
1084       return Latency::MUHU;
1085     }
1086   } else {
1087     if (!IsMipsArchVariant(kMips32r6)) {
1088       return 1 + Latency::MULTU + Latency::MFHI;
1089     } else {
1090       return 1 + Latency::MUHU;
1091     }
1092   }
1093 }
1094 
MulOverflowLatency()1095 int MulOverflowLatency() {
1096   return MulLatency() + 4;  // Estimated max.
1097 }
1098 
ModLatency(bool is_operand_register = true)1099 int ModLatency(bool is_operand_register = true) {
1100   if (is_operand_register) {
1101     if (!IsMipsArchVariant(kMips32r6)) {
1102       return Latency::DIV + Latency::MFHI;
1103     } else {
1104       return 1;
1105     }
1106   } else {
1107     if (!IsMipsArchVariant(kMips32r6)) {
1108       return 1 + Latency::DIV + Latency::MFHI;
1109     } else {
1110       return 2;
1111     }
1112   }
1113 }
1114 
ModuLatency(bool is_operand_register = true)1115 int ModuLatency(bool is_operand_register = true) {
1116   return ModLatency(is_operand_register);
1117 }
1118 
DivLatency(bool is_operand_register = true)1119 int DivLatency(bool is_operand_register = true) {
1120   if (is_operand_register) {
1121     if (!IsMipsArchVariant(kMips32r6)) {
1122       return Latency::DIV + Latency::MFLO;
1123     } else {
1124       return Latency::DIV;
1125     }
1126   } else {
1127     if (!IsMipsArchVariant(kMips32r6)) {
1128       return 1 + Latency::DIV + Latency::MFLO;
1129     } else {
1130       return 1 + Latency::DIV;
1131     }
1132   }
1133 }
1134 
DivuLatency(bool is_operand_register = true)1135 int DivuLatency(bool is_operand_register = true) {
1136   if (is_operand_register) {
1137     if (!IsMipsArchVariant(kMips32r6)) {
1138       return Latency::DIVU + Latency::MFLO;
1139     } else {
1140       return Latency::DIVU;
1141     }
1142   } else {
1143     if (!IsMipsArchVariant(kMips32r6)) {
1144       return 1 + Latency::DIVU + Latency::MFLO;
1145     } else {
1146       return 1 + Latency::DIVU;
1147     }
1148   }
1149 }
1150 
CtzLatency()1151 int CtzLatency() {
1152   if (IsMipsArchVariant(kMips32r6)) {
1153     return RorLatency(false) + 2 + ClzLatency();
1154   } else {
1155     return AdduLatency(false) + XorLatency() + AndLatency() + ClzLatency() + 1 +
1156            SubuLatency();
1157   }
1158 }
1159 
PopcntLatency()1160 int PopcntLatency() {
1161   return 4 * AndLatency() + SubuLatency() + 2 * AdduLatency() + MulLatency() +
1162          8;
1163 }
1164 
CompareFLatency()1165 int CompareFLatency() { return Latency::C_cond_S; }
1166 
CompareIsNanFLatency()1167 int CompareIsNanFLatency() { return CompareFLatency(); }
1168 
CompareIsNanF32Latency()1169 int CompareIsNanF32Latency() { return CompareIsNanFLatency(); }
1170 
Neg_sLatency()1171 int Neg_sLatency() {
1172   if (IsMipsArchVariant(kMips32r6)) {
1173     return Latency::NEG_S;
1174   } else {
1175     // Estimated.
1176     return CompareIsNanF32Latency() + 2 * Latency::BRANCH + Latency::NEG_S +
1177            Latency::MFC1 + 1 + XorLatency() + Latency::MTC1;
1178   }
1179 }
1180 
CompareIsNanF64Latency()1181 int CompareIsNanF64Latency() { return CompareIsNanFLatency(); }
1182 
Neg_dLatency()1183 int Neg_dLatency() {
1184   if (IsMipsArchVariant(kMips32r6)) {
1185     return Latency::NEG_D;
1186   } else {
1187     // Estimated.
1188     return CompareIsNanF64Latency() + 2 * Latency::BRANCH + Latency::NEG_D +
1189            Mfhc1Latency() + 1 + XorLatency() + Mthc1Latency();
1190   }
1191 }
1192 
CompareF32Latency()1193 int CompareF32Latency() { return CompareFLatency(); }
1194 
Move_sLatency()1195 int Move_sLatency() {
1196   return Latency::MOV_S;  // Estimated max.
1197 }
1198 
Float32MaxLatency()1199 int Float32MaxLatency() {
1200   // Estimated max.
1201   int latency = CompareIsNanF32Latency() + Latency::BRANCH;
1202   if (IsMipsArchVariant(kMips32r6)) {
1203     return latency + Latency::MAX_S;
1204   } else {
1205     return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1206            Latency::MFC1 + Move_sLatency();
1207   }
1208 }
1209 
CompareF64Latency()1210 int CompareF64Latency() { return CompareF32Latency(); }
1211 
Move_dLatency()1212 int Move_dLatency() {
1213   return Latency::MOV_D;  // Estimated max.
1214 }
1215 
Float64MaxLatency()1216 int Float64MaxLatency() {
1217   // Estimated max.
1218   int latency = CompareIsNanF64Latency() + Latency::BRANCH;
1219   if (IsMipsArchVariant(kMips32r6)) {
1220     return latency + Latency::MAX_D;
1221   } else {
1222     return latency + 5 * Latency::BRANCH + 2 * CompareF64Latency() +
1223            Latency::MFHC1 + 2 * Move_dLatency();
1224   }
1225 }
1226 
PrepareCallCFunctionLatency()1227 int PrepareCallCFunctionLatency() {
1228   int frame_alignment = TurboAssembler::ActivationFrameAlignment();
1229   if (frame_alignment > kSystemPointerSize) {
1230     return 1 + SubuLatency(false) + AndLatency(false) + 1;
1231   } else {
1232     return SubuLatency(false);
1233   }
1234 }
1235 
MovToFloatParametersLatency()1236 int MovToFloatParametersLatency() { return 2 * MoveLatency(); }
1237 
CallLatency()1238 int CallLatency() {
1239   // Estimated.
1240   return AdduLatency(false) + Latency::BRANCH + 3;
1241 }
1242 
CallCFunctionHelperLatency()1243 int CallCFunctionHelperLatency() {
1244   // Estimated.
1245   int latency = AndLatency(false) + Latency::BRANCH + 2 + CallLatency();
1246   if (base::OS::ActivationFrameAlignment() > kSystemPointerSize) {
1247     latency++;
1248   } else {
1249     latency += AdduLatency(false);
1250   }
1251   return latency;
1252 }
1253 
CallCFunctionLatency()1254 int CallCFunctionLatency() { return 1 + CallCFunctionHelperLatency(); }
1255 
MovFromFloatResultLatency()1256 int MovFromFloatResultLatency() { return MoveLatency(); }
1257 
Float32MinLatency()1258 int Float32MinLatency() {
1259   // Estimated max.
1260   return CompareIsNanF32Latency() + Latency::BRANCH +
1261          2 * (CompareF32Latency() + Latency::BRANCH) + Latency::MFC1 +
1262          2 * Latency::BRANCH + Move_sLatency();
1263 }
1264 
Float64MinLatency()1265 int Float64MinLatency() {
1266   // Estimated max.
1267   return CompareIsNanF64Latency() + Latency::BRANCH +
1268          2 * (CompareF64Latency() + Latency::BRANCH) + Mfhc1Latency() +
1269          2 * Latency::BRANCH + Move_dLatency();
1270 }
1271 
SmiUntagLatency()1272 int SmiUntagLatency() { return 1; }
1273 
PrepareForTailCallLatency()1274 int PrepareForTailCallLatency() {
1275   // Estimated max.
1276   return 2 * (LsaLatency() + AdduLatency(false)) + 2 + Latency::BRANCH +
1277          Latency::BRANCH + 2 * SubuLatency(false) + 2 + Latency::BRANCH + 1;
1278 }
1279 
JumpLatency()1280 int JumpLatency() {
1281   // Estimated max.
1282   return 1 + AdduLatency(false) + Latency::BRANCH + 2;
1283 }
1284 
AssertLatency()1285 int AssertLatency() { return 1; }
1286 
MultiPushLatency()1287 int MultiPushLatency() {
1288   int latency = SubuLatency(false);
1289   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
1290     latency++;
1291   }
1292   return latency;
1293 }
1294 
MultiPushFPULatency()1295 int MultiPushFPULatency() {
1296   int latency = SubuLatency(false);
1297   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
1298     latency += Sdc1Latency();
1299   }
1300   return latency;
1301 }
1302 
PushCallerSavedLatency(SaveFPRegsMode fp_mode)1303 int PushCallerSavedLatency(SaveFPRegsMode fp_mode) {
1304   int latency = MultiPushLatency();
1305   if (fp_mode == SaveFPRegsMode::kSave) {
1306     latency += MultiPushFPULatency();
1307   }
1308   return latency;
1309 }
1310 
MultiPopFPULatency()1311 int MultiPopFPULatency() {
1312   int latency = 0;
1313   for (int16_t i = 0; i < kNumRegisters; i++) {
1314     latency += Ldc1Latency();
1315   }
1316   return latency++;
1317 }
1318 
MultiPopLatency()1319 int MultiPopLatency() {
1320   int latency = 0;
1321   for (int16_t i = 0; i < kNumRegisters; i++) {
1322     latency++;
1323   }
1324   return latency++;
1325 }
1326 
PopCallerSavedLatency(SaveFPRegsMode fp_mode)1327 int PopCallerSavedLatency(SaveFPRegsMode fp_mode) {
1328   int latency = 0;
1329   if (fp_mode == SaveFPRegsMode::kSave) {
1330     latency += MultiPopFPULatency();
1331   }
1332   return latency + MultiPopLatency();
1333 }
1334 
AssembleArchJumpLatency()1335 int AssembleArchJumpLatency() {
1336   // Estimated max.
1337   return Latency::BRANCH;
1338 }
1339 
AssembleArchBinarySearchSwitchLatency(int cases)1340 int AssembleArchBinarySearchSwitchLatency(int cases) {
1341   if (cases < CodeGenerator::kBinarySearchSwitchMinimalCases) {
1342     return cases * (1 + Latency::BRANCH) + AssembleArchJumpLatency();
1343   }
1344   return 1 + Latency::BRANCH + AssembleArchBinarySearchSwitchLatency(cases / 2);
1345 }
1346 
GenerateSwitchTableLatency()1347 int GenerateSwitchTableLatency() {
1348   int latency = 0;
1349   if (kArchVariant >= kMips32r6) {
1350     latency = LsaLatency() + 2;
1351   } else {
1352     latency = 6;
1353   }
1354   latency += 2;
1355   return latency;
1356 }
1357 
AssembleArchTableSwitchLatency()1358 int AssembleArchTableSwitchLatency() {
1359   return Latency::BRANCH + GenerateSwitchTableLatency();
1360 }
1361 
AssembleReturnLatency()1362 int AssembleReturnLatency() {
1363   // Estimated max.
1364   return AdduLatency(false) + MultiPopLatency() + MultiPopFPULatency() +
1365          Latency::BRANCH + 1 + AdduLatency() + 8;
1366 }
1367 
TryInlineTruncateDoubleToILatency()1368 int TryInlineTruncateDoubleToILatency() {
1369   return 2 + Latency::TRUNC_W_D + Latency::MFC1 + 2 + AndLatency(false) +
1370          Latency::BRANCH;
1371 }
1372 
CallStubDelayedLatency()1373 int CallStubDelayedLatency() { return 1 + CallLatency(); }
1374 
TruncateDoubleToIDelayedLatency()1375 int TruncateDoubleToIDelayedLatency() {
1376   // TODO(mips): This no longer reflects how TruncateDoubleToI is called.
1377   return TryInlineTruncateDoubleToILatency() + 1 + SubuLatency(false) +
1378          Sdc1Latency() + CallStubDelayedLatency() + AdduLatency(false) + 1;
1379 }
1380 
CheckPageFlagLatency()1381 int CheckPageFlagLatency() {
1382   return 2 * AndLatency(false) + 1 + Latency::BRANCH;
1383 }
1384 
GetInstructionLatency(const Instruction* instr)1385 int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
1386   // Basic latency modeling for MIPS32 instructions. They have been determined
1387   // in an empirical way.
1388   switch (instr->arch_opcode()) {
1389     case kArchCallCodeObject:
1390 #if V8_ENABLE_WEBASSEMBLY
1391     case kArchCallWasmFunction:
1392 #endif  // V8_ENABLE_WEBASSEMBLY
1393       return CallLatency();
1394     case kArchTailCallCodeObject:
1395 #if V8_ENABLE_WEBASSEMBLY
1396     case kArchTailCallWasm:
1397 #endif  // V8_ENABLE_WEBASSEMBLY
1398     case kArchTailCallAddress:
1399       return JumpLatency();
1400     case kArchCallJSFunction: {
1401       int latency = 0;
1402       if (FLAG_debug_code) {
1403         latency = 1 + AssertLatency();
1404       }
1405       return latency + 1 + AdduLatency(false) + CallLatency();
1406     }
1407     case kArchPrepareCallCFunction:
1408       return PrepareCallCFunctionLatency();
1409     case kArchSaveCallerRegisters: {
1410       auto fp_mode =
1411           static_cast<SaveFPRegsMode>(MiscField::decode(instr->opcode()));
1412       return PushCallerSavedLatency(fp_mode);
1413     }
1414     case kArchRestoreCallerRegisters: {
1415       auto fp_mode =
1416           static_cast<SaveFPRegsMode>(MiscField::decode(instr->opcode()));
1417       return PopCallerSavedLatency(fp_mode);
1418     }
1419     case kArchPrepareTailCall:
1420       return 2;  // Estimated max.
1421     case kArchCallCFunction:
1422       return CallCFunctionLatency();
1423     case kArchJmp:
1424       return AssembleArchJumpLatency();
1425     case kArchBinarySearchSwitch:
1426       return AssembleArchBinarySearchSwitchLatency((instr->InputCount() - 2) /
1427                                                    2);
1428     case kArchTableSwitch:
1429       return AssembleArchTableSwitchLatency();
1430     case kArchAbortCSADcheck:
1431       return CallLatency() + 1;
1432     case kArchComment:
1433     case kArchDeoptimize:
1434       return 0;
1435     case kArchRet:
1436       return AssembleReturnLatency();
1437     case kArchTruncateDoubleToI:
1438       return TruncateDoubleToIDelayedLatency();
1439     case kArchStoreWithWriteBarrier:
1440       return AdduLatency() + 1 + CheckPageFlagLatency();
1441     case kArchStackSlot: {
1442       // Estimated max.
1443       return AdduLatency(false) + AndLatency(false) + AssertLatency() +
1444              AdduLatency(false) + AndLatency(false) + BranchShortLatency() + 1 +
1445              SubuLatency() + AdduLatency();
1446     }
1447     case kIeee754Float64Acos:
1448     case kIeee754Float64Acosh:
1449     case kIeee754Float64Asin:
1450     case kIeee754Float64Asinh:
1451     case kIeee754Float64Atan:
1452     case kIeee754Float64Atanh:
1453     case kIeee754Float64Atan2:
1454     case kIeee754Float64Cos:
1455     case kIeee754Float64Cosh:
1456     case kIeee754Float64Cbrt:
1457     case kIeee754Float64Exp:
1458     case kIeee754Float64Expm1:
1459     case kIeee754Float64Log:
1460     case kIeee754Float64Log1p:
1461     case kIeee754Float64Log10:
1462     case kIeee754Float64Log2:
1463     case kIeee754Float64Pow:
1464     case kIeee754Float64Sin:
1465     case kIeee754Float64Sinh:
1466     case kIeee754Float64Tan:
1467     case kIeee754Float64Tanh:
1468       return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1469              CallCFunctionLatency() + MovFromFloatResultLatency();
1470     case kMipsAdd:
1471       return AdduLatency(instr->InputAt(1)->IsRegister());
1472     case kMipsAnd:
1473       return AndLatency(instr->InputAt(1)->IsRegister());
1474     case kMipsOr:
1475       return OrLatency(instr->InputAt(1)->IsRegister());
1476     case kMipsXor:
1477       return XorLatency(instr->InputAt(1)->IsRegister());
1478     case kMipsSub:
1479       return SubuLatency(instr->InputAt(1)->IsRegister());
1480     case kMipsNor:
1481       return NorLatency(instr->InputAt(1)->IsRegister());
1482     case kMipsAddOvf:
1483       return AddOverflowLatency();
1484     case kMipsSubOvf:
1485       return SubOverflowLatency();
1486     case kMipsMul:
1487       return MulLatency(false);
1488     case kMipsMulHigh:
1489       return MulhLatency(instr->InputAt(1)->IsRegister());
1490     case kMipsMulHighU:
1491       return MulhuLatency(instr->InputAt(1)->IsRegister());
1492     case kMipsMulOvf:
1493       return MulOverflowLatency();
1494     case kMipsMod:
1495       return ModLatency(instr->InputAt(1)->IsRegister());
1496     case kMipsModU:
1497       return ModuLatency(instr->InputAt(1)->IsRegister());
1498     case kMipsDiv: {
1499       int latency = DivLatency(instr->InputAt(1)->IsRegister());
1500       if (IsMipsArchVariant(kMips32r6)) {
1501         return latency++;
1502       } else {
1503         return latency + MovzLatency();
1504       }
1505     }
1506     case kMipsDivU: {
1507       int latency = DivuLatency(instr->InputAt(1)->IsRegister());
1508       if (IsMipsArchVariant(kMips32r6)) {
1509         return latency++;
1510       } else {
1511         return latency + MovzLatency();
1512       }
1513     }
1514     case kMipsClz:
1515       return ClzLatency();
1516     case kMipsCtz:
1517       return CtzLatency();
1518     case kMipsPopcnt:
1519       return PopcntLatency();
1520     case kMipsShlPair: {
1521       if (instr->InputAt(2)->IsRegister()) {
1522         return ShlPairLatency();
1523       } else {
1524         return ShlPairLatency(false);
1525       }
1526     }
1527     case kMipsShrPair: {
1528       if (instr->InputAt(2)->IsRegister()) {
1529         return ShrPairLatency();
1530       } else {
1531         // auto immediate_operand = ImmediateOperand::cast(instr->InputAt(2));
1532         // return ShrPairLatency(false, immediate_operand->inline_32_value());
1533         return 1;
1534       }
1535     }
1536     case kMipsSarPair: {
1537       if (instr->InputAt(2)->IsRegister()) {
1538         return SarPairLatency();
1539       } else {
1540         return SarPairLatency(false);
1541       }
1542     }
1543     case kMipsExt:
1544       return ExtLatency();
1545     case kMipsIns:
1546       return InsLatency();
1547     case kMipsRor:
1548       return RorLatency(instr->InputAt(1)->IsRegister());
1549     case kMipsLsa:
1550       return LsaLatency();
1551     case kMipsModD:
1552       return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1553              CallCFunctionLatency() + MovFromFloatResultLatency();
1554     case kMipsAddPair:
1555       return AddPairLatency();
1556     case kMipsSubPair:
1557       return SubPairLatency();
1558     case kMipsMulPair:
1559       return MulPairLatency();
1560     case kMipsMaddS:
1561       return MaddSLatency();
1562     case kMipsMaddD:
1563       return MaddDLatency();
1564     case kMipsMsubS:
1565       return MsubSLatency();
1566     case kMipsMsubD:
1567       return MsubDLatency();
1568     case kMipsNegS:
1569       return Neg_sLatency();
1570     case kMipsNegD:
1571       return Neg_dLatency();
1572     case kMipsFloat64RoundDown:
1573     case kMipsFloat64RoundTruncate:
1574     case kMipsFloat64RoundUp:
1575     case kMipsFloat64RoundTiesEven:
1576       return Float64RoundLatency();
1577     case kMipsFloat32RoundDown:
1578     case kMipsFloat32RoundTruncate:
1579     case kMipsFloat32RoundUp:
1580     case kMipsFloat32RoundTiesEven:
1581       return Float32RoundLatency();
1582     case kMipsFloat32Max:
1583       return Float32MaxLatency();
1584     case kMipsFloat64Max:
1585       return Float64MaxLatency();
1586     case kMipsFloat32Min:
1587       return Float32MinLatency();
1588     case kMipsFloat64Min:
1589       return Float64MinLatency();
1590     case kMipsCvtSUw:
1591       return CvtSUwLatency();
1592     case kMipsCvtDUw:
1593       return CvtDUwLatency();
1594     case kMipsFloorWD:
1595       return FloorWDLatency();
1596     case kMipsCeilWD:
1597       return CeilWDLatency();
1598     case kMipsRoundWD:
1599       return RoundWDLatency();
1600     case kMipsTruncWD:
1601       return Trunc_w_dLatency() + Latency::MFC1;
1602     case kMipsTruncWS:
1603       return Latency::TRUNC_W_S + Latency::MFC1 + AdduLatency(false) +
1604              SltLatency() + MovnLatency();
1605     case kMipsTruncUwD:
1606       return Trunc_uw_dLatency();
1607     case kMipsTruncUwS:
1608       return Trunc_uw_sLatency() + AdduLatency(false) + MovzLatency();
1609     case kMipsFloat64ExtractLowWord32:
1610       return Latency::MFC1;
1611     case kMipsFloat64ExtractHighWord32:
1612       return Mfhc1Latency();
1613     case kMipsFloat64InsertLowWord32: {
1614       if (IsFp32Mode()) {
1615         return Latency::MTC1;
1616       } else {
1617         return Latency::MFHC1 + Latency::MTC1 + Latency::MTHC1;
1618       }
1619     }
1620     case kMipsFloat64InsertHighWord32:
1621       return Mthc1Latency();
1622     case kMipsFloat64SilenceNaN:
1623       return Latency::SUB_D;
1624     case kMipsSeb:
1625       return SebLatency();
1626     case kMipsSeh:
1627       return SehLatency();
1628     case kMipsUlhu:
1629       return UlhuLatency();
1630     case kMipsUlh:
1631       return UlhLatency();
1632     case kMipsUsh:
1633       return UshLatency();
1634     case kMipsUlw:
1635       return UlwLatency();
1636     case kMipsUsw:
1637       return UswLatency();
1638     case kMipsUlwc1:
1639       return Ulwc1Latency();
1640     case kMipsSwc1:
1641       return MoveLatency(false) + Latency::SWC1;  // Estimated max.
1642     case kMipsUswc1:
1643       return MoveLatency(false) + Uswc1Latency();  // Estimated max.
1644     case kMipsLdc1:
1645       return Ldc1Latency();
1646     case kMipsUldc1:
1647       return Uldc1Latency();
1648     case kMipsSdc1:
1649       return MoveLatency(false) + Sdc1Latency();  // Estimated max.
1650     case kMipsUsdc1:
1651       return MoveLatency(false) + Usdc1Latency();  // Estimated max.
1652     case kMipsPush: {
1653       if (instr->InputAt(0)->IsFPRegister()) {
1654         auto op = LocationOperand::cast(instr->InputAt(0));
1655         switch (op->representation()) {
1656           case MachineRepresentation::kFloat32:
1657             return Latency::SWC1 + SubuLatency(false);
1658           case MachineRepresentation::kFloat64:
1659             return Sdc1Latency() + SubuLatency(false);
1660           default: {
1661             UNREACHABLE();
1662           }
1663         }
1664       } else {
1665         return PushRegisterLatency();
1666       }
1667     }
1668     case kMipsPeek: {
1669       if (instr->OutputAt(0)->IsFPRegister()) {
1670         auto op = LocationOperand::cast(instr->OutputAt(0));
1671         if (op->representation() == MachineRepresentation::kFloat64) {
1672           return Ldc1Latency();
1673         } else {
1674           return Latency::LWC1;
1675         }
1676       } else {
1677         return 1;
1678       }
1679     }
1680     case kMipsStackClaim:
1681       return SubuLatency(false);
1682     case kMipsStoreToStackSlot: {
1683       if (instr->InputAt(0)->IsFPRegister()) {
1684         auto op = LocationOperand::cast(instr->InputAt(0));
1685         if (op->representation() == MachineRepresentation::kFloat64) {
1686           return Sdc1Latency();
1687         } else if (op->representation() == MachineRepresentation::kFloat32) {
1688           return Latency::SWC1;
1689         } else {
1690           return 1;  // Estimated value.
1691         }
1692       } else {
1693         return 1;
1694       }
1695     }
1696     case kMipsByteSwap32:
1697       return ByteSwapSignedLatency();
1698     case kAtomicLoadInt8:
1699     case kAtomicLoadUint8:
1700     case kAtomicLoadInt16:
1701     case kAtomicLoadUint16:
1702     case kAtomicLoadWord32:
1703       return 2;
1704     case kAtomicStoreWord8:
1705     case kAtomicStoreWord16:
1706     case kAtomicStoreWord32:
1707       return 3;
1708     case kAtomicExchangeInt8:
1709       return Word32AtomicExchangeLatency(true, 8);
1710     case kAtomicExchangeUint8:
1711       return Word32AtomicExchangeLatency(false, 8);
1712     case kAtomicExchangeInt16:
1713       return Word32AtomicExchangeLatency(true, 16);
1714     case kAtomicExchangeUint16:
1715       return Word32AtomicExchangeLatency(false, 16);
1716     case kAtomicExchangeWord32: {
1717       return 1 + AdduLatency() + Ldc1Latency() + 1 + ScLatency(0) +
1718              BranchShortLatency() + 1;
1719     }
1720     case kAtomicCompareExchangeInt8:
1721       return Word32AtomicCompareExchangeLatency(true, 8);
1722     case kAtomicCompareExchangeUint8:
1723       return Word32AtomicCompareExchangeLatency(false, 8);
1724     case kAtomicCompareExchangeInt16:
1725       return Word32AtomicCompareExchangeLatency(true, 16);
1726     case kAtomicCompareExchangeUint16:
1727       return Word32AtomicCompareExchangeLatency(false, 16);
1728     case kAtomicCompareExchangeWord32:
1729       return AdduLatency() + 1 + LlLatency(0) + BranchShortLatency() + 1;
1730     case kMipsTst:
1731       return AndLatency(instr->InputAt(1)->IsRegister());
1732     case kMipsCmpS:
1733       return MoveLatency() + CompareF32Latency();
1734     case kMipsCmpD:
1735       return MoveLatency() + CompareF64Latency();
1736     case kArchNop:
1737     case kArchThrowTerminator:
1738     case kMipsCmp:
1739       return 0;
1740     case kArchDebugBreak:
1741     case kArchFramePointer:
1742     case kArchParentFramePointer:
1743     case kMipsShl:
1744     case kMipsShr:
1745     case kMipsSar:
1746     case kMipsMov:
1747     case kMipsMaxS:
1748     case kMipsMinS:
1749     case kMipsMaxD:
1750     case kMipsMinD:
1751     case kMipsLbu:
1752     case kMipsLb:
1753     case kMipsSb:
1754     case kMipsLhu:
1755     case kMipsLh:
1756     case kMipsSh:
1757     case kMipsLw:
1758     case kMipsSw:
1759     case kMipsLwc1:
1760       return 1;
1761     case kMipsAddS:
1762       return Latency::ADD_S;
1763     case kMipsSubS:
1764       return Latency::SUB_S;
1765     case kMipsMulS:
1766       return Latency::MUL_S;
1767     case kMipsAbsS:
1768       return Latency::ABS_S;
1769     case kMipsAddD:
1770       return Latency::ADD_D;
1771     case kMipsSubD:
1772       return Latency::SUB_D;
1773     case kMipsAbsD:
1774       return Latency::ABS_D;
1775     case kMipsCvtSD:
1776       return Latency::CVT_S_D;
1777     case kMipsCvtDS:
1778       return Latency::CVT_D_S;
1779     case kMipsMulD:
1780       return Latency::MUL_D;
1781     case kMipsFloorWS:
1782       return Latency::FLOOR_W_S;
1783     case kMipsCeilWS:
1784       return Latency::CEIL_W_S;
1785     case kMipsRoundWS:
1786       return Latency::ROUND_W_S;
1787     case kMipsCvtDW:
1788       return Latency::CVT_D_W;
1789     case kMipsCvtSW:
1790       return Latency::CVT_S_W;
1791     case kMipsDivS:
1792       return Latency::DIV_S;
1793     case kMipsSqrtS:
1794       return Latency::SQRT_S;
1795     case kMipsDivD:
1796       return Latency::DIV_D;
1797     case kMipsSqrtD:
1798       return Latency::SQRT_D;
1799     default:
1800       return 1;
1801   }
1802 }
1803 
1804 }  // namespace compiler
1805 }  // namespace internal
1806 }  // namespace v8
1807