mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-03 17:31:50 +00:00
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269899 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
adcd739c2e
commit
2366631516
@ -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();
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user