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