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