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