diff options
| author | Simon Dardis <simon.dardis@imgtec.com> | 2016-05-18 10:38:01 +0000 |
|---|---|---|
| committer | Simon Dardis <simon.dardis@imgtec.com> | 2016-05-18 10:38:01 +0000 |
| commit | 669d8dd8e1585d32b0a6f9ee5d6bb8a01aeca235 (patch) | |
| tree | 8a54b801cafb61f8eed6ee207567b97e584af182 | |
| parent | c819d903e18f27d56cd0ceeae0d915be85bc8f4f (diff) | |
| download | bcm5719-llvm-669d8dd8e1585d32b0a6f9ee5d6bb8a01aeca235.tar.gz bcm5719-llvm-669d8dd8e1585d32b0a6f9ee5d6bb8a01aeca235.zip | |
[PATCH] [mips] Restrict the creation of compact branches
Restrict the creation of compact branches so that they do meet the ISA
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.
Recommit of rL269893 with reviewers comments.
Reviewers: dsanders, vkalintiris
Differential Review: http://reviews.llvm.org/D20284
llvm-svn: 269899
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 25 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/Mips32r6InstrFormats.td | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.cpp | 20 |
4 files changed, 47 insertions, 2 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. diff --git a/llvm/lib/Target/Mips/Mips32r6InstrFormats.td b/llvm/lib/Target/Mips/Mips32r6InstrFormats.td index 13216bebe5b..a20c683c1e5 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrFormats.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrFormats.td @@ -360,7 +360,7 @@ class SPECIAL_SDBBP_FM : MipsR6Inst { } // This class is ambiguous with other branches: -// BEQC/BNEC require that rs > rt +// BEQC/BNEC require that rs < rt && rs != 0 class CMP_BRANCH_2R_OFF16_FM<OPGROUP funct> : MipsR6Inst { bits<5> rs; bits<5> rt; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index e5c602f35e6..1da879b114e 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -282,6 +282,16 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( } } + // MIPSR6 forbids both operands being the zero register. + if (Subtarget.hasMips32r6() && (I->getNumOperands() > 1) && + (I->getOperand(0).isReg() && + (I->getOperand(0).getReg() == Mips::ZERO || + I->getOperand(0).getReg() == Mips::ZERO_64)) && + (I->getOperand(1).isReg() && + (I->getOperand(1).getReg() == Mips::ZERO || + I->getOperand(1).getReg() == Mips::ZERO_64))) + return 0; + if (Subtarget.hasMips32r6() || canUseShortMicroMipsCTI) { switch (Opcode) { case Mips::B: @@ -299,8 +309,12 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( else return Mips::BNEC; case Mips::BGE: + if (I->getOperand(0).getReg() == I->getOperand(1).getReg()) + return 0; return Mips::BGEC; case Mips::BGEU: + if (I->getOperand(0).getReg() == I->getOperand(1).getReg()) + return 0; return Mips::BGEUC; case Mips::BGEZ: return Mips::BGEZC; @@ -309,8 +323,12 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( case Mips::BLEZ: return Mips::BLEZC; case Mips::BLT: + if (I->getOperand(0).getReg() == I->getOperand(1).getReg()) + return 0; return Mips::BLTC; case Mips::BLTU: + if (I->getOperand(0).getReg() == I->getOperand(1).getReg()) + return 0; return Mips::BLTUC; case Mips::BLTZ: return Mips::BLTZC; @@ -330,7 +348,7 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( return Mips::JIC64; case Mips::JALR64Pseudo: return Mips::JIALC64; - default: + default: return 0; } } |

