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