Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/IceAssemblerMIPS32.cpp

Issue 2446273003: [SubZero] Generate relocations for MIPS (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Rebase on master Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceAssemblerMIPS32.h ('k') | src/IceInstMIPS32.h » ('j') | src/IceInstMIPS32.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698