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