Add support for conditional branch instructions with 64-bit register operands.

llvm-svn: 141694
This commit is contained in:
Akira Hatanaka 2011-10-11 18:49:17 +00:00
parent 0f41eee2a0
commit 4b6ac98fcf
4 changed files with 66 additions and 33 deletions

View File

@ -184,6 +184,14 @@ defm USW64 : StoreM64<0x2b, "usw", truncstorei32_u, 1>;
defm ULD : LoadM64<0x37, "uld", load_u, 1>;
defm USD : StoreM64<0x3f, "usd", store_u, 1>;
/// Jump and Branch Instructions
def BEQ64 : CBranch<0x04, "beq", seteq, CPU64Regs>;
def BNE64 : CBranch<0x05, "bne", setne, CPU64Regs>;
def BGEZ64 : CBranchZero<0x01, 1, "bgez", setge, CPU64Regs>;
def BGTZ64 : CBranchZero<0x07, 0, "bgtz", setgt, CPU64Regs>;
def BLEZ64 : CBranchZero<0x07, 0, "blez", setle, CPU64Regs>;
def BLTZ64 : CBranchZero<0x01, 0, "bltz", setlt, CPU64Regs>;
/// Multiply and Divide Instructions.
def DMULT : Mul64<0x1c, "dmult", IIImul>;
def DMULTu : Mul64<0x1d, "dmultu", IIImul>;

View File

@ -90,6 +90,21 @@ class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
let Inst{15-0} = imm16;
}
class CBranchBase<bits<6> op, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin>:
MipsInst<outs, ins, asmstr, pattern, itin>
{
bits<5> rs;
bits<5> rt;
bits<16> imm16;
let opcode = op;
let Inst{25-21} = rs;
let Inst{20-16} = rt;
let Inst{15-0} = imm16;
}
//===----------------------------------------------------------------------===//
// Format J instruction class in Mips : <|opcode|address|>
//===----------------------------------------------------------------------===//

View File

@ -226,9 +226,12 @@ MipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx,
//===----------------------------------------------------------------------===//
static unsigned GetAnalyzableBrOpc(unsigned Opc) {
return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ ||
Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ ||
Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::J) ? Opc : 0;
return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ ||
Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ ||
Opc == Mips::BEQ64 || Opc == Mips::BNE64 || Opc == Mips::BGTZ64 ||
Opc == Mips::BGEZ64 || Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 ||
Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::J) ?
Opc : 0;
}
/// GetOppositeBranchOpc - Return the inverse of the specified
@ -237,14 +240,20 @@ unsigned Mips::GetOppositeBranchOpc(unsigned Opc)
{
switch (Opc) {
default: llvm_unreachable("Illegal opcode!");
case Mips::BEQ : return Mips::BNE;
case Mips::BNE : return Mips::BEQ;
case Mips::BGTZ : return Mips::BLEZ;
case Mips::BGEZ : return Mips::BLTZ;
case Mips::BLTZ : return Mips::BGEZ;
case Mips::BLEZ : return Mips::BGTZ;
case Mips::BC1T : return Mips::BC1F;
case Mips::BC1F : return Mips::BC1T;
case Mips::BEQ : return Mips::BNE;
case Mips::BNE : return Mips::BEQ;
case Mips::BGTZ : return Mips::BLEZ;
case Mips::BGEZ : return Mips::BLTZ;
case Mips::BLTZ : return Mips::BGEZ;
case Mips::BLEZ : return Mips::BGTZ;
case Mips::BEQ64 : return Mips::BNE64;
case Mips::BNE64 : return Mips::BEQ64;
case Mips::BGTZ64 : return Mips::BLEZ64;
case Mips::BGEZ64 : return Mips::BLTZ64;
case Mips::BLTZ64 : return Mips::BGEZ64;
case Mips::BLEZ64 : return Mips::BGTZ64;
case Mips::BC1T : return Mips::BC1F;
case Mips::BC1F : return Mips::BC1T;
}
}

View File

@ -385,18 +385,24 @@ multiclass StoreM64<bits<6> op, string instr_asm, PatFrag OpNode,
}
// Conditional Branch
let isBranch = 1, isTerminator=1, hasDelaySlot = 1 in {
class CBranch<bits<6> op, string instr_asm, PatFrag cond_op>:
FI<op, (outs), (ins CPURegs:$a, CPURegs:$b, brtarget:$offset),
!strconcat(instr_asm, "\t$a, $b, $offset"),
[(brcond (i32 (cond_op CPURegs:$a, CPURegs:$b)), bb:$offset)],
IIBranch>;
class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$offset),
!strconcat(instr_asm, "\t$rs, $rt, $offset"),
[(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch> {
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
}
class CBranchZero<bits<6> op, string instr_asm, PatFrag cond_op>:
FI<op, (outs), (ins CPURegs:$src, brtarget:$offset),
!strconcat(instr_asm, "\t$src, $offset"),
[(brcond (i32 (cond_op CPURegs:$src, 0)), bb:$offset)],
IIBranch>;
class CBranchZero<bits<6> op, bits<5> _rt, string instr_asm, PatFrag cond_op,
RegisterClass RC>:
CBranchBase<op, (outs), (ins RC:$rs, brtarget:$offset),
!strconcat(instr_asm, "\t$rs, $offset"),
[(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch> {
let rt = _rt;
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
}
// SetCC
@ -683,17 +689,12 @@ let isIndirectBranch = 1 in
def JR : JumpFR<0x00, 0x08, "jr">;
def JAL : JumpLink<0x03, "jal">;
def JALR : JumpLinkReg<0x00, 0x09, "jalr">;
def BEQ : CBranch<0x04, "beq", seteq>;
def BNE : CBranch<0x05, "bne", setne>;
let rt=1 in
def BGEZ : CBranchZero<0x01, "bgez", setge>;
let rt=0 in {
def BGTZ : CBranchZero<0x07, "bgtz", setgt>;
def BLEZ : CBranchZero<0x07, "blez", setle>;
def BLTZ : CBranchZero<0x01, "bltz", setlt>;
}
def BEQ : CBranch<0x04, "beq", seteq, CPURegs>;
def BNE : CBranch<0x05, "bne", setne, CPURegs>;
def BGEZ : CBranchZero<0x01, 1, "bgez", setge, CPURegs>;
def BGTZ : CBranchZero<0x07, 0, "bgtz", setgt, CPURegs>;
def BLEZ : CBranchZero<0x07, 0, "blez", setle, CPURegs>;
def BLTZ : CBranchZero<0x01, 0, "bltz", setlt, CPURegs>;
def BGEZAL : BranchLink<"bgezal">;
def BLTZAL : BranchLink<"bltzal">;