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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 } | 189 } |
190 | 190 |
191 void AssemblerMIPS32::bind(Label *L) { | 191 void AssemblerMIPS32::bind(Label *L) { |
192 IOffsetT BoundPc = Buffer.size(); | 192 IOffsetT BoundPc = Buffer.size(); |
193 assert(!L->isBound()); // Labels can only be bound once. | 193 assert(!L->isBound()); // Labels can only be bound once. |
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 IOffsetT NextBrPc = decodeBranchOffset(Inst); |
| 200 if (NextBrPc != 0) |
| 201 NextBrPc = Position - NextBrPc; |
| 202 L->setPosition(NextBrPc); |
200 } | 203 } |
201 L->bindTo(BoundPc); | 204 L->bindTo(BoundPc); |
202 } | 205 } |
203 | 206 |
204 void AssemblerMIPS32::emitRsRt(IValueT Opcode, const Operand *OpRs, | 207 void AssemblerMIPS32::emitRsRt(IValueT Opcode, const Operand *OpRs, |
205 const Operand *OpRt, const char *InsnName) { | 208 const Operand *OpRt, const char *InsnName) { |
206 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); | 209 const IValueT Rs = encodeGPRegister(OpRs, "Rs", InsnName); |
207 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); | 210 const IValueT Rt = encodeGPRegister(OpRt, "Rt", InsnName); |
208 | 211 |
209 Opcode |= Rs << 21; | 212 Opcode |= Rs << 21; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 | 424 |
422 void AssemblerMIPS32::b(Label *TargetLabel) { | 425 void AssemblerMIPS32::b(Label *TargetLabel) { |
423 static constexpr Operand *OpRsNone = nullptr; | 426 static constexpr Operand *OpRsNone = nullptr; |
424 static constexpr Operand *OpRtNone = nullptr; | 427 static constexpr Operand *OpRtNone = nullptr; |
425 if (TargetLabel->isBound()) { | 428 if (TargetLabel->isBound()) { |
426 const int32_t Dest = TargetLabel->getPosition() - Buffer.size(); | 429 const int32_t Dest = TargetLabel->getPosition() - Buffer.size(); |
427 emitBr(CondMIPS32::AL, OpRsNone, OpRtNone, Dest); | 430 emitBr(CondMIPS32::AL, OpRsNone, OpRtNone, Dest); |
428 return; | 431 return; |
429 } | 432 } |
430 const IOffsetT Position = Buffer.size(); | 433 const IOffsetT Position = Buffer.size(); |
431 emitBr(CondMIPS32::AL, OpRsNone, OpRtNone, TargetLabel->getEncodedPosition()); | 434 IOffsetT PrevPosition = TargetLabel->getEncodedPosition(); |
| 435 if (PrevPosition != 0) |
| 436 PrevPosition = Position - PrevPosition; |
| 437 emitBr(CondMIPS32::AL, OpRsNone, OpRtNone, PrevPosition); |
432 TargetLabel->linkTo(*this, Position); | 438 TargetLabel->linkTo(*this, Position); |
433 } | 439 } |
434 | 440 |
435 void AssemblerMIPS32::c_eq_d(const Operand *OpFs, const Operand *OpFt) { | 441 void AssemblerMIPS32::c_eq_d(const Operand *OpFs, const Operand *OpFt) { |
436 static constexpr IValueT Opcode = 0x44000032; | 442 static constexpr IValueT Opcode = 0x44000032; |
437 emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0, | 443 emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0, |
438 "c.eq.d"); | 444 "c.eq.d"); |
439 } | 445 } |
440 | 446 |
441 void AssemblerMIPS32::c_eq_s(const Operand *OpFs, const Operand *OpFt) { | 447 void AssemblerMIPS32::c_eq_s(const Operand *OpFs, const Operand *OpFt) { |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 | 849 |
844 void AssemblerMIPS32::movn(const Operand *OpRd, const Operand *OpRs, | 850 void AssemblerMIPS32::movn(const Operand *OpRd, const Operand *OpRs, |
845 const Operand *OpRt) { | 851 const Operand *OpRt) { |
846 static constexpr IValueT Opcode = 0x0000000B; | 852 static constexpr IValueT Opcode = 0x0000000B; |
847 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "movn"); | 853 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "movn"); |
848 } | 854 } |
849 | 855 |
850 void AssemblerMIPS32::movn_d(const Operand *OpFd, const Operand *OpFs, | 856 void AssemblerMIPS32::movn_d(const Operand *OpFd, const Operand *OpFs, |
851 const Operand *OpFt) { | 857 const Operand *OpFt) { |
852 static constexpr IValueT Opcode = 0x44000013; | 858 static constexpr IValueT Opcode = 0x44000013; |
853 emitCOP1FmtRtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movn.d"); | 859 emitCOP1FmtRtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "movn.d"); |
854 } | 860 } |
855 | 861 |
856 void AssemblerMIPS32::movn_s(const Operand *OpFd, const Operand *OpFs, | 862 void AssemblerMIPS32::movn_s(const Operand *OpFd, const Operand *OpFs, |
857 const Operand *OpFt) { | 863 const Operand *OpFt) { |
858 static constexpr IValueT Opcode = 0x44000013; | 864 static constexpr IValueT Opcode = 0x44000013; |
859 emitCOP1FmtRtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movn.s"); | 865 emitCOP1FmtRtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movn.s"); |
860 } | 866 } |
861 | 867 |
862 void AssemblerMIPS32::movt(const Operand *OpRd, const Operand *OpRs, | 868 void AssemblerMIPS32::movt(const Operand *OpRd, const Operand *OpRs, |
863 const Operand *OpCc) { | 869 const Operand *OpCc) { |
864 IValueT Opcode = 0x00000001; | 870 IValueT Opcode = 0x00000001; |
865 const IValueT Rd = encodeGPRegister(OpRd, "Rd", "movt"); | 871 const IValueT Rd = encodeGPRegister(OpRd, "Rd", "movt"); |
866 const IValueT Rs = encodeGPRegister(OpRs, "Rs", "movt"); | 872 const IValueT Rs = encodeGPRegister(OpRs, "Rs", "movt"); |
867 OperandMIPS32FCC::FCC Cc = OperandMIPS32FCC::FCC0; | 873 OperandMIPS32FCC::FCC Cc = OperandMIPS32FCC::FCC0; |
868 if (const auto *OpFCC = llvm::dyn_cast<OperandMIPS32FCC>(OpCc)) { | 874 if (const auto *OpFCC = llvm::dyn_cast<OperandMIPS32FCC>(OpCc)) { |
869 Cc = OpFCC->getFCC(); | 875 Cc = OpFCC->getFCC(); |
870 } | 876 } |
871 const IValueT InstEncodingTrue = 1; | 877 const IValueT InstEncodingTrue = 1; |
872 Opcode |= Rd << 11; | 878 Opcode |= Rd << 11; |
873 Opcode |= InstEncodingTrue << 16; | 879 Opcode |= InstEncodingTrue << 16; |
874 Opcode |= Cc << 18; | 880 Opcode |= Cc << 18; |
875 Opcode |= Rs << 21; | 881 Opcode |= Rs << 21; |
876 emitInst(Opcode); | 882 emitInst(Opcode); |
877 } | 883 } |
878 | 884 |
879 void AssemblerMIPS32::movz_d(const Operand *OpFd, const Operand *OpFs, | 885 void AssemblerMIPS32::movz_d(const Operand *OpFd, const Operand *OpFs, |
880 const Operand *OpFt) { | 886 const Operand *OpFt) { |
881 static constexpr IValueT Opcode = 0x44000012; | 887 static constexpr IValueT Opcode = 0x44000012; |
882 emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movz.d"); | 888 emitCOP1FmtFtFsFd(Opcode, DoublePrecision, OpFd, OpFs, OpFt, "movz.d"); |
883 } | 889 } |
884 | 890 |
885 void AssemblerMIPS32::movz(const Operand *OpRd, const Operand *OpRs, | 891 void AssemblerMIPS32::movz(const Operand *OpRd, const Operand *OpRs, |
886 const Operand *OpRt) { | 892 const Operand *OpRt) { |
887 static constexpr IValueT Opcode = 0x0000000A; | 893 static constexpr IValueT Opcode = 0x0000000A; |
888 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "movz"); | 894 emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "movz"); |
889 } | 895 } |
890 | 896 |
891 void AssemblerMIPS32::movz_s(const Operand *OpFd, const Operand *OpFs, | 897 void AssemblerMIPS32::movz_s(const Operand *OpFd, const Operand *OpFs, |
892 const Operand *OpFt) { | 898 const Operand *OpFt) { |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 } | 1238 } |
1233 | 1239 |
1234 void AssemblerMIPS32::bcc(const CondMIPS32::Cond Cond, const Operand *OpRs, | 1240 void AssemblerMIPS32::bcc(const CondMIPS32::Cond Cond, const Operand *OpRs, |
1235 const Operand *OpRt, Label *TargetLabel) { | 1241 const Operand *OpRt, Label *TargetLabel) { |
1236 if (TargetLabel->isBound()) { | 1242 if (TargetLabel->isBound()) { |
1237 const int32_t Dest = TargetLabel->getPosition() - Buffer.size(); | 1243 const int32_t Dest = TargetLabel->getPosition() - Buffer.size(); |
1238 emitBr(Cond, OpRs, OpRt, Dest); | 1244 emitBr(Cond, OpRs, OpRt, Dest); |
1239 return; | 1245 return; |
1240 } | 1246 } |
1241 const IOffsetT Position = Buffer.size(); | 1247 const IOffsetT Position = Buffer.size(); |
1242 emitBr(Cond, OpRs, OpRt, TargetLabel->getEncodedPosition()); | 1248 IOffsetT PrevPosition = TargetLabel->getEncodedPosition(); |
| 1249 if (PrevPosition != 0) |
| 1250 PrevPosition = Position - PrevPosition; |
| 1251 emitBr(Cond, OpRs, OpRt, PrevPosition); |
1243 TargetLabel->linkTo(*this, Position); | 1252 TargetLabel->linkTo(*this, Position); |
1244 } | 1253 } |
1245 | 1254 |
1246 void AssemblerMIPS32::bzc(const CondMIPS32::Cond Cond, const Operand *OpRs, | 1255 void AssemblerMIPS32::bzc(const CondMIPS32::Cond Cond, const Operand *OpRs, |
1247 Label *TargetLabel) { | 1256 Label *TargetLabel) { |
1248 static constexpr Operand *OpRtNone = nullptr; | 1257 static constexpr Operand *OpRtNone = nullptr; |
1249 if (TargetLabel->isBound()) { | 1258 if (TargetLabel->isBound()) { |
1250 const int32_t Dest = TargetLabel->getPosition() - Buffer.size(); | 1259 const int32_t Dest = TargetLabel->getPosition() - Buffer.size(); |
1251 emitBr(Cond, OpRs, OpRtNone, Dest); | 1260 emitBr(Cond, OpRs, OpRtNone, Dest); |
1252 return; | 1261 return; |
1253 } | 1262 } |
1254 const IOffsetT Position = Buffer.size(); | 1263 const IOffsetT Position = Buffer.size(); |
1255 emitBr(Cond, OpRs, OpRtNone, TargetLabel->getEncodedPosition()); | 1264 IOffsetT PrevPosition = TargetLabel->getEncodedPosition(); |
| 1265 if (PrevPosition) |
| 1266 PrevPosition = Position - PrevPosition; |
| 1267 emitBr(Cond, OpRs, OpRtNone, PrevPosition); |
1256 TargetLabel->linkTo(*this, Position); | 1268 TargetLabel->linkTo(*this, Position); |
1257 } | 1269 } |
1258 | 1270 |
1259 } // end of namespace MIPS32 | 1271 } // end of namespace MIPS32 |
1260 } // end of namespace Ice | 1272 } // end of namespace Ice |
OLD | NEW |