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