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/instruction-scheduler.h"
6
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10
SchedulerSupported()11 bool InstructionScheduler::SchedulerSupported() { return true; }
12
GetTargetInstructionFlags(const Instruction * instr) const13 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 return kIsLoadOperation;
297
298 case kMips64ModD:
299 case kMips64ModS:
300 case kMips64MsaSt:
301 case kMips64Push:
302 case kMips64Sb:
303 case kMips64Sd:
304 case kMips64Sdc1:
305 case kMips64Sh:
306 case kMips64StackClaim:
307 case kMips64StoreToStackSlot:
308 case kMips64Sw:
309 case kMips64Swc1:
310 case kMips64Usd:
311 case kMips64Usdc1:
312 case kMips64Ush:
313 case kMips64Usw:
314 case kMips64Uswc1:
315 return kHasSideEffect;
316
317 #define CASE(Name) case k##Name:
318 COMMON_ARCH_OPCODE_LIST(CASE)
319 #undef CASE
320 // Already covered in architecture independent code.
321 UNREACHABLE();
322 }
323
324 UNREACHABLE();
325 }
326
327 enum Latency {
328 BRANCH = 4, // Estimated max.
329 RINT_S = 4, // Estimated.
330 RINT_D = 4, // Estimated.
331
332 MULT = 4,
333 MULTU = 4,
334 DMULT = 4,
335 DMULTU = 4,
336
337 MUL = 7,
338 DMUL = 7,
339 MUH = 7,
340 MUHU = 7,
341 DMUH = 7,
342 DMUHU = 7,
343
344 DIV = 50, // Min:11 Max:50
345 DDIV = 50,
346 DIVU = 50,
347 DDIVU = 50,
348
349 ABS_S = 4,
350 ABS_D = 4,
351 NEG_S = 4,
352 NEG_D = 4,
353 ADD_S = 4,
354 ADD_D = 4,
355 SUB_S = 4,
356 SUB_D = 4,
357 MAX_S = 4, // Estimated.
358 MIN_S = 4,
359 MAX_D = 4, // Estimated.
360 MIN_D = 4,
361 C_cond_S = 4,
362 C_cond_D = 4,
363 MUL_S = 4,
364
365 MADD_S = 4,
366 MSUB_S = 4,
367 NMADD_S = 4,
368 NMSUB_S = 4,
369
370 CABS_cond_S = 4,
371 CABS_cond_D = 4,
372
373 CVT_D_S = 4,
374 CVT_PS_PW = 4,
375
376 CVT_S_W = 4,
377 CVT_S_L = 4,
378 CVT_D_W = 4,
379 CVT_D_L = 4,
380
381 CVT_S_D = 4,
382
383 CVT_W_S = 4,
384 CVT_W_D = 4,
385 CVT_L_S = 4,
386 CVT_L_D = 4,
387
388 CEIL_W_S = 4,
389 CEIL_W_D = 4,
390 CEIL_L_S = 4,
391 CEIL_L_D = 4,
392
393 FLOOR_W_S = 4,
394 FLOOR_W_D = 4,
395 FLOOR_L_S = 4,
396 FLOOR_L_D = 4,
397
398 ROUND_W_S = 4,
399 ROUND_W_D = 4,
400 ROUND_L_S = 4,
401 ROUND_L_D = 4,
402
403 TRUNC_W_S = 4,
404 TRUNC_W_D = 4,
405 TRUNC_L_S = 4,
406 TRUNC_L_D = 4,
407
408 MOV_S = 4,
409 MOV_D = 4,
410
411 MOVF_S = 4,
412 MOVF_D = 4,
413
414 MOVN_S = 4,
415 MOVN_D = 4,
416
417 MOVT_S = 4,
418 MOVT_D = 4,
419
420 MOVZ_S = 4,
421 MOVZ_D = 4,
422
423 MUL_D = 5,
424 MADD_D = 5,
425 MSUB_D = 5,
426 NMADD_D = 5,
427 NMSUB_D = 5,
428
429 RECIP_S = 13,
430 RECIP_D = 26,
431
432 RSQRT_S = 17,
433 RSQRT_D = 36,
434
435 DIV_S = 17,
436 SQRT_S = 17,
437
438 DIV_D = 32,
439 SQRT_D = 32,
440
441 MTC1 = 4,
442 MTHC1 = 4,
443 DMTC1 = 4,
444 LWC1 = 4,
445 LDC1 = 4,
446
447 MFC1 = 1,
448 MFHC1 = 1,
449 DMFC1 = 1,
450 MFHI = 1,
451 MFLO = 1,
452 SWC1 = 1,
453 SDC1 = 1,
454 };
455
DadduLatency(bool is_operand_register=true)456 int DadduLatency(bool is_operand_register = true) {
457 if (is_operand_register) {
458 return 1;
459 } else {
460 return 2; // Estimated max.
461 }
462 }
463
DsubuLatency(bool is_operand_register=true)464 int DsubuLatency(bool is_operand_register = true) {
465 return DadduLatency(is_operand_register);
466 }
467
AndLatency(bool is_operand_register=true)468 int AndLatency(bool is_operand_register = true) {
469 return DadduLatency(is_operand_register);
470 }
471
OrLatency(bool is_operand_register=true)472 int OrLatency(bool is_operand_register = true) {
473 return DadduLatency(is_operand_register);
474 }
475
NorLatency(bool is_operand_register=true)476 int NorLatency(bool is_operand_register = true) {
477 if (is_operand_register) {
478 return 1;
479 } else {
480 return 2; // Estimated max.
481 }
482 }
483
XorLatency(bool is_operand_register=true)484 int XorLatency(bool is_operand_register = true) {
485 return DadduLatency(is_operand_register);
486 }
487
MulLatency(bool is_operand_register=true)488 int MulLatency(bool is_operand_register = true) {
489 if (is_operand_register) {
490 return Latency::MUL;
491 } else {
492 return Latency::MUL + 1;
493 }
494 }
495
DmulLatency(bool is_operand_register=true)496 int DmulLatency(bool is_operand_register = true) {
497 int latency = 0;
498 if (kArchVariant >= kMips64r6) {
499 latency = Latency::DMUL;
500 } else {
501 latency = Latency::DMULT + Latency::MFLO;
502 }
503 if (!is_operand_register) {
504 latency += 1;
505 }
506 return latency;
507 }
508
MulhLatency(bool is_operand_register=true)509 int MulhLatency(bool is_operand_register = true) {
510 int latency = 0;
511 if (kArchVariant >= kMips64r6) {
512 latency = Latency::MUH;
513 } else {
514 latency = Latency::MULT + Latency::MFHI;
515 }
516 if (!is_operand_register) {
517 latency += 1;
518 }
519 return latency;
520 }
521
MulhuLatency(bool is_operand_register=true)522 int MulhuLatency(bool is_operand_register = true) {
523 int latency = 0;
524 if (kArchVariant >= kMips64r6) {
525 latency = Latency::MUH;
526 } else {
527 latency = Latency::MULTU + Latency::MFHI;
528 }
529 if (!is_operand_register) {
530 latency += 1;
531 }
532 return latency;
533 }
534
DMulhLatency(bool is_operand_register=true)535 int DMulhLatency(bool is_operand_register = true) {
536 int latency = 0;
537 if (kArchVariant >= kMips64r6) {
538 latency = Latency::DMUH;
539 } else {
540 latency = Latency::DMULT + Latency::MFHI;
541 }
542 if (!is_operand_register) {
543 latency += 1;
544 }
545 return latency;
546 }
547
DivLatency(bool is_operand_register=true)548 int DivLatency(bool is_operand_register = true) {
549 if (is_operand_register) {
550 return Latency::DIV;
551 } else {
552 return Latency::DIV + 1;
553 }
554 }
555
DivuLatency(bool is_operand_register=true)556 int DivuLatency(bool is_operand_register = true) {
557 if (is_operand_register) {
558 return Latency::DIVU;
559 } else {
560 return Latency::DIVU + 1;
561 }
562 }
563
DdivLatency(bool is_operand_register=true)564 int DdivLatency(bool is_operand_register = true) {
565 int latency = 0;
566 if (kArchVariant >= kMips64r6) {
567 latency = Latency::DDIV;
568 } else {
569 latency = Latency::DDIV + Latency::MFLO;
570 }
571 if (!is_operand_register) {
572 latency += 1;
573 }
574 return latency;
575 }
576
DdivuLatency(bool is_operand_register=true)577 int DdivuLatency(bool is_operand_register = true) {
578 int latency = 0;
579 if (kArchVariant >= kMips64r6) {
580 latency = Latency::DDIVU;
581 } else {
582 latency = Latency::DDIVU + Latency::MFLO;
583 }
584 if (!is_operand_register) {
585 latency += 1;
586 }
587 return latency;
588 }
589
ModLatency(bool is_operand_register=true)590 int ModLatency(bool is_operand_register = true) {
591 int latency = 0;
592 if (kArchVariant >= kMips64r6) {
593 latency = 1;
594 } else {
595 latency = Latency::DIV + Latency::MFHI;
596 }
597 if (!is_operand_register) {
598 latency += 1;
599 }
600 return latency;
601 }
602
ModuLatency(bool is_operand_register=true)603 int ModuLatency(bool is_operand_register = true) {
604 int latency = 0;
605 if (kArchVariant >= kMips64r6) {
606 latency = 1;
607 } else {
608 latency = Latency::DIVU + Latency::MFHI;
609 }
610 if (!is_operand_register) {
611 latency += 1;
612 }
613 return latency;
614 }
615
DmodLatency(bool is_operand_register=true)616 int DmodLatency(bool is_operand_register = true) {
617 int latency = 0;
618 if (kArchVariant >= kMips64r6) {
619 latency = 1;
620 } else {
621 latency = Latency::DDIV + Latency::MFHI;
622 }
623 if (!is_operand_register) {
624 latency += 1;
625 }
626 return latency;
627 }
628
DmoduLatency(bool is_operand_register=true)629 int DmoduLatency(bool is_operand_register = true) {
630 int latency = 0;
631 if (kArchVariant >= kMips64r6) {
632 latency = 1;
633 } else {
634 latency = Latency::DDIV + Latency::MFHI;
635 }
636 if (!is_operand_register) {
637 latency += 1;
638 }
639 return latency;
640 }
641
MovzLatency()642 int MovzLatency() {
643 if (kArchVariant >= kMips64r6) {
644 return Latency::BRANCH + 1;
645 } else {
646 return 1;
647 }
648 }
649
MovnLatency()650 int MovnLatency() {
651 if (kArchVariant >= kMips64r6) {
652 return Latency::BRANCH + 1;
653 } else {
654 return 1;
655 }
656 }
657
DlsaLatency()658 int DlsaLatency() {
659 // Estimated max.
660 return DadduLatency() + 1;
661 }
662
CallLatency()663 int CallLatency() {
664 // Estimated.
665 return DadduLatency(false) + Latency::BRANCH + 5;
666 }
667
JumpLatency()668 int JumpLatency() {
669 // Estimated max.
670 return 1 + DadduLatency() + Latency::BRANCH + 2;
671 }
672
SmiUntagLatency()673 int SmiUntagLatency() { return 1; }
674
PrepareForTailCallLatency()675 int PrepareForTailCallLatency() {
676 // Estimated max.
677 return 2 * (DlsaLatency() + DadduLatency(false)) + 2 + Latency::BRANCH +
678 Latency::BRANCH + 2 * DsubuLatency(false) + 2 + Latency::BRANCH + 1;
679 }
680
AssemblePopArgumentsAdoptFrameLatency()681 int AssemblePopArgumentsAdoptFrameLatency() {
682 return 1 + Latency::BRANCH + 1 + SmiUntagLatency() +
683 PrepareForTailCallLatency();
684 }
685
AssertLatency()686 int AssertLatency() { return 1; }
687
PrepareCallCFunctionLatency()688 int PrepareCallCFunctionLatency() {
689 int frame_alignment = TurboAssembler::ActivationFrameAlignment();
690 if (frame_alignment > kPointerSize) {
691 return 1 + DsubuLatency(false) + AndLatency(false) + 1;
692 } else {
693 return DsubuLatency(false);
694 }
695 }
696
AdjustBaseAndOffsetLatency()697 int AdjustBaseAndOffsetLatency() {
698 return 3; // Estimated max.
699 }
700
AlignedMemoryLatency()701 int AlignedMemoryLatency() { return AdjustBaseAndOffsetLatency() + 1; }
702
UlhuLatency()703 int UlhuLatency() {
704 if (kArchVariant >= kMips64r6) {
705 return AlignedMemoryLatency();
706 } else {
707 return AdjustBaseAndOffsetLatency() + 2 * AlignedMemoryLatency() + 2;
708 }
709 }
710
UlwLatency()711 int UlwLatency() {
712 if (kArchVariant >= kMips64r6) {
713 return AlignedMemoryLatency();
714 } else {
715 // Estimated max.
716 return AdjustBaseAndOffsetLatency() + 3;
717 }
718 }
719
UlwuLatency()720 int UlwuLatency() {
721 if (kArchVariant >= kMips64r6) {
722 return AlignedMemoryLatency();
723 } else {
724 return UlwLatency() + 1;
725 }
726 }
727
UldLatency()728 int UldLatency() {
729 if (kArchVariant >= kMips64r6) {
730 return AlignedMemoryLatency();
731 } else {
732 // Estimated max.
733 return AdjustBaseAndOffsetLatency() + 3;
734 }
735 }
736
Ulwc1Latency()737 int Ulwc1Latency() {
738 if (kArchVariant >= kMips64r6) {
739 return AlignedMemoryLatency();
740 } else {
741 return UlwLatency() + Latency::MTC1;
742 }
743 }
744
Uldc1Latency()745 int Uldc1Latency() {
746 if (kArchVariant >= kMips64r6) {
747 return AlignedMemoryLatency();
748 } else {
749 return UldLatency() + Latency::DMTC1;
750 }
751 }
752
UshLatency()753 int UshLatency() {
754 if (kArchVariant >= kMips64r6) {
755 return AlignedMemoryLatency();
756 } else {
757 // Estimated max.
758 return AdjustBaseAndOffsetLatency() + 2 + 2 * AlignedMemoryLatency();
759 }
760 }
761
UswLatency()762 int UswLatency() {
763 if (kArchVariant >= kMips64r6) {
764 return AlignedMemoryLatency();
765 } else {
766 return AdjustBaseAndOffsetLatency() + 2;
767 }
768 }
769
UsdLatency()770 int UsdLatency() {
771 if (kArchVariant >= kMips64r6) {
772 return AlignedMemoryLatency();
773 } else {
774 return AdjustBaseAndOffsetLatency() + 2;
775 }
776 }
777
Uswc1Latency()778 int Uswc1Latency() {
779 if (kArchVariant >= kMips64r6) {
780 return AlignedMemoryLatency();
781 } else {
782 return Latency::MFC1 + UswLatency();
783 }
784 }
785
Usdc1Latency()786 int Usdc1Latency() {
787 if (kArchVariant >= kMips64r6) {
788 return AlignedMemoryLatency();
789 } else {
790 return Latency::DMFC1 + UsdLatency();
791 }
792 }
793
Lwc1Latency()794 int Lwc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::LWC1; }
795
Swc1Latency()796 int Swc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::SWC1; }
797
Sdc1Latency()798 int Sdc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::SDC1; }
799
Ldc1Latency()800 int Ldc1Latency() { return AdjustBaseAndOffsetLatency() + Latency::LDC1; }
801
MultiPushLatency()802 int MultiPushLatency() {
803 int latency = DsubuLatency(false);
804 for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
805 latency++;
806 }
807 return latency;
808 }
809
MultiPushFPULatency()810 int MultiPushFPULatency() {
811 int latency = DsubuLatency(false);
812 for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
813 latency += Sdc1Latency();
814 }
815 return latency;
816 }
817
PushCallerSavedLatency(SaveFPRegsMode fp_mode)818 int PushCallerSavedLatency(SaveFPRegsMode fp_mode) {
819 int latency = MultiPushLatency();
820 if (fp_mode == kSaveFPRegs) {
821 latency += MultiPushFPULatency();
822 }
823 return latency;
824 }
825
MultiPopLatency()826 int MultiPopLatency() {
827 int latency = DadduLatency(false);
828 for (int16_t i = 0; i < kNumRegisters; i++) {
829 latency++;
830 }
831 return latency;
832 }
833
MultiPopFPULatency()834 int MultiPopFPULatency() {
835 int latency = DadduLatency(false);
836 for (int16_t i = 0; i < kNumRegisters; i++) {
837 latency += Ldc1Latency();
838 }
839 return latency;
840 }
841
PopCallerSavedLatency(SaveFPRegsMode fp_mode)842 int PopCallerSavedLatency(SaveFPRegsMode fp_mode) {
843 int latency = MultiPopLatency();
844 if (fp_mode == kSaveFPRegs) {
845 latency += MultiPopFPULatency();
846 }
847 return latency;
848 }
849
CallCFunctionHelperLatency()850 int CallCFunctionHelperLatency() {
851 // Estimated.
852 int latency = AndLatency(false) + Latency::BRANCH + 2 + CallLatency();
853 if (base::OS::ActivationFrameAlignment() > kPointerSize) {
854 latency++;
855 } else {
856 latency += DadduLatency(false);
857 }
858 return latency;
859 }
860
CallCFunctionLatency()861 int CallCFunctionLatency() { return 1 + CallCFunctionHelperLatency(); }
862
AssembleArchJumpLatency()863 int AssembleArchJumpLatency() {
864 // Estimated max.
865 return Latency::BRANCH;
866 }
867
AssembleArchLookupSwitchLatency(const Instruction * instr)868 int AssembleArchLookupSwitchLatency(const Instruction* instr) {
869 int latency = 0;
870 for (size_t index = 2; index < instr->InputCount(); index += 2) {
871 latency += 1 + Latency::BRANCH;
872 }
873 return latency + AssembleArchJumpLatency();
874 }
875
GenerateSwitchTableLatency()876 int GenerateSwitchTableLatency() {
877 int latency = 0;
878 if (kArchVariant >= kMips64r6) {
879 latency = DlsaLatency() + 2;
880 } else {
881 latency = 6;
882 }
883 latency += 2;
884 return latency;
885 }
886
AssembleArchTableSwitchLatency()887 int AssembleArchTableSwitchLatency() {
888 return Latency::BRANCH + GenerateSwitchTableLatency();
889 }
890
DropAndRetLatency()891 int DropAndRetLatency() {
892 // Estimated max.
893 return DadduLatency(false) + JumpLatency();
894 }
895
AssemblerReturnLatency()896 int AssemblerReturnLatency() {
897 // Estimated max.
898 return DadduLatency(false) + MultiPopLatency() + MultiPopFPULatency() +
899 Latency::BRANCH + DadduLatency() + 1 + DropAndRetLatency();
900 }
901
TryInlineTruncateDoubleToILatency()902 int TryInlineTruncateDoubleToILatency() {
903 return 2 + Latency::TRUNC_W_D + Latency::MFC1 + 2 + AndLatency(false) +
904 Latency::BRANCH;
905 }
906
CallStubDelayedLatency()907 int CallStubDelayedLatency() { return 1 + CallLatency(); }
908
TruncateDoubleToIDelayedLatency()909 int TruncateDoubleToIDelayedLatency() {
910 return TryInlineTruncateDoubleToILatency() + 1 + DsubuLatency(false) +
911 Sdc1Latency() + CallStubDelayedLatency() + DadduLatency(false) + 1;
912 }
913
CheckPageFlagLatency()914 int CheckPageFlagLatency() {
915 return AndLatency(false) + AlignedMemoryLatency() + AndLatency(false) +
916 Latency::BRANCH;
917 }
918
SltuLatency(bool is_operand_register=true)919 int SltuLatency(bool is_operand_register = true) {
920 if (is_operand_register) {
921 return 1;
922 } else {
923 return 2; // Estimated max.
924 }
925 }
926
BranchShortHelperR6Latency()927 int BranchShortHelperR6Latency() {
928 return 2; // Estimated max.
929 }
930
BranchShortHelperLatency()931 int BranchShortHelperLatency() {
932 return SltuLatency() + 2; // Estimated max.
933 }
934
BranchShortLatency(BranchDelaySlot bdslot=PROTECT)935 int BranchShortLatency(BranchDelaySlot bdslot = PROTECT) {
936 if (kArchVariant >= kMips64r6 && bdslot == PROTECT) {
937 return BranchShortHelperR6Latency();
938 } else {
939 return BranchShortHelperLatency();
940 }
941 }
942
MoveLatency()943 int MoveLatency() { return 1; }
944
MovToFloatParametersLatency()945 int MovToFloatParametersLatency() { return 2 * MoveLatency(); }
946
MovFromFloatResultLatency()947 int MovFromFloatResultLatency() { return MoveLatency(); }
948
DaddOverflowLatency()949 int DaddOverflowLatency() {
950 // Estimated max.
951 return 6;
952 }
953
DsubOverflowLatency()954 int DsubOverflowLatency() {
955 // Estimated max.
956 return 6;
957 }
958
MulOverflowLatency()959 int MulOverflowLatency() {
960 // Estimated max.
961 return MulLatency() + MulhLatency() + 2;
962 }
963
DclzLatency()964 int DclzLatency() { return 1; }
965
CtzLatency()966 int CtzLatency() {
967 if (kArchVariant >= kMips64r6) {
968 return 3 + DclzLatency();
969 } else {
970 return DadduLatency(false) + XorLatency() + AndLatency() + DclzLatency() +
971 1 + DsubuLatency();
972 }
973 }
974
DctzLatency()975 int DctzLatency() {
976 if (kArchVariant >= kMips64r6) {
977 return 4;
978 } else {
979 return DadduLatency(false) + XorLatency() + AndLatency() + 1 +
980 DsubuLatency();
981 }
982 }
983
PopcntLatency()984 int PopcntLatency() {
985 return 2 + AndLatency() + DsubuLatency() + 1 + AndLatency() + 1 +
986 AndLatency() + DadduLatency() + 1 + DadduLatency() + 1 + AndLatency() +
987 1 + MulLatency() + 1;
988 }
989
DpopcntLatency()990 int DpopcntLatency() {
991 return 2 + AndLatency() + DsubuLatency() + 1 + AndLatency() + 1 +
992 AndLatency() + DadduLatency() + 1 + DadduLatency() + 1 + AndLatency() +
993 1 + DmulLatency() + 1;
994 }
995
CompareFLatency()996 int CompareFLatency() { return Latency::C_cond_S; }
997
CompareF32Latency()998 int CompareF32Latency() { return CompareFLatency(); }
999
CompareF64Latency()1000 int CompareF64Latency() { return CompareFLatency(); }
1001
CompareIsNanFLatency()1002 int CompareIsNanFLatency() { return CompareFLatency(); }
1003
CompareIsNanF32Latency()1004 int CompareIsNanF32Latency() { return CompareIsNanFLatency(); }
1005
CompareIsNanF64Latency()1006 int CompareIsNanF64Latency() { return CompareIsNanFLatency(); }
1007
NegsLatency()1008 int NegsLatency() {
1009 if (kArchVariant >= kMips64r6) {
1010 return Latency::NEG_S;
1011 } else {
1012 // Estimated.
1013 return CompareIsNanF32Latency() + 2 * Latency::BRANCH + Latency::NEG_S +
1014 Latency::MFC1 + 1 + XorLatency() + Latency::MTC1;
1015 }
1016 }
1017
NegdLatency()1018 int NegdLatency() {
1019 if (kArchVariant >= kMips64r6) {
1020 return Latency::NEG_D;
1021 } else {
1022 // Estimated.
1023 return CompareIsNanF64Latency() + 2 * Latency::BRANCH + Latency::NEG_D +
1024 Latency::DMFC1 + 1 + XorLatency() + Latency::DMTC1;
1025 }
1026 }
1027
Float64RoundLatency()1028 int Float64RoundLatency() {
1029 if (kArchVariant >= kMips64r6) {
1030 return Latency::RINT_D + 4;
1031 } else {
1032 // For ceil_l_d, floor_l_d, round_l_d, trunc_l_d latency is 4.
1033 return Latency::DMFC1 + 1 + Latency::BRANCH + Latency::MOV_D + 4 +
1034 Latency::DMFC1 + Latency::BRANCH + Latency::CVT_D_L + 2 +
1035 Latency::MTHC1;
1036 }
1037 }
1038
Float32RoundLatency()1039 int Float32RoundLatency() {
1040 if (kArchVariant >= kMips64r6) {
1041 return Latency::RINT_S + 4;
1042 } else {
1043 // For ceil_w_s, floor_w_s, round_w_s, trunc_w_s latency is 4.
1044 return Latency::MFC1 + 1 + Latency::BRANCH + Latency::MOV_S + 4 +
1045 Latency::MFC1 + Latency::BRANCH + Latency::CVT_S_W + 2 +
1046 Latency::MTC1;
1047 }
1048 }
1049
Float32MaxLatency()1050 int Float32MaxLatency() {
1051 // Estimated max.
1052 int latency = CompareIsNanF32Latency() + Latency::BRANCH;
1053 if (kArchVariant >= kMips64r6) {
1054 return latency + Latency::MAX_S;
1055 } else {
1056 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1057 Latency::MFC1 + 1 + Latency::MOV_S;
1058 }
1059 }
1060
Float64MaxLatency()1061 int Float64MaxLatency() {
1062 // Estimated max.
1063 int latency = CompareIsNanF64Latency() + Latency::BRANCH;
1064 if (kArchVariant >= kMips64r6) {
1065 return latency + Latency::MAX_D;
1066 } else {
1067 return latency + 5 * Latency::BRANCH + 2 * CompareF64Latency() +
1068 Latency::DMFC1 + Latency::MOV_D;
1069 }
1070 }
1071
Float32MinLatency()1072 int Float32MinLatency() {
1073 // Estimated max.
1074 int latency = CompareIsNanF32Latency() + Latency::BRANCH;
1075 if (kArchVariant >= kMips64r6) {
1076 return latency + Latency::MIN_S;
1077 } else {
1078 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1079 Latency::MFC1 + 1 + Latency::MOV_S;
1080 }
1081 }
1082
Float64MinLatency()1083 int Float64MinLatency() {
1084 // Estimated max.
1085 int latency = CompareIsNanF64Latency() + Latency::BRANCH;
1086 if (kArchVariant >= kMips64r6) {
1087 return latency + Latency::MIN_D;
1088 } else {
1089 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
1090 Latency::DMFC1 + Latency::MOV_D;
1091 }
1092 }
1093
TruncLSLatency(bool load_status)1094 int TruncLSLatency(bool load_status) {
1095 int latency = Latency::TRUNC_L_S + Latency::DMFC1;
1096 if (load_status) {
1097 latency += SltuLatency() + 7;
1098 }
1099 return latency;
1100 }
1101
TruncLDLatency(bool load_status)1102 int TruncLDLatency(bool load_status) {
1103 int latency = Latency::TRUNC_L_D + Latency::DMFC1;
1104 if (load_status) {
1105 latency += SltuLatency() + 7;
1106 }
1107 return latency;
1108 }
1109
TruncUlSLatency()1110 int TruncUlSLatency() {
1111 // Estimated max.
1112 return 2 * CompareF32Latency() + CompareIsNanF32Latency() +
1113 4 * Latency::BRANCH + Latency::SUB_S + 2 * Latency::TRUNC_L_S +
1114 3 * Latency::DMFC1 + OrLatency() + Latency::MTC1 + Latency::MOV_S +
1115 SltuLatency() + 4;
1116 }
1117
TruncUlDLatency()1118 int TruncUlDLatency() {
1119 // Estimated max.
1120 return 2 * CompareF64Latency() + CompareIsNanF64Latency() +
1121 4 * Latency::BRANCH + Latency::SUB_D + 2 * Latency::TRUNC_L_D +
1122 3 * Latency::DMFC1 + OrLatency() + Latency::DMTC1 + Latency::MOV_D +
1123 SltuLatency() + 4;
1124 }
1125
PushLatency()1126 int PushLatency() { return DadduLatency() + AlignedMemoryLatency(); }
1127
ByteSwapSignedLatency()1128 int ByteSwapSignedLatency() { return 2; }
1129
LlLatency(int offset)1130 int LlLatency(int offset) {
1131 bool is_one_instruction =
1132 (kArchVariant == kMips64r6) ? is_int9(offset) : is_int16(offset);
1133 if (is_one_instruction) {
1134 return 1;
1135 } else {
1136 return 3;
1137 }
1138 }
1139
ExtractBitsLatency(bool sign_extend,int size)1140 int ExtractBitsLatency(bool sign_extend, int size) {
1141 int latency = 2;
1142 if (sign_extend) {
1143 switch (size) {
1144 case 8:
1145 case 16:
1146 case 32:
1147 latency += 1;
1148 break;
1149 default:
1150 UNREACHABLE();
1151 }
1152 }
1153 return latency;
1154 }
1155
InsertBitsLatency()1156 int InsertBitsLatency() { return 2 + DsubuLatency(false) + 2; }
1157
ScLatency(int offset)1158 int ScLatency(int offset) {
1159 bool is_one_instruction =
1160 (kArchVariant == kMips64r6) ? is_int9(offset) : is_int16(offset);
1161 if (is_one_instruction) {
1162 return 1;
1163 } else {
1164 return 3;
1165 }
1166 }
1167
Word32AtomicExchangeLatency(bool sign_extend,int size)1168 int Word32AtomicExchangeLatency(bool sign_extend, int size) {
1169 return DadduLatency(false) + 1 + DsubuLatency() + 2 + LlLatency(0) +
1170 ExtractBitsLatency(sign_extend, size) + InsertBitsLatency() +
1171 ScLatency(0) + BranchShortLatency() + 1;
1172 }
1173
Word32AtomicCompareExchangeLatency(bool sign_extend,int size)1174 int Word32AtomicCompareExchangeLatency(bool sign_extend, int size) {
1175 return 2 + DsubuLatency() + 2 + LlLatency(0) +
1176 ExtractBitsLatency(sign_extend, size) + InsertBitsLatency() +
1177 ScLatency(0) + BranchShortLatency() + 1;
1178 }
1179
GetInstructionLatency(const Instruction * instr)1180 int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
1181 // Basic latency modeling for MIPS64 instructions. They have been determined
1182 // in empirical way.
1183 switch (instr->arch_opcode()) {
1184 case kArchCallCodeObject:
1185 case kArchCallWasmFunction:
1186 return CallLatency();
1187 case kArchTailCallCodeObjectFromJSFunction:
1188 case kArchTailCallCodeObject: {
1189 int latency = 0;
1190 if (instr->arch_opcode() == kArchTailCallCodeObjectFromJSFunction) {
1191 latency = AssemblePopArgumentsAdoptFrameLatency();
1192 }
1193 return latency + JumpLatency();
1194 }
1195 case kArchTailCallWasm:
1196 case kArchTailCallAddress:
1197 return JumpLatency();
1198 case kArchCallJSFunction: {
1199 int latency = 0;
1200 if (FLAG_debug_code) {
1201 latency = 1 + AssertLatency();
1202 }
1203 return latency + 1 + DadduLatency(false) + CallLatency();
1204 }
1205 case kArchPrepareCallCFunction:
1206 return PrepareCallCFunctionLatency();
1207 case kArchSaveCallerRegisters: {
1208 auto fp_mode =
1209 static_cast<SaveFPRegsMode>(MiscField::decode(instr->opcode()));
1210 return PushCallerSavedLatency(fp_mode);
1211 }
1212 case kArchRestoreCallerRegisters: {
1213 auto fp_mode =
1214 static_cast<SaveFPRegsMode>(MiscField::decode(instr->opcode()));
1215 return PopCallerSavedLatency(fp_mode);
1216 }
1217 case kArchPrepareTailCall:
1218 return 2;
1219 case kArchCallCFunction:
1220 return CallCFunctionLatency();
1221 case kArchJmp:
1222 return AssembleArchJumpLatency();
1223 case kArchLookupSwitch:
1224 return AssembleArchLookupSwitchLatency(instr);
1225 case kArchTableSwitch:
1226 return AssembleArchTableSwitchLatency();
1227 case kArchDebugAbort:
1228 return CallLatency() + 1;
1229 case kArchDebugBreak:
1230 return 1;
1231 case kArchComment:
1232 case kArchNop:
1233 case kArchThrowTerminator:
1234 case kArchDeoptimize:
1235 return 0;
1236 case kArchRet:
1237 return AssemblerReturnLatency();
1238 case kArchStackPointer:
1239 case kArchFramePointer:
1240 return 1;
1241 case kArchParentFramePointer:
1242 // Estimated max.
1243 return AlignedMemoryLatency();
1244 case kArchTruncateDoubleToI:
1245 return TruncateDoubleToIDelayedLatency();
1246 case kArchStoreWithWriteBarrier:
1247 return DadduLatency() + 1 + CheckPageFlagLatency();
1248 case kArchStackSlot:
1249 // Estimated max.
1250 return DadduLatency(false) + AndLatency(false) + AssertLatency() +
1251 DadduLatency(false) + AndLatency(false) + BranchShortLatency() +
1252 1 + DsubuLatency() + DadduLatency();
1253 case kArchWordPoisonOnSpeculation:
1254 return AndLatency();
1255 case kIeee754Float64Acos:
1256 case kIeee754Float64Acosh:
1257 case kIeee754Float64Asin:
1258 case kIeee754Float64Asinh:
1259 case kIeee754Float64Atan:
1260 case kIeee754Float64Atanh:
1261 case kIeee754Float64Atan2:
1262 case kIeee754Float64Cos:
1263 case kIeee754Float64Cosh:
1264 case kIeee754Float64Cbrt:
1265 case kIeee754Float64Exp:
1266 case kIeee754Float64Expm1:
1267 case kIeee754Float64Log:
1268 case kIeee754Float64Log1p:
1269 case kIeee754Float64Log10:
1270 case kIeee754Float64Log2:
1271 case kIeee754Float64Pow:
1272 case kIeee754Float64Sin:
1273 case kIeee754Float64Sinh:
1274 case kIeee754Float64Tan:
1275 case kIeee754Float64Tanh:
1276 return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1277 CallCFunctionLatency() + MovFromFloatResultLatency();
1278 case kMips64Add:
1279 case kMips64Dadd:
1280 return DadduLatency(instr->InputAt(1)->IsRegister());
1281 case kMips64DaddOvf:
1282 return DaddOverflowLatency();
1283 case kMips64Sub:
1284 case kMips64Dsub:
1285 return DsubuLatency(instr->InputAt(1)->IsRegister());
1286 case kMips64DsubOvf:
1287 return DsubOverflowLatency();
1288 case kMips64Mul:
1289 return MulLatency();
1290 case kMips64MulOvf:
1291 return MulOverflowLatency();
1292 case kMips64MulHigh:
1293 return MulhLatency();
1294 case kMips64MulHighU:
1295 return MulhuLatency();
1296 case kMips64DMulHigh:
1297 return DMulhLatency();
1298 case kMips64Div: {
1299 int latency = DivLatency(instr->InputAt(1)->IsRegister());
1300 if (kArchVariant >= kMips64r6) {
1301 return latency++;
1302 } else {
1303 return latency + MovzLatency();
1304 }
1305 }
1306 case kMips64DivU: {
1307 int latency = DivuLatency(instr->InputAt(1)->IsRegister());
1308 if (kArchVariant >= kMips64r6) {
1309 return latency++;
1310 } else {
1311 return latency + MovzLatency();
1312 }
1313 }
1314 case kMips64Mod:
1315 return ModLatency();
1316 case kMips64ModU:
1317 return ModuLatency();
1318 case kMips64Dmul:
1319 return DmulLatency();
1320 case kMips64Ddiv: {
1321 int latency = DdivLatency();
1322 if (kArchVariant >= kMips64r6) {
1323 return latency++;
1324 } else {
1325 return latency + MovzLatency();
1326 }
1327 }
1328 case kMips64DdivU: {
1329 int latency = DdivuLatency();
1330 if (kArchVariant >= kMips64r6) {
1331 return latency++;
1332 } else {
1333 return latency + MovzLatency();
1334 }
1335 }
1336 case kMips64Dmod:
1337 return DmodLatency();
1338 case kMips64DmodU:
1339 return DmoduLatency();
1340 case kMips64Dlsa:
1341 case kMips64Lsa:
1342 return DlsaLatency();
1343 case kMips64And:
1344 return AndLatency(instr->InputAt(1)->IsRegister());
1345 case kMips64And32: {
1346 bool is_operand_register = instr->InputAt(1)->IsRegister();
1347 int latency = AndLatency(is_operand_register);
1348 if (is_operand_register) {
1349 return latency + 2;
1350 } else {
1351 return latency + 1;
1352 }
1353 }
1354 case kMips64Or:
1355 return OrLatency(instr->InputAt(1)->IsRegister());
1356 case kMips64Or32: {
1357 bool is_operand_register = instr->InputAt(1)->IsRegister();
1358 int latency = OrLatency(is_operand_register);
1359 if (is_operand_register) {
1360 return latency + 2;
1361 } else {
1362 return latency + 1;
1363 }
1364 }
1365 case kMips64Nor:
1366 return NorLatency(instr->InputAt(1)->IsRegister());
1367 case kMips64Nor32: {
1368 bool is_operand_register = instr->InputAt(1)->IsRegister();
1369 int latency = NorLatency(is_operand_register);
1370 if (is_operand_register) {
1371 return latency + 2;
1372 } else {
1373 return latency + 1;
1374 }
1375 }
1376 case kMips64Xor:
1377 return XorLatency(instr->InputAt(1)->IsRegister());
1378 case kMips64Xor32: {
1379 bool is_operand_register = instr->InputAt(1)->IsRegister();
1380 int latency = XorLatency(is_operand_register);
1381 if (is_operand_register) {
1382 return latency + 2;
1383 } else {
1384 return latency + 1;
1385 }
1386 }
1387 case kMips64Clz:
1388 case kMips64Dclz:
1389 return DclzLatency();
1390 case kMips64Ctz:
1391 return CtzLatency();
1392 case kMips64Dctz:
1393 return DctzLatency();
1394 case kMips64Popcnt:
1395 return PopcntLatency();
1396 case kMips64Dpopcnt:
1397 return DpopcntLatency();
1398 case kMips64Shl:
1399 return 1;
1400 case kMips64Shr:
1401 case kMips64Sar:
1402 return 2;
1403 case kMips64Ext:
1404 case kMips64Ins:
1405 case kMips64Dext:
1406 case kMips64Dins:
1407 case kMips64Dshl:
1408 case kMips64Dshr:
1409 case kMips64Dsar:
1410 case kMips64Ror:
1411 case kMips64Dror:
1412 return 1;
1413 case kMips64Tst:
1414 return AndLatency(instr->InputAt(1)->IsRegister());
1415 case kMips64Mov:
1416 return 1;
1417 case kMips64CmpS:
1418 return MoveLatency() + CompareF32Latency();
1419 case kMips64AddS:
1420 return Latency::ADD_S;
1421 case kMips64SubS:
1422 return Latency::SUB_S;
1423 case kMips64MulS:
1424 return Latency::MUL_S;
1425 case kMips64DivS:
1426 return Latency::DIV_S;
1427 case kMips64ModS:
1428 return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1429 CallCFunctionLatency() + MovFromFloatResultLatency();
1430 case kMips64AbsS:
1431 return Latency::ABS_S;
1432 case kMips64NegS:
1433 return NegdLatency();
1434 case kMips64SqrtS:
1435 return Latency::SQRT_S;
1436 case kMips64MaxS:
1437 return Latency::MAX_S;
1438 case kMips64MinS:
1439 return Latency::MIN_S;
1440 case kMips64CmpD:
1441 return MoveLatency() + CompareF64Latency();
1442 case kMips64AddD:
1443 return Latency::ADD_D;
1444 case kMips64SubD:
1445 return Latency::SUB_D;
1446 case kMips64MulD:
1447 return Latency::MUL_D;
1448 case kMips64DivD:
1449 return Latency::DIV_D;
1450 case kMips64ModD:
1451 return PrepareCallCFunctionLatency() + MovToFloatParametersLatency() +
1452 CallCFunctionLatency() + MovFromFloatResultLatency();
1453 case kMips64AbsD:
1454 return Latency::ABS_D;
1455 case kMips64NegD:
1456 return NegdLatency();
1457 case kMips64SqrtD:
1458 return Latency::SQRT_D;
1459 case kMips64MaxD:
1460 return Latency::MAX_D;
1461 case kMips64MinD:
1462 return Latency::MIN_D;
1463 case kMips64Float64RoundDown:
1464 case kMips64Float64RoundTruncate:
1465 case kMips64Float64RoundUp:
1466 case kMips64Float64RoundTiesEven:
1467 return Float64RoundLatency();
1468 case kMips64Float32RoundDown:
1469 case kMips64Float32RoundTruncate:
1470 case kMips64Float32RoundUp:
1471 case kMips64Float32RoundTiesEven:
1472 return Float32RoundLatency();
1473 case kMips64Float32Max:
1474 return Float32MaxLatency();
1475 case kMips64Float64Max:
1476 return Float64MaxLatency();
1477 case kMips64Float32Min:
1478 return Float32MinLatency();
1479 case kMips64Float64Min:
1480 return Float64MinLatency();
1481 case kMips64Float64SilenceNaN:
1482 return Latency::SUB_D;
1483 case kMips64CvtSD:
1484 return Latency::CVT_S_D;
1485 case kMips64CvtDS:
1486 return Latency::CVT_D_S;
1487 case kMips64CvtDW:
1488 return Latency::MTC1 + Latency::CVT_D_W;
1489 case kMips64CvtSW:
1490 return Latency::MTC1 + Latency::CVT_S_W;
1491 case kMips64CvtSUw:
1492 return 1 + Latency::DMTC1 + Latency::CVT_S_L;
1493 case kMips64CvtSL:
1494 return Latency::DMTC1 + Latency::CVT_S_L;
1495 case kMips64CvtDL:
1496 return Latency::DMTC1 + Latency::CVT_D_L;
1497 case kMips64CvtDUw:
1498 return 1 + Latency::DMTC1 + Latency::CVT_D_L;
1499 case kMips64CvtDUl:
1500 return 2 * Latency::BRANCH + 3 + 2 * Latency::DMTC1 +
1501 2 * Latency::CVT_D_L + Latency::ADD_D;
1502 case kMips64CvtSUl:
1503 return 2 * Latency::BRANCH + 3 + 2 * Latency::DMTC1 +
1504 2 * Latency::CVT_S_L + Latency::ADD_S;
1505 case kMips64FloorWD:
1506 return Latency::FLOOR_W_D + Latency::MFC1;
1507 case kMips64CeilWD:
1508 return Latency::CEIL_W_D + Latency::MFC1;
1509 case kMips64RoundWD:
1510 return Latency::ROUND_W_D + Latency::MFC1;
1511 case kMips64TruncWD:
1512 return Latency::TRUNC_W_D + Latency::MFC1;
1513 case kMips64FloorWS:
1514 return Latency::FLOOR_W_S + Latency::MFC1;
1515 case kMips64CeilWS:
1516 return Latency::CEIL_W_S + Latency::MFC1;
1517 case kMips64RoundWS:
1518 return Latency::ROUND_W_S + Latency::MFC1;
1519 case kMips64TruncWS:
1520 return Latency::TRUNC_W_S + Latency::MFC1 + 2 + MovnLatency();
1521 case kMips64TruncLS:
1522 return TruncLSLatency(instr->OutputCount() > 1);
1523 case kMips64TruncLD:
1524 return TruncLDLatency(instr->OutputCount() > 1);
1525 case kMips64TruncUwD:
1526 // Estimated max.
1527 return CompareF64Latency() + 2 * Latency::BRANCH +
1528 2 * Latency::TRUNC_W_D + Latency::SUB_D + OrLatency() +
1529 Latency::MTC1 + Latency::MFC1 + Latency::MTHC1 + 1;
1530 case kMips64TruncUwS:
1531 // Estimated max.
1532 return CompareF32Latency() + 2 * Latency::BRANCH +
1533 2 * Latency::TRUNC_W_S + Latency::SUB_S + OrLatency() +
1534 Latency::MTC1 + 2 * Latency::MFC1 + 2 + MovzLatency();
1535 case kMips64TruncUlS:
1536 return TruncUlSLatency();
1537 case kMips64TruncUlD:
1538 return TruncUlDLatency();
1539 case kMips64BitcastDL:
1540 return Latency::DMFC1;
1541 case kMips64BitcastLD:
1542 return Latency::DMTC1;
1543 case kMips64Float64ExtractLowWord32:
1544 return Latency::MFC1;
1545 case kMips64Float64InsertLowWord32:
1546 return Latency::MFHC1 + Latency::MTC1 + Latency::MTHC1;
1547 case kMips64Float64ExtractHighWord32:
1548 return Latency::MFHC1;
1549 case kMips64Float64InsertHighWord32:
1550 return Latency::MTHC1;
1551 case kMips64Seb:
1552 case kMips64Seh:
1553 return 1;
1554 case kMips64Lbu:
1555 case kMips64Lb:
1556 case kMips64Lhu:
1557 case kMips64Lh:
1558 case kMips64Lwu:
1559 case kMips64Lw:
1560 case kMips64Ld:
1561 case kMips64Sb:
1562 case kMips64Sh:
1563 case kMips64Sw:
1564 case kMips64Sd:
1565 return AlignedMemoryLatency();
1566 case kMips64Lwc1:
1567 return Lwc1Latency();
1568 case kMips64Ldc1:
1569 return Ldc1Latency();
1570 case kMips64Swc1:
1571 return Swc1Latency();
1572 case kMips64Sdc1:
1573 return Sdc1Latency();
1574 case kMips64Ulhu:
1575 case kMips64Ulh:
1576 return UlhuLatency();
1577 case kMips64Ulwu:
1578 return UlwuLatency();
1579 case kMips64Ulw:
1580 return UlwLatency();
1581 case kMips64Uld:
1582 return UldLatency();
1583 case kMips64Ulwc1:
1584 return Ulwc1Latency();
1585 case kMips64Uldc1:
1586 return Uldc1Latency();
1587 case kMips64Ush:
1588 return UshLatency();
1589 case kMips64Usw:
1590 return UswLatency();
1591 case kMips64Usd:
1592 return UsdLatency();
1593 case kMips64Uswc1:
1594 return Uswc1Latency();
1595 case kMips64Usdc1:
1596 return Usdc1Latency();
1597 case kMips64Push: {
1598 int latency = 0;
1599 if (instr->InputAt(0)->IsFPRegister()) {
1600 latency = Sdc1Latency() + DsubuLatency(false);
1601 } else {
1602 latency = PushLatency();
1603 }
1604 return latency;
1605 }
1606 case kMips64Peek: {
1607 int latency = 0;
1608 if (instr->OutputAt(0)->IsFPRegister()) {
1609 auto op = LocationOperand::cast(instr->OutputAt(0));
1610 switch (op->representation()) {
1611 case MachineRepresentation::kFloat64:
1612 latency = Ldc1Latency();
1613 break;
1614 case MachineRepresentation::kFloat32:
1615 latency = Latency::LWC1;
1616 break;
1617 default:
1618 UNREACHABLE();
1619 }
1620 } else {
1621 latency = AlignedMemoryLatency();
1622 }
1623 return latency;
1624 }
1625 case kMips64StackClaim:
1626 return DsubuLatency(false);
1627 case kMips64StoreToStackSlot: {
1628 int latency = 0;
1629 if (instr->InputAt(0)->IsFPRegister()) {
1630 if (instr->InputAt(0)->IsSimd128Register()) {
1631 latency = 1; // Estimated value.
1632 } else {
1633 latency = Sdc1Latency();
1634 }
1635 } else {
1636 latency = AlignedMemoryLatency();
1637 }
1638 return latency;
1639 }
1640 case kMips64ByteSwap64:
1641 return ByteSwapSignedLatency();
1642 case kMips64ByteSwap32:
1643 return ByteSwapSignedLatency();
1644 case kWord32AtomicLoadInt8:
1645 case kWord32AtomicLoadUint8:
1646 case kWord32AtomicLoadInt16:
1647 case kWord32AtomicLoadUint16:
1648 case kWord32AtomicLoadWord32:
1649 return 2;
1650 case kWord32AtomicStoreWord8:
1651 case kWord32AtomicStoreWord16:
1652 case kWord32AtomicStoreWord32:
1653 return 3;
1654 case kWord32AtomicExchangeInt8:
1655 return Word32AtomicExchangeLatency(true, 8);
1656 case kWord32AtomicExchangeUint8:
1657 return Word32AtomicExchangeLatency(false, 8);
1658 case kWord32AtomicExchangeInt16:
1659 return Word32AtomicExchangeLatency(true, 16);
1660 case kWord32AtomicExchangeUint16:
1661 return Word32AtomicExchangeLatency(false, 16);
1662 case kWord32AtomicExchangeWord32:
1663 return 2 + LlLatency(0) + 1 + ScLatency(0) + BranchShortLatency() + 1;
1664 case kWord32AtomicCompareExchangeInt8:
1665 return Word32AtomicCompareExchangeLatency(true, 8);
1666 case kWord32AtomicCompareExchangeUint8:
1667 return Word32AtomicCompareExchangeLatency(false, 8);
1668 case kWord32AtomicCompareExchangeInt16:
1669 return Word32AtomicCompareExchangeLatency(true, 16);
1670 case kWord32AtomicCompareExchangeUint16:
1671 return Word32AtomicCompareExchangeLatency(false, 16);
1672 case kWord32AtomicCompareExchangeWord32:
1673 return 3 + LlLatency(0) + BranchShortLatency() + 1 + ScLatency(0) +
1674 BranchShortLatency() + 1;
1675 case kMips64AssertEqual:
1676 return AssertLatency();
1677 default:
1678 return 1;
1679 }
1680 }
1681
1682 } // namespace compiler
1683 } // namespace internal
1684 } // namespace v8
1685