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