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