1 // Copyright 2010 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 29 30 #include "v8.h" 31 32 #include "bootstrapper.h" 33 #include "codegen-inl.h" 34 #include "debug.h" 35 #include "runtime.h" 36 37 namespace v8 { 38 namespace internal { 39 40 MacroAssembler::MacroAssembler(void* buffer, int size) 41 : Assembler(buffer, size), 42 unresolved_(0), 43 generating_stub_(false), 44 allow_stub_calls_(true), 45 code_object_(Heap::undefined_value()) { 46 } 47 48 49 50 void MacroAssembler::Jump(Register target, Condition cond, 51 Register r1, const Operand& r2) { 52 Jump(Operand(target), cond, r1, r2); 53 } 54 55 56 void MacroAssembler::Jump(intptr_t target, RelocInfo::Mode rmode, 57 Condition cond, Register r1, const Operand& r2) { 58 Jump(Operand(target), cond, r1, r2); 59 } 60 61 62 void MacroAssembler::Jump(byte* target, RelocInfo::Mode rmode, 63 Condition cond, Register r1, const Operand& r2) { 64 ASSERT(!RelocInfo::IsCodeTarget(rmode)); 65 Jump(reinterpret_cast<intptr_t>(target), rmode, cond, r1, r2); 66 } 67 68 69 void MacroAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode, 70 Condition cond, Register r1, const Operand& r2) { 71 ASSERT(RelocInfo::IsCodeTarget(rmode)); 72 Jump(reinterpret_cast<intptr_t>(code.location()), rmode, cond); 73 } 74 75 76 void MacroAssembler::Call(Register target, 77 Condition cond, Register r1, const Operand& r2) { 78 Call(Operand(target), cond, r1, r2); 79 } 80 81 82 void MacroAssembler::Call(intptr_t target, RelocInfo::Mode rmode, 83 Condition cond, Register r1, const Operand& r2) { 84 Call(Operand(target), cond, r1, r2); 85 } 86 87 88 void MacroAssembler::Call(byte* target, RelocInfo::Mode rmode, 89 Condition cond, Register r1, const Operand& r2) { 90 ASSERT(!RelocInfo::IsCodeTarget(rmode)); 91 Call(reinterpret_cast<intptr_t>(target), rmode, cond, r1, r2); 92 } 93 94 95 void MacroAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode, 96 Condition cond, Register r1, const Operand& r2) { 97 ASSERT(RelocInfo::IsCodeTarget(rmode)); 98 Call(reinterpret_cast<intptr_t>(code.location()), rmode, cond, r1, r2); 99 } 100 101 102 void MacroAssembler::Ret(Condition cond, Register r1, const Operand& r2) { 103 Jump(Operand(ra), cond, r1, r2); 104 } 105 106 107 void MacroAssembler::LoadRoot(Register destination, 108 Heap::RootListIndex index) { 109 lw(destination, MemOperand(s4, index << kPointerSizeLog2)); 110 } 111 112 void MacroAssembler::LoadRoot(Register destination, 113 Heap::RootListIndex index, 114 Condition cond, 115 Register src1, const Operand& src2) { 116 Branch(NegateCondition(cond), 2, src1, src2); 117 nop(); 118 lw(destination, MemOperand(s4, index << kPointerSizeLog2)); 119 } 120 121 122 void MacroAssembler::RecordWrite(Register object, Register offset, 123 Register scratch) { 124 UNIMPLEMENTED_MIPS(); 125 } 126 127 128 // --------------------------------------------------------------------------- 129 // Instruction macros 130 131 void MacroAssembler::Add(Register rd, Register rs, const Operand& rt) { 132 if (rt.is_reg()) { 133 add(rd, rs, rt.rm()); 134 } else { 135 if (is_int16(rt.imm32_) && !MustUseAt(rt.rmode_)) { 136 addi(rd, rs, rt.imm32_); 137 } else { 138 // li handles the relocation. 139 ASSERT(!rs.is(at)); 140 li(at, rt); 141 add(rd, rs, at); 142 } 143 } 144 } 145 146 147 void MacroAssembler::Addu(Register rd, Register rs, const Operand& rt) { 148 if (rt.is_reg()) { 149 addu(rd, rs, rt.rm()); 150 } else { 151 if (is_int16(rt.imm32_) && !MustUseAt(rt.rmode_)) { 152 addiu(rd, rs, rt.imm32_); 153 } else { 154 // li handles the relocation. 155 ASSERT(!rs.is(at)); 156 li(at, rt); 157 addu(rd, rs, at); 158 } 159 } 160 } 161 162 163 void MacroAssembler::Mul(Register rd, Register rs, const Operand& rt) { 164 if (rt.is_reg()) { 165 mul(rd, rs, rt.rm()); 166 } else { 167 // li handles the relocation. 168 ASSERT(!rs.is(at)); 169 li(at, rt); 170 mul(rd, rs, at); 171 } 172 } 173 174 175 void MacroAssembler::Mult(Register rs, const Operand& rt) { 176 if (rt.is_reg()) { 177 mult(rs, rt.rm()); 178 } else { 179 // li handles the relocation. 180 ASSERT(!rs.is(at)); 181 li(at, rt); 182 mult(rs, at); 183 } 184 } 185 186 187 void MacroAssembler::Multu(Register rs, const Operand& rt) { 188 if (rt.is_reg()) { 189 multu(rs, rt.rm()); 190 } else { 191 // li handles the relocation. 192 ASSERT(!rs.is(at)); 193 li(at, rt); 194 multu(rs, at); 195 } 196 } 197 198 199 void MacroAssembler::Div(Register rs, const Operand& rt) { 200 if (rt.is_reg()) { 201 div(rs, rt.rm()); 202 } else { 203 // li handles the relocation. 204 ASSERT(!rs.is(at)); 205 li(at, rt); 206 div(rs, at); 207 } 208 } 209 210 211 void MacroAssembler::Divu(Register rs, const Operand& rt) { 212 if (rt.is_reg()) { 213 divu(rs, rt.rm()); 214 } else { 215 // li handles the relocation. 216 ASSERT(!rs.is(at)); 217 li(at, rt); 218 divu(rs, at); 219 } 220 } 221 222 223 void MacroAssembler::And(Register rd, Register rs, const Operand& rt) { 224 if (rt.is_reg()) { 225 and_(rd, rs, rt.rm()); 226 } else { 227 if (is_int16(rt.imm32_) && !MustUseAt(rt.rmode_)) { 228 andi(rd, rs, rt.imm32_); 229 } else { 230 // li handles the relocation. 231 ASSERT(!rs.is(at)); 232 li(at, rt); 233 and_(rd, rs, at); 234 } 235 } 236 } 237 238 239 void MacroAssembler::Or(Register rd, Register rs, const Operand& rt) { 240 if (rt.is_reg()) { 241 or_(rd, rs, rt.rm()); 242 } else { 243 if (is_int16(rt.imm32_) && !MustUseAt(rt.rmode_)) { 244 ori(rd, rs, rt.imm32_); 245 } else { 246 // li handles the relocation. 247 ASSERT(!rs.is(at)); 248 li(at, rt); 249 or_(rd, rs, at); 250 } 251 } 252 } 253 254 255 void MacroAssembler::Xor(Register rd, Register rs, const Operand& rt) { 256 if (rt.is_reg()) { 257 xor_(rd, rs, rt.rm()); 258 } else { 259 if (is_int16(rt.imm32_) && !MustUseAt(rt.rmode_)) { 260 xori(rd, rs, rt.imm32_); 261 } else { 262 // li handles the relocation. 263 ASSERT(!rs.is(at)); 264 li(at, rt); 265 xor_(rd, rs, at); 266 } 267 } 268 } 269 270 271 void MacroAssembler::Nor(Register rd, Register rs, const Operand& rt) { 272 if (rt.is_reg()) { 273 nor(rd, rs, rt.rm()); 274 } else { 275 // li handles the relocation. 276 ASSERT(!rs.is(at)); 277 li(at, rt); 278 nor(rd, rs, at); 279 } 280 } 281 282 283 void MacroAssembler::Slt(Register rd, Register rs, const Operand& rt) { 284 if (rt.is_reg()) { 285 slt(rd, rs, rt.rm()); 286 } else { 287 if (is_int16(rt.imm32_) && !MustUseAt(rt.rmode_)) { 288 slti(rd, rs, rt.imm32_); 289 } else { 290 // li handles the relocation. 291 ASSERT(!rs.is(at)); 292 li(at, rt); 293 slt(rd, rs, at); 294 } 295 } 296 } 297 298 299 void MacroAssembler::Sltu(Register rd, Register rs, const Operand& rt) { 300 if (rt.is_reg()) { 301 sltu(rd, rs, rt.rm()); 302 } else { 303 if (is_int16(rt.imm32_) && !MustUseAt(rt.rmode_)) { 304 sltiu(rd, rs, rt.imm32_); 305 } else { 306 // li handles the relocation. 307 ASSERT(!rs.is(at)); 308 li(at, rt); 309 sltu(rd, rs, at); 310 } 311 } 312 } 313 314 315 //------------Pseudo-instructions------------- 316 317 void MacroAssembler::movn(Register rd, Register rt) { 318 addiu(at, zero_reg, -1); // Fill at with ones. 319 xor_(rd, rt, at); 320 } 321 322 323 // load wartd in a register 324 void MacroAssembler::li(Register rd, Operand j, bool gen2instr) { 325 ASSERT(!j.is_reg()); 326 327 if (!MustUseAt(j.rmode_) && !gen2instr) { 328 // Normal load of an immediate value which does not need Relocation Info. 329 if (is_int16(j.imm32_)) { 330 addiu(rd, zero_reg, j.imm32_); 331 } else if (!(j.imm32_ & HIMask)) { 332 ori(rd, zero_reg, j.imm32_); 333 } else if (!(j.imm32_ & LOMask)) { 334 lui(rd, (HIMask & j.imm32_) >> 16); 335 } else { 336 lui(rd, (HIMask & j.imm32_) >> 16); 337 ori(rd, rd, (LOMask & j.imm32_)); 338 } 339 } else if (MustUseAt(j.rmode_) || gen2instr) { 340 if (MustUseAt(j.rmode_)) { 341 RecordRelocInfo(j.rmode_, j.imm32_); 342 } 343 // We need always the same number of instructions as we may need to patch 344 // this code to load another value which may need 2 instructions to load. 345 if (is_int16(j.imm32_)) { 346 nop(); 347 addiu(rd, zero_reg, j.imm32_); 348 } else if (!(j.imm32_ & HIMask)) { 349 nop(); 350 ori(rd, zero_reg, j.imm32_); 351 } else if (!(j.imm32_ & LOMask)) { 352 nop(); 353 lui(rd, (HIMask & j.imm32_) >> 16); 354 } else { 355 lui(rd, (HIMask & j.imm32_) >> 16); 356 ori(rd, rd, (LOMask & j.imm32_)); 357 } 358 } 359 } 360 361 362 // Exception-generating instructions and debugging support 363 void MacroAssembler::stop(const char* msg) { 364 // TO_UPGRADE: Just a break for now. Maybe we could upgrade it. 365 // We use the 0x54321 value to be able to find it easily when reading memory. 366 break_(0x54321); 367 } 368 369 370 void MacroAssembler::MultiPush(RegList regs) { 371 int16_t NumSaved = 0; 372 int16_t NumToPush = NumberOfBitsSet(regs); 373 374 addiu(sp, sp, -4 * NumToPush); 375 for (int16_t i = 0; i < kNumRegisters; i++) { 376 if ((regs & (1 << i)) != 0) { 377 sw(ToRegister(i), MemOperand(sp, 4 * (NumToPush - ++NumSaved))); 378 } 379 } 380 } 381 382 383 void MacroAssembler::MultiPushReversed(RegList regs) { 384 int16_t NumSaved = 0; 385 int16_t NumToPush = NumberOfBitsSet(regs); 386 387 addiu(sp, sp, -4 * NumToPush); 388 for (int16_t i = kNumRegisters; i > 0; i--) { 389 if ((regs & (1 << i)) != 0) { 390 sw(ToRegister(i), MemOperand(sp, 4 * (NumToPush - ++NumSaved))); 391 } 392 } 393 } 394 395 396 void MacroAssembler::MultiPop(RegList regs) { 397 int16_t NumSaved = 0; 398 399 for (int16_t i = kNumRegisters; i > 0; i--) { 400 if ((regs & (1 << i)) != 0) { 401 lw(ToRegister(i), MemOperand(sp, 4 * (NumSaved++))); 402 } 403 } 404 addiu(sp, sp, 4 * NumSaved); 405 } 406 407 408 void MacroAssembler::MultiPopReversed(RegList regs) { 409 int16_t NumSaved = 0; 410 411 for (int16_t i = 0; i < kNumRegisters; i++) { 412 if ((regs & (1 << i)) != 0) { 413 lw(ToRegister(i), MemOperand(sp, 4 * (NumSaved++))); 414 } 415 } 416 addiu(sp, sp, 4 * NumSaved); 417 } 418 419 420 // Emulated condtional branches do not emit a nop in the branch delay slot. 421 422 // Trashes the at register if no scratch register is provided. 423 void MacroAssembler::Branch(Condition cond, int16_t offset, Register rs, 424 const Operand& rt, Register scratch) { 425 Register r2; 426 if (rt.is_reg()) { 427 // We don't want any other register but scratch clobbered. 428 ASSERT(!scratch.is(rs) && !scratch.is(rt.rm_)); 429 r2 = rt.rm_; 430 } else if (cond != cc_always) { 431 // We don't want any other register but scratch clobbered. 432 ASSERT(!scratch.is(rs)); 433 r2 = scratch; 434 li(r2, rt); 435 } 436 437 switch (cond) { 438 case cc_always: 439 b(offset); 440 break; 441 case eq: 442 beq(rs, r2, offset); 443 break; 444 case ne: 445 bne(rs, r2, offset); 446 break; 447 448 // Signed comparison 449 case greater: 450 slt(scratch, r2, rs); 451 bne(scratch, zero_reg, offset); 452 break; 453 case greater_equal: 454 slt(scratch, rs, r2); 455 beq(scratch, zero_reg, offset); 456 break; 457 case less: 458 slt(scratch, rs, r2); 459 bne(scratch, zero_reg, offset); 460 break; 461 case less_equal: 462 slt(scratch, r2, rs); 463 beq(scratch, zero_reg, offset); 464 break; 465 466 // Unsigned comparison. 467 case Ugreater: 468 sltu(scratch, r2, rs); 469 bne(scratch, zero_reg, offset); 470 break; 471 case Ugreater_equal: 472 sltu(scratch, rs, r2); 473 beq(scratch, zero_reg, offset); 474 break; 475 case Uless: 476 sltu(scratch, rs, r2); 477 bne(scratch, zero_reg, offset); 478 break; 479 case Uless_equal: 480 sltu(scratch, r2, rs); 481 beq(scratch, zero_reg, offset); 482 break; 483 484 default: 485 UNREACHABLE(); 486 } 487 } 488 489 490 void MacroAssembler::Branch(Condition cond, Label* L, Register rs, 491 const Operand& rt, Register scratch) { 492 Register r2; 493 if (rt.is_reg()) { 494 r2 = rt.rm_; 495 } else if (cond != cc_always) { 496 r2 = scratch; 497 li(r2, rt); 498 } 499 500 // We use branch_offset as an argument for the branch instructions to be sure 501 // it is called just before generating the branch instruction, as needed. 502 503 switch (cond) { 504 case cc_always: 505 b(shifted_branch_offset(L, false)); 506 break; 507 case eq: 508 beq(rs, r2, shifted_branch_offset(L, false)); 509 break; 510 case ne: 511 bne(rs, r2, shifted_branch_offset(L, false)); 512 break; 513 514 // Signed comparison 515 case greater: 516 slt(scratch, r2, rs); 517 bne(scratch, zero_reg, shifted_branch_offset(L, false)); 518 break; 519 case greater_equal: 520 slt(scratch, rs, r2); 521 beq(scratch, zero_reg, shifted_branch_offset(L, false)); 522 break; 523 case less: 524 slt(scratch, rs, r2); 525 bne(scratch, zero_reg, shifted_branch_offset(L, false)); 526 break; 527 case less_equal: 528 slt(scratch, r2, rs); 529 beq(scratch, zero_reg, shifted_branch_offset(L, false)); 530 break; 531 532 // Unsigned comparison. 533 case Ugreater: 534 sltu(scratch, r2, rs); 535 bne(scratch, zero_reg, shifted_branch_offset(L, false)); 536 break; 537 case Ugreater_equal: 538 sltu(scratch, rs, r2); 539 beq(scratch, zero_reg, shifted_branch_offset(L, false)); 540 break; 541 case Uless: 542 sltu(scratch, rs, r2); 543 bne(scratch, zero_reg, shifted_branch_offset(L, false)); 544 break; 545 case Uless_equal: 546 sltu(scratch, r2, rs); 547 beq(scratch, zero_reg, shifted_branch_offset(L, false)); 548 break; 549 550 default: 551 UNREACHABLE(); 552 } 553 } 554 555 556 // Trashes the at register if no scratch register is provided. 557 // We need to use a bgezal or bltzal, but they can't be used directly with the 558 // slt instructions. We could use sub or add instead but we would miss overflow 559 // cases, so we keep slt and add an intermediate third instruction. 560 void MacroAssembler::BranchAndLink(Condition cond, int16_t offset, Register rs, 561 const Operand& rt, Register scratch) { 562 Register r2; 563 if (rt.is_reg()) { 564 r2 = rt.rm_; 565 } else if (cond != cc_always) { 566 r2 = scratch; 567 li(r2, rt); 568 } 569 570 switch (cond) { 571 case cc_always: 572 bal(offset); 573 break; 574 case eq: 575 bne(rs, r2, 2); 576 nop(); 577 bal(offset); 578 break; 579 case ne: 580 beq(rs, r2, 2); 581 nop(); 582 bal(offset); 583 break; 584 585 // Signed comparison 586 case greater: 587 slt(scratch, r2, rs); 588 addiu(scratch, scratch, -1); 589 bgezal(scratch, offset); 590 break; 591 case greater_equal: 592 slt(scratch, rs, r2); 593 addiu(scratch, scratch, -1); 594 bltzal(scratch, offset); 595 break; 596 case less: 597 slt(scratch, rs, r2); 598 addiu(scratch, scratch, -1); 599 bgezal(scratch, offset); 600 break; 601 case less_equal: 602 slt(scratch, r2, rs); 603 addiu(scratch, scratch, -1); 604 bltzal(scratch, offset); 605 break; 606 607 // Unsigned comparison. 608 case Ugreater: 609 sltu(scratch, r2, rs); 610 addiu(scratch, scratch, -1); 611 bgezal(scratch, offset); 612 break; 613 case Ugreater_equal: 614 sltu(scratch, rs, r2); 615 addiu(scratch, scratch, -1); 616 bltzal(scratch, offset); 617 break; 618 case Uless: 619 sltu(scratch, rs, r2); 620 addiu(scratch, scratch, -1); 621 bgezal(scratch, offset); 622 break; 623 case Uless_equal: 624 sltu(scratch, r2, rs); 625 addiu(scratch, scratch, -1); 626 bltzal(scratch, offset); 627 break; 628 629 default: 630 UNREACHABLE(); 631 } 632 } 633 634 635 void MacroAssembler::BranchAndLink(Condition cond, Label* L, Register rs, 636 const Operand& rt, Register scratch) { 637 Register r2; 638 if (rt.is_reg()) { 639 r2 = rt.rm_; 640 } else if (cond != cc_always) { 641 r2 = scratch; 642 li(r2, rt); 643 } 644 645 switch (cond) { 646 case cc_always: 647 bal(shifted_branch_offset(L, false)); 648 break; 649 case eq: 650 bne(rs, r2, 2); 651 nop(); 652 bal(shifted_branch_offset(L, false)); 653 break; 654 case ne: 655 beq(rs, r2, 2); 656 nop(); 657 bal(shifted_branch_offset(L, false)); 658 break; 659 660 // Signed comparison 661 case greater: 662 slt(scratch, r2, rs); 663 addiu(scratch, scratch, -1); 664 bgezal(scratch, shifted_branch_offset(L, false)); 665 break; 666 case greater_equal: 667 slt(scratch, rs, r2); 668 addiu(scratch, scratch, -1); 669 bltzal(scratch, shifted_branch_offset(L, false)); 670 break; 671 case less: 672 slt(scratch, rs, r2); 673 addiu(scratch, scratch, -1); 674 bgezal(scratch, shifted_branch_offset(L, false)); 675 break; 676 case less_equal: 677 slt(scratch, r2, rs); 678 addiu(scratch, scratch, -1); 679 bltzal(scratch, shifted_branch_offset(L, false)); 680 break; 681 682 // Unsigned comparison. 683 case Ugreater: 684 sltu(scratch, r2, rs); 685 addiu(scratch, scratch, -1); 686 bgezal(scratch, shifted_branch_offset(L, false)); 687 break; 688 case Ugreater_equal: 689 sltu(scratch, rs, r2); 690 addiu(scratch, scratch, -1); 691 bltzal(scratch, shifted_branch_offset(L, false)); 692 break; 693 case Uless: 694 sltu(scratch, rs, r2); 695 addiu(scratch, scratch, -1); 696 bgezal(scratch, shifted_branch_offset(L, false)); 697 break; 698 case Uless_equal: 699 sltu(scratch, r2, rs); 700 addiu(scratch, scratch, -1); 701 bltzal(scratch, shifted_branch_offset(L, false)); 702 break; 703 704 default: 705 UNREACHABLE(); 706 } 707 } 708 709 710 void MacroAssembler::Jump(const Operand& target, 711 Condition cond, Register rs, const Operand& rt) { 712 if (target.is_reg()) { 713 if (cond == cc_always) { 714 jr(target.rm()); 715 } else { 716 Branch(NegateCondition(cond), 2, rs, rt); 717 nop(); 718 jr(target.rm()); 719 } 720 } else { // !target.is_reg() 721 if (!MustUseAt(target.rmode_)) { 722 if (cond == cc_always) { 723 j(target.imm32_); 724 } else { 725 Branch(NegateCondition(cond), 2, rs, rt); 726 nop(); 727 j(target.imm32_); // will generate only one instruction. 728 } 729 } else { // MustUseAt(target) 730 li(at, rt); 731 if (cond == cc_always) { 732 jr(at); 733 } else { 734 Branch(NegateCondition(cond), 2, rs, rt); 735 nop(); 736 jr(at); // will generate only one instruction. 737 } 738 } 739 } 740 } 741 742 743 void MacroAssembler::Call(const Operand& target, 744 Condition cond, Register rs, const Operand& rt) { 745 if (target.is_reg()) { 746 if (cond == cc_always) { 747 jalr(target.rm()); 748 } else { 749 Branch(NegateCondition(cond), 2, rs, rt); 750 nop(); 751 jalr(target.rm()); 752 } 753 } else { // !target.is_reg() 754 if (!MustUseAt(target.rmode_)) { 755 if (cond == cc_always) { 756 jal(target.imm32_); 757 } else { 758 Branch(NegateCondition(cond), 2, rs, rt); 759 nop(); 760 jal(target.imm32_); // will generate only one instruction. 761 } 762 } else { // MustUseAt(target) 763 li(at, rt); 764 if (cond == cc_always) { 765 jalr(at); 766 } else { 767 Branch(NegateCondition(cond), 2, rs, rt); 768 nop(); 769 jalr(at); // will generate only one instruction. 770 } 771 } 772 } 773 } 774 775 void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) { 776 UNIMPLEMENTED_MIPS(); 777 } 778 779 780 void MacroAssembler::Drop(int count, Condition cond) { 781 UNIMPLEMENTED_MIPS(); 782 } 783 784 785 void MacroAssembler::Call(Label* target) { 786 UNIMPLEMENTED_MIPS(); 787 } 788 789 790 // --------------------------------------------------------------------------- 791 // Exception handling 792 793 void MacroAssembler::PushTryHandler(CodeLocation try_location, 794 HandlerType type) { 795 UNIMPLEMENTED_MIPS(); 796 } 797 798 799 void MacroAssembler::PopTryHandler() { 800 UNIMPLEMENTED_MIPS(); 801 } 802 803 804 805 // --------------------------------------------------------------------------- 806 // Activation frames 807 808 void MacroAssembler::CallStub(CodeStub* stub, Condition cond, 809 Register r1, const Operand& r2) { 810 UNIMPLEMENTED_MIPS(); 811 } 812 813 814 void MacroAssembler::StubReturn(int argc) { 815 UNIMPLEMENTED_MIPS(); 816 } 817 818 819 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) { 820 UNIMPLEMENTED_MIPS(); 821 } 822 823 824 void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) { 825 UNIMPLEMENTED_MIPS(); 826 } 827 828 829 void MacroAssembler::TailCallRuntime(const ExternalReference& ext, 830 int num_arguments, 831 int result_size) { 832 UNIMPLEMENTED_MIPS(); 833 } 834 835 836 void MacroAssembler::JumpToRuntime(const ExternalReference& builtin) { 837 UNIMPLEMENTED_MIPS(); 838 } 839 840 841 Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id, 842 bool* resolved) { 843 UNIMPLEMENTED_MIPS(); 844 return Handle<Code>(reinterpret_cast<Code*>(NULL)); // UNIMPLEMENTED RETURN 845 } 846 847 848 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 849 InvokeJSFlags flags) { 850 UNIMPLEMENTED_MIPS(); 851 } 852 853 854 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { 855 UNIMPLEMENTED_MIPS(); 856 } 857 858 859 void MacroAssembler::SetCounter(StatsCounter* counter, int value, 860 Register scratch1, Register scratch2) { 861 UNIMPLEMENTED_MIPS(); 862 } 863 864 865 void MacroAssembler::IncrementCounter(StatsCounter* counter, int value, 866 Register scratch1, Register scratch2) { 867 UNIMPLEMENTED_MIPS(); 868 } 869 870 871 void MacroAssembler::DecrementCounter(StatsCounter* counter, int value, 872 Register scratch1, Register scratch2) { 873 UNIMPLEMENTED_MIPS(); 874 } 875 876 877 878 void MacroAssembler::Assert(Condition cc, const char* msg, 879 Register rs, Operand rt) { 880 UNIMPLEMENTED_MIPS(); 881 } 882 883 884 void MacroAssembler::Check(Condition cc, const char* msg, 885 Register rs, Operand rt) { 886 UNIMPLEMENTED_MIPS(); 887 } 888 889 890 void MacroAssembler::Abort(const char* msg) { 891 UNIMPLEMENTED_MIPS(); 892 } 893 894 } } // namespace v8::internal 895 896