summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
diff options
context:
space:
mode:
authorToma Tabacu <toma.tabacu@imgtec.com>2015-06-09 10:34:31 +0000
committerToma Tabacu <toma.tabacu@imgtec.com>2015-06-09 10:34:31 +0000
commit5fa8fb5762df6746b73e5795c097516570986800 (patch)
treebd110f28d73210f7a1428ac6fdbd6983a0514b8a /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
parent329fc9b68a6bb2ba2acb74744b17b4ba264bef42 (diff)
downloadbcm5719-llvm-5fa8fb5762df6746b73e5795c097516570986800.tar.gz
bcm5719-llvm-5fa8fb5762df6746b73e5795c097516570986800.zip
[mips] [IAS] Add support for BNE and BEQ with an immediate operand.
Summary: For some branches, GAS accepts an immediate instead of the 2nd register operand. We only implement this for BNE and BEQ for now. Other branch instructions can be added later, if needed. Reviewers: dsanders Reviewed By: dsanders Subscribers: seanbruno, emaste, llvm-commits Differential Revision: http://reviews.llvm.org/D9666 llvm-svn: 239396
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 0d08138f8a9..5029482a40d 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -208,6 +208,9 @@ class MipsAsmParser : public MCTargetAsmParser {
bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
+ bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions);
+
void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
@@ -1616,6 +1619,8 @@ bool MipsAsmParser::needsExpansion(MCInst &Inst) {
case Mips::SWM_MM:
case Mips::JalOneReg:
case Mips::JalTwoReg:
+ case Mips::BneImm:
+ case Mips::BeqImm:
return true;
default:
return false;
@@ -1642,6 +1647,9 @@ bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
case Mips::JalOneReg:
case Mips::JalTwoReg:
return expandJalWithRegs(Inst, IDLoc, Instructions);
+ case Mips::BneImm:
+ case Mips::BeqImm:
+ return expandBranchImm(Inst, IDLoc, Instructions);
}
}
@@ -2032,6 +2040,59 @@ bool MipsAsmParser::expandUncondBranchMMPseudo(
return false;
}
+bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions) {
+ const MCOperand &DstRegOp = Inst.getOperand(0);
+ assert(DstRegOp.isReg() && "expected register operand kind");
+
+ const MCOperand &ImmOp = Inst.getOperand(1);
+ assert(ImmOp.isImm() && "expected immediate operand kind");
+
+ const MCOperand &MemOffsetOp = Inst.getOperand(2);
+ assert(MemOffsetOp.isImm() && "expected immediate operand kind");
+
+ unsigned OpCode = 0;
+ switch(Inst.getOpcode()) {
+ case Mips::BneImm:
+ OpCode = Mips::BNE;
+ break;
+ case Mips::BeqImm:
+ OpCode = Mips::BEQ;
+ break;
+ default:
+ llvm_unreachable("Unknown immediate branch pseudo-instruction.");
+ break;
+ }
+
+ int64_t ImmValue = ImmOp.getImm();
+ if (ImmValue == 0) {
+ MCInst BranchInst;
+ BranchInst.setOpcode(OpCode);
+ BranchInst.addOperand(DstRegOp);
+ BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
+ BranchInst.addOperand(MemOffsetOp);
+ Instructions.push_back(BranchInst);
+ } else {
+ warnIfNoMacro(IDLoc);
+
+ unsigned ATReg = getATReg(IDLoc);
+ if (!ATReg)
+ return true;
+
+ if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
+ Instructions))
+ return true;
+
+ MCInst BranchInst;
+ BranchInst.setOpcode(OpCode);
+ BranchInst.addOperand(DstRegOp);
+ BranchInst.addOperand(MCOperand::createReg(ATReg));
+ BranchInst.addOperand(MemOffsetOp);
+ Instructions.push_back(BranchInst);
+ }
+ return false;
+}
+
void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions,
bool isLoad, bool isImmOpnd) {
OpenPOWER on IntegriCloud