v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
instruction-scheduler-riscv.cc
Go to the documentation of this file.
1// Copyright 2021 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
7
8namespace v8 {
9namespace internal {
10namespace compiler {
11
12bool InstructionScheduler::SchedulerSupported() { return true; }
13
15 const Instruction* instr) const {
16 switch (instr->arch_opcode()) {
17 case kRiscvEnableDebugTrace:
18 case kRiscvDisableDebugTrace:
19#if V8_TARGET_ARCH_RISCV64
20 case kRiscvAdd32:
21 case kRiscvBitcastDL:
22 case kRiscvBitcastLD:
23 case kRiscvByteSwap64:
24 case kRiscvCvtDL:
25 case kRiscvCvtDUl:
26 case kRiscvCvtSL:
27 case kRiscvCvtSUl:
28 case kRiscvMulHigh64:
29 case kRiscvMulHighU64:
30 case kRiscvAdd64:
31 case kRiscvAddOvf64:
32 case kRiscvClz64:
33 case kRiscvDiv64:
34 case kRiscvDivU64:
35 case kRiscvZeroExtendWord:
36 case kRiscvSignExtendWord:
37 case kRiscvMod64:
38 case kRiscvModU64:
39 case kRiscvMul64:
40 case kRiscvMulOvf64:
41 case kRiscvRor64:
42 case kRiscvSar64:
43 case kRiscvShl64:
44 case kRiscvShr64:
45 case kRiscvSub64:
46 case kRiscvSubOvf64:
47 case kRiscvFloat64RoundDown:
48 case kRiscvFloat64RoundTiesEven:
49 case kRiscvFloat64RoundTruncate:
50 case kRiscvFloat64RoundUp:
51 case kRiscvSub32:
52 case kRiscvTruncLD:
53 case kRiscvTruncLS:
54 case kRiscvTruncUlD:
55 case kRiscvTruncUlS:
56 case kRiscvCmp32:
57 case kRiscvCmpZero32:
58#elif V8_TARGET_ARCH_RISCV32
59 case kRiscvAdd32:
60 case kRiscvAddPair:
61 case kRiscvSubPair:
62 case kRiscvMulPair:
63 case kRiscvAndPair:
64 case kRiscvOrPair:
65 case kRiscvXorPair:
66 case kRiscvShlPair:
67 case kRiscvShrPair:
68 case kRiscvSarPair:
69 case kRiscvAddOvf:
70 case kRiscvSubOvf:
71 case kRiscvSub32:
72#endif
73 case kRiscvSh1add:
74 case kRiscvSh2add:
75 case kRiscvSh3add:
76#if V8_TARGET_ARCH_RISCV64
77 case kRiscvAdduw:
78 case kRiscvSh1adduw:
79 case kRiscvSh2adduw:
80 case kRiscvSh3adduw:
81 case kRiscvSlliuw:
82#endif
83 case kRiscvAndn:
84 case kRiscvOrn:
85 case kRiscvXnor:
86 case kRiscvClz:
87 case kRiscvCtz:
88 case kRiscvCpop:
89#if V8_TARGET_ARCH_RISCV64
90 case kRiscvClzw:
91 case kRiscvCtzw:
92 case kRiscvCpopw:
93#endif
94 case kRiscvMax:
95 case kRiscvMaxu:
96 case kRiscvMin:
97 case kRiscvMinu:
98 case kRiscvSextb:
99 case kRiscvSexth:
100 case kRiscvZexth:
101 case kRiscvRev8:
102 case kRiscvBclr:
103 case kRiscvBclri:
104 case kRiscvBext:
105 case kRiscvBexti:
106 case kRiscvBinv:
107 case kRiscvBinvi:
108 case kRiscvBset:
109 case kRiscvBseti:
110 case kRiscvAbsD:
111 case kRiscvAbsS:
112 case kRiscvAddD:
113 case kRiscvAddS:
114 case kRiscvAnd:
115 case kRiscvAnd32:
116 case kRiscvAssertEqual:
117 case kRiscvBitcastInt32ToFloat32:
118 case kRiscvBitcastFloat32ToInt32:
119 case kRiscvByteSwap32:
120 case kRiscvCeilWD:
121 case kRiscvCeilWS:
122 case kRiscvClz32:
123 case kRiscvCmp:
124 case kRiscvCmpZero:
125 case kRiscvCmpD:
126 case kRiscvCmpS:
127 case kRiscvCvtDS:
128 case kRiscvCvtDUw:
129 case kRiscvCvtDW:
130 case kRiscvCvtSD:
131 case kRiscvCvtSUw:
132 case kRiscvCvtSW:
133 case kRiscvMulHighU32:
134 case kRiscvDiv32:
135 case kRiscvDivD:
136 case kRiscvDivS:
137 case kRiscvDivU32:
138 case kRiscvF64x2Abs:
139 case kRiscvF64x2Sqrt:
140 case kRiscvF64x2Pmin:
141 case kRiscvF64x2Pmax:
142 case kRiscvF64x2ConvertLowI32x4S:
143 case kRiscvF64x2ConvertLowI32x4U:
144 case kRiscvF64x2PromoteLowF32x4:
145 case kRiscvF64x2Ceil:
146 case kRiscvF64x2Floor:
147 case kRiscvF64x2Trunc:
148 case kRiscvF64x2NearestInt:
149 case kRiscvI64x2SplatI32Pair:
150 case kRiscvI64x2ExtractLane:
151 case kRiscvI64x2ReplaceLane:
152 case kRiscvI64x2ReplaceLaneI32Pair:
153 case kRiscvI64x2Shl:
154 case kRiscvI64x2ShrS:
155 case kRiscvI64x2ShrU:
156 case kRiscvF32x4Abs:
157 case kRiscvF32x4ExtractLane:
158 case kRiscvF32x4Sqrt:
159 case kRiscvF64x2Qfma:
160 case kRiscvF64x2Qfms:
161 case kRiscvF32x4Qfma:
162 case kRiscvF32x4Qfms:
163 case kRiscvF32x4ReplaceLane:
164 case kRiscvF32x4SConvertI32x4:
165 case kRiscvF32x4UConvertI32x4:
166 case kRiscvF32x4Pmin:
167 case kRiscvF32x4Pmax:
168 case kRiscvF32x4DemoteF64x2Zero:
169 case kRiscvF32x4Ceil:
170 case kRiscvF32x4Floor:
171 case kRiscvF32x4Trunc:
172 case kRiscvF32x4NearestInt:
173 case kRiscvF64x2ExtractLane:
174 case kRiscvF64x2ReplaceLane:
175 case kRiscvFloat32Max:
176 case kRiscvFloat32Min:
177 case kRiscvFloat32RoundDown:
178 case kRiscvFloat32RoundTiesEven:
179 case kRiscvFloat32RoundTruncate:
180 case kRiscvFloat32RoundUp:
181 case kRiscvFloat64ExtractLowWord32:
182 case kRiscvFloat64ExtractHighWord32:
183 case kRiscvFloat64InsertLowWord32:
184 case kRiscvFloat64InsertHighWord32:
185 case kRiscvFloat64Max:
186 case kRiscvFloat64Min:
187 case kRiscvFloat64SilenceNaN:
188 case kRiscvFloorWD:
189 case kRiscvFloorWS:
190 case kRiscvI64x2SConvertI32x4Low:
191 case kRiscvI64x2SConvertI32x4High:
192 case kRiscvI64x2UConvertI32x4Low:
193 case kRiscvI64x2UConvertI32x4High:
194 case kRiscvI16x8ExtractLaneU:
195 case kRiscvI16x8ExtractLaneS:
196 case kRiscvI16x8ReplaceLane:
197 case kRiscvI16x8Shl:
198 case kRiscvI16x8ShrS:
199 case kRiscvI16x8ShrU:
200 case kRiscvI32x4TruncSatF64x2SZero:
201 case kRiscvI32x4TruncSatF64x2UZero:
202 case kRiscvI32x4ExtractLane:
203 case kRiscvI32x4ReplaceLane:
204 case kRiscvI32x4SConvertF32x4:
205 case kRiscvI32x4Shl:
206 case kRiscvI32x4ShrS:
207 case kRiscvI32x4ShrU:
208 case kRiscvI32x4UConvertF32x4:
209 case kRiscvI8x16ExtractLaneU:
210 case kRiscvI8x16ExtractLaneS:
211 case kRiscvI8x16ReplaceLane:
212 case kRiscvI8x16Shl:
213 case kRiscvI8x16ShrS:
214 case kRiscvI8x16ShrU:
215 case kRiscvI8x16RoundingAverageU:
216 case kRiscvI8x16Popcnt:
217 case kRiscvMaxD:
218 case kRiscvMaxS:
219 case kRiscvMinD:
220 case kRiscvMinS:
221 case kRiscvMod32:
222 case kRiscvModU32:
223 case kRiscvMov:
224 case kRiscvMul32:
225 case kRiscvMulD:
226 case kRiscvMulHigh32:
227 case kRiscvMulOvf32:
228 case kRiscvMulS:
229 case kRiscvNegD:
230 case kRiscvNegS:
231 case kRiscvOr:
232 case kRiscvOr32:
233 case kRiscvRor32:
234 case kRiscvRoundWD:
235 case kRiscvRoundWS:
236 case kRiscvVnot:
237 case kRiscvS128Select:
238 case kRiscvS128Const:
239 case kRiscvS128Zero:
240 case kRiscvS128Load32Zero:
241 case kRiscvS128Load64Zero:
242 case kRiscvS128AllOnes:
243 case kRiscvV128AnyTrue:
244 case kRiscvI8x16Shuffle:
245 case kRiscvVwmul:
246 case kRiscvVwmulu:
247 case kRiscvVmv:
248 case kRiscvVandVv:
249 case kRiscvVorVv:
250 case kRiscvVnotVv:
251 case kRiscvVxorVv:
252 case kRiscvVmvSx:
253 case kRiscvVmvXs:
254 case kRiscvVfmvVf:
255 case kRiscvVcompress:
256 case kRiscvVaddVv:
257 case kRiscvVwaddVv:
258 case kRiscvVwadduVv:
259 case kRiscvVwadduWx:
260 case kRiscvVsubVv:
261 case kRiscvVnegVv:
262 case kRiscvVfnegVv:
263 case kRiscvVmaxuVv:
264 case kRiscvVmax:
265 case kRiscvVminsVv:
266 case kRiscvVminuVv:
267 case kRiscvVmulVv:
268 case kRiscvVdivu:
269 case kRiscvVsmulVv:
270 case kRiscvVmslt:
271 case kRiscvVgtsVv:
272 case kRiscvVgesVv:
273 case kRiscvVgeuVv:
274 case kRiscvVgtuVv:
275 case kRiscvVeqVv:
276 case kRiscvVneVv:
277 case kRiscvVAbs:
278 case kRiscvVaddSatUVv:
279 case kRiscvVaddSatSVv:
280 case kRiscvVsubSatUVv:
281 case kRiscvVsubSatSVv:
282 case kRiscvVrgather:
283 case kRiscvVslidedown:
284 case kRiscvVredminuVs:
285 case kRiscvVAllTrue:
286 case kRiscvVnclipu:
287 case kRiscvVnclip:
288 case kRiscvVsll:
289 case kRiscvVfaddVv:
290 case kRiscvVfsubVv:
291 case kRiscvVfmulVv:
292 case kRiscvVfdivVv:
293 case kRiscvVfminVv:
294 case kRiscvVfmaxVv:
295 case kRiscvVmfeqVv:
296 case kRiscvVmfneVv:
297 case kRiscvVmfltVv:
298 case kRiscvVmfleVv:
299 case kRiscvVmergeVx:
300 case kRiscvVzextVf2:
301 case kRiscvVsextVf2:
302 case kRiscvSar32:
303 case kRiscvSignExtendByte:
304 case kRiscvSignExtendShort:
305 case kRiscvShl32:
306 case kRiscvShr32:
307 case kRiscvSqrtD:
308 case kRiscvSqrtS:
309 case kRiscvSubD:
310 case kRiscvSubS:
311 case kRiscvTruncUwD:
312 case kRiscvTruncUwS:
313 case kRiscvTruncWD:
314 case kRiscvTruncWS:
315 case kRiscvTst32:
316 case kRiscvXor:
317 case kRiscvXor32:
318 return kNoOpcodeFlags;
319#if V8_TARGET_ARCH_RISCV64
320 case kRiscvTst64:
321 case kRiscvLd:
322 case kRiscvLwu:
323 case kRiscvUlwu:
324 case kRiscvWord64AtomicLoadUint64:
325 case kRiscvLoadDecompressTaggedSigned:
326 case kRiscvLoadDecompressTagged:
327 case kRiscvLoadDecodeSandboxedPointer:
328 case kRiscvAtomicLoadDecompressTaggedSigned:
329 case kRiscvAtomicLoadDecompressTagged:
330 case kRiscvAtomicStoreCompressTagged:
331 case kRiscvLoadDecompressProtected:
332#elif V8_TARGET_ARCH_RISCV32
333 case kRiscvWord32AtomicPairLoad:
334#endif
335 case kRiscvLb:
336 case kRiscvLbu:
337 case kRiscvLoadDouble:
338 case kRiscvLh:
339 case kRiscvLhu:
340 case kRiscvLw:
341 case kRiscvLoadFloat:
342 case kRiscvRvvLd:
343 case kRiscvPeek:
344 case kRiscvUld:
345 case kRiscvULoadDouble:
346 case kRiscvUlh:
347 case kRiscvUlhu:
348 case kRiscvUlw:
349 case kRiscvULoadFloat:
350 case kRiscvS128LoadSplat:
351 case kRiscvS128Load64ExtendU:
352 case kRiscvS128Load64ExtendS:
353 case kRiscvS128LoadLane:
354 return kIsLoadOperation;
355
356#if V8_TARGET_ARCH_RISCV64
357 case kRiscvSd:
358 case kRiscvUsd:
359 case kRiscvWord64AtomicStoreWord64:
360 case kRiscvWord64AtomicAddUint64:
361 case kRiscvWord64AtomicSubUint64:
362 case kRiscvWord64AtomicAndUint64:
363 case kRiscvWord64AtomicOrUint64:
364 case kRiscvWord64AtomicXorUint64:
365 case kRiscvWord64AtomicExchangeUint64:
366 case kRiscvWord64AtomicCompareExchangeUint64:
367 case kRiscvStoreCompressTagged:
368 case kRiscvStoreEncodeSandboxedPointer:
369 case kRiscvStoreIndirectPointer:
370#elif V8_TARGET_ARCH_RISCV32
371 case kRiscvWord32AtomicPairStore:
372 case kRiscvWord32AtomicPairAdd:
373 case kRiscvWord32AtomicPairSub:
374 case kRiscvWord32AtomicPairAnd:
375 case kRiscvWord32AtomicPairOr:
376 case kRiscvWord32AtomicPairXor:
377 case kRiscvWord32AtomicPairExchange:
378 case kRiscvWord32AtomicPairCompareExchange:
379#endif
380 case kRiscvModD:
381 case kRiscvModS:
382 case kRiscvRvvSt:
383 case kRiscvPush:
384 case kRiscvSb:
385 case kRiscvStoreDouble:
386 case kRiscvSh:
387 case kRiscvStackClaim:
388 case kRiscvStoreToStackSlot:
389 case kRiscvSw:
390 case kRiscvStoreFloat:
391 case kRiscvUStoreDouble:
392 case kRiscvUsh:
393 case kRiscvUsw:
394 case kRiscvUStoreFloat:
395 case kRiscvSync:
396 case kRiscvS128StoreLane:
397 return kHasSideEffect;
398
399#define CASE(Name) case k##Name:
401#undef CASE
402 // Already covered in architecture independent code.
403 UNREACHABLE();
404 }
405
406 UNREACHABLE();
407}
408
410 ADD = 1,
411
412 BRANCH = 4, // Estimated max.
413 RINT_S = 4, // Estimated.
414 RINT_D = 4, // Estimated.
415
416 // TODO(RISCV): remove MULT instructions (MIPS legacy).
417 MUL = 4,
418 MULW = 4,
419 MULH = 4,
420 MULHS = 4,
421 MULHU = 4,
422
423 DIVW = 50, // Min:11 Max:50
424 DIV = 50,
425 DIVU = 50,
426 DIVUW = 50,
427
430 ABS_S = FSGNJ_S,
431 ABS_D = FSGNJ_S,
432 NEG_S = FSGNJ_S,
433 NEG_D = FSGNJ_S,
434 ADD_S = 4,
435 ADD_D = 4,
436 SUB_S = 4,
437 SUB_D = 4,
438 MAX_S = 4, // Estimated.
439 MIN_S = 4,
440 MAX_D = 4, // Estimated.
441 MIN_D = 4,
442 C_cond_S = 4,
443 C_cond_D = 4,
444 MUL_S = 4,
445
446 MADD_S = 4,
447 MSUB_S = 4,
448 NMADD_S = 4,
449 NMSUB_S = 4,
450
451 CABS_cond_S = 4,
452 CABS_cond_D = 4,
453
454 CVT_D_S = 4,
455 CVT_PS_PW = 4,
456
457 CVT_S_W = 4,
458 CVT_S_L = 4,
459 CVT_D_W = 4,
460 CVT_D_L = 4,
461
462 CVT_S_D = 4,
463
464 CVT_W_S = 4,
465 CVT_W_D = 4,
466 CVT_L_S = 4,
467 CVT_L_D = 4,
468
469 CEIL_W_S = 4,
470 CEIL_W_D = 4,
471 CEIL_L_S = 4,
472 CEIL_L_D = 4,
473
474 FLOOR_W_S = 4,
475 FLOOR_W_D = 4,
476 FLOOR_L_S = 4,
477 FLOOR_L_D = 4,
478
479 ROUND_W_S = 4,
480 ROUND_W_D = 4,
481 ROUND_L_S = 4,
482 ROUND_L_D = 4,
483
484 TRUNC_W_S = 4,
485 TRUNC_W_D = 4,
486 TRUNC_L_S = 4,
487 TRUNC_L_D = 4,
488
489 MOV_S = 4,
490 MOV_D = 4,
491
492 MOVF_S = 4,
493 MOVF_D = 4,
494
495 MOVN_S = 4,
496 MOVN_D = 4,
497
498 MOVT_S = 4,
499 MOVT_D = 4,
500
501 MOVZ_S = 4,
502 MOVZ_D = 4,
503
504 MUL_D = 5,
505 MADD_D = 5,
506 MSUB_D = 5,
507 NMADD_D = 5,
508 NMSUB_D = 5,
509
510 RECIP_S = 13,
511 RECIP_D = 26,
512
513 RSQRT_S = 17,
514 RSQRT_D = 36,
515
516 DIV_S = 17,
517 SQRT_S = 17,
518
519 DIV_D = 32,
520 SQRT_D = 32,
521
527
535};
536
538 return 1;
539 // #if V8_TARGET_ARCH_RISCV32
540 // return 2; //lui+aii Estimated max.
541 // #elif V8_TARGET_ARCH_RISCV64
542 // return 4;
543 // #endif
544}
545
546inline int Add64Latency(bool is_operand_register = true) {
547 int latency = Latency::ADD;
548 if (!is_operand_register) {
549 latency += LoadConstantLatency();
550 }
551 return latency;
552}
553
554int Sub64Latency(bool is_operand_register = true) {
555 return Add64Latency(is_operand_register);
556}
557
558int ShiftLatency(bool is_operand_register = true) {
559 return Add64Latency(is_operand_register);
560}
561int AndLatency(bool is_operand_register = true) {
562 return Add64Latency(is_operand_register);
563}
564
565int OrLatency(bool is_operand_register = true) {
566 return Add64Latency(is_operand_register);
567}
568
569int NorLatency(bool is_operand_register = true) {
570 if (is_operand_register) {
571 return 1;
572 } else {
573 return 1 + LoadConstantLatency(); // Estimated max.
574 }
575}
576
577int XorLatency(bool is_operand_register = true) {
578 return Add64Latency(is_operand_register);
579}
580
581int Mul32Latency(bool is_operand_register = true) {
582 if (is_operand_register) {
583 return Latency::MULW;
584 } else {
585 return Latency::MULW + 1;
586 }
587}
588
589int Mul64Latency(bool is_operand_register = true) {
590 int latency = Latency::MUL;
591 if (!is_operand_register) {
592 latency += LoadConstantLatency();
593 }
594 return latency;
595}
596
597int Mulh32Latency(bool is_operand_register = true) {
598 int latency = Latency::MULH + ShiftLatency(true);
599 if (!is_operand_register) {
600 latency += LoadConstantLatency();
601 }
602 return latency;
603}
604
605int Mulhu32Latency(bool is_operand_register = true) {
606 int latency = Latency::MULHU + ShiftLatency(true) * 2;
607 if (!is_operand_register) {
608 latency += LoadConstantLatency();
609 } else {
610 latency += 1;
611 }
612 return latency;
613}
614
615int Mulh64Latency(bool is_operand_register = true) {
616 int latency = Latency::MULH;
617 if (!is_operand_register) {
618 latency += LoadConstantLatency();
619 }
620 return latency;
621}
622
623int Div32Latency(bool is_operand_register = true) {
624 if (is_operand_register) {
625 return Latency::DIVW;
626 } else {
627 return Latency::DIVW + 1;
628 }
629}
630
631int Divu32Latency(bool is_operand_register = true) {
632 if (is_operand_register) {
633 return Latency::DIVUW;
634 } else {
635 return Latency::DIVUW + LoadConstantLatency();
636 }
637}
638
639int Div64Latency(bool is_operand_register = true) {
640 int latency = Latency::DIV;
641 if (!is_operand_register) {
642 latency += LoadConstantLatency();
643 }
644 return latency;
645}
646
647int Divu64Latency(bool is_operand_register = true) {
648 int latency = Latency::DIVU;
649 if (!is_operand_register) {
650 latency += LoadConstantLatency();
651 }
652 return latency;
653}
654
655int Mod32Latency(bool is_operand_register = true) {
656 int latency = Latency::DIVW;
657 if (!is_operand_register) {
658 latency += LoadConstantLatency();
659 }
660 return latency;
661}
662
663int Modu32Latency(bool is_operand_register = true) {
664 int latency = Latency::DIVUW;
665 if (!is_operand_register) {
666 latency += LoadConstantLatency();
667 }
668 return latency;
669}
670
671int Mod64Latency(bool is_operand_register = true) {
672 int latency = Latency::DIV;
673 if (!is_operand_register) {
674 latency += LoadConstantLatency();
675 }
676 return latency;
677}
678
679int Modu64Latency(bool is_operand_register = true) {
680 int latency = Latency::DIV;
681 if (!is_operand_register) {
682 latency += LoadConstantLatency();
683 }
684 return latency;
685}
686
687int MovzLatency() { return 1; }
688
689int MovnLatency() { return 1; }
690
691int CallLatency() {
692 // Estimated.
693 return Add64Latency(false) + Latency::BRANCH + 5;
694}
695
696int JumpLatency() {
697 // Estimated max.
698 return 1 + Add64Latency() + Latency::BRANCH + 2;
699}
700
701int SmiUntagLatency() { return 1; }
702
704 // Estimated max.
705 return 2 * (Add64Latency() + 1 + Add64Latency(false)) + 2 + Latency::BRANCH +
706 Latency::BRANCH + 2 * Sub64Latency(false) + 2 + Latency::BRANCH + 1;
707}
708
710 return 1 + Latency::BRANCH + 1 + SmiUntagLatency() +
712}
713
714int AssertLatency() { return 1; }
715
717 int frame_alignment = MacroAssembler::ActivationFrameAlignment();
718 if (frame_alignment > kSystemPointerSize) {
719 return 1 + Sub64Latency(false) + AndLatency(false) + 1;
720 } else {
721 return Sub64Latency(false);
722 }
723}
724
726 return 3; // Estimated max.
727}
728
730
731int UlhuLatency() {
733}
734
735int UlwLatency() {
736 // Estimated max.
737 return AdjustBaseAndOffsetLatency() + 3;
738}
739
740int UlwuLatency() { return UlwLatency() + 1; }
741
742int UldLatency() {
743 // Estimated max.
744 return AdjustBaseAndOffsetLatency() + 3;
745}
746
747int ULoadFloatLatency() { return UlwLatency() + Latency::MOVT_FREG; }
748
749int ULoadDoubleLatency() { return UldLatency() + Latency::MOVT_DREG; }
750
751int UshLatency() {
752 // Estimated max.
754}
755
756int UswLatency() { return AdjustBaseAndOffsetLatency() + 2; }
757
758int UsdLatency() { return AdjustBaseAndOffsetLatency() + 2; }
759
760int UStoreFloatLatency() { return Latency::MOVF_FREG + UswLatency(); }
761
762int UStoreDoubleLatency() { return Latency::MOVF_HIGH_DREG + UsdLatency(); }
763
765 return AdjustBaseAndOffsetLatency() + Latency::LOAD_FLOAT;
766}
767
769 return AdjustBaseAndOffsetLatency() + Latency::STORE_FLOAT;
770}
771
773 return AdjustBaseAndOffsetLatency() + Latency::STORE_DOUBLE;
774}
775
777 return AdjustBaseAndOffsetLatency() + Latency::LOAD_DOUBLE;
778}
779
780int MultiPushLatency() {
781 int latency = Sub64Latency(false);
782 for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
783 latency++;
784 }
785 return latency;
786}
787
789 int latency = Sub64Latency(false);
790 for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
791 latency += StoreDoubleLatency();
792 }
793 return latency;
794}
795
797 int latency = MultiPushLatency();
798 if (fp_mode == SaveFPRegsMode::kSave) {
799 latency += MultiPushFPULatency();
800 }
801 return latency;
802}
803
804int MultiPopLatency() {
805 int latency = Add64Latency(false);
806 for (int16_t i = 0; i < kNumRegisters; i++) {
807 latency++;
808 }
809 return latency;
810}
811
812int MultiPopFPULatency() {
813 int latency = Add64Latency(false);
814 for (int16_t i = 0; i < kNumRegisters; i++) {
815 latency += LoadDoubleLatency();
816 }
817 return latency;
818}
819
821 int latency = MultiPopLatency();
822 if (fp_mode == SaveFPRegsMode::kSave) {
823 latency += MultiPopFPULatency();
824 }
825 return latency;
826}
827
829 // Estimated.
830 int latency = AndLatency(false) + Latency::BRANCH + 2 + CallLatency();
832 latency++;
833 } else {
834 latency += Add64Latency(false);
835 }
836 return latency;
837}
838
840
842 // Estimated max.
843 return Latency::BRANCH;
844}
845
847 int latency = 6;
848 latency += 2;
849 return latency;
850}
851
853 return Latency::BRANCH + GenerateSwitchTableLatency();
854}
855
856int DropAndRetLatency() {
857 // Estimated max.
858 return Add64Latency(false) + JumpLatency();
859}
860
862 // Estimated max.
863 return Add64Latency(false) + MultiPopLatency() + MultiPopFPULatency() +
864 Latency::BRANCH + Add64Latency() + 1 + DropAndRetLatency();
865}
866
868 return 2 + Latency::TRUNC_W_D + Latency::MOVF_FREG + 2 + AndLatency(false) +
869 Latency::BRANCH;
870}
871
872int CallStubDelayedLatency() { return 1 + CallLatency(); }
873
875 // TODO(riscv): This no longer reflects how TruncateDoubleToI is called.
876 return TryInlineTruncateDoubleToILatency() + 1 + Sub64Latency(false) +
878 1;
879}
880
882 return AndLatency(false) + AlignedMemoryLatency() + AndLatency(false) +
883 Latency::BRANCH;
884}
885
886int SltuLatency(bool is_operand_register = true) {
887 if (is_operand_register) {
888 return 1;
889 } else {
890 return 2; // Estimated max.
891 }
892}
893
895 return SltuLatency() + 2; // Estimated max.
896}
897
899
900int MoveLatency() { return 1; }
901
902int MovToFloatParametersLatency() { return 2 * MoveLatency(); }
903
904int MovFromFloatResultLatency() { return MoveLatency(); }
905
907 // Estimated max.
908 return 6;
909}
910
912 // Estimated max.
913 return 6;
914}
915
917 // Estimated max.
918 return Mul32Latency() + Mulh32Latency() + 2;
919}
920
922 // Estimated max.
923 return Mul64Latency() + Mulh64Latency() + 2;
924}
925
926// TODO(RISCV): This is incorrect for RISC-V.
928 if (CpuFeatures::IsSupported(ZBB)) return 1;
929 return 12;
930}
931
932int CompareFLatency() { return Latency::C_cond_S; }
933
934int CompareF32Latency() { return CompareFLatency(); }
935
936int CompareF64Latency() { return CompareFLatency(); }
937
938int CompareIsNanFLatency() { return CompareFLatency(); }
939
941
943
944int NegsLatency() {
945 // Estimated.
946 return CompareIsNanF32Latency() + 2 * Latency::BRANCH + Latency::NEG_S +
947 Latency::MOVF_FREG + 1 + XorLatency() + Latency::MOVT_FREG;
948}
949
950int NegdLatency() {
951 // Estimated.
952 return CompareIsNanF64Latency() + 2 * Latency::BRANCH + Latency::NEG_D +
953 Latency::MOVF_HIGH_DREG + 1 + XorLatency() + Latency::MOVT_DREG;
954}
955
956#if V8_TARGET_ARCH_RISCV64
958 // For ceil_l_d, floor_l_d, round_l_d, trunc_l_d latency is 4.
959 return Latency::MOVF_HIGH_DREG + 1 + Latency::BRANCH + Latency::MOV_D + 4 +
960 Latency::MOVF_HIGH_DREG + Latency::BRANCH + Latency::CVT_D_L + 2 +
961 Latency::MOVT_HIGH_FREG;
962}
963#endif
965 // For ceil_w_s, floor_w_s, round_w_s, trunc_w_s latency is 4.
966 return Latency::MOVF_FREG + 1 + Latency::BRANCH + Latency::MOV_S + 4 +
967 Latency::MOVF_FREG + Latency::BRANCH + Latency::CVT_S_W + 2 +
968 Latency::MOVT_FREG;
969}
970
971int Float32MaxLatency() {
972 // Estimated max.
973 int latency = CompareIsNanF32Latency() + Latency::BRANCH;
974 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
975 Latency::MOVF_FREG + 1 + Latency::MOV_S;
976}
977
978int Float64MaxLatency() {
979 // Estimated max.
980 int latency = CompareIsNanF64Latency() + Latency::BRANCH;
981 return latency + 5 * Latency::BRANCH + 2 * CompareF64Latency() +
982 Latency::MOVF_HIGH_DREG + Latency::MOV_D;
983}
984
985int Float32MinLatency() {
986 // Estimated max.
987 int latency = CompareIsNanF32Latency() + Latency::BRANCH;
988 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
989 Latency::MOVF_FREG + 1 + Latency::MOV_S;
990}
991
992int Float64MinLatency() {
993 // Estimated max.
994 int latency = CompareIsNanF64Latency() + Latency::BRANCH;
995 return latency + 5 * Latency::BRANCH + 2 * CompareF32Latency() +
996 Latency::MOVF_HIGH_DREG + Latency::MOV_D;
997}
998
999int TruncLSLatency(bool load_status) {
1000 int latency = Latency::TRUNC_L_S + Latency::MOVF_HIGH_DREG;
1001 if (load_status) {
1002 latency += SltuLatency() + 7;
1003 }
1004 return latency;
1005}
1006
1007int TruncLDLatency(bool load_status) {
1008 int latency = Latency::TRUNC_L_D + Latency::MOVF_HIGH_DREG;
1009 if (load_status) {
1010 latency += SltuLatency() + 7;
1011 }
1012 return latency;
1013}
1014
1015int TruncUlSLatency() {
1016 // Estimated max.
1017 return 2 * CompareF32Latency() + CompareIsNanF32Latency() +
1018 4 * Latency::BRANCH + Latency::SUB_S + 2 * Latency::TRUNC_L_S +
1019 3 * Latency::MOVF_HIGH_DREG + OrLatency() + Latency::MOVT_FREG +
1020 Latency::MOV_S + SltuLatency() + 4;
1021}
1022
1023int TruncUlDLatency() {
1024 // Estimated max.
1025 return 2 * CompareF64Latency() + CompareIsNanF64Latency() +
1026 4 * Latency::BRANCH + Latency::SUB_D + 2 * Latency::TRUNC_L_D +
1027 3 * Latency::MOVF_HIGH_DREG + OrLatency() + Latency::MOVT_DREG +
1028 Latency::MOV_D + SltuLatency() + 4;
1029}
1030
1031int PushLatency() { return Add64Latency() + AlignedMemoryLatency(); }
1032
1033int ByteSwapSignedLatency() { return 2; }
1034
1035int LlLatency(int offset) {
1036 bool is_one_instruction = is_int12(offset);
1037 if (is_one_instruction) {
1038 return 1;
1039 } else {
1040 return 3;
1041 }
1042}
1043
1044int ExtractBitsLatency(bool sign_extend, int size) {
1045 int latency = 2;
1046 if (sign_extend) {
1047 switch (size) {
1048 case 8:
1049 case 16:
1050 case 32:
1051 latency += 1;
1052 break;
1053 default:
1054 UNREACHABLE();
1055 }
1056 }
1057 return latency;
1058}
1059
1060int InsertBitsLatency() { return 2 + Sub64Latency(false) + 2; }
1061
1062int ScLatency(int offset) { return 3; }
1063
1064int Word32AtomicExchangeLatency(bool sign_extend, int size) {
1065 return Add64Latency(false) + 1 + Sub64Latency() + 2 + LlLatency(0) +
1066 ExtractBitsLatency(sign_extend, size) + InsertBitsLatency() +
1067 ScLatency(0) + BranchShortLatency() + 1;
1068}
1069
1070int Word32AtomicCompareExchangeLatency(bool sign_extend, int size) {
1071 return 2 + Sub64Latency() + 2 + LlLatency(0) +
1072 ExtractBitsLatency(sign_extend, size) + InsertBitsLatency() +
1073 ScLatency(0) + BranchShortLatency() + 1;
1074}
1075
1076int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
1077 // TODO(RISCV): Verify these latencies for RISC-V (currently using MIPS
1078 // numbers).
1079 switch (instr->arch_opcode()) {
1080 case kArchCallCodeObject:
1081 case kArchCallWasmFunction:
1082 return CallLatency();
1083 case kArchTailCallCodeObject:
1084 case kArchTailCallWasm:
1085 case kArchTailCallAddress:
1086 return JumpLatency();
1087 case kArchCallJSFunction: {
1088 int latency = 0;
1089 if (v8_flags.debug_code) {
1090 latency = 1 + AssertLatency();
1091 }
1092 return latency + 1 + Add64Latency(false) + CallLatency();
1093 }
1094 case kArchPrepareCallCFunction:
1096 case kArchSaveCallerRegisters: {
1097 auto fp_mode =
1098 static_cast<SaveFPRegsMode>(MiscField::decode(instr->opcode()));
1099 return PushCallerSavedLatency(fp_mode);
1100 }
1101 case kArchRestoreCallerRegisters: {
1102 auto fp_mode =
1103 static_cast<SaveFPRegsMode>(MiscField::decode(instr->opcode()));
1104 return PopCallerSavedLatency(fp_mode);
1105 }
1106 case kArchPrepareTailCall:
1107 return 2;
1108 case kArchCallCFunction:
1109 return CallCFunctionLatency();
1110 case kArchJmp:
1111 return AssembleArchJumpLatency();
1112 case kArchTableSwitch:
1114 case kArchAbortCSADcheck:
1115 return CallLatency() + 1;
1116 case kArchDebugBreak:
1117 return 1;
1118 case kArchComment:
1119 case kArchNop:
1120 case kArchThrowTerminator:
1121 case kArchDeoptimize:
1122 return 0;
1123 case kArchRet:
1124 return AssemblerReturnLatency();
1125 case kArchFramePointer:
1126 return 1;
1127 case kArchParentFramePointer:
1128 // Estimated max.
1129 return AlignedMemoryLatency();
1130 case kArchTruncateDoubleToI:
1132 case kArchStoreWithWriteBarrier:
1133 return Add64Latency() + 1 + CheckPageFlagLatency();
1134 case kArchStackSlot:
1135 // Estimated max.
1136 return Add64Latency(false) + AndLatency(false) + AssertLatency() +
1137 Add64Latency(false) + AndLatency(false) + BranchShortLatency() +
1138 1 + Sub64Latency() + Add64Latency();
1139 case kIeee754Float64Acos:
1140 case kIeee754Float64Acosh:
1141 case kIeee754Float64Asin:
1142 case kIeee754Float64Asinh:
1143 case kIeee754Float64Atan:
1144 case kIeee754Float64Atanh:
1145 case kIeee754Float64Atan2:
1146 case kIeee754Float64Cos:
1147 case kIeee754Float64Cosh:
1148 case kIeee754Float64Cbrt:
1149 case kIeee754Float64Exp:
1150 case kIeee754Float64Expm1:
1151 case kIeee754Float64Log:
1152 case kIeee754Float64Log1p:
1153 case kIeee754Float64Log10:
1154 case kIeee754Float64Log2:
1155 case kIeee754Float64Pow:
1156 case kIeee754Float64Sin:
1157 case kIeee754Float64Sinh:
1158 case kIeee754Float64Tan:
1159 case kIeee754Float64Tanh:
1162#if V8_TARGET_ARCH_RISCV64
1163 case kRiscvAdd32:
1164 case kRiscvAdd64:
1165 return Add64Latency(instr->InputAt(1)->IsRegister());
1166 case kRiscvAddOvf64:
1167 return AddOverflow64Latency();
1168 case kRiscvSub32:
1169 case kRiscvSub64:
1170 return Sub64Latency(instr->InputAt(1)->IsRegister());
1171 case kRiscvSubOvf64:
1172 return SubOverflow64Latency();
1173 case kRiscvMulHigh64:
1174 return Mulh64Latency();
1175 case kRiscvMul64:
1176 return Mul64Latency();
1177 case kRiscvMulOvf64:
1178 return MulOverflow64Latency();
1179 case kRiscvDiv64: {
1180 int latency = Div64Latency();
1181 return latency + MovzLatency();
1182 }
1183 case kRiscvDivU64: {
1184 int latency = Divu64Latency();
1185 return latency + MovzLatency();
1186 }
1187 case kRiscvMod64:
1188 return Mod64Latency();
1189 case kRiscvModU64:
1190 return Modu64Latency();
1191#elif V8_TARGET_ARCH_RISCV32
1192 case kRiscvAdd32:
1193 return Add64Latency(instr->InputAt(1)->IsRegister());
1194 case kRiscvAddOvf:
1195 return AddOverflow64Latency();
1196 case kRiscvSub32:
1197 return Sub64Latency(instr->InputAt(1)->IsRegister());
1198 case kRiscvSubOvf:
1199 return SubOverflow64Latency();
1200#endif
1201 case kRiscvMul32:
1202 return Mul32Latency();
1203 case kRiscvMulOvf32:
1204 return MulOverflow32Latency();
1205 case kRiscvMulHigh32:
1206 return Mulh32Latency();
1207 case kRiscvMulHighU32:
1208 return Mulhu32Latency();
1209 case kRiscvDiv32: {
1210 int latency = Div32Latency(instr->InputAt(1)->IsRegister());
1211 return latency + MovzLatency();
1212 }
1213 case kRiscvDivU32: {
1214 int latency = Divu32Latency(instr->InputAt(1)->IsRegister());
1215 return latency + MovzLatency();
1216 }
1217 case kRiscvMod32:
1218 return Mod32Latency();
1219 case kRiscvModU32:
1220 return Modu32Latency();
1221 case kRiscvAnd:
1222 return AndLatency(instr->InputAt(1)->IsRegister());
1223 case kRiscvAnd32: {
1224 bool is_operand_register = instr->InputAt(1)->IsRegister();
1225 int latency = AndLatency(is_operand_register);
1226 if (is_operand_register) {
1227 return latency + 2;
1228 } else {
1229 return latency + 1;
1230 }
1231 }
1232 case kRiscvOr:
1233 return OrLatency(instr->InputAt(1)->IsRegister());
1234 case kRiscvOr32: {
1235 bool is_operand_register = instr->InputAt(1)->IsRegister();
1236 int latency = OrLatency(is_operand_register);
1237 if (is_operand_register) {
1238 return latency + 2;
1239 } else {
1240 return latency + 1;
1241 }
1242 }
1243 case kRiscvXor:
1244 return XorLatency(instr->InputAt(1)->IsRegister());
1245 case kRiscvXor32: {
1246 bool is_operand_register = instr->InputAt(1)->IsRegister();
1247 int latency = XorLatency(is_operand_register);
1248 if (is_operand_register) {
1249 return latency + 2;
1250 } else {
1251 return latency + 1;
1252 }
1253 }
1254 case kRiscvClz32:
1255#if V8_TARGET_ARCH_RISCV64
1256 case kRiscvClz64:
1257#endif
1258 return Clz64Latency();
1259 case kRiscvShl32:
1260 return 1;
1261 case kRiscvShr32:
1262 case kRiscvSar32:
1263#if V8_TARGET_ARCH_RISCV64
1264 case kRiscvZeroExtendWord:
1265#endif
1266 return 2;
1267#if V8_TARGET_ARCH_RISCV64
1268 case kRiscvSignExtendWord:
1269 case kRiscvShl64:
1270 case kRiscvShr64:
1271 case kRiscvSar64:
1272 case kRiscvRor64:
1273 case kRiscvTst64:
1274#endif
1275 case kRiscvTst32:
1276 return AndLatency(instr->InputAt(0)->IsRegister());
1277 case kRiscvRor32:
1278 return 1;
1279 case kRiscvMov:
1280 return 1;
1281 case kRiscvCmpS:
1282 return MoveLatency() + CompareF32Latency();
1283 case kRiscvAddS:
1284 return Latency::ADD_S;
1285 case kRiscvSubS:
1286 return Latency::SUB_S;
1287 case kRiscvMulS:
1288 return Latency::MUL_S;
1289 case kRiscvDivS:
1290 return Latency::DIV_S;
1291 case kRiscvModS:
1294 case kRiscvAbsS:
1295 return Latency::ABS_S;
1296 case kRiscvNegS:
1297 return NegdLatency();
1298 case kRiscvSqrtS:
1299 return Latency::SQRT_S;
1300 case kRiscvMaxS:
1301 return Latency::MAX_S;
1302 case kRiscvMinS:
1303 return Latency::MIN_S;
1304 case kRiscvCmpD:
1305 return MoveLatency() + CompareF64Latency();
1306 case kRiscvAddD:
1307 return Latency::ADD_D;
1308 case kRiscvSubD:
1309 return Latency::SUB_D;
1310 case kRiscvMulD:
1311 return Latency::MUL_D;
1312 case kRiscvDivD:
1313 return Latency::DIV_D;
1314 case kRiscvModD:
1317 case kRiscvAbsD:
1318 return Latency::ABS_D;
1319 case kRiscvNegD:
1320 return NegdLatency();
1321 case kRiscvSqrtD:
1322 return Latency::SQRT_D;
1323 case kRiscvMaxD:
1324 return Latency::MAX_D;
1325 case kRiscvMinD:
1326 return Latency::MIN_D;
1327#if V8_TARGET_ARCH_RISCV64
1328 case kRiscvFloat64RoundDown:
1329 case kRiscvFloat64RoundTruncate:
1330 case kRiscvFloat64RoundUp:
1331 case kRiscvFloat64RoundTiesEven:
1332 return Float64RoundLatency();
1333#endif
1334 case kRiscvFloat32RoundDown:
1335 case kRiscvFloat32RoundTruncate:
1336 case kRiscvFloat32RoundUp:
1337 case kRiscvFloat32RoundTiesEven:
1338 return Float32RoundLatency();
1339 case kRiscvFloat32Max:
1340 return Float32MaxLatency();
1341 case kRiscvFloat64Max:
1342 return Float64MaxLatency();
1343 case kRiscvFloat32Min:
1344 return Float32MinLatency();
1345 case kRiscvFloat64Min:
1346 return Float64MinLatency();
1347 case kRiscvFloat64SilenceNaN:
1348 return Latency::SUB_D;
1349 case kRiscvCvtSD:
1350 return Latency::CVT_S_D;
1351 case kRiscvCvtDS:
1352 return Latency::CVT_D_S;
1353 case kRiscvCvtDW:
1354 return Latency::MOVT_FREG + Latency::CVT_D_W;
1355 case kRiscvCvtSW:
1356 return Latency::MOVT_FREG + Latency::CVT_S_W;
1357 case kRiscvCvtSUw:
1358 return 1 + Latency::MOVT_DREG + Latency::CVT_S_L;
1359#if V8_TARGET_ARCH_RISCV64
1360 case kRiscvCvtSL:
1361 return Latency::MOVT_DREG + Latency::CVT_S_L;
1362 case kRiscvCvtDL:
1363 return Latency::MOVT_DREG + Latency::CVT_D_L;
1364 case kRiscvCvtDUl:
1365 return 2 * Latency::BRANCH + 3 + 2 * Latency::MOVT_DREG +
1366 2 * Latency::CVT_D_L + Latency::ADD_D;
1367 case kRiscvCvtSUl:
1368 return 2 * Latency::BRANCH + 3 + 2 * Latency::MOVT_DREG +
1369 2 * Latency::CVT_S_L + Latency::ADD_S;
1370#endif
1371 case kRiscvCvtDUw:
1372 return 1 + Latency::MOVT_DREG + Latency::CVT_D_L;
1373 case kRiscvFloorWD:
1374 return Latency::FLOOR_W_D + Latency::MOVF_FREG;
1375 case kRiscvCeilWD:
1376 return Latency::CEIL_W_D + Latency::MOVF_FREG;
1377 case kRiscvRoundWD:
1378 return Latency::ROUND_W_D + Latency::MOVF_FREG;
1379 case kRiscvTruncWD:
1380 return Latency::TRUNC_W_D + Latency::MOVF_FREG;
1381 case kRiscvFloorWS:
1382 return Latency::FLOOR_W_S + Latency::MOVF_FREG;
1383 case kRiscvCeilWS:
1384 return Latency::CEIL_W_S + Latency::MOVF_FREG;
1385 case kRiscvRoundWS:
1386 return Latency::ROUND_W_S + Latency::MOVF_FREG;
1387 case kRiscvTruncWS:
1388 return Latency::TRUNC_W_S + Latency::MOVF_FREG + 2 + MovnLatency();
1389#if V8_TARGET_ARCH_RISCV64
1390 case kRiscvTruncLS:
1391 return TruncLSLatency(instr->OutputCount() > 1);
1392 case kRiscvTruncLD:
1393 return TruncLDLatency(instr->OutputCount() > 1);
1394 case kRiscvTruncUlS:
1395 return TruncUlSLatency();
1396 case kRiscvTruncUlD:
1397 return TruncUlDLatency();
1398 case kRiscvBitcastDL:
1399 return Latency::MOVF_HIGH_DREG;
1400 case kRiscvBitcastLD:
1401 return Latency::MOVT_DREG;
1402#endif
1403 case kRiscvTruncUwD:
1404 // Estimated max.
1405 return CompareF64Latency() + 2 * Latency::BRANCH +
1406 2 * Latency::TRUNC_W_D + Latency::SUB_D + OrLatency() +
1407 Latency::MOVT_FREG + Latency::MOVF_FREG + Latency::MOVT_HIGH_FREG +
1408 1;
1409 case kRiscvTruncUwS:
1410 // Estimated max.
1411 return CompareF32Latency() + 2 * Latency::BRANCH +
1412 2 * Latency::TRUNC_W_S + Latency::SUB_S + OrLatency() +
1413 Latency::MOVT_FREG + 2 * Latency::MOVF_FREG + 2 + MovzLatency();
1414 case kRiscvFloat64ExtractLowWord32:
1415 return Latency::MOVF_FREG;
1416 case kRiscvFloat64InsertLowWord32:
1417 return Latency::MOVF_HIGH_FREG + Latency::MOVT_FREG +
1418 Latency::MOVT_HIGH_FREG;
1419 case kRiscvFloat64ExtractHighWord32:
1420 return Latency::MOVF_HIGH_FREG;
1421 case kRiscvFloat64InsertHighWord32:
1422 return Latency::MOVT_HIGH_FREG;
1423 case kRiscvSignExtendByte:
1424 case kRiscvSignExtendShort:
1425 return 1;
1426 case kRiscvLbu:
1427 case kRiscvLb:
1428 case kRiscvLhu:
1429 case kRiscvLh:
1430 case kRiscvLw:
1431#if V8_TARGET_ARCH_RISCV64
1432 case kRiscvLd:
1433 case kRiscvSd:
1434 case kRiscvLwu:
1435#endif
1436 case kRiscvSb:
1437 case kRiscvSh:
1438 case kRiscvSw:
1439 return AlignedMemoryLatency();
1440 case kRiscvLoadFloat:
1441 return ULoadFloatLatency();
1442 case kRiscvLoadDouble:
1443 return LoadDoubleLatency();
1444 case kRiscvStoreFloat:
1445 return StoreFloatLatency();
1446 case kRiscvStoreDouble:
1447 return StoreDoubleLatency();
1448 case kRiscvUlhu:
1449 case kRiscvUlh:
1450 return UlhuLatency();
1451#if V8_TARGET_ARCH_RISCV64
1452 case kRiscvUlwu:
1453 return UlwuLatency();
1454 case kRiscvUld:
1455 return UldLatency();
1456 case kRiscvUsd:
1457 return UsdLatency();
1458#endif
1459 case kRiscvUlw:
1460 return UlwLatency();
1461 case kRiscvULoadFloat:
1462 return ULoadFloatLatency();
1463 case kRiscvULoadDouble:
1464 return ULoadDoubleLatency();
1465 case kRiscvUsh:
1466 return UshLatency();
1467 case kRiscvUsw:
1468 return UswLatency();
1469 case kRiscvUStoreFloat:
1470 return UStoreFloatLatency();
1471 case kRiscvUStoreDouble:
1472 return UStoreDoubleLatency();
1473 case kRiscvPush: {
1474 int latency = 0;
1475 if (instr->InputAt(0)->IsFPRegister()) {
1476 latency = StoreDoubleLatency() + Sub64Latency(false);
1477 } else {
1478 latency = PushLatency();
1479 }
1480 return latency;
1481 }
1482 case kRiscvPeek: {
1483 int latency = 0;
1484 if (instr->OutputAt(0)->IsFPRegister()) {
1485 auto op = LocationOperand::cast(instr->OutputAt(0));
1486 switch (op->representation()) {
1488 latency = LoadDoubleLatency();
1489 break;
1491 latency = Latency::LOAD_FLOAT;
1492 break;
1493 default:
1494 UNREACHABLE();
1495 }
1496 } else {
1497 latency = AlignedMemoryLatency();
1498 }
1499 return latency;
1500 }
1501 case kRiscvStackClaim:
1502 return Sub64Latency(false);
1503 case kRiscvStoreToStackSlot: {
1504 int latency = 0;
1505 if (instr->InputAt(0)->IsFPRegister()) {
1506 if (instr->InputAt(0)->IsSimd128Register()) {
1507 latency = 1; // Estimated value.
1508 } else {
1509 latency = StoreDoubleLatency();
1510 }
1511 } else {
1512 latency = AlignedMemoryLatency();
1513 }
1514 return latency;
1515 }
1516 case kAtomicLoadInt8:
1517 case kAtomicLoadUint8:
1518 case kAtomicLoadInt16:
1519 case kAtomicLoadUint16:
1520 case kAtomicLoadWord32:
1521 return 2;
1522 case kAtomicStoreWord8:
1523 case kAtomicStoreWord16:
1524 case kAtomicStoreWord32:
1525 return 3;
1526 case kAtomicExchangeInt8:
1527 return Word32AtomicExchangeLatency(true, 8);
1528 case kAtomicExchangeUint8:
1529 return Word32AtomicExchangeLatency(false, 8);
1530 case kAtomicExchangeInt16:
1531 return Word32AtomicExchangeLatency(true, 16);
1532 case kAtomicExchangeUint16:
1533 return Word32AtomicExchangeLatency(false, 16);
1534 case kAtomicExchangeWord32:
1535 return 2 + LlLatency(0) + 1 + ScLatency(0) + BranchShortLatency() + 1;
1536 case kAtomicCompareExchangeInt8:
1537 return Word32AtomicCompareExchangeLatency(true, 8);
1538 case kAtomicCompareExchangeUint8:
1539 return Word32AtomicCompareExchangeLatency(false, 8);
1540 case kAtomicCompareExchangeInt16:
1541 return Word32AtomicCompareExchangeLatency(true, 16);
1542 case kAtomicCompareExchangeUint16:
1543 return Word32AtomicCompareExchangeLatency(false, 16);
1544 case kAtomicCompareExchangeWord32:
1545 return 3 + LlLatency(0) + BranchShortLatency() + 1 + ScLatency(0) +
1546 BranchShortLatency() + 1;
1547 case kRiscvAssertEqual:
1548 return AssertLatency();
1549#ifdef V8_TARGET_ARCH_RISCV64
1550 case kRiscvLoadDecompressProtected:
1551 return 11;
1552#endif
1553 default:
1554 return 1;
1555 }
1556}
1557
1558} // namespace compiler
1559} // namespace internal
1560} // namespace v8
static constexpr T decode(U value)
Definition bit-field.h:66
static int ActivationFrameAlignment()
static bool IsSupported(CpuFeature f)
int GetTargetInstructionFlags(const Instruction *instr) const
static int GetInstructionLatency(const Instruction *instr)
static LocationOperand * cast(InstructionOperand *op)
#define COMMON_ARCH_OPCODE_LIST(V)
int32_t offset
Instruction * instr
int NorLatency(bool is_operand_register=true)
int Modu32Latency(bool is_operand_register=true)
int Divu64Latency(bool is_operand_register=true)
int Word32AtomicExchangeLatency(bool sign_extend, int size)
int ExtractBitsLatency(bool sign_extend, int size)
int Div32Latency(bool is_operand_register=true)
int Mul64Latency(bool is_operand_register=true)
int Div64Latency(bool is_operand_register=true)
int OrLatency(bool is_operand_register=true)
int PopCallerSavedLatency(SaveFPRegsMode fp_mode)
int Add64Latency(bool is_operand_register=true)
int XorLatency(bool is_operand_register=true)
int Mulhu32Latency(bool is_operand_register=true)
int Mulh64Latency(bool is_operand_register=true)
int Sub64Latency(bool is_operand_register=true)
int Modu64Latency(bool is_operand_register=true)
int Mod64Latency(bool is_operand_register=true)
int Mod32Latency(bool is_operand_register=true)
int AndLatency(bool is_operand_register=true)
int ShiftLatency(bool is_operand_register=true)
int Divu32Latency(bool is_operand_register=true)
int PushCallerSavedLatency(SaveFPRegsMode fp_mode)
int Word32AtomicCompareExchangeLatency(bool sign_extend, int size)
int SltuLatency(bool is_operand_register=true)
int Mulh32Latency(bool is_operand_register=true)
int Mul32Latency(bool is_operand_register=true)
constexpr int kSystemPointerSize
Definition globals.h:410
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr int kNumRegisters