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