| 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 |