summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
diff options
context:
space:
mode:
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>2016-02-22 16:00:23 +0000
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>2016-02-22 16:00:23 +0000
commitd665a66b0f094f3f85fd30e9d7888481e3035ca0 (patch)
tree7b662d8248cf6599cf3f42eac77e9b054e7ea1f3 /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
parent02cbeb2222ce12f2eaccace0be0e09869a6209e0 (diff)
downloadbcm5719-llvm-d665a66b0f094f3f85fd30e9d7888481e3035ca0.tar.gz
bcm5719-llvm-d665a66b0f094f3f85fd30e9d7888481e3035ca0.zip
[mips] added support for trunc macro
Author: obucina Reviewers: dsanders Differential Revision: http://reviews.llvm.org/D15745 llvm-svn: 261529
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 247200b7318..b1f9d20ebff 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -220,6 +220,9 @@ class MipsAsmParser : public MCTargetAsmParser {
SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
const bool Signed);
+ bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions);
+
bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
@@ -2054,6 +2057,15 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
case Mips::DUDivMacro:
return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
: MER_Success;
+ case Mips::PseudoTRUNC_W_S:
+ return expandTrunc(Inst, false, false, IDLoc, Instructions) ? MER_Fail
+ : MER_Success;
+ case Mips::PseudoTRUNC_W_D32:
+ return expandTrunc(Inst, true, false, IDLoc, Instructions) ? MER_Fail
+ : MER_Success;
+ case Mips::PseudoTRUNC_W_D:
+ return expandTrunc(Inst, true, true, IDLoc, Instructions) ? MER_Fail
+ : MER_Success;
case Mips::Ulh:
return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
case Mips::Ulhu:
@@ -3057,6 +3069,44 @@ bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
return false;
}
+bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
+ SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions) {
+
+ assert(Inst.getNumOperands() == 3 && "Invalid operand count");
+ assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
+ Inst.getOperand(2).isReg() && "Invalid instruction operand.");
+
+ unsigned FirstReg = Inst.getOperand(0).getReg();
+ unsigned SecondReg = Inst.getOperand(1).getReg();
+ unsigned ThirdReg = Inst.getOperand(2).getReg();
+
+ if (hasMips1() && !hasMips2()) {
+ unsigned ATReg = getATReg(IDLoc);
+ if (!ATReg)
+ return true;
+ emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, Instructions);
+ emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, Instructions);
+ createNop(false, IDLoc, Instructions);
+ emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, Instructions);
+ emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, Instructions);
+ emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, Instructions);
+ createNop(false, IDLoc, Instructions);
+ emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
+ : Mips::CVT_W_S,
+ FirstReg, SecondReg, IDLoc, Instructions);
+ emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, Instructions);
+ createNop(false, IDLoc, Instructions);
+ return false;
+ }
+
+ emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
+ : Mips::TRUNC_W_S,
+ FirstReg, SecondReg, IDLoc, Instructions);
+
+ return false;
+}
+
bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
if (hasMips32r6() || hasMips64r6()) {
OpenPOWER on IntegriCloud