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