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
8namespace v8 {
9namespace internal {
10namespace compiler {
11
12bool InstructionScheduler::SchedulerSupported() { return true; }
13
14int 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
421enum 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
550int DadduLatency(bool is_operand_register = true) {
551  if (is_operand_register) {
552    return 1;
553  } else {
554    return 2;  // Estimated max.
555  }
556}
557
558int DsubuLatency(bool is_operand_register = true) {
559  return DadduLatency(is_operand_register);
560}
561
562int AndLatency(bool is_operand_register = true) {
563  return DadduLatency(is_operand_register);
564}
565
566int OrLatency(bool is_operand_register = true) {
567  return DadduLatency(is_operand_register);
568}
569
570int NorLatency(bool is_operand_register = true) {
571  if (is_operand_register) {
572    return 1;
573  } else {
574    return 2;  // Estimated max.
575  }
576}
577
578int XorLatency(bool is_operand_register = true) {
579  return DadduLatency(is_operand_register);
580}
581
582int 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
590int 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
603int 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
616int 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
629int 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
642int 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
650int 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
658int 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
671int 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
684int 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
697int 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
710int 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
723int 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
736int MovzLatency() {
737  if (kArchVariant >= kMips64r6) {
738    return Latency::BRANCH + 1;
739  } else {
740    return 1;
741  }
742}
743
744int MovnLatency() {
745  if (kArchVariant >= kMips64r6) {
746    return Latency::BRANCH + 1;
747  } else {
748    return 1;
749  }
750}
751
752int DlsaLatency() {
753  // Estimated max.
754  return DadduLatency() + 1;
755}
756
757int CallLatency() {
758  // Estimated.
759  return DadduLatency(false) + Latency::BRANCH + 5;
760}
761
762int JumpLatency() {
763  // Estimated max.
764  return 1 + DadduLatency() + Latency::BRANCH + 2;
765}
766
767int SmiUntagLatency() { return 1; }
768
769int 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
775int AssertLatency() { return 1; }
776
777int 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
786int AdjustBaseAndOffsetLatency() {
787  return 3;  // Estimated max.
788}
789
790int AlignedMemoryLatency() { return AdjustBaseAndOffsetLatency() + 1; }
791
792int UlhuLatency() {
793  if (kArchVariant >= kMips64r6) {
794    return AlignedMemoryLatency();
795  } else {
796    return AdjustBaseAndOffsetLatency() + 2 * AlignedMemoryLatency() + 2;
797  }
798}
799
800int UlwLatency() {
801  if (kArchVariant >= kMips64r6) {
802    return AlignedMemoryLatency();
803  } else {
804    // Estimated max.
805    return AdjustBaseAndOffsetLatency() + 3;
806  }
807}
808
809int UlwuLatency() {
810  if (kArchVariant >= kMips64r6) {
811    return AlignedMemoryLatency();
812  } else {
813    return UlwLatency() + 1;
814  }
815}
816
817int UldLatency() {
818  if (kArchVariant >= kMips64r6) {
819    return AlignedMemoryLatency();
820  } else {
821    // Estimated max.
822    return AdjustBaseAndOffsetLatency() + 3;
823  }
824}
825
826int Ulwc1Latency() {
827  if (kArchVariant >= kMips64r6) {
828    return AlignedMemoryLatency();
829  } else {
830    return UlwLatency() + Latency::MTC1;
831  }
832}
833
834int Uldc1Latency() {
835  if (kArchVariant >= kMips64r6) {
836    return AlignedMemoryLatency();
837  } else {
838    return UldLatency() + Latency::DMTC1;
839  }
840}
841
842int UshLatency() {
843  if (kArchVariant >= kMips64r6) {
844    return AlignedMemoryLatency();
845  } else {
846    // Estimated max.
847    return AdjustBaseAndOffsetLatency() + 2 + 2 * AlignedMemoryLatency();
848  }
849}
850
851int UswLatency() {
852  if (kArchVariant >= kMips64r6) {
853    return AlignedMemoryLatency();
854  } else {
855    return AdjustBaseAndOffsetLatency() + 2;
856  }
857}
858
859int UsdLatency() {
860  if (kArchVariant >= kMips64r6) {
861    return AlignedMemoryLatency();
862  } else {
863    return AdjustBaseAndOffsetLatency() + 2;
864  }
865}
866
867int Uswc1Latency() {
868  if (kArchVariant >= kMips64r6) {
869    return AlignedMemoryLatency();
870  } else {
871    return Latency::MFC1 + UswLatency();
872  }
873}
874
875int Usdc1Latency() {
876  if (kArchVariant >= kMips64r6) {
877    return AlignedMemoryLatency();
878  } else {
879    return Latency::DMFC1 + UsdLatency();
880  }
881}
882
883int Lwc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::LWC1; }
884
885int Swc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::SWC1; }
886
887int Sdc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::SDC1; }
888
889int Ldc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::LDC1; }
890
891int MultiPushLatency() {
892  int latency = DsubuLatency(false);
893  for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
894    latency++;
895  }
896  return latency;
897}
898
899int 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
907int PushCallerSavedLatency(SaveFPRegsMode fp_mode) {
908  int latency = MultiPushLatency();
909  if (fp_mode == SaveFPRegsMode::kSave) {
910    latency += MultiPushFPULatency();
911  }
912  return latency;
913}
914
915int MultiPopLatency() {
916  int latency = DadduLatency(false);
917  for (int16_t i = 0; i < kNumRegisters; i++) {
918    latency++;
919  }
920  return latency;
921}
922
923int MultiPopFPULatency() {
924  int latency = DadduLatency(false);
925  for (int16_t i = 0; i < kNumRegisters; i++) {
926    latency += Ldc1Latency();
927  }
928  return latency;
929}
930
931int PopCallerSavedLatency(SaveFPRegsMode fp_mode) {
932  int latency = MultiPopLatency();
933  if (fp_mode == SaveFPRegsMode::kSave) {
934    latency += MultiPopFPULatency();
935  }
936  return latency;
937}
938
939int 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
950int CallCFunctionLatency() { return 1 + CallCFunctionHelperLatency(); }
951
952int AssembleArchJumpLatency() {
953  // Estimated max.
954  return Latency::BRANCH;
955}
956
957int 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
968int AssembleArchTableSwitchLatency() {
969  return Latency::BRANCH + GenerateSwitchTableLatency();
970}
971
972int DropAndRetLatency() {
973  // Estimated max.
974  return DadduLatency(false) + JumpLatency();
975}
976
977int AssemblerReturnLatency() {
978  // Estimated max.
979  return DadduLatency(false) + MultiPopLatency() + MultiPopFPULatency() +
980         Latency::BRANCH + DadduLatency() + 1 + DropAndRetLatency();
981}
982
983int TryInlineTruncateDoubleToILatency() {
984  return 2 + Latency::TRUNC_W_D + Latency::MFC1 + 2 + AndLatency(false) +
985         Latency::BRANCH;
986}
987
988int CallStubDelayedLatency() { return 1 + CallLatency(); }
989
990int 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
996int CheckPageFlagLatency() {
997  return AndLatency(false) + AlignedMemoryLatency() + AndLatency(false) +
998         Latency::BRANCH;
999}
1000
1001int SltuLatency(bool is_operand_register = true) {
1002  if (is_operand_register) {
1003    return 1;
1004  } else {
1005    return 2;  // Estimated max.
1006  }
1007}
1008
1009int BranchShortHelperR6Latency() {
1010  return 2;  // Estimated max.
1011}
1012
1013int BranchShortHelperLatency() {
1014  return SltuLatency() + 2;  // Estimated max.
1015}
1016
1017int BranchShortLatency(BranchDelaySlot bdslot = PROTECT) {
1018  if (kArchVariant >= kMips64r6 && bdslot == PROTECT) {
1019    return BranchShortHelperR6Latency();
1020  } else {
1021    return BranchShortHelperLatency();
1022  }
1023}
1024
1025int MoveLatency() { return 1; }
1026
1027int MovToFloatParametersLatency() { return 2 * MoveLatency(); }
1028
1029int MovFromFloatResultLatency() { return MoveLatency(); }
1030
1031int DaddOverflowLatency() {
1032  // Estimated max.
1033  return 6;
1034}
1035
1036int DsubOverflowLatency() {
1037  // Estimated max.
1038  return 6;
1039}
1040
1041int MulOverflowLatency() {
1042  // Estimated max.
1043  return MulLatency() + MulhLatency() + 2;
1044}
1045
1046int DclzLatency() { return 1; }
1047
1048int CtzLatency() {
1049  if (kArchVariant >= kMips64r6) {
1050    return 3 + DclzLatency();
1051  } else {
1052    return DadduLatency(false) + XorLatency() + AndLatency() + DclzLatency() +
1053           1 + DsubuLatency();
1054  }
1055}
1056
1057int DctzLatency() {
1058  if (kArchVariant >= kMips64r6) {
1059    return 4;
1060  } else {
1061    return DadduLatency(false) + XorLatency() + AndLatency() + 1 +
1062           DsubuLatency();
1063  }
1064}
1065
1066int PopcntLatency() {
1067  return 2 + AndLatency() + DsubuLatency() + 1 + AndLatency() + 1 +
1068         AndLatency() + DadduLatency() + 1 + DadduLatency() + 1 + AndLatency() +
1069         1 + MulLatency() + 1;
1070}
1071
1072int DpopcntLatency() {
1073  return 2 + AndLatency() + DsubuLatency() + 1 + AndLatency() + 1 +
1074         AndLatency() + DadduLatency() + 1 + DadduLatency() + 1 + AndLatency() +
1075         1 + DmulLatency() + 1;
1076}
1077
1078int CompareFLatency() { return Latency::C_cond_S; }
1079
1080int CompareF32Latency() { return CompareFLatency(); }
1081
1082int CompareF64Latency() { return CompareFLatency(); }
1083
1084int CompareIsNanFLatency() { return CompareFLatency(); }
1085
1086int CompareIsNanF32Latency() { return CompareIsNanFLatency(); }
1087
1088int CompareIsNanF64Latency() { return CompareIsNanFLatency(); }
1089
1090int 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
1100int 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
1110int 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
1121int 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
1132int 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
1143int 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
1154int 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
1165int 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
1176int 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
1184int 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
1192int 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
1200int 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
1208int PushLatency() { return DadduLatency() + AlignedMemoryLatency(); }
1209
1210int ByteSwapSignedLatency() { return 2; }
1211
1212int 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
1222int 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
1238int InsertBitsLatency() { return 2 + DsubuLatency(false) + 2; }
1239
1240int 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
1250int 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
1256int 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
1262int 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