MacroAssembler-mips-shared-inl.h (50252B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jit_mips_shared_MacroAssembler_mips_shared_inl_h 8 #define jit_mips_shared_MacroAssembler_mips_shared_inl_h 9 10 #include "jit/mips-shared/MacroAssembler-mips-shared.h" 11 12 namespace js { 13 namespace jit { 14 15 //{{{ check_macroassembler_style 16 17 void MacroAssembler::moveFloat16ToGPR(FloatRegister src, Register dest) { 18 MOZ_CRASH("Not supported for this target"); 19 } 20 21 void MacroAssembler::moveGPRToFloat16(Register src, FloatRegister dest) { 22 MOZ_CRASH("Not supported for this target"); 23 } 24 25 void MacroAssembler::moveFloat32ToGPR(FloatRegister src, Register dest) { 26 moveFromFloat32(src, dest); 27 } 28 29 void MacroAssembler::moveGPRToFloat32(Register src, FloatRegister dest) { 30 moveToFloat32(src, dest); 31 } 32 33 void MacroAssembler::moveLowDoubleToGPR(FloatRegister src, Register dest) { 34 MOZ_CRASH("Not supported for this target"); 35 } 36 37 void MacroAssembler::move8ZeroExtend(Register src, Register dest) { 38 as_andi(dest, src, 0xff); 39 } 40 41 void MacroAssembler::move8SignExtend(Register src, Register dest) { 42 ma_seb(dest, src); 43 } 44 45 void MacroAssembler::move16SignExtend(Register src, Register dest) { 46 ma_seh(dest, src); 47 } 48 49 void MacroAssembler::loadAbiReturnAddress(Register dest) { movePtr(ra, dest); } 50 51 // =============================================================== 52 // Logical instructions 53 54 void MacroAssembler::not32(Register reg) { ma_not(reg, reg); } 55 56 void MacroAssembler::and32(Register src, Register dest) { 57 as_and(dest, dest, src); 58 } 59 60 void MacroAssembler::and32(Imm32 imm, Register dest) { ma_and(dest, imm); } 61 62 void MacroAssembler::and32(Imm32 imm, Register src, Register dest) { 63 ma_and(dest, src, imm); 64 } 65 66 void MacroAssembler::and32(Imm32 imm, const Address& dest) { 67 UseScratchRegisterScope temps(*this); 68 Register scratch2 = temps.Acquire(); 69 load32(dest, scratch2); 70 ma_and(scratch2, imm); 71 store32(scratch2, dest); 72 } 73 74 void MacroAssembler::and32(const Address& src, Register dest) { 75 UseScratchRegisterScope temps(*this); 76 Register scratch2 = temps.Acquire(); 77 load32(src, scratch2); 78 ma_and(dest, scratch2); 79 } 80 81 void MacroAssembler::or32(Register src, Register dest) { ma_or(dest, src); } 82 83 void MacroAssembler::or32(Imm32 imm, Register dest) { ma_or(dest, imm); } 84 85 void MacroAssembler::or32(Imm32 imm, Register src, Register dest) { 86 ma_or(dest, src, imm); 87 } 88 89 void MacroAssembler::or32(Imm32 imm, const Address& dest) { 90 UseScratchRegisterScope temps(*this); 91 Register scratch2 = temps.Acquire(); 92 load32(dest, scratch2); 93 ma_or(scratch2, imm); 94 store32(scratch2, dest); 95 } 96 97 void MacroAssembler::xor32(Register src, Register dest) { ma_xor(dest, src); } 98 99 void MacroAssembler::xor32(Imm32 imm, Register dest) { ma_xor(dest, imm); } 100 101 void MacroAssembler::xor32(Imm32 imm, Register src, Register dest) { 102 ma_xor(dest, src, imm); 103 } 104 105 void MacroAssembler::xor32(Imm32 imm, const Address& dest) { 106 UseScratchRegisterScope temps(*this); 107 Register scratch2 = temps.Acquire(); 108 load32(dest, scratch2); 109 ma_xor(scratch2, imm); 110 store32(scratch2, dest); 111 } 112 113 void MacroAssembler::xor32(const Address& src, Register dest) { 114 UseScratchRegisterScope temps(*this); 115 Register scratch2 = temps.Acquire(); 116 load32(src, scratch2); 117 ma_xor(dest, scratch2); 118 } 119 120 // =============================================================== 121 // Swap instructions 122 123 void MacroAssembler::byteSwap16SignExtend(Register reg) { 124 ma_wsbh(reg, reg); 125 ma_seh(reg, reg); 126 } 127 128 void MacroAssembler::byteSwap16ZeroExtend(Register reg) { 129 ma_wsbh(reg, reg); 130 ma_and(reg, Imm32(0xFFFF)); 131 } 132 133 void MacroAssembler::byteSwap32(Register reg) { 134 ma_wsbh(reg, reg); 135 ma_ror(reg, reg, Imm32(16)); 136 } 137 138 // =============================================================== 139 // Arithmetic instructions 140 141 void MacroAssembler::add32(Register src, Register dest) { 142 as_addu(dest, dest, src); 143 } 144 145 void MacroAssembler::add32(Imm32 imm, Register dest) { 146 ma_addu(dest, dest, imm); 147 } 148 149 void MacroAssembler::add32(Imm32 imm, Register src, Register dest) { 150 ma_addu(dest, src, imm); 151 } 152 153 void MacroAssembler::add32(Imm32 imm, const Address& dest) { 154 UseScratchRegisterScope temps(*this); 155 Register scratch2 = temps.Acquire(); 156 load32(dest, scratch2); 157 ma_addu(scratch2, imm); 158 store32(scratch2, dest); 159 } 160 161 void MacroAssembler::add32(const Address& src, Register dest) { 162 UseScratchRegisterScope temps(*this); 163 Register scratch2 = temps.Acquire(); 164 load32(src, scratch2); 165 as_addu(dest, dest, scratch2); 166 } 167 168 void MacroAssembler::addPtr(Imm32 imm, const Address& dest) { 169 UseScratchRegisterScope temps(*this); 170 Register scratch = temps.Acquire(); 171 loadPtr(dest, scratch); 172 addPtr(imm, scratch); 173 storePtr(scratch, dest); 174 } 175 176 void MacroAssembler::addPtr(const Address& src, Register dest) { 177 UseScratchRegisterScope temps(*this); 178 Register scratch = temps.Acquire(); 179 loadPtr(src, scratch); 180 addPtr(scratch, dest); 181 } 182 183 void MacroAssembler::addDouble(FloatRegister src, FloatRegister dest) { 184 as_addd(dest, dest, src); 185 } 186 187 void MacroAssembler::addFloat32(FloatRegister src, FloatRegister dest) { 188 as_adds(dest, dest, src); 189 } 190 191 void MacroAssembler::sub32(Register src, Register dest) { 192 as_subu(dest, dest, src); 193 } 194 195 void MacroAssembler::sub32(Imm32 imm, Register dest) { 196 ma_subu(dest, dest, imm); 197 } 198 199 void MacroAssembler::sub32(const Address& src, Register dest) { 200 UseScratchRegisterScope temps(*this); 201 Register scratch2 = temps.Acquire(); 202 load32(src, scratch2); 203 as_subu(dest, dest, scratch2); 204 } 205 206 void MacroAssembler::subPtr(Register src, const Address& dest) { 207 UseScratchRegisterScope temps(*this); 208 Register scratch2 = temps.Acquire(); 209 loadPtr(dest, scratch2); 210 subPtr(src, scratch2); 211 storePtr(scratch2, dest); 212 } 213 214 void MacroAssembler::subPtr(const Address& addr, Register dest) { 215 UseScratchRegisterScope temps(*this); 216 Register scratch2 = temps.Acquire(); 217 loadPtr(addr, scratch2); 218 subPtr(scratch2, dest); 219 } 220 221 void MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) { 222 as_subd(dest, dest, src); 223 } 224 225 void MacroAssembler::subFloat32(FloatRegister src, FloatRegister dest) { 226 as_subs(dest, dest, src); 227 } 228 229 void MacroAssembler::mul32(Register rhs, Register srcDest) { 230 as_mul(srcDest, srcDest, rhs); 231 } 232 233 void MacroAssembler::mul32(Imm32 imm, Register srcDest) { 234 UseScratchRegisterScope temps(*this); 235 Register scratch2 = temps.Acquire(); 236 move32(imm, scratch2); 237 mul32(scratch2, srcDest); 238 } 239 240 void MacroAssembler::mulFloat32(FloatRegister src, FloatRegister dest) { 241 as_muls(dest, dest, src); 242 } 243 244 void MacroAssembler::mulDouble(FloatRegister src, FloatRegister dest) { 245 as_muld(dest, dest, src); 246 } 247 248 void MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, 249 FloatRegister dest) { 250 UseScratchRegisterScope temps(*this); 251 Register scratch = temps.Acquire(); 252 movePtr(imm, scratch); 253 loadDouble(Address(scratch, 0), ScratchDoubleReg); 254 mulDouble(ScratchDoubleReg, dest); 255 } 256 257 void MacroAssembler::quotient32(Register lhs, Register rhs, Register dest, 258 bool isUnsigned) { 259 #ifdef MIPSR6 260 if (isUnsigned) { 261 as_divu(dest, lhs, rhs); 262 } else { 263 as_div(dest, lhs, rhs); 264 } 265 #else 266 if (isUnsigned) { 267 as_divu(lhs, rhs); 268 } else { 269 as_div(lhs, rhs); 270 } 271 as_mflo(dest); 272 #endif 273 } 274 275 void MacroAssembler::remainder32(Register lhs, Register rhs, Register dest, 276 bool isUnsigned) { 277 #ifdef MIPSR6 278 if (isUnsigned) { 279 as_modu(dest, lhs, rhs); 280 } else { 281 as_mod(dest, lhs, rhs); 282 } 283 #else 284 if (isUnsigned) { 285 as_divu(lhs, rhs); 286 } else { 287 as_div(lhs, rhs); 288 } 289 as_mfhi(dest); 290 #endif 291 } 292 293 void MacroAssembler::divFloat32(FloatRegister src, FloatRegister dest) { 294 as_divs(dest, dest, src); 295 } 296 297 void MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) { 298 as_divd(dest, dest, src); 299 } 300 301 void MacroAssembler::neg32(Register reg) { ma_negu(reg, reg); } 302 303 void MacroAssembler::negateDouble(FloatRegister reg) { as_negd(reg, reg); } 304 305 void MacroAssembler::negateFloat(FloatRegister reg) { as_negs(reg, reg); } 306 307 void MacroAssembler::abs32(Register src, Register dest) { 308 // TODO: There's probably a better way to do this. 309 if (src != dest) { 310 move32(src, dest); 311 } 312 Label positive; 313 branchTest32(Assembler::NotSigned, dest, dest, &positive); 314 neg32(dest); 315 bind(&positive); 316 } 317 318 void MacroAssembler::absFloat32(FloatRegister src, FloatRegister dest) { 319 as_abss(dest, src); 320 } 321 322 void MacroAssembler::absDouble(FloatRegister src, FloatRegister dest) { 323 as_absd(dest, src); 324 } 325 326 void MacroAssembler::sqrtFloat32(FloatRegister src, FloatRegister dest) { 327 as_sqrts(dest, src); 328 } 329 330 void MacroAssembler::sqrtDouble(FloatRegister src, FloatRegister dest) { 331 as_sqrtd(dest, src); 332 } 333 334 void MacroAssembler::min32(Register lhs, Register rhs, Register dest) { 335 minMax32(lhs, rhs, dest, /* isMax = */ false); 336 } 337 338 void MacroAssembler::min32(Register lhs, Imm32 rhs, Register dest) { 339 minMax32(lhs, rhs, dest, /* isMax = */ false); 340 } 341 342 void MacroAssembler::max32(Register lhs, Register rhs, Register dest) { 343 minMax32(lhs, rhs, dest, /* isMax = */ true); 344 } 345 346 void MacroAssembler::max32(Register lhs, Imm32 rhs, Register dest) { 347 minMax32(lhs, rhs, dest, /* isMax = */ true); 348 } 349 350 void MacroAssembler::minPtr(Register lhs, Register rhs, Register dest) { 351 minMaxPtr(lhs, rhs, dest, /* isMax = */ false); 352 } 353 354 void MacroAssembler::minPtr(Register lhs, ImmWord rhs, Register dest) { 355 minMaxPtr(lhs, rhs, dest, /* isMax = */ false); 356 } 357 358 void MacroAssembler::maxPtr(Register lhs, Register rhs, Register dest) { 359 minMaxPtr(lhs, rhs, dest, /* isMax = */ true); 360 } 361 362 void MacroAssembler::maxPtr(Register lhs, ImmWord rhs, Register dest) { 363 minMaxPtr(lhs, rhs, dest, /* isMax = */ true); 364 } 365 366 void MacroAssembler::minFloat32(FloatRegister other, FloatRegister srcDest, 367 bool handleNaN) { 368 minMaxFloat32(srcDest, other, handleNaN, false); 369 } 370 371 void MacroAssembler::minDouble(FloatRegister other, FloatRegister srcDest, 372 bool handleNaN) { 373 minMaxDouble(srcDest, other, handleNaN, false); 374 } 375 376 void MacroAssembler::maxFloat32(FloatRegister other, FloatRegister srcDest, 377 bool handleNaN) { 378 minMaxFloat32(srcDest, other, handleNaN, true); 379 } 380 381 void MacroAssembler::maxDouble(FloatRegister other, FloatRegister srcDest, 382 bool handleNaN) { 383 minMaxDouble(srcDest, other, handleNaN, true); 384 } 385 386 // =============================================================== 387 // Shift functions 388 389 void MacroAssembler::lshift32(Register src, Register dest) { 390 ma_sll(dest, dest, src); 391 } 392 393 void MacroAssembler::flexibleLshift32(Register src, Register dest) { 394 lshift32(src, dest); 395 } 396 397 void MacroAssembler::flexibleLshiftPtr(Register shift, Register srcDest) { 398 lshiftPtr(shift, srcDest); 399 } 400 401 void MacroAssembler::lshift32(Imm32 imm, Register dest) { 402 lshift32(imm, dest, dest); 403 } 404 405 void MacroAssembler::lshift32(Imm32 imm, Register src, Register dest) { 406 ma_sll(dest, src, imm); 407 } 408 409 void MacroAssembler::rshift32(Register src, Register dest) { 410 ma_srl(dest, dest, src); 411 } 412 413 void MacroAssembler::flexibleRshift32(Register src, Register dest) { 414 rshift32(src, dest); 415 } 416 417 void MacroAssembler::rshift32(Imm32 imm, Register dest) { 418 rshift32(imm, dest, dest); 419 } 420 421 void MacroAssembler::rshift32(Imm32 imm, Register src, Register dest) { 422 ma_srl(dest, src, imm); 423 } 424 425 void MacroAssembler::rshift32Arithmetic(Register src, Register dest) { 426 ma_sra(dest, dest, src); 427 } 428 429 void MacroAssembler::flexibleRshift32Arithmetic(Register src, Register dest) { 430 rshift32Arithmetic(src, dest); 431 } 432 433 void MacroAssembler::rshift32Arithmetic(Imm32 imm, Register dest) { 434 rshift32Arithmetic(imm, dest, dest); 435 } 436 437 void MacroAssembler::rshift32Arithmetic(Imm32 imm, Register src, 438 Register dest) { 439 ma_sra(dest, src, imm); 440 } 441 442 void MacroAssembler::flexibleRshiftPtr(Register shift, Register srcDest) { 443 rshiftPtr(shift, srcDest); 444 } 445 446 void MacroAssembler::flexibleRshiftPtrArithmetic(Register shift, 447 Register srcDest) { 448 rshiftPtrArithmetic(shift, srcDest); 449 } 450 451 // =============================================================== 452 // Rotation functions 453 void MacroAssembler::rotateLeft(Imm32 count, Register input, Register dest) { 454 if (count.value) { 455 ma_rol(dest, input, count); 456 } else { 457 ma_move(dest, input); 458 } 459 } 460 void MacroAssembler::rotateLeft(Register count, Register input, Register dest) { 461 ma_rol(dest, input, count); 462 } 463 void MacroAssembler::rotateRight(Imm32 count, Register input, Register dest) { 464 if (count.value) { 465 ma_ror(dest, input, count); 466 } else { 467 ma_move(dest, input); 468 } 469 } 470 void MacroAssembler::rotateRight(Register count, Register input, 471 Register dest) { 472 ma_ror(dest, input, count); 473 } 474 475 // =============================================================== 476 // Bit counting functions 477 478 void MacroAssembler::clz32(Register src, Register dest, bool knownNotZero) { 479 as_clz(dest, src); 480 } 481 482 void MacroAssembler::ctz32(Register src, Register dest, bool knownNotZero) { 483 ma_ctz(dest, src); 484 } 485 486 void MacroAssembler::popcnt32(Register input, Register output, Register tmp) { 487 // Equivalent to GCC output of mozilla::CountPopulation32() 488 ma_move(output, input); 489 ma_sra(tmp, input, Imm32(1)); 490 ma_and(tmp, Imm32(0x55555555)); 491 ma_subu(output, tmp); 492 ma_sra(tmp, output, Imm32(2)); 493 ma_and(output, Imm32(0x33333333)); 494 ma_and(tmp, Imm32(0x33333333)); 495 ma_addu(output, tmp); 496 ma_srl(tmp, output, Imm32(4)); 497 ma_addu(output, tmp); 498 ma_and(output, Imm32(0xF0F0F0F)); 499 ma_sll(tmp, output, Imm32(8)); 500 ma_addu(output, tmp); 501 ma_sll(tmp, output, Imm32(16)); 502 ma_addu(output, tmp); 503 ma_sra(output, output, Imm32(24)); 504 } 505 506 // =============================================================== 507 // Condition functions 508 509 void MacroAssembler::cmp8Set(Condition cond, Address lhs, Imm32 rhs, 510 Register dest) { 511 UseScratchRegisterScope temps(*this); 512 Register scratch2 = temps.Acquire(); 513 MOZ_ASSERT(scratch2 != lhs.base); 514 515 switch (cond) { 516 case Assembler::Equal: 517 case Assembler::NotEqual: 518 case Assembler::Above: 519 case Assembler::AboveOrEqual: 520 case Assembler::Below: 521 case Assembler::BelowOrEqual: 522 load8ZeroExtend(lhs, scratch2); 523 ma_cmp_set(dest, scratch2, Imm32(uint8_t(rhs.value)), cond); 524 break; 525 526 case Assembler::GreaterThan: 527 case Assembler::GreaterThanOrEqual: 528 case Assembler::LessThan: 529 case Assembler::LessThanOrEqual: 530 load8SignExtend(lhs, scratch2); 531 ma_cmp_set(dest, scratch2, Imm32(int8_t(rhs.value)), cond); 532 break; 533 534 default: 535 MOZ_CRASH("unexpected condition"); 536 } 537 } 538 539 void MacroAssembler::cmp16Set(Condition cond, Address lhs, Imm32 rhs, 540 Register dest) { 541 UseScratchRegisterScope temps(*this); 542 Register scratch2 = temps.Acquire(); 543 MOZ_ASSERT(scratch2 != lhs.base); 544 545 switch (cond) { 546 case Assembler::Equal: 547 case Assembler::NotEqual: 548 case Assembler::Above: 549 case Assembler::AboveOrEqual: 550 case Assembler::Below: 551 case Assembler::BelowOrEqual: 552 load16ZeroExtend(lhs, scratch2); 553 ma_cmp_set(dest, scratch2, Imm32(uint16_t(rhs.value)), cond); 554 break; 555 556 case Assembler::GreaterThan: 557 case Assembler::GreaterThanOrEqual: 558 case Assembler::LessThan: 559 case Assembler::LessThanOrEqual: 560 load16SignExtend(lhs, scratch2); 561 ma_cmp_set(dest, scratch2, Imm32(int16_t(rhs.value)), cond); 562 break; 563 564 default: 565 MOZ_CRASH("unexpected condition"); 566 } 567 } 568 569 // =============================================================== 570 // Branch functions 571 572 void MacroAssembler::branch8(Condition cond, const Address& lhs, Imm32 rhs, 573 Label* label) { 574 UseScratchRegisterScope temps(*this); 575 Register scratch2 = temps.Acquire(); 576 MOZ_ASSERT(scratch2 != lhs.base); 577 578 switch (cond) { 579 case Assembler::Equal: 580 case Assembler::NotEqual: 581 case Assembler::Above: 582 case Assembler::AboveOrEqual: 583 case Assembler::Below: 584 case Assembler::BelowOrEqual: 585 load8ZeroExtend(lhs, scratch2); 586 branch32(cond, scratch2, Imm32(uint8_t(rhs.value)), label); 587 break; 588 589 case Assembler::GreaterThan: 590 case Assembler::GreaterThanOrEqual: 591 case Assembler::LessThan: 592 case Assembler::LessThanOrEqual: 593 load8SignExtend(lhs, scratch2); 594 branch32(cond, scratch2, Imm32(int8_t(rhs.value)), label); 595 break; 596 597 default: 598 MOZ_CRASH("unexpected condition"); 599 } 600 } 601 602 void MacroAssembler::branch8(Condition cond, const BaseIndex& lhs, Register rhs, 603 Label* label) { 604 UseScratchRegisterScope temps(*this); 605 Register scratch2 = temps.Acquire(); 606 MOZ_ASSERT(scratch2 != lhs.base); 607 608 computeScaledAddress(lhs, scratch2); 609 610 switch (cond) { 611 case Assembler::Equal: 612 case Assembler::NotEqual: 613 case Assembler::Above: 614 case Assembler::AboveOrEqual: 615 case Assembler::Below: 616 case Assembler::BelowOrEqual: 617 load8ZeroExtend(Address(scratch2, lhs.offset), scratch2); 618 branch32(cond, scratch2, rhs, label); 619 break; 620 621 case Assembler::GreaterThan: 622 case Assembler::GreaterThanOrEqual: 623 case Assembler::LessThan: 624 case Assembler::LessThanOrEqual: 625 load8SignExtend(Address(scratch2, lhs.offset), scratch2); 626 branch32(cond, scratch2, rhs, label); 627 break; 628 629 default: 630 MOZ_CRASH("unexpected condition"); 631 } 632 } 633 634 void MacroAssembler::branch16(Condition cond, const Address& lhs, Imm32 rhs, 635 Label* label) { 636 UseScratchRegisterScope temps(*this); 637 Register scratch2 = temps.Acquire(); 638 MOZ_ASSERT(scratch2 != lhs.base); 639 640 switch (cond) { 641 case Assembler::Equal: 642 case Assembler::NotEqual: 643 case Assembler::Above: 644 case Assembler::AboveOrEqual: 645 case Assembler::Below: 646 case Assembler::BelowOrEqual: 647 load16ZeroExtend(lhs, scratch2); 648 branch32(cond, scratch2, Imm32(uint16_t(rhs.value)), label); 649 break; 650 651 case Assembler::GreaterThan: 652 case Assembler::GreaterThanOrEqual: 653 case Assembler::LessThan: 654 case Assembler::LessThanOrEqual: 655 load16SignExtend(lhs, scratch2); 656 branch32(cond, scratch2, Imm32(int16_t(rhs.value)), label); 657 break; 658 659 default: 660 MOZ_CRASH("unexpected condition"); 661 } 662 } 663 664 void MacroAssembler::branch32(Condition cond, Register lhs, Register rhs, 665 Label* label) { 666 ma_b(lhs, rhs, label, cond); 667 } 668 669 void MacroAssembler::branch32(Condition cond, Register lhs, Imm32 imm, 670 Label* label) { 671 ma_b(lhs, imm, label, cond); 672 } 673 674 void MacroAssembler::branch32(Condition cond, const Address& lhs, Register rhs, 675 Label* label) { 676 UseScratchRegisterScope temps(*this); 677 Register scratch2 = temps.Acquire(); 678 load32(lhs, scratch2); 679 ma_b(scratch2, rhs, label, cond); 680 } 681 682 void MacroAssembler::branch32(Condition cond, const Address& lhs, Imm32 rhs, 683 Label* label) { 684 UseScratchRegisterScope temps(*this); 685 Register scratch2 = temps.Acquire(); 686 load32(lhs, scratch2); 687 ma_b(scratch2, rhs, label, cond); 688 } 689 690 void MacroAssembler::branch32(Condition cond, const AbsoluteAddress& lhs, 691 Register rhs, Label* label) { 692 UseScratchRegisterScope temps(*this); 693 Register scratch2 = temps.Acquire(); 694 load32(lhs, scratch2); 695 ma_b(scratch2, rhs, label, cond); 696 } 697 698 void MacroAssembler::branch32(Condition cond, const AbsoluteAddress& lhs, 699 Imm32 rhs, Label* label) { 700 UseScratchRegisterScope temps(*this); 701 Register scratch2 = temps.Acquire(); 702 load32(lhs, scratch2); 703 ma_b(scratch2, rhs, label, cond); 704 } 705 706 void MacroAssembler::branch32(Condition cond, const BaseIndex& lhs, Imm32 rhs, 707 Label* label) { 708 UseScratchRegisterScope temps(*this); 709 Register scratch2 = temps.Acquire(); 710 load32(lhs, scratch2); 711 ma_b(scratch2, rhs, label, cond); 712 } 713 714 void MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress addr, 715 Imm32 imm, Label* label) { 716 UseScratchRegisterScope temps(*this); 717 Register scratch2 = temps.Acquire(); 718 load32(addr, scratch2); 719 ma_b(scratch2, imm, label, cond); 720 } 721 722 void MacroAssembler::branchPtr(Condition cond, Register lhs, Register rhs, 723 Label* label) { 724 ma_b(lhs, rhs, label, cond); 725 } 726 727 void MacroAssembler::branchPtr(Condition cond, Register lhs, Imm32 rhs, 728 Label* label) { 729 ma_b(lhs, rhs, label, cond); 730 } 731 732 void MacroAssembler::branchPtr(Condition cond, Register lhs, ImmPtr rhs, 733 Label* label) { 734 ma_b(lhs, rhs, label, cond); 735 } 736 737 void MacroAssembler::branchPtr(Condition cond, Register lhs, ImmGCPtr rhs, 738 Label* label) { 739 ma_b(lhs, rhs, label, cond); 740 } 741 742 void MacroAssembler::branchPtr(Condition cond, Register lhs, ImmWord rhs, 743 Label* label) { 744 ma_b(lhs, rhs, label, cond); 745 } 746 747 void MacroAssembler::branchPtr(Condition cond, const Address& lhs, Register rhs, 748 Label* label) { 749 UseScratchRegisterScope temps(*this); 750 Register scratch2 = temps.Acquire(); 751 loadPtr(lhs, scratch2); 752 branchPtr(cond, scratch2, rhs, label); 753 } 754 755 void MacroAssembler::branchPtr(Condition cond, const Address& lhs, ImmPtr rhs, 756 Label* label) { 757 UseScratchRegisterScope temps(*this); 758 Register scratch2 = temps.Acquire(); 759 loadPtr(lhs, scratch2); 760 branchPtr(cond, scratch2, rhs, label); 761 } 762 763 void MacroAssembler::branchPtr(Condition cond, const Address& lhs, ImmGCPtr rhs, 764 Label* label) { 765 UseScratchRegisterScope temps(*this); 766 Register scratch2 = temps.Acquire(); 767 loadPtr(lhs, scratch2); 768 branchPtr(cond, scratch2, rhs, label); 769 } 770 771 void MacroAssembler::branchPtr(Condition cond, const Address& lhs, ImmWord rhs, 772 Label* label) { 773 UseScratchRegisterScope temps(*this); 774 Register scratch2 = temps.Acquire(); 775 loadPtr(lhs, scratch2); 776 branchPtr(cond, scratch2, rhs, label); 777 } 778 779 void MacroAssembler::branchPtr(Condition cond, const AbsoluteAddress& lhs, 780 Register rhs, Label* label) { 781 UseScratchRegisterScope temps(*this); 782 Register scratch2 = temps.Acquire(); 783 loadPtr(lhs, scratch2); 784 branchPtr(cond, scratch2, rhs, label); 785 } 786 787 void MacroAssembler::branchPtr(Condition cond, const AbsoluteAddress& lhs, 788 ImmWord rhs, Label* label) { 789 UseScratchRegisterScope temps(*this); 790 Register scratch2 = temps.Acquire(); 791 loadPtr(lhs, scratch2); 792 branchPtr(cond, scratch2, rhs, label); 793 } 794 795 void MacroAssembler::branchPtr(Condition cond, wasm::SymbolicAddress lhs, 796 Register rhs, Label* label) { 797 UseScratchRegisterScope temps(*this); 798 Register scratch2 = temps.Acquire(); 799 loadPtr(lhs, scratch2); 800 branchPtr(cond, scratch2, rhs, label); 801 } 802 803 void MacroAssembler::branchPtr(Condition cond, const BaseIndex& lhs, 804 ImmWord rhs, Label* label) { 805 UseScratchRegisterScope temps(*this); 806 Register scratch2 = temps.Acquire(); 807 loadPtr(lhs, scratch2); 808 branchPtr(cond, scratch2, rhs, label); 809 } 810 811 void MacroAssembler::branchPtr(Condition cond, const BaseIndex& lhs, 812 Register rhs, Label* label) { 813 UseScratchRegisterScope temps(*this); 814 Register scratch = temps.Acquire(); 815 loadPtr(lhs, scratch); 816 branchPtr(cond, scratch, rhs, label); 817 } 818 819 void MacroAssembler::branchFloat(DoubleCondition cond, FloatRegister lhs, 820 FloatRegister rhs, Label* label) { 821 ma_bc1s(lhs, rhs, label, cond); 822 } 823 824 void MacroAssembler::branchTruncateFloat32ToInt32(FloatRegister src, 825 Register dest, Label* fail) { 826 convertFloat32ToInt32(src, dest, fail, false); 827 } 828 829 void MacroAssembler::branchDouble(DoubleCondition cond, FloatRegister lhs, 830 FloatRegister rhs, Label* label) { 831 ma_bc1d(lhs, rhs, label, cond); 832 } 833 834 template <typename T> 835 void MacroAssembler::branchAdd32(Condition cond, T src, Register dest, 836 Label* overflow) { 837 switch (cond) { 838 case Overflow: 839 ma_add32TestOverflow(dest, dest, src, overflow); 840 break; 841 case CarryClear: 842 case CarrySet: 843 ma_add32TestCarry(cond, dest, dest, src, overflow); 844 break; 845 default: 846 MOZ_CRASH("NYI"); 847 } 848 } 849 850 template <typename T> 851 void MacroAssembler::branchSub32(Condition cond, T src, Register dest, 852 Label* overflow) { 853 switch (cond) { 854 case Overflow: 855 ma_sub32TestOverflow(dest, dest, src, overflow); 856 break; 857 case NonZero: 858 case Zero: 859 case Signed: 860 case NotSigned: 861 ma_subu(dest, src); 862 ma_b(dest, dest, overflow, cond); 863 break; 864 default: 865 MOZ_CRASH("NYI"); 866 } 867 } 868 869 template <typename T> 870 void MacroAssembler::branchMul32(Condition cond, T src, Register dest, 871 Label* overflow) { 872 MOZ_ASSERT(cond == Assembler::Overflow); 873 ma_mul32TestOverflow(dest, dest, src, overflow); 874 } 875 876 template <typename T> 877 void MacroAssembler::branchRshift32(Condition cond, T src, Register dest, 878 Label* label) { 879 MOZ_ASSERT(cond == Zero || cond == NonZero); 880 rshift32(src, dest); 881 branch32(cond == Zero ? Equal : NotEqual, dest, Imm32(0), label); 882 } 883 884 void MacroAssembler::branchNeg32(Condition cond, Register reg, Label* label) { 885 MOZ_ASSERT(cond == Overflow); 886 neg32(reg); 887 branch32(Assembler::Equal, reg, Imm32(INT32_MIN), label); 888 } 889 890 template <typename T> 891 void MacroAssembler::branchAddPtr(Condition cond, T src, Register dest, 892 Label* label) { 893 switch (cond) { 894 case Overflow: 895 ma_addPtrTestOverflow(dest, dest, src, label); 896 break; 897 case CarryClear: 898 case CarrySet: 899 ma_addPtrTestCarry(cond, dest, dest, src, label); 900 break; 901 case Signed: 902 case NotSigned: 903 ma_addPtrTestSigned(cond, dest, dest, src, label); 904 break; 905 default: 906 MOZ_CRASH("NYI"); 907 } 908 } 909 910 template <typename T> 911 void MacroAssembler::branchSubPtr(Condition cond, T src, Register dest, 912 Label* label) { 913 switch (cond) { 914 case Overflow: 915 ma_subPtrTestOverflow(dest, dest, src, label); 916 break; 917 case NonZero: 918 case Zero: 919 case Signed: 920 case NotSigned: 921 subPtr(src, dest); 922 ma_b(dest, dest, label, cond); 923 break; 924 default: 925 MOZ_CRASH("NYI"); 926 } 927 } 928 929 void MacroAssembler::branchMulPtr(Condition cond, Register src, Register dest, 930 Label* label) { 931 MOZ_ASSERT(cond == Assembler::Overflow); 932 ma_mulPtrTestOverflow(dest, dest, src, label); 933 } 934 935 void MacroAssembler::branchNegPtr(Condition cond, Register reg, Label* label) { 936 MOZ_ASSERT(cond == Assembler::Overflow); 937 negPtr(reg); 938 branchPtr(Assembler::Equal, reg, ImmWord(INTPTR_MIN), label); 939 } 940 941 void MacroAssembler::decBranchPtr(Condition cond, Register lhs, Imm32 rhs, 942 Label* label) { 943 subPtr(rhs, lhs); 944 branchPtr(cond, lhs, Imm32(0), label); 945 } 946 947 void MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, 948 Label* label) { 949 MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || 950 cond == NotSigned); 951 if (lhs == rhs) { 952 ma_b(lhs, rhs, label, cond); 953 } else { 954 UseScratchRegisterScope temps(*this); 955 Register scratch = temps.Acquire(); 956 as_and(scratch, lhs, rhs); 957 ma_b(scratch, scratch, label, cond); 958 } 959 } 960 961 void MacroAssembler::branchTest32(Condition cond, Register lhs, Imm32 rhs, 962 Label* label) { 963 MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || 964 cond == NotSigned); 965 UseScratchRegisterScope temps(*this); 966 Register scratch = temps.Acquire(); 967 ma_and(scratch, lhs, rhs); 968 ma_b(scratch, scratch, label, cond); 969 } 970 971 void MacroAssembler::branchTest32(Condition cond, const Address& lhs, Imm32 rhs, 972 Label* label) { 973 MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || 974 cond == NotSigned); 975 UseScratchRegisterScope temps(*this); 976 Register scratch = temps.Acquire(); 977 load32(lhs, scratch); 978 and32(rhs, scratch); 979 ma_b(scratch, scratch, label, cond); 980 } 981 982 void MacroAssembler::branchTest32(Condition cond, const AbsoluteAddress& lhs, 983 Imm32 rhs, Label* label) { 984 MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || 985 cond == NotSigned); 986 UseScratchRegisterScope temps(*this); 987 Register scratch = temps.Acquire(); 988 load32(lhs, scratch); 989 and32(rhs, scratch); 990 ma_b(scratch, scratch, label, cond); 991 } 992 993 void MacroAssembler::branchTestPtr(Condition cond, Register lhs, Register rhs, 994 Label* label) { 995 MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || 996 cond == NotSigned); 997 if (lhs == rhs) { 998 ma_b(lhs, rhs, label, cond); 999 } else { 1000 UseScratchRegisterScope temps(*this); 1001 Register scratch = temps.Acquire(); 1002 as_and(scratch, lhs, rhs); 1003 ma_b(scratch, scratch, label, cond); 1004 } 1005 } 1006 1007 void MacroAssembler::branchTestPtr(Condition cond, Register lhs, Imm32 rhs, 1008 Label* label) { 1009 MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || 1010 cond == NotSigned); 1011 UseScratchRegisterScope temps(*this); 1012 Register scratch = temps.Acquire(); 1013 ma_and(scratch, lhs, rhs); 1014 ma_b(scratch, scratch, label, cond); 1015 } 1016 1017 void MacroAssembler::branchTestPtr(Condition cond, Register lhs, ImmWord rhs, 1018 Label* label) { 1019 MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || 1020 cond == NotSigned); 1021 UseScratchRegisterScope temps(*this); 1022 Register scratch = temps.Acquire(); 1023 ma_li(scratch, rhs); 1024 as_and(scratch, lhs, scratch); 1025 ma_b(scratch, scratch, label, cond); 1026 } 1027 1028 void MacroAssembler::branchTestPtr(Condition cond, const Address& lhs, 1029 Imm32 rhs, Label* label) { 1030 UseScratchRegisterScope temps(*this); 1031 Register scratch2 = temps.Acquire(); 1032 loadPtr(lhs, scratch2); 1033 branchTestPtr(cond, scratch2, rhs, label); 1034 } 1035 1036 void MacroAssembler::branchTestUndefined(Condition cond, Register tag, 1037 Label* label) { 1038 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1039 ma_b(tag, ImmTag(JSVAL_TAG_UNDEFINED), label, cond); 1040 } 1041 1042 void MacroAssembler::branchTestUndefined(Condition cond, const Address& address, 1043 Label* label) { 1044 UseScratchRegisterScope temps(*this); 1045 Register scratch2 = temps.Acquire(); 1046 Register tag = extractTag(address, scratch2); 1047 branchTestUndefined(cond, tag, label); 1048 } 1049 1050 void MacroAssembler::branchTestUndefined(Condition cond, 1051 const BaseIndex& address, 1052 Label* label) { 1053 UseScratchRegisterScope temps(*this); 1054 Register scratch2 = temps.Acquire(); 1055 Register tag = extractTag(address, scratch2); 1056 branchTestUndefined(cond, tag, label); 1057 } 1058 1059 void MacroAssembler::branchTestInt32(Condition cond, Register tag, 1060 Label* label) { 1061 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1062 ma_b(tag, ImmTag(JSVAL_TAG_INT32), label, cond); 1063 } 1064 1065 void MacroAssembler::branchTestInt32(Condition cond, const Address& address, 1066 Label* label) { 1067 UseScratchRegisterScope temps(*this); 1068 Register scratch2 = temps.Acquire(); 1069 Register tag = extractTag(address, scratch2); 1070 branchTestInt32(cond, tag, label); 1071 } 1072 1073 void MacroAssembler::branchTestInt32(Condition cond, const BaseIndex& address, 1074 Label* label) { 1075 UseScratchRegisterScope temps(*this); 1076 Register scratch2 = temps.Acquire(); 1077 Register tag = extractTag(address, scratch2); 1078 branchTestInt32(cond, tag, label); 1079 } 1080 1081 void MacroAssembler::branchTestDouble(Condition cond, const Address& address, 1082 Label* label) { 1083 UseScratchRegisterScope temps(*this); 1084 Register scratch2 = temps.Acquire(); 1085 Register tag = extractTag(address, scratch2); 1086 branchTestDouble(cond, tag, label); 1087 } 1088 1089 void MacroAssembler::branchTestDouble(Condition cond, const BaseIndex& address, 1090 Label* label) { 1091 UseScratchRegisterScope temps(*this); 1092 Register scratch2 = temps.Acquire(); 1093 Register tag = extractTag(address, scratch2); 1094 branchTestDouble(cond, tag, label); 1095 } 1096 1097 void MacroAssembler::branchTestDoubleTruthy(bool b, FloatRegister value, 1098 Label* label) { 1099 ma_lid(ScratchDoubleReg, 0.0); 1100 DoubleCondition cond = b ? DoubleNotEqual : DoubleEqualOrUnordered; 1101 ma_bc1d(value, ScratchDoubleReg, label, cond); 1102 } 1103 1104 void MacroAssembler::branchTestNumber(Condition cond, Register tag, 1105 Label* label) { 1106 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1107 Condition actual = cond == Equal ? BelowOrEqual : Above; 1108 ma_b(tag, ImmTag(JS::detail::ValueUpperInclNumberTag), label, actual); 1109 } 1110 1111 void MacroAssembler::branchTestBoolean(Condition cond, Register tag, 1112 Label* label) { 1113 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1114 ma_b(tag, ImmTag(JSVAL_TAG_BOOLEAN), label, cond); 1115 } 1116 1117 void MacroAssembler::branchTestBoolean(Condition cond, const Address& address, 1118 Label* label) { 1119 UseScratchRegisterScope temps(*this); 1120 Register scratch2 = temps.Acquire(); 1121 Register tag = extractTag(address, scratch2); 1122 branchTestBoolean(cond, tag, label); 1123 } 1124 1125 void MacroAssembler::branchTestBoolean(Condition cond, const BaseIndex& address, 1126 Label* label) { 1127 UseScratchRegisterScope temps(*this); 1128 Register scratch2 = temps.Acquire(); 1129 Register tag = extractTag(address, scratch2); 1130 branchTestBoolean(cond, tag, label); 1131 } 1132 1133 void MacroAssembler::branchTestString(Condition cond, Register tag, 1134 Label* label) { 1135 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1136 ma_b(tag, ImmTag(JSVAL_TAG_STRING), label, cond); 1137 } 1138 1139 void MacroAssembler::branchTestString(Condition cond, const Address& address, 1140 Label* label) { 1141 UseScratchRegisterScope temps(*this); 1142 Register scratch2 = temps.Acquire(); 1143 Register tag = extractTag(address, scratch2); 1144 branchTestString(cond, tag, label); 1145 } 1146 1147 void MacroAssembler::branchTestString(Condition cond, const BaseIndex& address, 1148 Label* label) { 1149 UseScratchRegisterScope temps(*this); 1150 Register scratch2 = temps.Acquire(); 1151 Register tag = extractTag(address, scratch2); 1152 branchTestString(cond, tag, label); 1153 } 1154 1155 void MacroAssembler::branchTestSymbol(Condition cond, Register tag, 1156 Label* label) { 1157 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1158 ma_b(tag, ImmTag(JSVAL_TAG_SYMBOL), label, cond); 1159 } 1160 1161 void MacroAssembler::branchTestSymbol(Condition cond, const BaseIndex& address, 1162 Label* label) { 1163 UseScratchRegisterScope temps(*this); 1164 Register scratch2 = temps.Acquire(); 1165 Register tag = extractTag(address, scratch2); 1166 branchTestSymbol(cond, tag, label); 1167 } 1168 1169 void MacroAssembler::branchTestSymbol(Condition cond, const Address& address, 1170 Label* label) { 1171 UseScratchRegisterScope temps(*this); 1172 Register scratch2 = temps.Acquire(); 1173 Register tag = extractTag(address, scratch2); 1174 branchTestSymbol(cond, tag, label); 1175 } 1176 1177 void MacroAssembler::branchTestBigInt(Condition cond, Register tag, 1178 Label* label) { 1179 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1180 ma_b(tag, ImmTag(JSVAL_TAG_BIGINT), label, cond); 1181 } 1182 1183 void MacroAssembler::branchTestBigInt(Condition cond, const Address& address, 1184 Label* label) { 1185 UseScratchRegisterScope temps(*this); 1186 Register scratch2 = temps.Acquire(); 1187 Register tag = extractTag(address, scratch2); 1188 branchTestBigInt(cond, tag, label); 1189 } 1190 1191 void MacroAssembler::branchTestNull(Condition cond, Register tag, 1192 Label* label) { 1193 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1194 ma_b(tag, ImmTag(JSVAL_TAG_NULL), label, cond); 1195 } 1196 1197 void MacroAssembler::branchTestNull(Condition cond, const Address& address, 1198 Label* label) { 1199 UseScratchRegisterScope temps(*this); 1200 Register scratch2 = temps.Acquire(); 1201 Register tag = extractTag(address, scratch2); 1202 branchTestNull(cond, tag, label); 1203 } 1204 1205 void MacroAssembler::branchTestNull(Condition cond, const BaseIndex& address, 1206 Label* label) { 1207 UseScratchRegisterScope temps(*this); 1208 Register scratch2 = temps.Acquire(); 1209 Register tag = extractTag(address, scratch2); 1210 branchTestNull(cond, tag, label); 1211 } 1212 1213 void MacroAssembler::branchTestObject(Condition cond, Register tag, 1214 Label* label) { 1215 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1216 ma_b(tag, ImmTag(JSVAL_TAG_OBJECT), label, cond); 1217 } 1218 1219 void MacroAssembler::branchTestObject(Condition cond, const Address& address, 1220 Label* label) { 1221 UseScratchRegisterScope temps(*this); 1222 Register scratch2 = temps.Acquire(); 1223 Register tag = extractTag(address, scratch2); 1224 branchTestObject(cond, tag, label); 1225 } 1226 1227 void MacroAssembler::branchTestObject(Condition cond, const BaseIndex& address, 1228 Label* label) { 1229 UseScratchRegisterScope temps(*this); 1230 Register scratch2 = temps.Acquire(); 1231 Register tag = extractTag(address, scratch2); 1232 branchTestObject(cond, tag, label); 1233 } 1234 1235 void MacroAssembler::branchTestGCThing(Condition cond, const Address& address, 1236 Label* label) { 1237 branchTestGCThingImpl(cond, address, label); 1238 } 1239 1240 void MacroAssembler::branchTestGCThing(Condition cond, const BaseIndex& address, 1241 Label* label) { 1242 branchTestGCThingImpl(cond, address, label); 1243 } 1244 1245 void MacroAssembler::branchTestGCThing(Condition cond, 1246 const ValueOperand& address, 1247 Label* label) { 1248 branchTestGCThingImpl(cond, address, label); 1249 } 1250 1251 template <typename T> 1252 void MacroAssembler::branchTestGCThingImpl(Condition cond, const T& address, 1253 Label* label) { 1254 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1255 UseScratchRegisterScope temps(*this); 1256 Register scratch2 = temps.Acquire(); 1257 Register tag = extractTag(address, scratch2); 1258 ma_b(tag, ImmTag(JS::detail::ValueLowerInclGCThingTag), label, 1259 (cond == Equal) ? AboveOrEqual : Below); 1260 } 1261 1262 void MacroAssembler::branchTestPrimitive(Condition cond, Register tag, 1263 Label* label) { 1264 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1265 ma_b(tag, ImmTag(JS::detail::ValueUpperExclPrimitiveTag), label, 1266 (cond == Equal) ? Below : AboveOrEqual); 1267 } 1268 1269 void MacroAssembler::branchTestMagic(Condition cond, Register tag, 1270 Label* label) { 1271 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1272 ma_b(tag, ImmTag(JSVAL_TAG_MAGIC), label, cond); 1273 } 1274 1275 void MacroAssembler::branchTestMagic(Condition cond, const Address& address, 1276 Label* label) { 1277 UseScratchRegisterScope temps(*this); 1278 Register scratch2 = temps.Acquire(); 1279 Register tag = extractTag(address, scratch2); 1280 branchTestMagic(cond, tag, label); 1281 } 1282 1283 void MacroAssembler::branchTestMagic(Condition cond, const BaseIndex& address, 1284 Label* label) { 1285 UseScratchRegisterScope temps(*this); 1286 Register scratch2 = temps.Acquire(); 1287 Register tag = extractTag(address, scratch2); 1288 branchTestMagic(cond, tag, label); 1289 } 1290 1291 template <typename T> 1292 void MacroAssembler::testNumberSet(Condition cond, const T& src, 1293 Register dest) { 1294 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1295 UseScratchRegisterScope temps(*this); 1296 Register scratch2 = temps.Acquire(); 1297 Register tag = extractTag(src, scratch2); 1298 ma_cmp_set(dest, tag, ImmTag(JS::detail::ValueUpperInclNumberTag), 1299 cond == Equal ? BelowOrEqual : Above); 1300 } 1301 1302 template <typename T> 1303 void MacroAssembler::testBooleanSet(Condition cond, const T& src, 1304 Register dest) { 1305 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1306 UseScratchRegisterScope temps(*this); 1307 Register scratch2 = temps.Acquire(); 1308 Register tag = extractTag(src, scratch2); 1309 ma_cmp_set(dest, tag, ImmTag(JSVAL_TAG_BOOLEAN), cond); 1310 } 1311 1312 template <typename T> 1313 void MacroAssembler::testStringSet(Condition cond, const T& src, 1314 Register dest) { 1315 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1316 UseScratchRegisterScope temps(*this); 1317 Register scratch2 = temps.Acquire(); 1318 Register tag = extractTag(src, scratch2); 1319 ma_cmp_set(dest, tag, ImmTag(JSVAL_TAG_STRING), cond); 1320 } 1321 1322 template <typename T> 1323 void MacroAssembler::testSymbolSet(Condition cond, const T& src, 1324 Register dest) { 1325 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1326 UseScratchRegisterScope temps(*this); 1327 Register scratch2 = temps.Acquire(); 1328 Register tag = extractTag(src, scratch2); 1329 ma_cmp_set(dest, tag, ImmTag(JSVAL_TAG_SYMBOL), cond); 1330 } 1331 1332 template <typename T> 1333 void MacroAssembler::testBigIntSet(Condition cond, const T& src, 1334 Register dest) { 1335 MOZ_ASSERT(cond == Equal || cond == NotEqual); 1336 UseScratchRegisterScope temps(*this); 1337 Register scratch2 = temps.Acquire(); 1338 Register tag = extractTag(src, scratch2); 1339 ma_cmp_set(dest, tag, ImmTag(JSVAL_TAG_BIGINT), cond); 1340 } 1341 1342 void MacroAssembler::branchToComputedAddress(const BaseIndex& addr) { 1343 UseScratchRegisterScope temps(*this); 1344 Register scratch = temps.Acquire(); 1345 loadPtr(addr, scratch); 1346 branch(scratch); 1347 } 1348 1349 void MacroAssembler::cmp32Move32(Condition cond, Register lhs, Imm32 rhs, 1350 Register src, Register dest) { 1351 UseScratchRegisterScope temps(*this); 1352 Register scratch = temps.Acquire(); 1353 MOZ_ASSERT(src != scratch && dest != scratch); 1354 cmp32Set(cond, lhs, rhs, scratch); 1355 #ifdef MIPSR6 1356 as_selnez(src, src, scratch); 1357 as_seleqz(dest, dest, scratch); 1358 as_or(dest, dest, src); 1359 #else 1360 as_movn(dest, src, scratch); 1361 #endif 1362 } 1363 1364 void MacroAssembler::cmp32Move32(Condition cond, Register lhs, Register rhs, 1365 Register src, Register dest) { 1366 UseScratchRegisterScope temps(*this); 1367 Register scratch = temps.Acquire(); 1368 MOZ_ASSERT(src != scratch && dest != scratch); 1369 cmp32Set(cond, lhs, rhs, scratch); 1370 #ifdef MIPSR6 1371 as_selnez(src, src, scratch); 1372 as_seleqz(dest, dest, scratch); 1373 as_or(dest, dest, src); 1374 #else 1375 as_movn(dest, src, scratch); 1376 #endif 1377 } 1378 1379 void MacroAssembler::cmp32MovePtr(Condition cond, Register lhs, Imm32 rhs, 1380 Register src, Register dest) { 1381 UseScratchRegisterScope temps(*this); 1382 Register scratch = temps.Acquire(); 1383 MOZ_ASSERT(src != scratch && dest != scratch); 1384 cmp32Set(cond, lhs, rhs, scratch); 1385 #ifdef MIPSR6 1386 as_selnez(src, src, scratch); 1387 as_seleqz(dest, dest, scratch); 1388 as_or(dest, dest, src); 1389 #else 1390 as_movn(dest, src, scratch); 1391 #endif 1392 } 1393 1394 void MacroAssembler::cmp32Move32(Condition cond, Register lhs, 1395 const Address& rhs, Register src, 1396 Register dest) { 1397 UseScratchRegisterScope temps(*this); 1398 Register scratch2 = temps.Acquire(); 1399 load32(rhs, scratch2); 1400 cmp32Move32(cond, lhs, scratch2, src, dest); 1401 } 1402 1403 void MacroAssembler::cmp32Load32(Condition cond, Register lhs, 1404 const Address& rhs, const Address& src, 1405 Register dest) { 1406 UseScratchRegisterScope temps(*this); 1407 Register scratch = temps.Acquire(); 1408 MOZ_ASSERT(lhs != scratch && dest != scratch); 1409 load32(rhs, scratch); 1410 cmp32Load32(cond, lhs, scratch, src, dest); 1411 } 1412 1413 void MacroAssembler::cmp32Load32(Condition cond, Register lhs, Register rhs, 1414 const Address& src, Register dest) { 1415 Label skip; 1416 branch32(Assembler::InvertCondition(cond), lhs, rhs, &skip); 1417 load32(src, dest); 1418 bind(&skip); 1419 } 1420 1421 void MacroAssembler::cmp32Load32(Condition cond, Register lhs, Imm32 rhs, 1422 const Address& src, Register dest) { 1423 Label skip; 1424 branch32(Assembler::InvertCondition(cond), lhs, rhs, &skip); 1425 load32(src, dest); 1426 bind(&skip); 1427 } 1428 1429 void MacroAssembler::cmp32LoadPtr(Condition cond, const Address& lhs, Imm32 rhs, 1430 const Address& src, Register dest) { 1431 Label skip; 1432 branch32(Assembler::InvertCondition(cond), lhs, rhs, &skip); 1433 loadPtr(src, dest); 1434 bind(&skip); 1435 } 1436 1437 void MacroAssembler::test32LoadPtr(Condition cond, const Address& addr, 1438 Imm32 mask, const Address& src, 1439 Register dest) { 1440 MOZ_RELEASE_ASSERT(!JitOptions.spectreStringMitigations); 1441 Label skip; 1442 branchTest32(Assembler::InvertCondition(cond), addr, mask, &skip); 1443 loadPtr(src, dest); 1444 bind(&skip); 1445 } 1446 1447 void MacroAssembler::test32MovePtr(Condition cond, Register operand, Imm32 mask, 1448 Register src, Register dest) { 1449 MOZ_ASSERT(cond == Assembler::Zero || cond == Assembler::NonZero); 1450 Label skip; 1451 branchTest32(Assembler::InvertCondition(cond), operand, mask, &skip); 1452 movePtr(src, dest); 1453 bind(&skip); 1454 } 1455 1456 void MacroAssembler::test32MovePtr(Condition cond, const Address& addr, 1457 Imm32 mask, Register src, Register dest) { 1458 MOZ_ASSERT(cond == Assembler::Zero || cond == Assembler::NonZero); 1459 Label skip; 1460 branchTest32(Assembler::InvertCondition(cond), addr, mask, &skip); 1461 movePtr(src, dest); 1462 bind(&skip); 1463 } 1464 1465 void MacroAssembler::spectreBoundsCheck32(Register index, Register length, 1466 Register maybeScratch, 1467 Label* failure) { 1468 MOZ_RELEASE_ASSERT(!JitOptions.spectreIndexMasking); 1469 branch32(Assembler::BelowOrEqual, length, index, failure); 1470 } 1471 1472 void MacroAssembler::spectreBoundsCheck32(Register index, const Address& length, 1473 Register maybeScratch, 1474 Label* failure) { 1475 MOZ_RELEASE_ASSERT(!JitOptions.spectreIndexMasking); 1476 branch32(Assembler::BelowOrEqual, length, index, failure); 1477 } 1478 1479 void MacroAssembler::spectreBoundsCheckPtr(Register index, Register length, 1480 Register maybeScratch, 1481 Label* failure) { 1482 MOZ_RELEASE_ASSERT(!JitOptions.spectreIndexMasking); 1483 branchPtr(Assembler::BelowOrEqual, length, index, failure); 1484 } 1485 1486 void MacroAssembler::spectreBoundsCheckPtr(Register index, 1487 const Address& length, 1488 Register maybeScratch, 1489 Label* failure) { 1490 MOZ_RELEASE_ASSERT(!JitOptions.spectreIndexMasking); 1491 branchPtr(Assembler::BelowOrEqual, length, index, failure); 1492 } 1493 1494 void MacroAssembler::spectreMovePtr(Condition cond, Register src, 1495 Register dest) { 1496 MOZ_CRASH(); 1497 } 1498 1499 void MacroAssembler::spectreZeroRegister(Condition cond, Register scratch, 1500 Register dest) { 1501 MOZ_CRASH(); 1502 } 1503 1504 // ======================================================================== 1505 // Memory access primitives. 1506 1507 FaultingCodeOffset MacroAssembler::storeDouble(FloatRegister src, 1508 const Address& addr) { 1509 return ma_sd(src, addr); 1510 } 1511 FaultingCodeOffset MacroAssembler::storeDouble(FloatRegister src, 1512 const BaseIndex& addr) { 1513 return ma_sd(src, addr); 1514 } 1515 1516 FaultingCodeOffset MacroAssembler::storeFloat32(FloatRegister src, 1517 const Address& addr) { 1518 return ma_ss(src, addr); 1519 } 1520 FaultingCodeOffset MacroAssembler::storeFloat32(FloatRegister src, 1521 const BaseIndex& addr) { 1522 return ma_ss(src, addr); 1523 } 1524 1525 FaultingCodeOffset MacroAssembler::storeFloat16(FloatRegister src, 1526 const Address& dest, Register) { 1527 MOZ_CRASH("Not supported for this target"); 1528 } 1529 FaultingCodeOffset MacroAssembler::storeFloat16(FloatRegister src, 1530 const BaseIndex& dest, 1531 Register) { 1532 MOZ_CRASH("Not supported for this target"); 1533 } 1534 1535 void MacroAssembler::memoryBarrier(MemoryBarrier barrier) { 1536 if (!barrier.isNone()) { 1537 as_sync(); 1538 } 1539 } 1540 1541 // =============================================================== 1542 // Clamping functions. 1543 1544 void MacroAssembler::clampIntToUint8(Register reg) { 1545 // If reg is < 0, then we want to clamp to 0. 1546 UseScratchRegisterScope temps(*this); 1547 Register scratch = temps.Acquire(); 1548 Register scratch2 = temps.Acquire(); 1549 as_slti(scratch, reg, 0); 1550 #ifdef MIPSR6 1551 as_seleqz(reg, reg, scratch); 1552 #else 1553 as_movn(reg, zero, scratch); 1554 #endif 1555 // If reg is >= 255, then we want to clamp to 255. 1556 ma_li(scratch2, Imm32(255)); 1557 as_slti(scratch, reg, 255); 1558 #ifdef MIPSR6 1559 as_seleqz(scratch2, scratch2, scratch); 1560 as_selnez(reg, reg, scratch); 1561 as_or(reg, reg, scratch2); 1562 #else 1563 as_movz(reg, scratch2, scratch); 1564 #endif 1565 } 1566 1567 //}}} check_macroassembler_style 1568 // =============================================================== 1569 1570 } // namespace jit 1571 } // namespace js 1572 1573 #endif /* jit_mips_shared_MacroAssembler_mips_shared_inl_h */