summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MCTargetDesc
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@imgtec.com>2016-05-18 09:21:44 +0000
committerSimon Dardis <simon.dardis@imgtec.com>2016-05-18 09:21:44 +0000
commit1549a2f46a8da1dac4a305df3b8c7dbbf9ba403c (patch)
tree612b272b8d3e1b8cd21dc75a00dc5a52b77530ac /llvm/lib/Target/Mips/MCTargetDesc
parent68388a0a9988ee4ec762a1605f3884709391345b (diff)
downloadbcm5719-llvm-1549a2f46a8da1dac4a305df3b8c7dbbf9ba403c.tar.gz
bcm5719-llvm-1549a2f46a8da1dac4a305df3b8c7dbbf9ba403c.zip
[mips] Restrict the creation of compact branches
Restrict the creation of compact branches so that they meet the ISA encoding requirements. Notably do not permit $zero to be used as a operand for compact branches and ensure that some other branches fulfil the requirement that rs != rt. Fixup cases where $rs > $rt for bnec and beqc. Reviewers: dsanders, vkalintiris Differential Review: http://reviews.llvm.org/D20284 llvm-svn: 269893
Diffstat (limited to 'llvm/lib/Target/Mips/MCTargetDesc')
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp25
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h2
2 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index f92a807e5e5..7e0fc30dc48 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -106,6 +106,26 @@ static void LowerDins(MCInst& InstIn) {
return;
}
+// Fix a bad compact branch encoding for beqc/bnec.
+void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const {
+
+ // Encoding may be illegal !(rs < rt), but this situation is
+ // easily fixed.
+ unsigned RegOp0 = Inst.getOperand(0).getReg();
+ unsigned RegOp1 = Inst.getOperand(1).getReg();
+
+ unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0);
+ unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1);
+
+ assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!");
+ if (Reg0 < Reg1)
+ return;
+
+ Inst.getOperand(0).setReg(RegOp1);
+ Inst.getOperand(1).setReg(RegOp0);
+
+}
+
bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
return STI.getFeatureBits()[Mips::FeatureMicroMips];
}
@@ -160,6 +180,11 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
// Double extract instruction is chosen by pos and size operands
case Mips::DINS:
LowerDins(TmpInst);
+ break;
+ // Compact branches.
+ case Mips::BEQC:
+ case Mips::BNEC:
+ LowerCompactBranch(TmpInst);
}
unsigned long N = Fixups.size();
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
index fbc9e8c0cde..01daaa25296 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -253,6 +253,8 @@ public:
unsigned getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ private:
+ void LowerCompactBranch(MCInst& Inst) const;
}; // class MipsMCCodeEmitter
} // namespace llvm.
OpenPOWER on IntegriCloud