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

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: Addressed review comments 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
« no previous file with comments | « src/IceAssemblerMIPS32.h ('k') | src/IceInstMIPS32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceAssemblerMIPS32.h ('k') | src/IceInstMIPS32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698