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/codegen/macro-assembler.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 kMips64AbsD:
18     case kMips64AbsS:
19     case kMips64Add:
20     case kMips64AddD:
21     case kMips64AddS:
22     case kMips64And:
23     case kMips64And32:
24     case kMips64AssertEqual:
25     case kMips64BitcastDL:
26     case kMips64BitcastLD:
27     case kMips64ByteSwap32:
28     case kMips64ByteSwap64:
29     case kMips64CeilWD:
30     case kMips64CeilWS:
31     case kMips64Clz:
32     case kMips64Cmp:
33     case kMips64CmpD:
34     case kMips64CmpS:
35     case kMips64Ctz:
36     case kMips64CvtDL:
37     case kMips64CvtDS:
38     case kMips64CvtDUl:
39     case kMips64CvtDUw:
40     case kMips64CvtDW:
41     case kMips64CvtSD:
42     case kMips64CvtSL:
43     case kMips64CvtSUl:
44     case kMips64CvtSUw:
45     case kMips64CvtSW:
46     case kMips64DMulHigh:
47     case kMips64MulHighU:
48     case kMips64Dadd:
49     case kMips64DaddOvf:
50     case kMips64Dclz:
51     case kMips64Dctz:
52     case kMips64Ddiv:
53     case kMips64DdivU:
54     case kMips64Dext:
55     case kMips64Dins:
56     case kMips64Div:
57     case kMips64DivD:
58     case kMips64DivS:
59     case kMips64DivU:
60     case kMips64Dlsa:
61     case kMips64Dmod:
62     case kMips64DmodU:
63     case kMips64Dmul:
64     case kMips64Dpopcnt:
65     case kMips64Dror:
66     case kMips64Dsar:
67     case kMips64Dshl:
68     case kMips64Dshr:
69     case kMips64Dsub:
70     case kMips64DsubOvf:
71     case kMips64Ext:
72     case kMips64F64x2Abs:
73     case kMips64F64x2Neg:
74     case kMips64F64x2Sqrt:
75     case kMips64F64x2Add:
76     case kMips64F64x2Sub:
77     case kMips64F64x2Mul:
78     case kMips64F64x2Div:
79     case kMips64F64x2Min:
80     case kMips64F64x2Max:
81     case kMips64F64x2Eq:
82     case kMips64F64x2Ne:
83     case kMips64F64x2Lt:
84     case kMips64F64x2Le:
85     case kMips64I64x2Add:
86     case kMips64I64x2Sub:
87     case kMips64I64x2Mul:
88     case kMips64I64x2Neg:
89     case kMips64I64x2Shl:
90     case kMips64I64x2ShrS:
91     case kMips64I64x2ShrU:
92     case kMips64F32x4Abs:
93     case kMips64F32x4Add:
94     case kMips64F32x4AddHoriz:
95     case kMips64F32x4Eq:
96     case kMips64F32x4ExtractLane:
97     case kMips64F32x4Lt:
98     case kMips64F32x4Le:
99     case kMips64F32x4Max:
100     case kMips64F32x4Min:
101     case kMips64F32x4Mul:
102     case kMips64F32x4Div:
103     case kMips64F32x4Ne:
104     case kMips64F32x4Neg:
105     case kMips64F32x4Sqrt:
106     case kMips64F32x4RecipApprox:
107     case kMips64F32x4RecipSqrtApprox:
108     case kMips64F32x4ReplaceLane:
109     case kMips64F32x4SConvertI32x4:
110     case kMips64F32x4Splat:
111     case kMips64F32x4Sub:
112     case kMips64F32x4UConvertI32x4:
113     case kMips64F64x2Splat:
114     case kMips64F64x2ExtractLane:
115     case kMips64F64x2ReplaceLane:
116     case kMips64Float32Max:
117     case kMips64Float32Min:
118     case kMips64Float32RoundDown:
119     case kMips64Float32RoundTiesEven:
120     case kMips64Float32RoundTruncate:
121     case kMips64Float32RoundUp:
122     case kMips64Float64ExtractLowWord32:
123     case kMips64Float64ExtractHighWord32:
124     case kMips64Float64InsertLowWord32:
125     case kMips64Float64InsertHighWord32:
126     case kMips64Float64Max:
127     case kMips64Float64Min:
128     case kMips64Float64RoundDown:
129     case kMips64Float64RoundTiesEven:
130     case kMips64Float64RoundTruncate:
131     case kMips64Float64RoundUp:
132     case kMips64Float64SilenceNaN:
133     case kMips64FloorWD:
134     case kMips64FloorWS:
135     case kMips64I16x8Add:
136     case kMips64I16x8AddHoriz:
137     case kMips64I16x8AddSaturateS:
138     case kMips64I16x8AddSaturateU:
139     case kMips64I16x8Eq:
140     case kMips64I16x8ExtractLaneU:
141     case kMips64I16x8ExtractLaneS:
142     case kMips64I16x8GeS:
143     case kMips64I16x8GeU:
144     case kMips64I16x8GtS:
145     case kMips64I16x8GtU:
146     case kMips64I16x8MaxS:
147     case kMips64I16x8MaxU:
148     case kMips64I16x8MinS:
149     case kMips64I16x8MinU:
150     case kMips64I16x8Mul:
151     case kMips64I16x8Ne:
152     case kMips64I16x8Neg:
153     case kMips64I16x8ReplaceLane:
154     case kMips64I8x16SConvertI16x8:
155     case kMips64I16x8SConvertI32x4:
156     case kMips64I16x8SConvertI8x16High:
157     case kMips64I16x8SConvertI8x16Low:
158     case kMips64I16x8Shl:
159     case kMips64I16x8ShrS:
160     case kMips64I16x8ShrU:
161     case kMips64I16x8Splat:
162     case kMips64I16x8Sub:
163     case kMips64I16x8SubSaturateS:
164     case kMips64I16x8SubSaturateU:
165     case kMips64I8x16UConvertI16x8:
166     case kMips64I16x8UConvertI32x4:
167     case kMips64I16x8UConvertI8x16High:
168     case kMips64I16x8UConvertI8x16Low:
169     case kMips64I16x8RoundingAverageU:
170     case kMips64I16x8Abs:
171     case kMips64I32x4Add:
172     case kMips64I32x4AddHoriz:
173     case kMips64I32x4Eq:
174     case kMips64I32x4ExtractLane:
175     case kMips64I32x4GeS:
176     case kMips64I32x4GeU:
177     case kMips64I32x4GtS:
178     case kMips64I32x4GtU:
179     case kMips64I32x4MaxS:
180     case kMips64I32x4MaxU:
181     case kMips64I32x4MinS:
182     case kMips64I32x4MinU:
183     case kMips64I32x4Mul:
184     case kMips64I32x4Ne:
185     case kMips64I32x4Neg:
186     case kMips64I32x4ReplaceLane:
187     case kMips64I32x4SConvertF32x4:
188     case kMips64I32x4SConvertI16x8High:
189     case kMips64I32x4SConvertI16x8Low:
190     case kMips64I32x4Shl:
191     case kMips64I32x4ShrS:
192     case kMips64I32x4ShrU:
193     case kMips64I32x4Splat:
194     case kMips64I32x4Sub:
195     case kMips64I32x4UConvertF32x4:
196     case kMips64I32x4UConvertI16x8High:
197     case kMips64I32x4UConvertI16x8Low:
198     case kMips64I32x4Abs:
199     case kMips64I8x16Add:
200     case kMips64I8x16AddSaturateS:
201     case kMips64I8x16AddSaturateU:
202     case kMips64I8x16Eq:
203     case kMips64I8x16ExtractLaneU:
204     case kMips64I8x16ExtractLaneS:
205     case kMips64I8x16GeS:
206     case kMips64I8x16GeU:
207     case kMips64I8x16GtS:
208     case kMips64I8x16GtU:
209     case kMips64I8x16MaxS:
210     case kMips64I8x16MaxU:
211     case kMips64I8x16MinS:
212     case kMips64I8x16MinU:
213     case kMips64I8x16Mul:
214     case kMips64I8x16Ne:
215     case kMips64I8x16Neg:
216     case kMips64I8x16ReplaceLane:
217     case kMips64I8x16Shl:
218     case kMips64I8x16ShrS:
219     case kMips64I8x16ShrU:
220     case kMips64I8x16Splat:
221     case kMips64I8x16Sub:
222     case kMips64I8x16SubSaturateS:
223     case kMips64I8x16SubSaturateU:
224     case kMips64I8x16RoundingAverageU:
225     case kMips64I8x16Abs:
226     case kMips64Ins:
227     case kMips64Lsa:
228     case kMips64MaxD:
229     case kMips64MaxS:
230     case kMips64MinD:
231     case kMips64MinS:
232     case kMips64Mod:
233     case kMips64ModU:
234     case kMips64Mov:
235     case kMips64Mul:
236     case kMips64MulD:
237     case kMips64MulHigh:
238     case kMips64MulOvf:
239     case kMips64MulS:
240     case kMips64NegD:
241     case kMips64NegS:
242     case kMips64Nor:
243     case kMips64Nor32:
244     case kMips64Or:
245     case kMips64Or32:
246     case kMips64Popcnt:
247     case kMips64Ror:
248     case kMips64RoundWD:
249     case kMips64RoundWS:
250     case kMips64S128And:
251     case kMips64S128Or:
252     case kMips64S128Not:
253     case kMips64S128Select:
254     case kMips64S128AndNot:
255     case kMips64S128Xor:
256     case kMips64S128Zero:
257     case kMips64S16x8InterleaveEven:
258     case kMips64S16x8InterleaveOdd:
259     case kMips64S16x8InterleaveLeft:
260     case kMips64S16x8InterleaveRight:
261     case kMips64S16x8PackEven:
262     case kMips64S16x8PackOdd:
263     case kMips64S16x2Reverse:
264     case kMips64S16x4Reverse:
265     case kMips64S1x16AllTrue:
266     case kMips64S1x16AnyTrue:
267     case kMips64S1x4AllTrue:
268     case kMips64S1x4AnyTrue:
269     case kMips64S1x8AllTrue:
270     case kMips64S1x8AnyTrue:
271     case kMips64S32x4InterleaveEven:
272     case kMips64S32x4InterleaveOdd:
273     case kMips64S32x4InterleaveLeft:
274     case kMips64S32x4InterleaveRight:
275     case kMips64S32x4PackEven:
276     case kMips64S32x4PackOdd:
277     case kMips64S32x4Shuffle:
278     case kMips64S8x16Concat:
279     case kMips64S8x16InterleaveEven:
280     case kMips64S8x16InterleaveOdd:
281     case kMips64S8x16InterleaveLeft:
282     case kMips64S8x16InterleaveRight:
283     case kMips64S8x16PackEven:
284     case kMips64S8x16PackOdd:
285     case kMips64S8x2Reverse:
286     case kMips64S8x4Reverse:
287     case kMips64S8x8Reverse:
288     case kMips64S8x16Shuffle:
289     case kMips64S8x16Swizzle:
290     case kMips64Sar:
291     case kMips64Seb:
292     case kMips64Seh:
293     case kMips64Shl:
294     case kMips64Shr:
295     case kMips64SqrtD:
296     case kMips64SqrtS:
297     case kMips64Sub:
298     case kMips64SubD:
299     case kMips64SubS:
300     case kMips64TruncLD:
301     case kMips64TruncLS:
302     case kMips64TruncUlD:
303     case kMips64TruncUlS:
304     case kMips64TruncUwD:
305     case kMips64TruncUwS:
306     case kMips64TruncWD:
307     case kMips64TruncWS:
308     case kMips64Tst:
309     case kMips64Xor:
310     case kMips64Xor32:
311       return kNoOpcodeFlags;
312 
313     case kMips64Lb:
314     case kMips64Lbu:
315     case kMips64Ld:
316     case kMips64Ldc1:
317     case kMips64Lh:
318     case kMips64Lhu:
319     case kMips64Lw:
320     case kMips64Lwc1:
321     case kMips64Lwu:
322     case kMips64MsaLd:
323     case kMips64Peek:
324     case kMips64Uld:
325     case kMips64Uldc1:
326     case kMips64Ulh:
327     case kMips64Ulhu:
328     case kMips64Ulw:
329     case kMips64Ulwu:
330     case kMips64Ulwc1:
331     case kMips64S8x16LoadSplat:
332     case kMips64S16x8LoadSplat:
333     case kMips64S32x4LoadSplat:
334     case kMips64S64x2LoadSplat:
335     case kMips64I16x8Load8x8S:
336     case kMips64I16x8Load8x8U:
337     case kMips64I32x4Load16x4S:
338     case kMips64I32x4Load16x4U:
339     case kMips64I64x2Load32x2S:
340     case kMips64I64x2Load32x2U:
341     case kMips64Word64AtomicLoadUint8:
342     case kMips64Word64AtomicLoadUint16:
343     case kMips64Word64AtomicLoadUint32:
344     case kMips64Word64AtomicLoadUint64:
345 
346       return kIsLoadOperation;
347 
348     case kMips64ModD:
349     case kMips64ModS:
350     case kMips64MsaSt:
351     case kMips64Push:
352     case kMips64Sb:
353     case kMips64Sd:
354     case kMips64Sdc1:
355     case kMips64Sh:
356     case kMips64StackClaim:
357     case kMips64StoreToStackSlot:
358     case kMips64Sw:
359     case kMips64Swc1:
360     case kMips64Usd:
361     case kMips64Usdc1:
362     case kMips64Ush:
363     case kMips64Usw:
364     case kMips64Uswc1:
365     case kMips64Sync:
366     case kMips64Word64AtomicStoreWord8:
367     case kMips64Word64AtomicStoreWord16:
368     case kMips64Word64AtomicStoreWord32:
369     case kMips64Word64AtomicStoreWord64:
370     case kMips64Word64AtomicAddUint8:
371     case kMips64Word64AtomicAddUint16:
372     case kMips64Word64AtomicAddUint32:
373     case kMips64Word64AtomicAddUint64:
374     case kMips64Word64AtomicSubUint8:
375     case kMips64Word64AtomicSubUint16:
376     case kMips64Word64AtomicSubUint32:
377     case kMips64Word64AtomicSubUint64:
378     case kMips64Word64AtomicAndUint8:
379     case kMips64Word64AtomicAndUint16:
380     case kMips64Word64AtomicAndUint32:
381     case kMips64Word64AtomicAndUint64:
382     case kMips64Word64AtomicOrUint8:
383     case kMips64Word64AtomicOrUint16:
384     case kMips64Word64AtomicOrUint32:
385     case kMips64Word64AtomicOrUint64:
386     case kMips64Word64AtomicXorUint8:
387     case kMips64Word64AtomicXorUint16:
388     case kMips64Word64AtomicXorUint32:
389     case kMips64Word64AtomicXorUint64:
390     case kMips64Word64AtomicExchangeUint8:
391     case kMips64Word64AtomicExchangeUint16:
392     case kMips64Word64AtomicExchangeUint32:
393     case kMips64Word64AtomicExchangeUint64:
394     case kMips64Word64AtomicCompareExchangeUint8:
395     case kMips64Word64AtomicCompareExchangeUint16:
396     case kMips64Word64AtomicCompareExchangeUint32:
397     case kMips64Word64AtomicCompareExchangeUint64:
398       return kHasSideEffect;
399 
400 #define CASE(Name) case k##Name:
401       COMMON_ARCH_OPCODE_LIST(CASE)
402 #undef CASE
403       // Already covered in architecture independent code.
404       UNREACHABLE();
405   }
406 
407   UNREACHABLE();
408 }
409 
410 enum Latency {
411   BRANCH = 4,  // Estimated max.
412   RINT_S = 4,  // Estimated.
413   RINT_D = 4,  // Estimated.
414 
415   MULT = 4,
416   MULTU = 4,
417   DMULT = 4,
418   DMULTU = 4,
419 
420   MUL = 7,
421   DMUL = 7,
422   MUH = 7,
423   MUHU = 7,
424   DMUH = 7,
425   DMUHU = 7,
426 
427   DIV = 50,  // Min:11 Max:50
428   DDIV = 50,
429   DIVU = 50,
430   DDIVU = 50,
431 
432   ABS_S = 4,
433   ABS_D = 4,
434   NEG_S = 4,
435   NEG_D = 4,
436   ADD_S = 4,
437   ADD_D = 4,
438   SUB_S = 4,
439   SUB_D = 4,
440   MAX_S = 4,  // Estimated.
441   MIN_S = 4,
442   MAX_D = 4,  // Estimated.
443   MIN_D = 4,
444   C_cond_S = 4,
445   C_cond_D = 4,
446   MUL_S = 4,
447 
448   MADD_S = 4,
449   MSUB_S = 4,
450   NMADD_S = 4,
451   NMSUB_S = 4,
452 
453   CABS_cond_S = 4,
454   CABS_cond_D = 4,
455 
456   CVT_D_S = 4,
457   CVT_PS_PW = 4,
458 
459   CVT_S_W = 4,
460   CVT_S_L = 4,
461   CVT_D_W = 4,
462   CVT_D_L = 4,
463 
464   CVT_S_D = 4,
465 
466   CVT_W_S = 4,
467   CVT_W_D = 4,
468   CVT_L_S = 4,
469   CVT_L_D = 4,
470 
471   CEIL_W_S = 4,
472   CEIL_W_D = 4,
473   CEIL_L_S = 4,
474   CEIL_L_D = 4,
475 
476   FLOOR_W_S = 4,
477   FLOOR_W_D = 4,
478   FLOOR_L_S = 4,
479   FLOOR_L_D = 4,
480 
481   ROUND_W_S = 4,
482   ROUND_W_D = 4,
483   ROUND_L_S = 4,
484   ROUND_L_D = 4,
485 
486   TRUNC_W_S = 4,
487   TRUNC_W_D = 4,
488   TRUNC_L_S = 4,
489   TRUNC_L_D = 4,
490 
491   MOV_S = 4,
492   MOV_D = 4,
493 
494   MOVF_S = 4,
495   MOVF_D = 4,
496 
497   MOVN_S = 4,
498   MOVN_D = 4,
499 
500   MOVT_S = 4,
501   MOVT_D = 4,
502 
503   MOVZ_S = 4,
504   MOVZ_D = 4,
505 
506   MUL_D = 5,
507   MADD_D = 5,
508   MSUB_D = 5,
509   NMADD_D = 5,
510   NMSUB_D = 5,
511 
512   RECIP_S = 13,
513   RECIP_D = 26,
514 
515   RSQRT_S = 17,
516   RSQRT_D = 36,
517 
518   DIV_S = 17,
519   SQRT_S = 17,
520 
521   DIV_D = 32,
522   SQRT_D = 32,
523 
524   MTC1 = 4,
525   MTHC1 = 4,
526   DMTC1 = 4,
527   LWC1 = 4,
528   LDC1 = 4,
529 
530   MFC1 = 1,
531   MFHC1 = 1,
532   DMFC1 = 1,
533   MFHI = 1,
534   MFLO = 1,
535   SWC1 = 1,
536   SDC1 = 1,
537 };
538 
DadduLatency(bool is_operand_register=true)539 int DadduLatency(bool is_operand_register = true) {
540   if (is_operand_register) {
541     return 1;
542   } else {
543     return 2;  // Estimated max.
544   }
545 }
546 
DsubuLatency(bool is_operand_register=true)547 int DsubuLatency(bool is_operand_register = true) {
548   return DadduLatency(is_operand_register);
549 }
550 
AndLatency(bool is_operand_register=true)551 int AndLatency(bool is_operand_register = true) {
552   return DadduLatency(is_operand_register);
553 }
554 
OrLatency(bool is_operand_register=true)555 int OrLatency(bool is_operand_register = true) {
556   return DadduLatency(is_operand_register);
557 }
558 
NorLatency(bool is_operand_register=true)559 int NorLatency(bool is_operand_register = true) {
560   if (is_operand_register) {
561     return 1;
562   } else {
563     return 2;  // Estimated max.
564   }
565 }
566 
XorLatency(bool is_operand_register=true)567 int XorLatency(bool is_operand_register = true) {
568   return DadduLatency(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     return Latency::MUL;
574   } else {
575     return Latency::MUL + 1;
576   }
577 }
578 
DmulLatency(bool is_operand_register=true)579 int DmulLatency(bool is_operand_register = true) {
580   int latency = 0;
581   if (kArchVariant >= kMips64r6) {
582     latency = Latency::DMUL;
583   } else {
584     latency = Latency::DMULT + Latency::MFLO;
585   }
586   if (!is_operand_register) {
587     latency += 1;
588   }
589   return latency;
590 }
591 
MulhLatency(bool is_operand_register=true)592 int MulhLatency(bool is_operand_register = true) {
593   int latency = 0;
594   if (kArchVariant >= kMips64r6) {
595     latency = Latency::MUH;
596   } else {
597     latency = Latency::MULT + Latency::MFHI;
598   }
599   if (!is_operand_register) {
600     latency += 1;
601   }
602   return latency;
603 }
604 
MulhuLatency(bool is_operand_register=true)605 int MulhuLatency(bool is_operand_register = true) {
606   int latency = 0;
607   if (kArchVariant >= kMips64r6) {
608     latency = Latency::MUH;
609   } else {
610     latency = Latency::MULTU + Latency::MFHI;
611   }
612   if (!is_operand_register) {
613     latency += 1;
614   }
615   return latency;
616 }
617 
DMulhLatency(bool is_operand_register=true)618 int DMulhLatency(bool is_operand_register = true) {
619   int latency = 0;
620   if (kArchVariant >= kMips64r6) {
621     latency = Latency::DMUH;
622   } else {
623     latency = Latency::DMULT + Latency::MFHI;
624   }
625   if (!is_operand_register) {
626     latency += 1;
627   }
628   return latency;
629 }
630 
DivLatency(bool is_operand_register=true)631 int DivLatency(bool is_operand_register = true) {
632   if (is_operand_register) {
633     return Latency::DIV;
634   } else {
635     return Latency::DIV + 1;
636   }
637 }
638 
DivuLatency(bool is_operand_register=true)639 int DivuLatency(bool is_operand_register = true) {
640   if (is_operand_register) {
641     return Latency::DIVU;
642   } else {
643     return Latency::DIVU + 1;
644   }
645 }
646 
DdivLatency(bool is_operand_register=true)647 int DdivLatency(bool is_operand_register = true) {
648   int latency = 0;
649   if (kArchVariant >= kMips64r6) {
650     latency = Latency::DDIV;
651   } else {
652     latency = Latency::DDIV + Latency::MFLO;
653   }
654   if (!is_operand_register) {
655     latency += 1;
656   }
657   return latency;
658 }
659 
DdivuLatency(bool is_operand_register=true)660 int DdivuLatency(bool is_operand_register = true) {
661   int latency = 0;
662   if (kArchVariant >= kMips64r6) {
663     latency = Latency::DDIVU;
664   } else {
665     latency = Latency::DDIVU + Latency::MFLO;
666   }
667   if (!is_operand_register) {
668     latency += 1;
669   }
670   return latency;
671 }
672 
ModLatency(bool is_operand_register=true)673 int ModLatency(bool is_operand_register = true) {
674   int latency = 0;
675   if (kArchVariant >= kMips64r6) {
676     latency = 1;
677   } else {
678     latency = Latency::DIV + Latency::MFHI;
679   }
680   if (!is_operand_register) {
681     latency += 1;
682   }
683   return latency;
684 }
685 
ModuLatency(bool is_operand_register=true)686 int ModuLatency(bool is_operand_register = true) {
687   int latency = 0;
688   if (kArchVariant >= kMips64r6) {
689     latency = 1;
690   } else {
691     latency = Latency::DIVU + Latency::MFHI;
692   }
693   if (!is_operand_register) {
694     latency += 1;
695   }
696   return latency;
697 }
698 
DmodLatency(bool is_operand_register=true)699 int DmodLatency(bool is_operand_register = true) {
700   int latency = 0;
701   if (kArchVariant >= kMips64r6) {
702     latency = 1;
703   } else {
704     latency = Latency::DDIV + Latency::MFHI;
705   }
706   if (!is_operand_register) {
707     latency += 1;
708   }
709   return latency;
710 }
711 
DmoduLatency(bool is_operand_register=true)712 int DmoduLatency(bool is_operand_register = true) {
713   int latency = 0;
714   if (kArchVariant >= kMips64r6) {
715     latency = 1;
716   } else {
717     latency = Latency::DDIV + Latency::MFHI;
718   }
719   if (!is_operand_register) {
720     latency += 1;
721   }
722   return latency;
723 }
724 
MovzLatency()725 int MovzLatency() {
726   if (kArchVariant >= kMips64r6) {
727     return Latency::BRANCH + 1;
728   } else {
729     return 1;
730   }
731 }
732 
MovnLatency()733 int MovnLatency() {
734   if (kArchVariant >= kMips64r6) {
735     return Latency::BRANCH + 1;
736   } else {
737     return 1;
738   }
739 }
740 
DlsaLatency()741 int DlsaLatency() {
742   // Estimated max.
743   return DadduLatency() + 1;
744 }
745 
CallLatency()746 int CallLatency() {
747   // Estimated.
748   return DadduLatency(false) + Latency::BRANCH + 5;
749 }
750 
JumpLatency()751 int JumpLatency() {
752   // Estimated max.
753   return 1 + DadduLatency() + Latency::BRANCH + 2;
754 }
755 
SmiUntagLatency()756 int SmiUntagLatency() { return 1; }
757 
PrepareForTailCallLatency()758 int PrepareForTailCallLatency() {
759   // Estimated max.
760   return 2 * (DlsaLatency() + DadduLatency(false)) + 2 + Latency::BRANCH +
761          Latency::BRANCH + 2 * DsubuLatency(false) + 2 + Latency::BRANCH + 1;
762 }
763 
AssemblePopArgumentsAdoptFrameLatency()764 int AssemblePopArgumentsAdoptFrameLatency() {
765   return 1 + Latency::BRANCH + 1 + SmiUntagLatency() +
766          PrepareForTailCallLatency();
767 }
768 
AssertLatency()769 int AssertLatency() { return 1; }
770 
PrepareCallCFunctionLatency()771 int PrepareCallCFunctionLatency() {
772   int frame_alignment = TurboAssembler::ActivationFrameAlignment();
773   if (frame_alignment > kSystemPointerSize) {
774     return 1 + DsubuLatency(false) + AndLatency(false) + 1;
775   } else {
776     return DsubuLatency(false);
777   }
778 }
779 
AdjustBaseAndOffsetLatency()780 int AdjustBaseAndOffsetLatency() {
781   return 3;  // Estimated max.
782 }
783 
AlignedMemoryLatency()784 int AlignedMemoryLatency() { return AdjustBaseAndOffsetLatency() + 1; }
785 
UlhuLatency()786 int UlhuLatency() {
787   if (kArchVariant >= kMips64r6) {
788     return AlignedMemoryLatency();
789   } else {
790     return AdjustBaseAndOffsetLatency() + 2 * AlignedMemoryLatency() + 2;
791   }
792 }
793 
UlwLatency()794 int UlwLatency() {
795   if (kArchVariant >= kMips64r6) {
796     return AlignedMemoryLatency();
797   } else {
798     // Estimated max.
799     return AdjustBaseAndOffsetLatency() + 3;
800   }
801 }
802 
UlwuLatency()803 int UlwuLatency() {
804   if (kArchVariant >= kMips64r6) {
805     return AlignedMemoryLatency();
806   } else {
807     return UlwLatency() + 1;
808   }
809 }
810 
UldLatency()811 int UldLatency() {
812   if (kArchVariant >= kMips64r6) {
813     return AlignedMemoryLatency();
814   } else {
815     // Estimated max.
816     return AdjustBaseAndOffsetLatency() + 3;
817   }
818 }
819 
Ulwc1Latency()820 int Ulwc1Latency() {
821   if (kArchVariant >= kMips64r6) {
822     return AlignedMemoryLatency();
823   } else {
824     return UlwLatency() + Latency::MTC1;
825   }
826 }
827 
Uldc1Latency()828 int Uldc1Latency() {
829   if (kArchVariant >= kMips64r6) {
830     return AlignedMemoryLatency();
831   } else {
832     return UldLatency() + Latency::DMTC1;
833   }
834 }
835 
UshLatency()836 int UshLatency() {
837   if (kArchVariant >= kMips64r6) {
838     return AlignedMemoryLatency();
839   } else {
840     // Estimated max.
841     return AdjustBaseAndOffsetLatency() + 2 + 2 * AlignedMemoryLatency();
842   }
843 }
844 
UswLatency()845 int UswLatency() {
846   if (kArchVariant >= kMips64r6) {
847     return AlignedMemoryLatency();
848   } else {
849     return AdjustBaseAndOffsetLatency() + 2;
850   }
851 }
852 
UsdLatency()853 int UsdLatency() {
854   if (kArchVariant >= kMips64r6) {
855     return AlignedMemoryLatency();
856   } else {
857     return AdjustBaseAndOffsetLatency() + 2;
858   }
859 }
860 
Uswc1Latency()861 int Uswc1Latency() {
862   if (kArchVariant >= kMips64r6) {
863     return AlignedMemoryLatency();
864   } else {
865     return Latency::MFC1 + UswLatency();
866   }
867 }
868 
Usdc1Latency()869 int Usdc1Latency() {
870   if (kArchVariant >= kMips64r6) {
871     return AlignedMemoryLatency();
872   } else {
873     return Latency::DMFC1 + UsdLatency();
874   }
875 }
876 
Lwc1Latency()877 int Lwc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::LWC1; }
878 
Swc1Latency()879 int Swc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::SWC1; }
880 
Sdc1Latency()881 int Sdc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::SDC1; }
882 
Ldc1Latency()883 int Ldc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::LDC1; }
884 
MultiPushLatency()885 int MultiPushLatency() {
886   int latency = DsubuLatency(false);
887   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
888     latency++;
889   }
890   return latency;
891 }
892 
MultiPushFPULatency()893 int MultiPushFPULatency() {
894   int latency = DsubuLatency(false);
895   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
896     latency += Sdc1Latency();
897   }
898   return latency;
899 }
900 
PushCallerSavedLatency(SaveFPRegsMode fp_mode)901 int PushCallerSavedLatency(SaveFPRegsMode fp_mode) {
902   int latency = MultiPushLatency();
903   if (fp_mode == kSaveFPRegs) {
904     latency += MultiPushFPULatency();
905   }
906   return latency;
907 }
908 
MultiPopLatency()909 int MultiPopLatency() {
910   int latency = DadduLatency(false);
911   for (int16_t i = 0; i < kNumRegisters; i++) {
912     latency++;
913   }
914   return latency;
915 }
916 
MultiPopFPULatency()917 int MultiPopFPULatency() {
918   int latency = DadduLatency(false);
919   for (int16_t i = 0; i < kNumRegisters; i++) {
920     latency += Ldc1Latency();
921   }
922   return latency;
923 }
924 
PopCallerSavedLatency(SaveFPRegsMode fp_mode)925 int PopCallerSavedLatency(SaveFPRegsMode fp_mode) {
926   int latency = MultiPopLatency();
927   if (fp_mode == kSaveFPRegs) {
928     latency += MultiPopFPULatency();
929   }
930   return latency;
931 }
932 
CallCFunctionHelperLatency()933 int CallCFunctionHelperLatency() {
934   // Estimated.
935   int latency = AndLatency(false) + Latency::BRANCH + 2 + CallLatency();
936   if (base::OS::ActivationFrameAlignment() > kSystemPointerSize) {
937     latency++;
938   } else {
939     latency += DadduLatency(false);
940   }
941   return latency;
942 }
943 
CallCFunctionLatency()944 int CallCFunctionLatency() { return 1 + CallCFunctionHelperLatency(); }
945 
AssembleArchJumpLatency()946 int AssembleArchJumpLatency() {
947   // Estimated max.
948   return Latency::BRANCH;
949 }
950 
GenerateSwitchTableLatency()951 int GenerateSwitchTableLatency() {
952   int latency = 0;
953   if (kArchVariant >= kMips64r6) {
954     latency = DlsaLatency() + 2;
955   } else {
956     latency = 6;
957   }
958   latency += 2;
959   return latency;
960 }
961 
AssembleArchTableSwitchLatency()962 int AssembleArchTableSwitchLatency() {
963   return Latency::BRANCH + GenerateSwitchTableLatency();
964 }
965 
DropAndRetLatency()966 int DropAndRetLatency() {
967   // Estimated max.
968   return DadduLatency(false) + JumpLatency();
969 }
970 
AssemblerReturnLatency()971 int AssemblerReturnLatency() {
972   // Estimated max.
973   return DadduLatency(false) + MultiPopLatency() + MultiPopFPULatency() +
974          Latency::BRANCH + DadduLatency() + 1 + DropAndRetLatency();
975 }
976 
TryInlineTruncateDoubleToILatency()977 int TryInlineTruncateDoubleToILatency() {
978   return 2 + Latency::TRUNC_W_D + Latency::MFC1 + 2 + AndLatency(false) +
979          Latency::BRANCH;
980 }
981 
CallStubDelayedLatency()982 int CallStubDelayedLatency() { return 1 + CallLatency(); }
983 
TruncateDoubleToIDelayedLatency()984 int TruncateDoubleToIDelayedLatency() {
985   // TODO(mips): This no longer reflects how TruncateDoubleToI is called.
986   return TryInlineTruncateDoubleToILatency() + 1 + DsubuLatency(false) +
987          Sdc1Latency() + CallStubDelayedLatency() + DadduLatency(false) + 1;
988 }
989 
CheckPageFlagLatency()990 int CheckPageFlagLatency() {
991   return AndLatency(false) + AlignedMemoryLatency() + AndLatency(false) +
992          Latency::BRANCH;
993 }
994 
SltuLatency(bool is_operand_register=true)995 int SltuLatency(bool is_operand_register = true) {
996   if (is_operand_register) {
997     return 1;
998   } else {
999     return 2;  // Estimated max.
1000   }
1001 }
1002 
BranchShortHelperR6Latency()1003 int BranchShortHelperR6Latency() {
1004   return 2;  // Estimated max.
1005 }
1006 
BranchShortHelperLatency()1007 int BranchShortHelperLatency() {
1008   return SltuLatency() + 2;  // Estimated max.
1009 }
1010 
BranchShortLatency(BranchDelaySlot bdslot=PROTECT)1011 int BranchShortLatency(BranchDelaySlot bdslot = PROTECT) {
1012   if (kArchVariant >= kMips64r6 && bdslot == PROTECT) {
1013     return BranchShortHelperR6Latency();
1014   } else {
1015     return BranchShortHelperLatency();
1016   }
1017 }
1018 
MoveLatency()1019 int MoveLatency() { return 1; }
1020 
MovToFloatParametersLatency()1021 int MovToFloatParametersLatency() { return 2 * MoveLatency(); }
1022 
MovFromFloatResultLatency()1023 int MovFromFloatResultLatency() { return MoveLatency(); }
1024 
DaddOverflowLatency()1025 int DaddOverflowLatency() {
1026   // Estimated max.
1027   return 6;
1028 }
1029 
DsubOverflowLatency()1030 int DsubOverflowLatency() {
1031   // Estimated max.
1032   return 6;
1033 }
1034 
MulOverflowLatency()1035 int MulOverflowLatency() {
1036   // Estimated max.
1037   return MulLatency() + MulhLatency() + 2;
1038 }
1039 
DclzLatency()1040 int DclzLatency() { return 1; }
1041 
CtzLatency()1042 int CtzLatency() {
1043   if (kArchVariant >= kMips64r6) {
1044     return 3 + DclzLatency();
1045   } else {
1046     return DadduLatency(false) + XorLatency() + AndLatency() + DclzLatency() +
1047            1 + DsubuLatency();
1048   }
1049 }
1050 
DctzLatency()1051 int DctzLatency() {
1052   if (kArchVariant >= kMips64r6) {
1053     return 4;
1054   } else {
1055     return DadduLatency(false) + XorLatency() + AndLatency() + 1 +
1056            DsubuLatency();
1057   }
1058 }
1059 
PopcntLatency()1060 int PopcntLatency() {
1061   return 2 + AndLatency() + DsubuLatency() + 1 + AndLatency() + 1 +
1062          AndLatency() + DadduLatency() + 1 + DadduLatency() + 1 + AndLatency() +
1063          1 + MulLatency() + 1;
1064 }
1065 
DpopcntLatency()1066 int DpopcntLatency() {
1067   return 2 + AndLatency() + DsubuLatency() + 1 + AndLatency() + 1 +
1068          AndLatency() + DadduLatency() + 1 + DadduLatency() + 1 + AndLatency() +
1069          1 + DmulLatency() + 1;
1070 }
1071 
CompareFLatency()1072 int CompareFLatency() { return Latency::C_cond_S; }
1073 
CompareF32Latency()1074 int CompareF32Latency() { return CompareFLatency(); }
1075 
CompareF64Latency()1076 int CompareF64Latency() { return CompareFLatency(); }
1077 
CompareIsNanFLatency()1078 int CompareIsNanFLatency() { return CompareFLatency(); }
1079 
CompareIsNanF32Latency()1080 int CompareIsNanF32Latency() { return CompareIsNanFLatency(); }
1081 
CompareIsNanF64Latency()1082 int CompareIsNanF64Latency() { return CompareIsNanFLatency(); }
1083 
NegsLatency()1084 int NegsLatency() {
1085   if (kArchVariant >= kMips64r6) {
1086     return Latency::NEG_S;
1087   } else {
1088     // Estimated.
1089     return CompareIsNanF32Latency() + 2 * Latency::BRANCH + Latency::NEG_S +
1090            Latency::MFC1 + 1 + XorLatency() + Latency::MTC1;
1091   }
1092 }
1093 
NegdLatency()1094 int NegdLatency() {
1095   if (kArchVariant >= kMips64r6) {
1096     return Latency::NEG_D;
1097   } else {
1098     // Estimated.
1099     return CompareIsNanF64Latency() + 2 * Latency::BRANCH + Latency::NEG_D +
1100            Latency::DMFC1 + 1 + XorLatency() + Latency::DMTC1;
1101   }
1102 }
1103 
Float64RoundLatency()1104 int Float64RoundLatency() {
1105   if (kArchVariant >= kMips64r6) {
1106     return Latency::RINT_D + 4;
1107   } else {
1108     // For ceil_l_d, floor_l_d, round_l_d, trunc_l_d latency is 4.
1109     return Latency::DMFC1 + 1 + Latency::BRANCH + Latency::MOV_D + 4 +
1110            Latency::DMFC1 + Latency::BRANCH + Latency::CVT_D_L + 2 +
1111            Latency::MTHC1;
1112   }
1113 }
1114 
Float32RoundLatency()1115 int Float32RoundLatency() {
1116   if (kArchVariant >= kMips64r6) {
1117     return Latency::RINT_S + 4;
1118   } else {
1119     // For ceil_w_s, floor_w_s, round_w_s, trunc_w_s latency is 4.
1120     return Latency::MFC1 + 1 + Latency::BRANCH + Latency::MOV_S + 4 +
1121            Latency::MFC1 + Latency::BRANCH + Latency::CVT_S_W + 2 +
1122            Latency::MTC1;
1123   }
1124 }
1125 
Float32MaxLatency()1126 int Float32MaxLatency() {
1127   // Estimated max.
1128   int latency = CompareIsNanF32Latency() + Latency::BRANCH;
1129   if (kArchVariant >= kMips64r6) {
1130     return latency + Latency::MAX_S;
1131   } else {
1132     return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1133            Latency::MFC1 + 1 + Latency::MOV_S;
1134   }
1135 }
1136 
Float64MaxLatency()1137 int Float64MaxLatency() {
1138   // Estimated max.
1139   int latency = CompareIsNanF64Latency() + Latency::BRANCH;
1140   if (kArchVariant >= kMips64r6) {
1141     return latency + Latency::MAX_D;
1142   } else {
1143     return latency + 5 * Latency::BRANCH + 2 * CompareF64Latency() +
1144            Latency::DMFC1 + Latency::MOV_D;
1145   }
1146 }
1147 
Float32MinLatency()1148 int Float32MinLatency() {
1149   // Estimated max.
1150   int latency = CompareIsNanF32Latency() + Latency::BRANCH;
1151   if (kArchVariant >= kMips64r6) {
1152     return latency + Latency::MIN_S;
1153   } else {
1154     return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1155            Latency::MFC1 + 1 + Latency::MOV_S;
1156   }
1157 }
1158 
Float64MinLatency()1159 int Float64MinLatency() {
1160   // Estimated max.
1161   int latency = CompareIsNanF64Latency() + Latency::BRANCH;
1162   if (kArchVariant >= kMips64r6) {
1163     return latency + Latency::MIN_D;
1164   } else {
1165     return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1166            Latency::DMFC1 + Latency::MOV_D;
1167   }
1168 }
1169 
TruncLSLatency(bool load_status)1170 int TruncLSLatency(bool load_status) {
1171   int latency = Latency::TRUNC_L_S + Latency::DMFC1;
1172   if (load_status) {
1173     latency += SltuLatency() + 7;
1174   }
1175   return latency;
1176 }
1177 
TruncLDLatency(bool load_status)1178 int TruncLDLatency(bool load_status) {
1179   int latency = Latency::TRUNC_L_D + Latency::DMFC1;
1180   if (load_status) {
1181     latency += SltuLatency() + 7;
1182   }
1183   return latency;
1184 }
1185 
TruncUlSLatency()1186 int TruncUlSLatency() {
1187   // Estimated max.
1188   return 2 * CompareF32Latency() + CompareIsNanF32Latency() +
1189          4 * Latency::BRANCH + Latency::SUB_S + 2 * Latency::TRUNC_L_S +
1190          3 * Latency::DMFC1 + OrLatency() + Latency::MTC1 + Latency::MOV_S +
1191          SltuLatency() + 4;
1192 }
1193 
TruncUlDLatency()1194 int TruncUlDLatency() {
1195   // Estimated max.
1196   return 2 * CompareF64Latency() + CompareIsNanF64Latency() +
1197          4 * Latency::BRANCH + Latency::SUB_D + 2 * Latency::TRUNC_L_D +
1198          3 * Latency::DMFC1 + OrLatency() + Latency::DMTC1 + Latency::MOV_D +
1199          SltuLatency() + 4;
1200 }
1201 
PushLatency()1202 int PushLatency() { return DadduLatency() + AlignedMemoryLatency(); }
1203 
ByteSwapSignedLatency()1204 int ByteSwapSignedLatency() { return 2; }
1205 
LlLatency(int offset)1206 int LlLatency(int offset) {
1207   bool is_one_instruction =
1208       (kArchVariant == kMips64r6) ? is_int9(offset) : is_int16(offset);
1209   if (is_one_instruction) {
1210     return 1;
1211   } else {
1212     return 3;
1213   }
1214 }
1215 
ExtractBitsLatency(bool sign_extend,int size)1216 int ExtractBitsLatency(bool sign_extend, int size) {
1217   int latency = 2;
1218   if (sign_extend) {
1219     switch (size) {
1220       case 8:
1221       case 16:
1222       case 32:
1223         latency += 1;
1224         break;
1225       default:
1226         UNREACHABLE();
1227     }
1228   }
1229   return latency;
1230 }
1231 
InsertBitsLatency()1232 int InsertBitsLatency() { return 2 + DsubuLatency(false) + 2; }
1233 
ScLatency(int offset)1234 int ScLatency(int offset) {
1235   bool is_one_instruction =
1236       (kArchVariant == kMips64r6) ? is_int9(offset) : is_int16(offset);
1237   if (is_one_instruction) {
1238     return 1;
1239   } else {
1240     return 3;
1241   }
1242 }
1243 
Word32AtomicExchangeLatency(bool sign_extend,int size)1244 int Word32AtomicExchangeLatency(bool sign_extend, int size) {
1245   return DadduLatency(false) + 1 + DsubuLatency() + 2 + LlLatency(0) +
1246          ExtractBitsLatency(sign_extend, size) + InsertBitsLatency() +
1247          ScLatency(0) + BranchShortLatency() + 1;
1248 }
1249 
Word32AtomicCompareExchangeLatency(bool sign_extend,int size)1250 int Word32AtomicCompareExchangeLatency(bool sign_extend, int size) {
1251   return 2 + DsubuLatency() + 2 + LlLatency(0) +
1252          ExtractBitsLatency(sign_extend, size) + InsertBitsLatency() +
1253          ScLatency(0) + BranchShortLatency() + 1;
1254 }
1255 
GetInstructionLatency(const Instruction * instr)1256 int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
1257   // Basic latency modeling for MIPS64 instructions. They have been determined
1258   // in empirical way.
1259   switch (instr->arch_opcode()) {
1260     case kArchCallCodeObject:
1261     case kArchCallWasmFunction:
1262       return CallLatency();
1263     case kArchTailCallCodeObjectFromJSFunction:
1264     case kArchTailCallCodeObject: {
1265       int latency = 0;
1266       if (instr->arch_opcode() == kArchTailCallCodeObjectFromJSFunction) {
1267         latency = AssemblePopArgumentsAdoptFrameLatency();
1268       }
1269       return latency + JumpLatency();
1270     }
1271     case kArchTailCallWasm:
1272     case kArchTailCallAddress:
1273       return JumpLatency();
1274     case kArchCallJSFunction: {
1275       int latency = 0;
1276       if (FLAG_debug_code) {
1277         latency = 1 + AssertLatency();
1278       }
1279       return latency + 1 + DadduLatency(false) + CallLatency();
1280     }
1281     case kArchPrepareCallCFunction:
1282       return PrepareCallCFunctionLatency();
1283     case kArchSaveCallerRegisters: {
1284       auto fp_mode =
1285           static_cast<SaveFPRegsMode>(MiscField::decode(instr->opcode()));
1286       return PushCallerSavedLatency(fp_mode);
1287     }
1288     case kArchRestoreCallerRegisters: {
1289       auto fp_mode =
1290           static_cast<SaveFPRegsMode>(MiscField::decode(instr->opcode()));
1291       return PopCallerSavedLatency(fp_mode);
1292     }
1293     case kArchPrepareTailCall:
1294       return 2;
1295     case kArchCallCFunction:
1296       return CallCFunctionLatency();
1297     case kArchJmp:
1298       return AssembleArchJumpLatency();
1299     case kArchTableSwitch:
1300       return AssembleArchTableSwitchLatency();
1301     case kArchAbortCSAAssert:
1302       return CallLatency() + 1;
1303     case kArchDebugBreak:
1304       return 1;
1305     case kArchComment:
1306     case kArchNop:
1307     case kArchThrowTerminator:
1308     case kArchDeoptimize:
1309       return 0;
1310     case kArchRet:
1311       return AssemblerReturnLatency();
1312     case kArchFramePointer:
1313       return 1;
1314     case kArchParentFramePointer:
1315       // Estimated max.
1316       return AlignedMemoryLatency();
1317     case kArchTruncateDoubleToI:
1318       return TruncateDoubleToIDelayedLatency();
1319     case kArchStoreWithWriteBarrier:
1320       return DadduLatency() + 1 + CheckPageFlagLatency();
1321     case kArchStackSlot:
1322       // Estimated max.
1323       return DadduLatency(false) + AndLatency(false) + AssertLatency() +
1324              DadduLatency(false) + AndLatency(false) + BranchShortLatency() +
1325              1 + DsubuLatency() + DadduLatency();
1326     case kArchWordPoisonOnSpeculation:
1327       return AndLatency();
1328     case kIeee754Float64Acos:
1329     case kIeee754Float64Acosh:
1330     case kIeee754Float64Asin:
1331     case kIeee754Float64Asinh:
1332     case kIeee754Float64Atan:
1333     case kIeee754Float64Atanh:
1334     case kIeee754Float64Atan2:
1335     case kIeee754Float64Cos:
1336     case kIeee754Float64Cosh:
1337     case kIeee754Float64Cbrt:
1338     case kIeee754Float64Exp:
1339     case kIeee754Float64Expm1:
1340     case kIeee754Float64Log:
1341     case kIeee754Float64Log1p:
1342     case kIeee754Float64Log10:
1343     case kIeee754Float64Log2:
1344     case kIeee754Float64Pow:
1345     case kIeee754Float64Sin:
1346     case kIeee754Float64Sinh:
1347     case kIeee754Float64Tan:
1348     case kIeee754Float64Tanh:
1349       return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1350              CallCFunctionLatency() + MovFromFloatResultLatency();
1351     case kMips64Add:
1352     case kMips64Dadd:
1353       return DadduLatency(instr->InputAt(1)->IsRegister());
1354     case kMips64DaddOvf:
1355       return DaddOverflowLatency();
1356     case kMips64Sub:
1357     case kMips64Dsub:
1358       return DsubuLatency(instr->InputAt(1)->IsRegister());
1359     case kMips64DsubOvf:
1360       return DsubOverflowLatency();
1361     case kMips64Mul:
1362       return MulLatency();
1363     case kMips64MulOvf:
1364       return MulOverflowLatency();
1365     case kMips64MulHigh:
1366       return MulhLatency();
1367     case kMips64MulHighU:
1368       return MulhuLatency();
1369     case kMips64DMulHigh:
1370       return DMulhLatency();
1371     case kMips64Div: {
1372       int latency = DivLatency(instr->InputAt(1)->IsRegister());
1373       if (kArchVariant >= kMips64r6) {
1374         return latency++;
1375       } else {
1376         return latency + MovzLatency();
1377       }
1378     }
1379     case kMips64DivU: {
1380       int latency = DivuLatency(instr->InputAt(1)->IsRegister());
1381       if (kArchVariant >= kMips64r6) {
1382         return latency++;
1383       } else {
1384         return latency + MovzLatency();
1385       }
1386     }
1387     case kMips64Mod:
1388       return ModLatency();
1389     case kMips64ModU:
1390       return ModuLatency();
1391     case kMips64Dmul:
1392       return DmulLatency();
1393     case kMips64Ddiv: {
1394       int latency = DdivLatency();
1395       if (kArchVariant >= kMips64r6) {
1396         return latency++;
1397       } else {
1398         return latency + MovzLatency();
1399       }
1400     }
1401     case kMips64DdivU: {
1402       int latency = DdivuLatency();
1403       if (kArchVariant >= kMips64r6) {
1404         return latency++;
1405       } else {
1406         return latency + MovzLatency();
1407       }
1408     }
1409     case kMips64Dmod:
1410       return DmodLatency();
1411     case kMips64DmodU:
1412       return DmoduLatency();
1413     case kMips64Dlsa:
1414     case kMips64Lsa:
1415       return DlsaLatency();
1416     case kMips64And:
1417       return AndLatency(instr->InputAt(1)->IsRegister());
1418     case kMips64And32: {
1419       bool is_operand_register = instr->InputAt(1)->IsRegister();
1420       int latency = AndLatency(is_operand_register);
1421       if (is_operand_register) {
1422         return latency + 2;
1423       } else {
1424         return latency + 1;
1425       }
1426     }
1427     case kMips64Or:
1428       return OrLatency(instr->InputAt(1)->IsRegister());
1429     case kMips64Or32: {
1430       bool is_operand_register = instr->InputAt(1)->IsRegister();
1431       int latency = OrLatency(is_operand_register);
1432       if (is_operand_register) {
1433         return latency + 2;
1434       } else {
1435         return latency + 1;
1436       }
1437     }
1438     case kMips64Nor:
1439       return NorLatency(instr->InputAt(1)->IsRegister());
1440     case kMips64Nor32: {
1441       bool is_operand_register = instr->InputAt(1)->IsRegister();
1442       int latency = NorLatency(is_operand_register);
1443       if (is_operand_register) {
1444         return latency + 2;
1445       } else {
1446         return latency + 1;
1447       }
1448     }
1449     case kMips64Xor:
1450       return XorLatency(instr->InputAt(1)->IsRegister());
1451     case kMips64Xor32: {
1452       bool is_operand_register = instr->InputAt(1)->IsRegister();
1453       int latency = XorLatency(is_operand_register);
1454       if (is_operand_register) {
1455         return latency + 2;
1456       } else {
1457         return latency + 1;
1458       }
1459     }
1460     case kMips64Clz:
1461     case kMips64Dclz:
1462       return DclzLatency();
1463     case kMips64Ctz:
1464       return CtzLatency();
1465     case kMips64Dctz:
1466       return DctzLatency();
1467     case kMips64Popcnt:
1468       return PopcntLatency();
1469     case kMips64Dpopcnt:
1470       return DpopcntLatency();
1471     case kMips64Shl:
1472       return 1;
1473     case kMips64Shr:
1474     case kMips64Sar:
1475       return 2;
1476     case kMips64Ext:
1477     case kMips64Ins:
1478     case kMips64Dext:
1479     case kMips64Dins:
1480     case kMips64Dshl:
1481     case kMips64Dshr:
1482     case kMips64Dsar:
1483     case kMips64Ror:
1484     case kMips64Dror:
1485       return 1;
1486     case kMips64Tst:
1487       return AndLatency(instr->InputAt(1)->IsRegister());
1488     case kMips64Mov:
1489       return 1;
1490     case kMips64CmpS:
1491       return MoveLatency() + CompareF32Latency();
1492     case kMips64AddS:
1493       return Latency::ADD_S;
1494     case kMips64SubS:
1495       return Latency::SUB_S;
1496     case kMips64MulS:
1497       return Latency::MUL_S;
1498     case kMips64DivS:
1499       return Latency::DIV_S;
1500     case kMips64ModS:
1501       return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1502              CallCFunctionLatency() + MovFromFloatResultLatency();
1503     case kMips64AbsS:
1504       return Latency::ABS_S;
1505     case kMips64NegS:
1506       return NegdLatency();
1507     case kMips64SqrtS:
1508       return Latency::SQRT_S;
1509     case kMips64MaxS:
1510       return Latency::MAX_S;
1511     case kMips64MinS:
1512       return Latency::MIN_S;
1513     case kMips64CmpD:
1514       return MoveLatency() + CompareF64Latency();
1515     case kMips64AddD:
1516       return Latency::ADD_D;
1517     case kMips64SubD:
1518       return Latency::SUB_D;
1519     case kMips64MulD:
1520       return Latency::MUL_D;
1521     case kMips64DivD:
1522       return Latency::DIV_D;
1523     case kMips64ModD:
1524       return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1525              CallCFunctionLatency() + MovFromFloatResultLatency();
1526     case kMips64AbsD:
1527       return Latency::ABS_D;
1528     case kMips64NegD:
1529       return NegdLatency();
1530     case kMips64SqrtD:
1531       return Latency::SQRT_D;
1532     case kMips64MaxD:
1533       return Latency::MAX_D;
1534     case kMips64MinD:
1535       return Latency::MIN_D;
1536     case kMips64Float64RoundDown:
1537     case kMips64Float64RoundTruncate:
1538     case kMips64Float64RoundUp:
1539     case kMips64Float64RoundTiesEven:
1540       return Float64RoundLatency();
1541     case kMips64Float32RoundDown:
1542     case kMips64Float32RoundTruncate:
1543     case kMips64Float32RoundUp:
1544     case kMips64Float32RoundTiesEven:
1545       return Float32RoundLatency();
1546     case kMips64Float32Max:
1547       return Float32MaxLatency();
1548     case kMips64Float64Max:
1549       return Float64MaxLatency();
1550     case kMips64Float32Min:
1551       return Float32MinLatency();
1552     case kMips64Float64Min:
1553       return Float64MinLatency();
1554     case kMips64Float64SilenceNaN:
1555       return Latency::SUB_D;
1556     case kMips64CvtSD:
1557       return Latency::CVT_S_D;
1558     case kMips64CvtDS:
1559       return Latency::CVT_D_S;
1560     case kMips64CvtDW:
1561       return Latency::MTC1 + Latency::CVT_D_W;
1562     case kMips64CvtSW:
1563       return Latency::MTC1 + Latency::CVT_S_W;
1564     case kMips64CvtSUw:
1565       return 1 + Latency::DMTC1 + Latency::CVT_S_L;
1566     case kMips64CvtSL:
1567       return Latency::DMTC1 + Latency::CVT_S_L;
1568     case kMips64CvtDL:
1569       return Latency::DMTC1 + Latency::CVT_D_L;
1570     case kMips64CvtDUw:
1571       return 1 + Latency::DMTC1 + Latency::CVT_D_L;
1572     case kMips64CvtDUl:
1573       return 2 * Latency::BRANCH + 3 + 2 * Latency::DMTC1 +
1574              2 * Latency::CVT_D_L + Latency::ADD_D;
1575     case kMips64CvtSUl:
1576       return 2 * Latency::BRANCH + 3 + 2 * Latency::DMTC1 +
1577              2 * Latency::CVT_S_L + Latency::ADD_S;
1578     case kMips64FloorWD:
1579       return Latency::FLOOR_W_D + Latency::MFC1;
1580     case kMips64CeilWD:
1581       return Latency::CEIL_W_D + Latency::MFC1;
1582     case kMips64RoundWD:
1583       return Latency::ROUND_W_D + Latency::MFC1;
1584     case kMips64TruncWD:
1585       return Latency::TRUNC_W_D + Latency::MFC1;
1586     case kMips64FloorWS:
1587       return Latency::FLOOR_W_S + Latency::MFC1;
1588     case kMips64CeilWS:
1589       return Latency::CEIL_W_S + Latency::MFC1;
1590     case kMips64RoundWS:
1591       return Latency::ROUND_W_S + Latency::MFC1;
1592     case kMips64TruncWS:
1593       return Latency::TRUNC_W_S + Latency::MFC1 + 2 + MovnLatency();
1594     case kMips64TruncLS:
1595       return TruncLSLatency(instr->OutputCount() > 1);
1596     case kMips64TruncLD:
1597       return TruncLDLatency(instr->OutputCount() > 1);
1598     case kMips64TruncUwD:
1599       // Estimated max.
1600       return CompareF64Latency() + 2 * Latency::BRANCH +
1601              2 * Latency::TRUNC_W_D + Latency::SUB_D + OrLatency() +
1602              Latency::MTC1 + Latency::MFC1 + Latency::MTHC1 + 1;
1603     case kMips64TruncUwS:
1604       // Estimated max.
1605       return CompareF32Latency() + 2 * Latency::BRANCH +
1606              2 * Latency::TRUNC_W_S + Latency::SUB_S + OrLatency() +
1607              Latency::MTC1 + 2 * Latency::MFC1 + 2 + MovzLatency();
1608     case kMips64TruncUlS:
1609       return TruncUlSLatency();
1610     case kMips64TruncUlD:
1611       return TruncUlDLatency();
1612     case kMips64BitcastDL:
1613       return Latency::DMFC1;
1614     case kMips64BitcastLD:
1615       return Latency::DMTC1;
1616     case kMips64Float64ExtractLowWord32:
1617       return Latency::MFC1;
1618     case kMips64Float64InsertLowWord32:
1619       return Latency::MFHC1 + Latency::MTC1 + Latency::MTHC1;
1620     case kMips64Float64ExtractHighWord32:
1621       return Latency::MFHC1;
1622     case kMips64Float64InsertHighWord32:
1623       return Latency::MTHC1;
1624     case kMips64Seb:
1625     case kMips64Seh:
1626       return 1;
1627     case kMips64Lbu:
1628     case kMips64Lb:
1629     case kMips64Lhu:
1630     case kMips64Lh:
1631     case kMips64Lwu:
1632     case kMips64Lw:
1633     case kMips64Ld:
1634     case kMips64Sb:
1635     case kMips64Sh:
1636     case kMips64Sw:
1637     case kMips64Sd:
1638       return AlignedMemoryLatency();
1639     case kMips64Lwc1:
1640       return Lwc1Latency();
1641     case kMips64Ldc1:
1642       return Ldc1Latency();
1643     case kMips64Swc1:
1644       return Swc1Latency();
1645     case kMips64Sdc1:
1646       return Sdc1Latency();
1647     case kMips64Ulhu:
1648     case kMips64Ulh:
1649       return UlhuLatency();
1650     case kMips64Ulwu:
1651       return UlwuLatency();
1652     case kMips64Ulw:
1653       return UlwLatency();
1654     case kMips64Uld:
1655       return UldLatency();
1656     case kMips64Ulwc1:
1657       return Ulwc1Latency();
1658     case kMips64Uldc1:
1659       return Uldc1Latency();
1660     case kMips64Ush:
1661       return UshLatency();
1662     case kMips64Usw:
1663       return UswLatency();
1664     case kMips64Usd:
1665       return UsdLatency();
1666     case kMips64Uswc1:
1667       return Uswc1Latency();
1668     case kMips64Usdc1:
1669       return Usdc1Latency();
1670     case kMips64Push: {
1671       int latency = 0;
1672       if (instr->InputAt(0)->IsFPRegister()) {
1673         latency = Sdc1Latency() + DsubuLatency(false);
1674       } else {
1675         latency = PushLatency();
1676       }
1677       return latency;
1678     }
1679     case kMips64Peek: {
1680       int latency = 0;
1681       if (instr->OutputAt(0)->IsFPRegister()) {
1682         auto op = LocationOperand::cast(instr->OutputAt(0));
1683         switch (op->representation()) {
1684           case MachineRepresentation::kFloat64:
1685             latency = Ldc1Latency();
1686             break;
1687           case MachineRepresentation::kFloat32:
1688             latency = Latency::LWC1;
1689             break;
1690           default:
1691             UNREACHABLE();
1692         }
1693       } else {
1694         latency = AlignedMemoryLatency();
1695       }
1696       return latency;
1697     }
1698     case kMips64StackClaim:
1699       return DsubuLatency(false);
1700     case kMips64StoreToStackSlot: {
1701       int latency = 0;
1702       if (instr->InputAt(0)->IsFPRegister()) {
1703         if (instr->InputAt(0)->IsSimd128Register()) {
1704           latency = 1;  // Estimated value.
1705         } else {
1706           latency = Sdc1Latency();
1707         }
1708       } else {
1709         latency = AlignedMemoryLatency();
1710       }
1711       return latency;
1712     }
1713     case kMips64ByteSwap64:
1714       return ByteSwapSignedLatency();
1715     case kMips64ByteSwap32:
1716       return ByteSwapSignedLatency();
1717     case kWord32AtomicLoadInt8:
1718     case kWord32AtomicLoadUint8:
1719     case kWord32AtomicLoadInt16:
1720     case kWord32AtomicLoadUint16:
1721     case kWord32AtomicLoadWord32:
1722       return 2;
1723     case kWord32AtomicStoreWord8:
1724     case kWord32AtomicStoreWord16:
1725     case kWord32AtomicStoreWord32:
1726       return 3;
1727     case kWord32AtomicExchangeInt8:
1728       return Word32AtomicExchangeLatency(true, 8);
1729     case kWord32AtomicExchangeUint8:
1730       return Word32AtomicExchangeLatency(false, 8);
1731     case kWord32AtomicExchangeInt16:
1732       return Word32AtomicExchangeLatency(true, 16);
1733     case kWord32AtomicExchangeUint16:
1734       return Word32AtomicExchangeLatency(false, 16);
1735     case kWord32AtomicExchangeWord32:
1736       return 2 + LlLatency(0) + 1 + ScLatency(0) + BranchShortLatency() + 1;
1737     case kWord32AtomicCompareExchangeInt8:
1738       return Word32AtomicCompareExchangeLatency(true, 8);
1739     case kWord32AtomicCompareExchangeUint8:
1740       return Word32AtomicCompareExchangeLatency(false, 8);
1741     case kWord32AtomicCompareExchangeInt16:
1742       return Word32AtomicCompareExchangeLatency(true, 16);
1743     case kWord32AtomicCompareExchangeUint16:
1744       return Word32AtomicCompareExchangeLatency(false, 16);
1745     case kWord32AtomicCompareExchangeWord32:
1746       return 3 + LlLatency(0) + BranchShortLatency() + 1 + ScLatency(0) +
1747              BranchShortLatency() + 1;
1748     case kMips64AssertEqual:
1749       return AssertLatency();
1750     default:
1751       return 1;
1752   }
1753 }
1754 
1755 }  // namespace compiler
1756 }  // namespace internal
1757 }  // namespace v8
1758