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 8namespace v8 { 9namespace internal { 10namespace compiler { 11 12bool InstructionScheduler::SchedulerSupported() { return true; } 13 14int 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 396enum 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 527int ClzLatency() { 528 if (IsMipsArchVariant(kLoongson)) { 529 return (6 + 2 * Latency::BRANCH); 530 } else { 531 return 1; 532 } 533} 534 535int 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 547int AdduLatency(bool is_operand_register = true) { 548 if (is_operand_register) { 549 return 1; 550 } else { 551 return 2; // Estimated max. 552 } 553} 554 555int XorLatency(bool is_operand_register = true) { 556 return AdduLatency(is_operand_register); 557} 558 559int AndLatency(bool is_operand_register = true) { 560 return AdduLatency(is_operand_register); 561} 562 563int OrLatency(bool is_operand_register = true) { 564 return AdduLatency(is_operand_register); 565} 566 567int SubuLatency(bool is_operand_register = true) { 568 return AdduLatency(is_operand_register); 569} 570 571int 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 587int NorLatency(bool is_operand_register = true) { 588 if (is_operand_register) { 589 return 1; 590 } else { 591 return 2; 592 } 593} 594 595int InsLatency() { 596 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 597 return 1; 598 } else { 599 return SubuLatency(false) + 7; 600 } 601} 602 603int 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 617int 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 633int 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 655int ExtLatency() { 656 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 657 return 1; 658 } else { 659 // Estimated max. 660 return 2; 661 } 662} 663 664int LsaLatency() { 665 // Estimated max. 666 return AdduLatency() + 1; 667} 668 669int SltLatency(bool is_operand_register = true) { 670 if (is_operand_register) { 671 return 1; 672 } else { 673 return 2; // Estimated max. 674 } 675} 676 677int SltuLatency(bool is_operand_register = true) { 678 return SltLatency(is_operand_register); 679} 680 681int AddPairLatency() { return 3 * AdduLatency() + SltLatency(); } 682 683int SubPairLatency() { return SltuLatency() + 3 * SubuLatency(); } 684 685int 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 695int MulPairLatency() { 696 return MuluLatency() + 2 * MulLatency() + 2 * AdduLatency(); 697} 698 699int MaddSLatency() { 700 if (IsMipsArchVariant(kMips32r2)) { 701 return Latency::MADD_D; 702 } else { 703 return Latency::MUL_D + Latency::ADD_D; 704 } 705} 706 707int MaddDLatency() { 708 if (IsMipsArchVariant(kMips32r2)) { 709 return Latency::MADD_D; 710 } else { 711 return Latency::MUL_D + Latency::ADD_D; 712 } 713} 714 715int MsubSLatency() { 716 if (IsMipsArchVariant(kMips32r2)) { 717 return Latency::MSUB_S; 718 } else { 719 return Latency::MUL_S + Latency::SUB_S; 720 } 721} 722 723int MsubDLatency() { 724 if (IsMipsArchVariant(kMips32r2)) { 725 return Latency::MSUB_D; 726 } else { 727 return Latency::MUL_D + Latency::SUB_D; 728 } 729} 730 731int Mfhc1Latency() { 732 if (IsFp32Mode()) { 733 return Latency::MFC1; 734 } else { 735 return 1; 736 } 737} 738 739int Mthc1Latency() { 740 if (IsFp32Mode()) { 741 return Latency::MTC1; 742 } else { 743 return 1; 744 } 745} 746 747int 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 755int 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 765int 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 775int 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 785int CvtSUwLatency() { return CvtDUwLatency() + Latency::CVT_S_D; } 786 787int 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 795int FloorWDLatency() { return Floor_w_dLatency() + Latency::MFC1; } 796 797int 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 805int CeilWDLatency() { return Ceil_w_dLatency() + Latency::MFC1; } 806 807int 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 815int RoundWDLatency() { return Round_w_dLatency() + Latency::MFC1; } 816 817int 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 825int MovnLatency() { 826 if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) { 827 return Latency::BRANCH + 1; 828 } else { 829 return 1; 830 } 831} 832 833int 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 839int 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 845int MovzLatency() { 846 if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) { 847 return Latency::BRANCH + 1; 848 } else { 849 return 1; 850 } 851} 852 853int FmoveLowLatency() { 854 if (IsFp32Mode()) { 855 return Latency::MTC1; 856 } else { 857 return Latency::MFHC1 + Latency::MTC1 + Latency::MTHC1; 858 } 859} 860 861int SebLatency() { 862 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 863 return 1; 864 } else { 865 return 2; 866 } 867} 868 869int SehLatency() { 870 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 871 return 1; 872 } else { 873 return 2; 874 } 875} 876 877int UlhuLatency() { 878 if (IsMipsArchVariant(kMips32r6)) { 879 return 1; 880 } else { 881 return 4; 882 } 883} 884 885int UlhLatency() { 886 if (IsMipsArchVariant(kMips32r6)) { 887 return 1; 888 } else { 889 return 4; 890 } 891} 892 893int AdjustBaseAndOffsetLatency() { 894 return 3; // Estimated max. 895} 896 897int UshLatency() { 898 if (IsMipsArchVariant(kMips32r6)) { 899 return 1; 900 } else { 901 return AdjustBaseAndOffsetLatency() + 4; // Estimated max. 902 } 903} 904 905int UlwLatency() { 906 if (IsMipsArchVariant(kMips32r6)) { 907 return 1; 908 } else { 909 return AdjustBaseAndOffsetLatency() + 3; // Estimated max. 910 } 911} 912 913int UswLatency() { 914 if (IsMipsArchVariant(kMips32r6)) { 915 return 1; 916 } else { 917 return AdjustBaseAndOffsetLatency() + 2; 918 } 919} 920 921int Ulwc1Latency() { 922 if (IsMipsArchVariant(kMips32r6)) { 923 return Latency::LWC1; 924 } else { 925 return UlwLatency() + Latency::MTC1; 926 } 927} 928 929int Uswc1Latency() { 930 if (IsMipsArchVariant(kMips32r6)) { 931 return Latency::SWC1; 932 } else { 933 return Latency::MFC1 + UswLatency(); 934 } 935} 936 937int 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 946int Uldc1Latency() { 947 if (IsMipsArchVariant(kMips32r6)) { 948 return Ldc1Latency(); 949 } else { 950 return 2 * UlwLatency() + Latency::MTC1 + Mthc1Latency(); 951 } 952} 953 954int 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 963int Usdc1Latency() { 964 if (IsMipsArchVariant(kMips32r6)) { 965 return Sdc1Latency(); 966 } else { 967 return Latency::MFC1 + 2 * UswLatency() + Mfhc1Latency(); 968 } 969} 970 971int PushRegisterLatency() { return AdduLatency(false) + 1; } 972 973int 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 982int 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 992int 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 1011int NegLatency() { return 1; } 1012 1013int InsertBitsLatency() { 1014 return RorLatency() + InsLatency() + SubuLatency(false) + NegLatency() + 1015 RorLatency(); 1016} 1017 1018int 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 1028int BranchShortHelperR6Latency() { 1029 return 2; // Estimated max. 1030} 1031 1032int BranchShortHelperLatency() { 1033 return SltLatency() + 2; // Estimated max. 1034} 1035 1036int BranchShortLatency(BranchDelaySlot bdslot = PROTECT) { 1037 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) { 1038 return BranchShortHelperR6Latency(); 1039 } else { 1040 return BranchShortHelperLatency(); 1041 } 1042} 1043 1044int 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 1050int Word32AtomicCompareExchangeLatency(bool sign_extend, int size) { 1051 return AdduLatency() + 1 + SubuLatency() + 2 + LlLatency(0) + 1052 ExtractBitsLatency(size, sign_extend) + BranchShortLatency() + 1; 1053} 1054 1055int AddOverflowLatency() { 1056 return 6; // Estimated max. 1057} 1058 1059int SubOverflowLatency() { 1060 return 6; // Estimated max. 1061} 1062 1063int 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 1079int 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 1095int MulOverflowLatency() { 1096 return MulLatency() + 4; // Estimated max. 1097} 1098 1099int 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 1115int ModuLatency(bool is_operand_register = true) { 1116 return ModLatency(is_operand_register); 1117} 1118 1119int 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 1135int 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 1151int 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 1160int PopcntLatency() { 1161 return 4 * AndLatency() + SubuLatency() + 2 * AdduLatency() + MulLatency() + 1162 8; 1163} 1164 1165int CompareFLatency() { return Latency::C_cond_S; } 1166 1167int CompareIsNanFLatency() { return CompareFLatency(); } 1168 1169int CompareIsNanF32Latency() { return CompareIsNanFLatency(); } 1170 1171int 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 1181int CompareIsNanF64Latency() { return CompareIsNanFLatency(); } 1182 1183int 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 1193int CompareF32Latency() { return CompareFLatency(); } 1194 1195int Move_sLatency() { 1196 return Latency::MOV_S; // Estimated max. 1197} 1198 1199int 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 1210int CompareF64Latency() { return CompareF32Latency(); } 1211 1212int Move_dLatency() { 1213 return Latency::MOV_D; // Estimated max. 1214} 1215 1216int 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 1227int 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 1236int MovToFloatParametersLatency() { return 2 * MoveLatency(); } 1237 1238int CallLatency() { 1239 // Estimated. 1240 return AdduLatency(false) + Latency::BRANCH + 3; 1241} 1242 1243int 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 1254int CallCFunctionLatency() { return 1 + CallCFunctionHelperLatency(); } 1255 1256int MovFromFloatResultLatency() { return MoveLatency(); } 1257 1258int Float32MinLatency() { 1259 // Estimated max. 1260 return CompareIsNanF32Latency() + Latency::BRANCH + 1261 2 * (CompareF32Latency() + Latency::BRANCH) + Latency::MFC1 + 1262 2 * Latency::BRANCH + Move_sLatency(); 1263} 1264 1265int Float64MinLatency() { 1266 // Estimated max. 1267 return CompareIsNanF64Latency() + Latency::BRANCH + 1268 2 * (CompareF64Latency() + Latency::BRANCH) + Mfhc1Latency() + 1269 2 * Latency::BRANCH + Move_dLatency(); 1270} 1271 1272int SmiUntagLatency() { return 1; } 1273 1274int 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 1280int JumpLatency() { 1281 // Estimated max. 1282 return 1 + AdduLatency(false) + Latency::BRANCH + 2; 1283} 1284 1285int AssertLatency() { return 1; } 1286 1287int MultiPushLatency() { 1288 int latency = SubuLatency(false); 1289 for (int16_t i = kNumRegisters - 1; i >= 0; i--) { 1290 latency++; 1291 } 1292 return latency; 1293} 1294 1295int 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 1303int PushCallerSavedLatency(SaveFPRegsMode fp_mode) { 1304 int latency = MultiPushLatency(); 1305 if (fp_mode == SaveFPRegsMode::kSave) { 1306 latency += MultiPushFPULatency(); 1307 } 1308 return latency; 1309} 1310 1311int MultiPopFPULatency() { 1312 int latency = 0; 1313 for (int16_t i = 0; i < kNumRegisters; i++) { 1314 latency += Ldc1Latency(); 1315 } 1316 return latency++; 1317} 1318 1319int MultiPopLatency() { 1320 int latency = 0; 1321 for (int16_t i = 0; i < kNumRegisters; i++) { 1322 latency++; 1323 } 1324 return latency++; 1325} 1326 1327int PopCallerSavedLatency(SaveFPRegsMode fp_mode) { 1328 int latency = 0; 1329 if (fp_mode == SaveFPRegsMode::kSave) { 1330 latency += MultiPopFPULatency(); 1331 } 1332 return latency + MultiPopLatency(); 1333} 1334 1335int AssembleArchJumpLatency() { 1336 // Estimated max. 1337 return Latency::BRANCH; 1338} 1339 1340int 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 1347int 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 1358int AssembleArchTableSwitchLatency() { 1359 return Latency::BRANCH + GenerateSwitchTableLatency(); 1360} 1361 1362int AssembleReturnLatency() { 1363 // Estimated max. 1364 return AdduLatency(false) + MultiPopLatency() + MultiPopFPULatency() + 1365 Latency::BRANCH + 1 + AdduLatency() + 8; 1366} 1367 1368int TryInlineTruncateDoubleToILatency() { 1369 return 2 + Latency::TRUNC_W_D + Latency::MFC1 + 2 + AndLatency(false) + 1370 Latency::BRANCH; 1371} 1372 1373int CallStubDelayedLatency() { return 1 + CallLatency(); } 1374 1375int 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 1381int CheckPageFlagLatency() { 1382 return 2 * AndLatency(false) + 1 + Latency::BRANCH; 1383} 1384 1385int 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