| OLD | NEW |
| 1 //===- subzero/src/IceAssemblerMIPS32.cpp - MIPS32 Assembler --------------===// | 1 //===- subzero/src/IceAssemblerMIPS32.cpp - MIPS32 Assembler --------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); | 218 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); |
| 219 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); | 219 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); |
| 220 | 220 |
| 221 Opcode |= Rs << 21; | 221 Opcode |= Rs << 21; |
| 222 Opcode |= Rt << 16; | 222 Opcode |= Rt << 16; |
| 223 Opcode |= Imm & 0xffff; | 223 Opcode |= Imm & 0xffff; |
| 224 | 224 |
| 225 emitInst(Opcode); | 225 emitInst(Opcode); |
| 226 } | 226 } |
| 227 | 227 |
| 228 void AssemblerMIPS32::emitRtRsImm16Rel(IValueT Opcode, const Operand *OpRt, |
| 229 const Operand *OpRs, |
| 230 const Operand *OpImm, |
| 231 const RelocOp Reloc, |
| 232 const char *InsnName) { |
| 233 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); |
| 234 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); |
| 235 uint32_t Imm16 = 0; |
| 236 |
| 237 if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpImm)) { |
| 238 emitFixup(createMIPS32Fixup(Reloc, OpRel)); |
| 239 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpImm)) { |
| 240 Imm16 = C32->getValue(); |
| 241 } else { |
| 242 llvm::report_fatal_error(std::string(InsnName) + ": Invalid 3rd operand"); |
| 243 } |
| 244 |
| 245 Opcode |= Rs << 21; |
| 246 Opcode |= Rt << 16; |
| 247 Opcode |= Imm16 & 0xffff; |
| 248 |
| 249 emitInst(Opcode); |
| 250 } |
| 251 |
| 228 void AssemblerMIPS32::emitFtRsImm16(IValueT Opcode, const Operand *OpFt, | 252 void AssemblerMIPS32::emitFtRsImm16(IValueT Opcode, const Operand *OpFt, |
| 229 const Operand *OpRs, const uint32_t Imm, | 253 const Operand *OpRs, const uint32_t Imm, |
| 230 const char *InsnName) { | 254 const char *InsnName) { |
| 231 const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName); | 255 const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName); |
| 232 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); | 256 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); |
| 233 | 257 |
| 234 Opcode |= Rs << 21; | 258 Opcode |= Rs << 21; |
| 235 Opcode |= Ft << 16; | 259 Opcode |= Ft << 16; |
| 236 Opcode |= Imm & 0xffff; | 260 Opcode |= Imm & 0xffff; |
| 237 | 261 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 void AssemblerMIPS32::abs_d(const Operand *OpFd, const Operand *OpFs) { | 364 void AssemblerMIPS32::abs_d(const Operand *OpFd, const Operand *OpFs) { |
| 341 static constexpr IValueT Opcode = 0x44000005; | 365 static constexpr IValueT Opcode = 0x44000005; |
| 342 emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "abs.d"); | 366 emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "abs.d"); |
| 343 } | 367 } |
| 344 | 368 |
| 345 void AssemblerMIPS32::abs_s(const Operand *OpFd, const Operand *OpFs) { | 369 void AssemblerMIPS32::abs_s(const Operand *OpFd, const Operand *OpFs) { |
| 346 static constexpr IValueT Opcode = 0x44000005; | 370 static constexpr IValueT Opcode = 0x44000005; |
| 347 emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "abs.s"); | 371 emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "abs.s"); |
| 348 } | 372 } |
| 349 | 373 |
| 374 void AssemblerMIPS32::addi(const Operand *OpRt, const Operand *OpRs, |
| 375 const uint32_t Imm) { |
| 376 static constexpr IValueT Opcode = 0x20000000; |
| 377 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addi"); |
| 378 } |
| 379 |
| 350 void AssemblerMIPS32::add_d(const Operand *OpFd, const Operand *OpFs, | 380 void AssemblerMIPS32::add_d(const Operand *OpFd, const Operand *OpFs, |
| 351 const Operand *OpFt) { | 381 const Operand *OpFt) { |
| 352 static constexpr IValueT Opcode = 0x44000000; | 382 static constexpr IValueT Opcode = 0x44000000; |
| 353 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "add.d"); | 383 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "add.d"); |
| 354 } | 384 } |
| 355 | 385 |
| 356 void AssemblerMIPS32::add_s(const Operand *OpFd, const Operand *OpFs, | 386 void AssemblerMIPS32::add_s(const Operand *OpFd, const Operand *OpFs, |
| 357 const Operand *OpFt) { | 387 const Operand *OpFt) { |
| 358 static constexpr IValueT Opcode = 0x44000000; | 388 static constexpr IValueT Opcode = 0x44000000; |
| 359 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "add.s"); | 389 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "add.s"); |
| 360 } | 390 } |
| 361 | 391 |
| 362 void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs, | 392 void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs, |
| 363 const uint32_t Imm) { | 393 const uint32_t Imm) { |
| 364 static constexpr IValueT Opcode = 0x24000000; | 394 static constexpr IValueT Opcode = 0x24000000; |
| 365 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addiu"); | 395 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "addiu"); |
| 366 } | 396 } |
| 367 | 397 |
| 398 void AssemblerMIPS32::addiu(const Operand *OpRt, const Operand *OpRs, |
| 399 const Operand *OpImm, const RelocOp Reloc) { |
| 400 static constexpr IValueT Opcode = 0x24000000; |
| 401 emitRtRsImm16Rel(Opcode, OpRt, OpRs, OpImm, Reloc, "addiu"); |
| 402 } |
| 403 |
| 368 void AssemblerMIPS32::addu(const Operand *OpRd, const Operand *OpRs, | 404 void AssemblerMIPS32::addu(const Operand *OpRd, const Operand *OpRs, |
| 369 const Operand *OpRt) { | 405 const Operand *OpRt) { |
| 370 static constexpr IValueT Opcode = 0x00000021; | 406 static constexpr IValueT Opcode = 0x00000021; |
| 371 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "addu"); | 407 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "addu"); |
| 372 } | 408 } |
| 373 | 409 |
| 374 void AssemblerMIPS32::and_(const Operand *OpRd, const Operand *OpRs, | 410 void AssemblerMIPS32::and_(const Operand *OpRd, const Operand *OpRs, |
| 375 const Operand *OpRt) { | 411 const Operand *OpRt) { |
| 376 static constexpr IValueT Opcode = 0x00000024; | 412 static constexpr IValueT Opcode = 0x00000024; |
| 377 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "and"); | 413 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "and"); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 const Operand *OpFt) { | 571 const Operand *OpFt) { |
| 536 static constexpr IValueT Opcode = 0x44000003; | 572 static constexpr IValueT Opcode = 0x44000003; |
| 537 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "div.s"); | 573 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "div.s"); |
| 538 } | 574 } |
| 539 | 575 |
| 540 void AssemblerMIPS32::divu(const Operand *OpRs, const Operand *OpRt) { | 576 void AssemblerMIPS32::divu(const Operand *OpRs, const Operand *OpRt) { |
| 541 static constexpr IValueT Opcode = 0x0000001B; | 577 static constexpr IValueT Opcode = 0x0000001B; |
| 542 emitRsRt(Opcode, OpRs, OpRt, "divu"); | 578 emitRsRt(Opcode, OpRs, OpRt, "divu"); |
| 543 } | 579 } |
| 544 | 580 |
| 545 void AssemblerMIPS32::lui(const Operand *OpRt, const uint16_t Imm) { | 581 MIPS32Fixup *AssemblerMIPS32::createMIPS32Fixup(const RelocOp Reloc, |
| 582 const Constant *RelOp) { |
| 583 MIPS32Fixup *Fixup = new (allocate<MIPS32Fixup>()) MIPS32Fixup(); |
| 584 switch (Reloc) { |
| 585 case RelocOp::RO_Hi: |
| 586 Fixup->set_kind(llvm::ELF::R_MIPS_HI16); |
| 587 break; |
| 588 case RelocOp::RO_Lo: |
| 589 Fixup->set_kind(llvm::ELF::R_MIPS_LO16); |
| 590 break; |
| 591 case RelocOp::RO_Jal: |
| 592 Fixup->set_kind(llvm::ELF::R_MIPS_26); |
| 593 break; |
| 594 default: |
| 595 llvm::report_fatal_error("Fixup: Invalid Reloc type"); |
| 596 break; |
| 597 } |
| 598 Fixup->set_value(RelOp); |
| 599 Buffer.installFixup(Fixup); |
| 600 return Fixup; |
| 601 } |
| 602 |
| 603 size_t MIPS32Fixup::emit(GlobalContext *Ctx, const Assembler &Asm) const { |
| 604 if (!BuildDefs::dump()) |
| 605 return InstMIPS32::InstSize; |
| 606 Ostream &Str = Ctx->getStrEmit(); |
| 607 IValueT Inst = Asm.load<IValueT>(position()); |
| 608 const auto Symbol = symbol().toString(); |
| 609 Str << "\t" |
| 610 << ".word " << llvm::format_hex(Inst, 8) << " # "; |
| 611 switch (kind()) { |
| 612 case llvm::ELF::R_MIPS_HI16: |
| 613 Str << "R_MIPS_HI16 "; |
| 614 break; |
| 615 case llvm::ELF::R_MIPS_LO16: |
| 616 Str << "R_MIPS_LO16 "; |
| 617 break; |
| 618 case llvm::ELF::R_MIPS_26: |
| 619 Str << "R_MIPS_26 "; |
| 620 break; |
| 621 default: |
| 622 Str << "Unknown "; |
| 623 break; |
| 624 } |
| 625 Str << Symbol << "\n"; |
| 626 return InstMIPS32::InstSize; |
| 627 } |
| 628 |
| 629 void MIPS32Fixup::emitOffset(Assembler *Asm) const { |
| 630 const IValueT Inst = Asm->load<IValueT>(position()); |
| 631 IValueT ImmMask = 0; |
| 632 const IValueT Imm = offset(); |
| 633 if (kind() == llvm::ELF::R_MIPS_26) { |
| 634 ImmMask = 0x03FFFFFF; |
| 635 } else { |
| 636 ImmMask = 0x0000FFFF; |
| 637 } |
| 638 Asm->store(position(), (Inst & ~ImmMask) | (Imm & ImmMask)); |
| 639 } |
| 640 |
| 641 void AssemblerMIPS32::jal(const ConstantRelocatable *Target) { |
| 642 IValueT Opcode = 0x0C000000; |
| 643 emitFixup(createMIPS32Fixup(RelocOp::RO_Jal, Target)); |
| 644 emitInst(Opcode); |
| 645 nop(); |
| 646 } |
| 647 |
| 648 void AssemblerMIPS32::lui(const Operand *OpRt, const Operand *OpImm, |
| 649 const RelocOp Reloc) { |
| 546 IValueT Opcode = 0x3C000000; | 650 IValueT Opcode = 0x3C000000; |
| 547 const IValueT Rt = encodeGPRegister(OpRt, "Rt", "lui"); | 651 const IValueT Rt = encodeGPRegister(OpRt, "Rt", "lui"); |
| 652 IValueT Imm16 = 0; |
| 653 |
| 654 if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpImm)) { |
| 655 emitFixup(createMIPS32Fixup(Reloc, OpRel)); |
| 656 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpImm)) { |
| 657 Imm16 = C32->getValue(); |
| 658 } else { |
| 659 llvm::report_fatal_error("lui: Invalid 2nd operand"); |
| 660 } |
| 661 |
| 548 Opcode |= Rt << 16; | 662 Opcode |= Rt << 16; |
| 549 Opcode |= Imm; | 663 Opcode |= Imm16; |
| 550 emitInst(Opcode); | 664 emitInst(Opcode); |
| 551 } | 665 } |
| 552 | 666 |
| 667 void AssemblerMIPS32::ldc1(const Operand *OpRt, const Operand *OpBase, |
| 668 const Operand *OpOff, const RelocOp Reloc) { |
| 669 IValueT Opcode = 0xD4000000; |
| 670 const IValueT Rt = encodeFPRegister(OpRt, "Ft", "ldc1"); |
| 671 const IValueT Base = encodeGPRegister(OpBase, "Base", "ldc1"); |
| 672 IValueT Imm16 = 0; |
| 673 |
| 674 if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpOff)) { |
| 675 emitFixup(createMIPS32Fixup(Reloc, OpRel)); |
| 676 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpOff)) { |
| 677 Imm16 = C32->getValue(); |
| 678 } else { |
| 679 llvm::report_fatal_error("ldc1: Invalid 2nd operand"); |
| 680 } |
| 681 |
| 682 Opcode |= Base << 21; |
| 683 Opcode |= Rt << 16; |
| 684 Opcode |= Imm16; |
| 685 emitInst(Opcode); |
| 686 } |
| 687 |
| 553 void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase, | 688 void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase, |
| 554 const uint32_t Offset) { | 689 const uint32_t Offset) { |
| 555 switch (OpRt->getType()) { | 690 switch (OpRt->getType()) { |
| 556 case IceType_i1: | 691 case IceType_i1: |
| 557 case IceType_i8: { | 692 case IceType_i8: { |
| 558 static constexpr IValueT Opcode = 0x80000000; | 693 static constexpr IValueT Opcode = 0x80000000; |
| 559 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lb"); | 694 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lb"); |
| 560 break; | 695 break; |
| 561 } | 696 } |
| 562 case IceType_i16: { | 697 case IceType_i16: { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 576 } | 711 } |
| 577 case IceType_f64: { | 712 case IceType_f64: { |
| 578 static constexpr IValueT Opcode = 0xD4000000; | 713 static constexpr IValueT Opcode = 0xD4000000; |
| 579 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "ldc1"); | 714 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "ldc1"); |
| 580 break; | 715 break; |
| 581 } | 716 } |
| 582 default: { UnimplementedError(getFlags()); } | 717 default: { UnimplementedError(getFlags()); } |
| 583 } | 718 } |
| 584 } | 719 } |
| 585 | 720 |
| 721 void AssemblerMIPS32::lwc1(const Operand *OpRt, const Operand *OpBase, |
| 722 const Operand *OpOff, const RelocOp Reloc) { |
| 723 IValueT Opcode = 0xC4000000; |
| 724 const IValueT Rt = encodeFPRegister(OpRt, "Ft", "lwc1"); |
| 725 const IValueT Base = encodeGPRegister(OpBase, "Base", "lwc1"); |
| 726 IValueT Imm16 = 0; |
| 727 |
| 728 if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpOff)) { |
| 729 emitFixup(createMIPS32Fixup(Reloc, OpRel)); |
| 730 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpOff)) { |
| 731 Imm16 = C32->getValue(); |
| 732 } else { |
| 733 llvm::report_fatal_error("lwc1: Invalid 2nd operand"); |
| 734 } |
| 735 |
| 736 Opcode |= Base << 21; |
| 737 Opcode |= Rt << 16; |
| 738 Opcode |= Imm16; |
| 739 emitInst(Opcode); |
| 740 } |
| 741 |
| 586 void AssemblerMIPS32::mfc1(const Operand *OpRt, const Operand *OpFs) { | 742 void AssemblerMIPS32::mfc1(const Operand *OpRt, const Operand *OpFs) { |
| 587 static constexpr IValueT Opcode = 0x44000000; | 743 static constexpr IValueT Opcode = 0x44000000; |
| 588 emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mfc1"); | 744 emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mfc1"); |
| 589 } | 745 } |
| 590 | 746 |
| 591 void AssemblerMIPS32::mfhi(const Operand *OpRd) { | 747 void AssemblerMIPS32::mfhi(const Operand *OpRd) { |
| 592 IValueT Opcode = 0x000000010; | 748 IValueT Opcode = 0x000000010; |
| 593 IValueT Rd = encodeGPRegister(OpRd, "Rd", "mfhi"); | 749 IValueT Rd = encodeGPRegister(OpRd, "Rd", "mfhi"); |
| 594 Opcode |= Rd << 11; | 750 Opcode |= Rd << 11; |
| 595 emitInst(Opcode); | 751 emitInst(Opcode); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 613 } | 769 } |
| 614 | 770 |
| 615 void AssemblerMIPS32::move(const Operand *OpRd, const Operand *OpRs) { | 771 void AssemblerMIPS32::move(const Operand *OpRd, const Operand *OpRs) { |
| 616 | 772 |
| 617 const Type DstType = OpRd->getType(); | 773 const Type DstType = OpRd->getType(); |
| 618 const Type SrcType = OpRs->getType(); | 774 const Type SrcType = OpRs->getType(); |
| 619 | 775 |
| 620 if ((isScalarIntegerType(DstType) && isScalarFloatingType(SrcType)) || | 776 if ((isScalarIntegerType(DstType) && isScalarFloatingType(SrcType)) || |
| 621 (isScalarFloatingType(DstType) && isScalarIntegerType(SrcType))) { | 777 (isScalarFloatingType(DstType) && isScalarIntegerType(SrcType))) { |
| 622 if (isScalarFloatingType(DstType)) { | 778 if (isScalarFloatingType(DstType)) { |
| 623 mtc1(OpRd, OpRs); | 779 mtc1(OpRs, OpRd); |
| 624 } else { | 780 } else { |
| 625 mfc1(OpRd, OpRs); | 781 mfc1(OpRd, OpRs); |
| 626 } | 782 } |
| 627 } else { | 783 } else { |
| 628 switch (DstType) { | 784 switch (DstType) { |
| 629 case IceType_f32: | 785 case IceType_f32: |
| 630 mov_s(OpRd, OpRs); | 786 mov_s(OpRd, OpRs); |
| 631 break; | 787 break; |
| 632 case IceType_f64: | 788 case IceType_f64: |
| 633 mov_d(OpRd, OpRs); | 789 mov_d(OpRd, OpRs); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 static constexpr IValueT Opcode = 0x44000002; | 907 static constexpr IValueT Opcode = 0x44000002; |
| 752 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "mul.d"); | 908 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "mul.d"); |
| 753 } | 909 } |
| 754 | 910 |
| 755 void AssemblerMIPS32::mul_s(const Operand *OpFd, const Operand *OpFs, | 911 void AssemblerMIPS32::mul_s(const Operand *OpFd, const Operand *OpFs, |
| 756 const Operand *OpFt) { | 912 const Operand *OpFt) { |
| 757 static constexpr IValueT Opcode = 0x44000002; | 913 static constexpr IValueT Opcode = 0x44000002; |
| 758 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s"); | 914 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s"); |
| 759 } | 915 } |
| 760 | 916 |
| 917 void AssemblerMIPS32::mult(const Operand *OpRs, const Operand *OpRt) { |
| 918 static constexpr IValueT Opcode = 0x00000018; |
| 919 emitRsRt(Opcode, OpRs, OpRt, "mult"); |
| 920 } |
| 921 |
| 761 void AssemblerMIPS32::multu(const Operand *OpRs, const Operand *OpRt) { | 922 void AssemblerMIPS32::multu(const Operand *OpRs, const Operand *OpRt) { |
| 762 static constexpr IValueT Opcode = 0x00000019; | 923 static constexpr IValueT Opcode = 0x00000019; |
| 763 emitRsRt(Opcode, OpRs, OpRt, "multu"); | 924 emitRsRt(Opcode, OpRs, OpRt, "multu"); |
| 764 } | 925 } |
| 765 | 926 |
| 766 void AssemblerMIPS32::nor(const Operand *OpRd, const Operand *OpRs, | 927 void AssemblerMIPS32::nor(const Operand *OpRd, const Operand *OpRs, |
| 767 const Operand *OpRt) { | 928 const Operand *OpRt) { |
| 768 static constexpr IValueT Opcode = 0x00000027; | 929 static constexpr IValueT Opcode = 0x00000027; |
| 769 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "nor"); | 930 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "nor"); |
| 770 } | 931 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 static constexpr IValueT Opcode = 0x44000001; | 1029 static constexpr IValueT Opcode = 0x44000001; |
| 869 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "sub.s"); | 1030 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "sub.s"); |
| 870 } | 1031 } |
| 871 | 1032 |
| 872 void AssemblerMIPS32::subu(const Operand *OpRd, const Operand *OpRs, | 1033 void AssemblerMIPS32::subu(const Operand *OpRd, const Operand *OpRs, |
| 873 const Operand *OpRt) { | 1034 const Operand *OpRt) { |
| 874 static constexpr IValueT Opcode = 0x00000023; | 1035 static constexpr IValueT Opcode = 0x00000023; |
| 875 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "subu"); | 1036 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "subu"); |
| 876 } | 1037 } |
| 877 | 1038 |
| 1039 void AssemblerMIPS32::sdc1(const Operand *OpRt, const Operand *OpBase, |
| 1040 const Operand *OpOff, const RelocOp Reloc) { |
| 1041 IValueT Opcode = 0xF4000000; |
| 1042 const IValueT Rt = encodeFPRegister(OpRt, "Ft", "sdc1"); |
| 1043 const IValueT Base = encodeGPRegister(OpBase, "Base", "sdc1"); |
| 1044 IValueT Imm16 = 0; |
| 1045 |
| 1046 if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpOff)) { |
| 1047 emitFixup(createMIPS32Fixup(Reloc, OpRel)); |
| 1048 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpOff)) { |
| 1049 Imm16 = C32->getValue(); |
| 1050 } else { |
| 1051 llvm::report_fatal_error("sdc1: Invalid 2nd operand"); |
| 1052 } |
| 1053 |
| 1054 Opcode |= Base << 21; |
| 1055 Opcode |= Rt << 16; |
| 1056 Opcode |= Imm16; |
| 1057 emitInst(Opcode); |
| 1058 } |
| 1059 |
| 878 void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase, | 1060 void AssemblerMIPS32::sw(const Operand *OpRt, const Operand *OpBase, |
| 879 const uint32_t Offset) { | 1061 const uint32_t Offset) { |
| 880 switch (OpRt->getType()) { | 1062 switch (OpRt->getType()) { |
| 881 case IceType_i1: | 1063 case IceType_i1: |
| 882 case IceType_i8: { | 1064 case IceType_i8: { |
| 883 static constexpr IValueT Opcode = 0xA0000000; | 1065 static constexpr IValueT Opcode = 0xA0000000; |
| 884 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sb"); | 1066 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "sb"); |
| 885 break; | 1067 break; |
| 886 } | 1068 } |
| 887 case IceType_i16: { | 1069 case IceType_i16: { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 901 } | 1083 } |
| 902 case IceType_f64: { | 1084 case IceType_f64: { |
| 903 static constexpr IValueT Opcode = 0xF4000000; | 1085 static constexpr IValueT Opcode = 0xF4000000; |
| 904 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "sdc1"); | 1086 emitFtRsImm16(Opcode, OpRt, OpBase, Offset, "sdc1"); |
| 905 break; | 1087 break; |
| 906 } | 1088 } |
| 907 default: { UnimplementedError(getFlags()); } | 1089 default: { UnimplementedError(getFlags()); } |
| 908 } | 1090 } |
| 909 } | 1091 } |
| 910 | 1092 |
| 1093 void AssemblerMIPS32::swc1(const Operand *OpRt, const Operand *OpBase, |
| 1094 const Operand *OpOff, const RelocOp Reloc) { |
| 1095 IValueT Opcode = 0xE4000000; |
| 1096 const IValueT Rt = encodeFPRegister(OpRt, "Ft", "swc1"); |
| 1097 const IValueT Base = encodeGPRegister(OpBase, "Base", "swc1"); |
| 1098 IValueT Imm16 = 0; |
| 1099 |
| 1100 if (const auto *OpRel = llvm::dyn_cast<ConstantRelocatable>(OpOff)) { |
| 1101 emitFixup(createMIPS32Fixup(Reloc, OpRel)); |
| 1102 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(OpOff)) { |
| 1103 Imm16 = C32->getValue(); |
| 1104 } else { |
| 1105 llvm::report_fatal_error("swc1: Invalid 2nd operand"); |
| 1106 } |
| 1107 |
| 1108 Opcode |= Base << 21; |
| 1109 Opcode |= Rt << 16; |
| 1110 Opcode |= Imm16; |
| 1111 emitInst(Opcode); |
| 1112 } |
| 1113 |
| 911 void AssemblerMIPS32::teq(const Operand *OpRs, const Operand *OpRt, | 1114 void AssemblerMIPS32::teq(const Operand *OpRs, const Operand *OpRt, |
| 912 const uint32_t TrapCode) { | 1115 const uint32_t TrapCode) { |
| 913 IValueT Opcode = 0x00000034; | 1116 IValueT Opcode = 0x00000034; |
| 914 const IValueT Rs = encodeGPRegister(OpRs, "Rs", "teq"); | 1117 const IValueT Rs = encodeGPRegister(OpRs, "Rs", "teq"); |
| 915 const IValueT Rt = encodeGPRegister(OpRt, "Rt", "teq"); | 1118 const IValueT Rt = encodeGPRegister(OpRt, "Rt", "teq"); |
| 916 Opcode |= (TrapCode & 0xFFFFF) << 6; | 1119 Opcode |= (TrapCode & 0xFFFFF) << 6; |
| 917 Opcode |= Rt << 16; | 1120 Opcode |= Rt << 16; |
| 918 Opcode |= Rs << 21; | 1121 Opcode |= Rs << 21; |
| 919 emitInst(Opcode); | 1122 emitInst(Opcode); |
| 920 } | 1123 } |
| 921 | 1124 |
| 922 void AssemblerMIPS32::trunc_l_d(const Operand *OpFd, const Operand *OpFs) { | 1125 void AssemblerMIPS32::trunc_l_d(const Operand *OpFd, const Operand *OpFs) { |
| 923 static constexpr IValueT Opcode = 0x4400000D; | 1126 static constexpr IValueT Opcode = 0x4400000D; |
| 924 emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "trunc.l.d"); | 1127 emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "trunc.l.d"); |
| 925 } | 1128 } |
| 926 | 1129 |
| 927 void AssemblerMIPS32::trunc_l_s(const Operand *OpFd, const Operand *OpFs) { | 1130 void AssemblerMIPS32::trunc_l_s(const Operand *OpFd, const Operand *OpFs) { |
| 928 static constexpr IValueT Opcode = 0x4400000D; | 1131 static constexpr IValueT Opcode = 0x4400000D; |
| 929 emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "trunc.l.s"); | 1132 emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "trunc.l.s"); |
| 930 } | 1133 } |
| 931 | 1134 |
| 932 void AssemblerMIPS32::trunc_w_d(const Operand *OpFd, const Operand *OpFs) { | 1135 void AssemblerMIPS32::trunc_w_d(const Operand *OpFd, const Operand *OpFs) { |
| 933 static constexpr IValueT Opcode = 0x4400000D; | 1136 static constexpr IValueT Opcode = 0x4400000D; |
| 934 emitCOP1FmtFsFd(Opcode, Word, OpFd, OpFs, "trunc.w.d"); | 1137 emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "trunc.w.d"); |
| 935 } | 1138 } |
| 936 | 1139 |
| 937 void AssemblerMIPS32::trunc_w_s(const Operand *OpFd, const Operand *OpFs) { | 1140 void AssemblerMIPS32::trunc_w_s(const Operand *OpFd, const Operand *OpFs) { |
| 938 static constexpr IValueT Opcode = 0x4400000D; | 1141 static constexpr IValueT Opcode = 0x4400000D; |
| 939 emitCOP1FmtFsFd(Opcode, Word, OpFd, OpFs, "trunc.w.s"); | 1142 emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "trunc.w.s"); |
| 940 } | 1143 } |
| 941 | 1144 |
| 942 void AssemblerMIPS32::xor_(const Operand *OpRd, const Operand *OpRs, | 1145 void AssemblerMIPS32::xor_(const Operand *OpRd, const Operand *OpRs, |
| 943 const Operand *OpRt) { | 1146 const Operand *OpRt) { |
| 944 static constexpr IValueT Opcode = 0x00000026; | 1147 static constexpr IValueT Opcode = 0x00000026; |
| 945 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "xor"); | 1148 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "xor"); |
| 946 } | 1149 } |
| 947 | 1150 |
| 948 void AssemblerMIPS32::xori(const Operand *OpRt, const Operand *OpRs, | 1151 void AssemblerMIPS32::xori(const Operand *OpRt, const Operand *OpRs, |
| 949 const uint32_t Imm) { | 1152 const uint32_t Imm) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 emitBr(Cond, OpRs, OpRtNone, Dest); | 1223 emitBr(Cond, OpRs, OpRtNone, Dest); |
| 1021 return; | 1224 return; |
| 1022 } | 1225 } |
| 1023 const IOffsetT Position = Buffer.size(); | 1226 const IOffsetT Position = Buffer.size(); |
| 1024 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition()); | 1227 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition()); |
| 1025 TargetLabel->linkTo(*this, Position); | 1228 TargetLabel->linkTo(*this, Position); |
| 1026 } | 1229 } |
| 1027 | 1230 |
| 1028 } // end of namespace MIPS32 | 1231 } // end of namespace MIPS32 |
| 1029 } // end of namespace Ice | 1232 } // end of namespace Ice |
| OLD | NEW |