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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 while (L->isLinked()) { | 194 while (L->isLinked()) { |
195 IOffsetT Position = L->getLinkPosition(); | 195 IOffsetT Position = L->getLinkPosition(); |
196 IOffsetT Dest = BoundPc - Position; | 196 IOffsetT Dest = BoundPc - Position; |
197 IValueT Inst = Buffer.load<IValueT>(Position); | 197 IValueT Inst = Buffer.load<IValueT>(Position); |
198 Buffer.store<IValueT>(Position, encodeBranchOffset(Dest, Inst)); | 198 Buffer.store<IValueT>(Position, encodeBranchOffset(Dest, Inst)); |
199 L->setPosition(decodeBranchOffset(Inst)); | 199 L->setPosition(decodeBranchOffset(Inst)); |
200 } | 200 } |
201 L->bindTo(BoundPc); | 201 L->bindTo(BoundPc); |
202 } | 202 } |
203 | 203 |
| 204 void AssemblerMIPS32::emitRsRt(IValueT Opcode, const Operand *OpRs, |
| 205 const Operand *OpRt, const char *InsnName) { |
| 206 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); |
| 207 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); |
| 208 |
| 209 Opcode |= Rs << 21; |
| 210 Opcode |= Rt << 16; |
| 211 |
| 212 emitInst(Opcode); |
| 213 } |
| 214 |
204 void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt, | 215 void AssemblerMIPS32::emitRtRsImm16(IValueT Opcode, const Operand *OpRt, |
205 const Operand *OpRs, const uint32_t Imm, | 216 const Operand *OpRs, const uint32_t Imm, |
206 const char *InsnName) { | 217 const char *InsnName) { |
207 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); | 218 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); |
208 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); | 219 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); |
209 | 220 |
210 Opcode |= Rs << 21; | 221 Opcode |= Rs << 21; |
211 Opcode |= Rt << 16; | 222 Opcode |= Rt << 16; |
212 Opcode |= Imm & 0xffff; | 223 Opcode |= Imm & 0xffff; |
213 | 224 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 void AssemblerMIPS32::cvt_s_l(const Operand *OpFd, const Operand *OpFs) { | 513 void AssemblerMIPS32::cvt_s_l(const Operand *OpFd, const Operand *OpFs) { |
503 static constexpr IValueT Opcode = 0x44000020; | 514 static constexpr IValueT Opcode = 0x44000020; |
504 emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "cvt.s.l"); | 515 emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "cvt.s.l"); |
505 } | 516 } |
506 | 517 |
507 void AssemblerMIPS32::cvt_s_w(const Operand *OpFd, const Operand *OpFs) { | 518 void AssemblerMIPS32::cvt_s_w(const Operand *OpFd, const Operand *OpFs) { |
508 static constexpr IValueT Opcode = 0x44000020; | 519 static constexpr IValueT Opcode = 0x44000020; |
509 emitCOP1FmtFsFd(Opcode, Word, OpFd, OpFs, "cvt.s.w"); | 520 emitCOP1FmtFsFd(Opcode, Word, OpFd, OpFs, "cvt.s.w"); |
510 } | 521 } |
511 | 522 |
| 523 void AssemblerMIPS32::div(const Operand *OpRs, const Operand *OpRt) { |
| 524 static constexpr IValueT Opcode = 0x0000001A; |
| 525 emitRsRt(Opcode, OpRs, OpRt, "div"); |
| 526 } |
| 527 |
512 void AssemblerMIPS32::div_d(const Operand *OpFd, const Operand *OpFs, | 528 void AssemblerMIPS32::div_d(const Operand *OpFd, const Operand *OpFs, |
513 const Operand *OpFt) { | 529 const Operand *OpFt) { |
514 static constexpr IValueT Opcode = 0x44000003; | 530 static constexpr IValueT Opcode = 0x44000003; |
515 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "div.d"); | 531 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "div.d"); |
516 } | 532 } |
517 | 533 |
518 void AssemblerMIPS32::div_s(const Operand *OpFd, const Operand *OpFs, | 534 void AssemblerMIPS32::div_s(const Operand *OpFd, const Operand *OpFs, |
519 const Operand *OpFt) { | 535 const Operand *OpFt) { |
520 static constexpr IValueT Opcode = 0x44000003; | 536 static constexpr IValueT Opcode = 0x44000003; |
521 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "div.s"); | 537 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "div.s"); |
522 } | 538 } |
523 | 539 |
| 540 void AssemblerMIPS32::lui(const Operand *OpRt, const uint16_t Imm) { |
| 541 IValueT Opcode = 0x3C000000; |
| 542 const IValueT Rt = encodeGPRegister(OpRt, "Rt", "lui"); |
| 543 Opcode |= Rt << 16; |
| 544 Opcode |= Imm; |
| 545 emitInst(Opcode); |
| 546 } |
| 547 |
524 void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase, | 548 void AssemblerMIPS32::lw(const Operand *OpRt, const Operand *OpBase, |
525 const uint32_t Offset) { | 549 const uint32_t Offset) { |
526 switch (OpRt->getType()) { | 550 switch (OpRt->getType()) { |
527 case IceType_i1: | 551 case IceType_i1: |
528 case IceType_i8: { | 552 case IceType_i8: { |
529 static constexpr IValueT Opcode = 0x80000000; | 553 static constexpr IValueT Opcode = 0x80000000; |
530 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lb"); | 554 emitRtRsImm16(Opcode, OpRt, OpBase, Offset, "lb"); |
531 break; | 555 break; |
532 } | 556 } |
533 case IceType_i16: { | 557 case IceType_i16: { |
(...skipping 18 matching lines...) Expand all Loading... |
552 } | 576 } |
553 default: { UnimplementedError(getFlags()); } | 577 default: { UnimplementedError(getFlags()); } |
554 } | 578 } |
555 } | 579 } |
556 | 580 |
557 void AssemblerMIPS32::mfc1(const Operand *OpRt, const Operand *OpFs) { | 581 void AssemblerMIPS32::mfc1(const Operand *OpRt, const Operand *OpFs) { |
558 static constexpr IValueT Opcode = 0x44000000; | 582 static constexpr IValueT Opcode = 0x44000000; |
559 emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mfc1"); | 583 emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mfc1"); |
560 } | 584 } |
561 | 585 |
| 586 void AssemblerMIPS32::mfhi(const Operand *OpRd) { |
| 587 IValueT Opcode = 0x000000010; |
| 588 IValueT Rd = encodeGPRegister(OpRd, "Rd", "mfhi"); |
| 589 Opcode |= Rd << 11; |
| 590 emitInst(Opcode); |
| 591 } |
| 592 |
| 593 void AssemblerMIPS32::mflo(const Operand *OpRd) { |
| 594 IValueT Opcode = 0x000000012; |
| 595 IValueT Rd = encodeGPRegister(OpRd, "Rd", "mflo"); |
| 596 Opcode |= Rd << 11; |
| 597 emitInst(Opcode); |
| 598 } |
| 599 |
562 void AssemblerMIPS32::mov_d(const Operand *OpFd, const Operand *OpFs) { | 600 void AssemblerMIPS32::mov_d(const Operand *OpFd, const Operand *OpFs) { |
563 static constexpr IValueT Opcode = 0x44000006; | 601 static constexpr IValueT Opcode = 0x44000006; |
564 emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "mov.d"); | 602 emitCOP1FmtFsFd(Opcode, DoublePrecision, OpFd, OpFs, "mov.d"); |
565 } | 603 } |
566 | 604 |
567 void AssemblerMIPS32::mov_s(const Operand *OpFd, const Operand *OpFs) { | 605 void AssemblerMIPS32::mov_s(const Operand *OpFd, const Operand *OpFs) { |
568 static constexpr IValueT Opcode = 0x44000006; | 606 static constexpr IValueT Opcode = 0x44000006; |
569 emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "mov.s"); | 607 emitCOP1FmtFsFd(Opcode, SinglePrecision, OpFd, OpFs, "mov.s"); |
570 } | 608 } |
571 | 609 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 const Operand *OpFt) { | 708 const Operand *OpFt) { |
671 static constexpr IValueT Opcode = 0x44000012; | 709 static constexpr IValueT Opcode = 0x44000012; |
672 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movz.s"); | 710 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movz.s"); |
673 } | 711 } |
674 | 712 |
675 void AssemblerMIPS32::mtc1(const Operand *OpRt, const Operand *OpFs) { | 713 void AssemblerMIPS32::mtc1(const Operand *OpRt, const Operand *OpFs) { |
676 static constexpr IValueT Opcode = 0x44800000; | 714 static constexpr IValueT Opcode = 0x44800000; |
677 emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mtc1"); | 715 emitCOP1MovRtFs(Opcode, OpRt, OpFs, "mtc1"); |
678 } | 716 } |
679 | 717 |
| 718 void AssemblerMIPS32::mthi(const Operand *OpRs) { |
| 719 IValueT Opcode = 0x000000011; |
| 720 IValueT Rs = encodeGPRegister(OpRs, "Rs", "mthi"); |
| 721 Opcode |= Rs << 21; |
| 722 emitInst(Opcode); |
| 723 } |
| 724 |
| 725 void AssemblerMIPS32::mtlo(const Operand *OpRs) { |
| 726 IValueT Opcode = 0x000000013; |
| 727 IValueT Rs = encodeGPRegister(OpRs, "Rs", "mtlo"); |
| 728 Opcode |= Rs << 21; |
| 729 emitInst(Opcode); |
| 730 } |
| 731 |
| 732 void AssemblerMIPS32::mul(const Operand *OpRd, const Operand *OpRs, |
| 733 const Operand *OpRt) { |
| 734 static constexpr IValueT Opcode = 0x70000002; |
| 735 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "mul"); |
| 736 } |
| 737 |
680 void AssemblerMIPS32::mul_d(const Operand *OpFd, const Operand *OpFs, | 738 void AssemblerMIPS32::mul_d(const Operand *OpFd, const Operand *OpFs, |
681 const Operand *OpFt) { | 739 const Operand *OpFt) { |
682 static constexpr IValueT Opcode = 0x44000002; | 740 static constexpr IValueT Opcode = 0x44000002; |
683 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "mul.d"); | 741 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "mul.d"); |
684 } | 742 } |
685 | 743 |
686 void AssemblerMIPS32::mul_s(const Operand *OpFd, const Operand *OpFs, | 744 void AssemblerMIPS32::mul_s(const Operand *OpFd, const Operand *OpFs, |
687 const Operand *OpFt) { | 745 const Operand *OpFt) { |
688 static constexpr IValueT Opcode = 0x44000002; | 746 static constexpr IValueT Opcode = 0x44000002; |
689 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s"); | 747 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "mul.s"); |
690 } | 748 } |
691 | 749 |
| 750 void AssemblerMIPS32::multu(const Operand *OpRs, const Operand *OpRt) { |
| 751 static constexpr IValueT Opcode = 0x00000019; |
| 752 emitRsRt(Opcode, OpRs, OpRt, "multu"); |
| 753 } |
| 754 |
692 void AssemblerMIPS32::nor(const Operand *OpRd, const Operand *OpRs, | 755 void AssemblerMIPS32::nor(const Operand *OpRd, const Operand *OpRs, |
693 const Operand *OpRt) { | 756 const Operand *OpRt) { |
694 static constexpr IValueT Opcode = 0x00000027; | 757 static constexpr IValueT Opcode = 0x00000027; |
695 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "nor"); | 758 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "nor"); |
696 } | 759 } |
697 | 760 |
698 void AssemblerMIPS32::or_(const Operand *OpRd, const Operand *OpRs, | 761 void AssemblerMIPS32::or_(const Operand *OpRd, const Operand *OpRs, |
699 const Operand *OpRt) { | 762 const Operand *OpRt) { |
700 static constexpr IValueT Opcode = 0x00000025; | 763 static constexpr IValueT Opcode = 0x00000025; |
701 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "or"); | 764 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "or"); |
(...skipping 10 matching lines...) Expand all Loading... |
712 emitInst(Opcode); | 775 emitInst(Opcode); |
713 nop(); // delay slot | 776 nop(); // delay slot |
714 } | 777 } |
715 | 778 |
716 void AssemblerMIPS32::sll(const Operand *OpRd, const Operand *OpRt, | 779 void AssemblerMIPS32::sll(const Operand *OpRd, const Operand *OpRt, |
717 const uint32_t Sa) { | 780 const uint32_t Sa) { |
718 static constexpr IValueT Opcode = 0x00000000; | 781 static constexpr IValueT Opcode = 0x00000000; |
719 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "sll"); | 782 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "sll"); |
720 } | 783 } |
721 | 784 |
| 785 void AssemblerMIPS32::sllv(const Operand *OpRd, const Operand *OpRt, |
| 786 const Operand *OpRs) { |
| 787 static constexpr IValueT Opcode = 0x00000004; |
| 788 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "sllv"); |
| 789 } |
| 790 |
722 void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs, | 791 void AssemblerMIPS32::slt(const Operand *OpRd, const Operand *OpRs, |
723 const Operand *OpRt) { | 792 const Operand *OpRt) { |
724 static constexpr IValueT Opcode = 0x0000002A; | 793 static constexpr IValueT Opcode = 0x0000002A; |
725 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "slt"); | 794 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "slt"); |
726 } | 795 } |
727 | 796 |
728 void AssemblerMIPS32::slti(const Operand *OpRt, const Operand *OpRs, | 797 void AssemblerMIPS32::slti(const Operand *OpRt, const Operand *OpRs, |
729 const uint32_t Imm) { | 798 const uint32_t Imm) { |
730 static constexpr IValueT Opcode = 0x28000000; | 799 static constexpr IValueT Opcode = 0x28000000; |
731 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "slti"); | 800 emitRtRsImm16(Opcode, OpRt, OpRs, Imm, "slti"); |
(...skipping 26 matching lines...) Expand all Loading... |
758 static constexpr IValueT Opcode = 0x00000003; | 827 static constexpr IValueT Opcode = 0x00000003; |
759 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "sra"); | 828 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "sra"); |
760 } | 829 } |
761 | 830 |
762 void AssemblerMIPS32::srl(const Operand *OpRd, const Operand *OpRt, | 831 void AssemblerMIPS32::srl(const Operand *OpRd, const Operand *OpRt, |
763 const uint32_t Sa) { | 832 const uint32_t Sa) { |
764 static constexpr IValueT Opcode = 0x00000002; | 833 static constexpr IValueT Opcode = 0x00000002; |
765 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "srl"); | 834 emitRdRtSa(Opcode, OpRd, OpRt, Sa, "srl"); |
766 } | 835 } |
767 | 836 |
| 837 void AssemblerMIPS32::srlv(const Operand *OpRd, const Operand *OpRt, |
| 838 const Operand *OpRs) { |
| 839 static constexpr IValueT Opcode = 0x00000006; |
| 840 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "srlv"); |
| 841 } |
| 842 |
768 void AssemblerMIPS32::sub_d(const Operand *OpFd, const Operand *OpFs, | 843 void AssemblerMIPS32::sub_d(const Operand *OpFd, const Operand *OpFs, |
769 const Operand *OpFt) { | 844 const Operand *OpFt) { |
770 static constexpr IValueT Opcode = 0x44000001; | 845 static constexpr IValueT Opcode = 0x44000001; |
771 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "sub.d"); | 846 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "sub.d"); |
772 } | 847 } |
773 | 848 |
774 void AssemblerMIPS32::sub_s(const Operand *OpFd, const Operand *OpFs, | 849 void AssemblerMIPS32::sub_s(const Operand *OpFd, const Operand *OpFs, |
775 const Operand *OpFt) { | 850 const Operand *OpFt) { |
776 static constexpr IValueT Opcode = 0x44000001; | 851 static constexpr IValueT Opcode = 0x44000001; |
777 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "sub.s"); | 852 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "sub.s"); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 emitBr(Cond, OpRs, OpRtNone, Dest); | 1003 emitBr(Cond, OpRs, OpRtNone, Dest); |
929 return; | 1004 return; |
930 } | 1005 } |
931 const IOffsetT Position = Buffer.size(); | 1006 const IOffsetT Position = Buffer.size(); |
932 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition()); | 1007 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition()); |
933 TargetLabel->linkTo(*this, Position); | 1008 TargetLabel->linkTo(*this, Position); |
934 } | 1009 } |
935 | 1010 |
936 } // end of namespace MIPS32 | 1011 } // end of namespace MIPS32 |
937 } // end of namespace Ice | 1012 } // end of namespace Ice |
OLD | NEW |