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