Removed SELECT_CC custom lowering. This is not needed anymore, the SELECT node

is lowered properly and covers everything LowerSELECT_CC did.
Added method printUnsignedImm in AsmPrinter to print uimm16 operands. This
avoid the ugly instruction by instruction checking in printOperand.
Added a swap instruction present in the allegrex core.
Added two conditional instructions present in the allegrex core : MOVZ and MOVN.
They both allow a more efficient SELECT operation for integers.
Also added SELECT patterns to optimize MOVZ and MOVN usage.
The brcond and setcc patterns were cleaned: redundant and suboptimal patterns
were
removed. The suboptimals were replaced by more efficient ones.
Fixed some instructions that were using immZExt16 instead of immSExt16.

llvm-svn: 54724
This commit is contained in:
Bruno Cardoso Lopes 2008-08-13 07:13:40 +00:00
parent 703a64c38d
commit 92c64ae2d0
5 changed files with 126 additions and 75 deletions

View File

@ -62,6 +62,7 @@ namespace {
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
void printOperand(const MachineInstr *MI, int opNum);
void printUnsignedImm(const MachineInstr *MI, int opNum);
void printMemOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
void printFCCOperand(const MachineInstr *MI, int opNum,
@ -383,11 +384,7 @@ printOperand(const MachineInstr *MI, int opNum)
break;
case MachineOperand::MO_Immediate:
if ((MI->getOpcode() == Mips::SLTiu) || (MI->getOpcode() == Mips::ORi) ||
(MI->getOpcode() == Mips::LUi) || (MI->getOpcode() == Mips::ANDi))
O << (unsigned short int)MO.getImm();
else
O << (short int)MO.getImm();
O << (short int)MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
@ -407,7 +404,6 @@ printOperand(const MachineInstr *MI, int opNum)
<< '_' << MO.getIndex();
break;
// FIXME: Verify correct
case MachineOperand::MO_ConstantPoolIndex:
O << TAI->getPrivateGlobalPrefix() << "CPI"
<< getFunctionNumber() << "_" << MO.getIndex();
@ -420,6 +416,16 @@ printOperand(const MachineInstr *MI, int opNum)
if (closeP) O << ")";
}
void MipsAsmPrinter::
printUnsignedImm(const MachineInstr *MI, int opNum)
{
const MachineOperand &MO = MI->getOperand(opNum);
if (MO.getType() == MachineOperand::MO_Immediate)
O << (unsigned short int)MO.getImm();
else
printOperand(MI, opNum);
}
void MipsAsmPrinter::
printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier)
{

View File

@ -46,6 +46,7 @@ getTargetNodeName(unsigned Opcode) const
case MipsISD::Lo : return "MipsISD::Lo";
case MipsISD::GPRel : return "MipsISD::GPRel";
case MipsISD::Ret : return "MipsISD::Ret";
case MipsISD::CMov : return "MipsISD::CMov";
case MipsISD::SelectCC : return "MipsISD::SelectCC";
case MipsISD::FPSelectCC : return "MipsISD::FPSelectCC";
case MipsISD::FPBrcond : return "MipsISD::FPBrcond";
@ -99,7 +100,6 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
setOperationAction(ISD::SELECT, MVT::f32, Custom);
setOperationAction(ISD::SELECT, MVT::i32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
setOperationAction(ISD::SETCC, MVT::f32, Custom);
setOperationAction(ISD::BRCOND, MVT::Other, Custom);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
@ -120,8 +120,6 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
setOperationAction(ISD::ROTL, MVT::i32, Expand);
setOperationAction(ISD::ROTR, MVT::i32, Expand);
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
@ -149,6 +147,9 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
if (!Subtarget->hasBitCount())
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
if (!Subtarget->hasSwap())
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
setStackPointerRegisterToSaveRestore(Mips::SP);
computeRegisterProperties();
}
@ -176,7 +177,6 @@ LowerOperation(SDValue Op, SelectionDAG &DAG)
case ISD::OR: return LowerANDOR(Op, DAG);
case ISD::RET: return LowerRET(Op, DAG);
case ISD::SELECT: return LowerSELECT(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
case ISD::SETCC: return LowerSETCC(Op, DAG);
}
return SDValue();
@ -450,31 +450,23 @@ LowerSELECT(SDValue Op, SelectionDAG &DAG)
SDValue True = Op.getOperand(1);
SDValue False = Op.getOperand(2);
// if the incomming condition comes from fpcmp, the select
// operation must use FPSelectCC, otherwise SelectCC.
if (Cond.getOpcode() != MipsISD::FPCmp)
// if the incomming condition comes from a integer compare, the select
// operation must be SelectCC or a conditional move if the subtarget
// supports it.
if (Cond.getOpcode() != MipsISD::FPCmp) {
if (Subtarget->hasCondMov() && !True.getValueType().isFloatingPoint())
return Op;
return DAG.getNode(MipsISD::SelectCC, True.getValueType(),
Cond, True, False);
}
// if the incomming condition comes from fpcmp, the select
// operation must use FPSelectCC.
SDValue CCNode = Cond.getOperand(2);
return DAG.getNode(MipsISD::FPSelectCC, True.getValueType(),
Cond, True, False, CCNode);
}
SDValue MipsTargetLowering::
LowerSELECT_CC(SDValue Op, SelectionDAG &DAG)
{
SDValue LHS = Op.getOperand(0);
SDValue RHS = Op.getOperand(1);
SDValue True = Op.getOperand(2);
SDValue False = Op.getOperand(3);
SDValue CC = Op.getOperand(4);
SDValue SetCCRes = DAG.getNode(ISD::SETCC, LHS.getValueType(), LHS, RHS, CC);
return DAG.getNode(MipsISD::SelectCC, True.getValueType(),
SetCCRes, True, False);
}
SDValue MipsTargetLowering::
LowerGlobalAddress(SDValue Op, SelectionDAG &DAG)
{

View File

@ -40,6 +40,9 @@ namespace llvm {
// Handle gp_rel (small data/bss sections) relocation.
GPRel,
// Conditional Move
CMov,
// Select CC Pseudo Instruction
SelectCC,
@ -99,7 +102,6 @@ namespace llvm {
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG);
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG);

View File

@ -21,6 +21,9 @@ def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
def SDT_MipsSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>,
SDTCisSameAs<2, 3>, SDTCisInt<1>]>;
def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>,
SDTCisInt<4>]>;
def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
@ -48,11 +51,16 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
// Select Condition Code
def MipsSelectCC : SDNode<"MipsISD::SelectCC", SDT_MipsSelectCC>;
// Conditional Move
def MipsCMov : SDNode<"MipsISD::CMov", SDT_MipsCMov>;
//===----------------------------------------------------------------------===//
// Mips Instruction Predicate Definitions.
//===----------------------------------------------------------------------===//
def HasSEInReg : Predicate<"Subtarget.hasSEInReg()">;
def HasBitCount : Predicate<"Subtarget.hasBitCount()">;
def HasSwap : Predicate<"Subtarget.hasSwap()">;
def HasCondMov : Predicate<"Subtarget.hasCondMov()">;
//===----------------------------------------------------------------------===//
// Mips Operand, Complex Patterns and Transformations Definitions.
@ -61,10 +69,14 @@ def HasBitCount : Predicate<"Subtarget.hasBitCount()">;
// Instruction operand types
def brtarget : Operand<OtherVT>;
def calltarget : Operand<i32>;
def uimm16 : Operand<i32>;
def simm16 : Operand<i32>;
def shamt : Operand<i32>;
// Unsigned Operand
def uimm16 : Operand<i32> {
let PrintMethod = "printUnsignedImm";
}
// Address operand
def mem : Operand<i32> {
let PrintMethod = "printMemOperand";
@ -143,6 +155,14 @@ class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
!strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>;
class ArithOverflowI<bits<6> op, string instr_asm, SDNode OpNode,
Operand Od, PatLeaf imm_type> :
FI< op,
(outs CPURegs:$dst),
(ins CPURegs:$b, Od:$c),
!strconcat(instr_asm, "\t$dst, $b, $c"),
[], IIAlu>;
// Arithmetic Multiply ADD/SUB
let rd=0 in
class MArithR<bits<6> func, string instr_asm> :
@ -352,6 +372,18 @@ class SignExtInReg<bits<6> func, string instr_asm, ValueType vt>:
!strconcat(instr_asm, "\t$dst, $src"),
[(set CPURegs:$dst, (sext_inreg CPURegs:$src, vt))], NoItinerary>;
// Byte Swap
class ByteSwap<bits<6> func, string instr_asm>:
FR< 0x1f, func, (outs CPURegs:$dst), (ins CPURegs:$src),
!strconcat(instr_asm, "\t$dst, $src"),
[(set CPURegs:$dst, (bswap CPURegs:$src))], NoItinerary>;
// Conditional Move
class CondMov<bits<6> func, string instr_asm, PatLeaf MovCode>:
FR< 0x00, func, (outs CPURegs:$dst), (ins CPURegs:$F, CPURegs:$T,
CPURegs:$cond), !strconcat(instr_asm, "\t$dst, $T, $cond"),
[(set CPURegs:$dst, (MipsCMov CPURegs:$F, CPURegs:$T,
CPURegs:$cond, MovCode))], NoItinerary>;
//===----------------------------------------------------------------------===//
// Pseudo instructions
@ -402,10 +434,10 @@ def Select_CC : PseudoSelCC<CPURegs, "# MipsSelect_CC_i32">;
//===----------------------------------------------------------------------===//
/// Arithmetic Instructions (ALU Immediate)
def ADDiu : ArithI<0x09, "addiu", add, uimm16, immZExt16>;
def ADDi : ArithI<0x08, "addi", add, simm16, immSExt16>;
def ADDiu : ArithI<0x09, "addiu", add, simm16, immSExt16>;
def ADDi : ArithOverflowI<0x08, "addi", add, simm16, immSExt16>;
def SLTi : SetCC_I<0x0a, "slti", setlt, simm16, immSExt16>;
def SLTiu : SetCC_I<0x0b, "sltiu", setult, uimm16, immZExt16>;
def SLTiu : SetCC_I<0x0b, "sltiu", setult, simm16, immSExt16>;
def ANDi : LogicI<0x0c, "andi", and>;
def ORi : LogicI<0x0d, "ori", or>;
def XORi : LogicI<0x0e, "xori", xor>;
@ -495,8 +527,23 @@ let Predicates = [HasSEInReg] in {
/// Count Leading
let Predicates = [HasBitCount] in {
def CLZ : CountLeading<0b010110, "clz", ctlz>;
//def CLO : CountLeading<0b010110, "clo">;
let rt = 0 in
def CLZ : CountLeading<0b010110, "clz", ctlz>;
}
/// Byte Swap
let Predicates = [HasSwap] in {
let shamt = 0x3, rs = 0 in
def WSBW : ByteSwap<0x20, "wsbw">;
}
/// Conditional Move
def MIPS_CMOV_ZERO : PatLeaf<(i32 0)>;
def MIPS_CMOV_NZERO : PatLeaf<(i32 1)>;
let Predicates = [HasCondMov], isTwoAddress = 1 in {
def MOVN : CondMov<0x0a, "movn", MIPS_CMOV_NZERO>;
def MOVZ : CondMov<0x0b, "movz", MIPS_CMOV_ZERO>;
}
/// No operation
@ -573,55 +620,65 @@ def : Pat<(not CPURegs:$in),
(NOR CPURegs:$in, ZERO)>;
// extended load and stores
def : Pat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
def : Pat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
def : Pat<(extloadi1 addr:$src), (LBu addr:$src)>;
def : Pat<(extloadi8 addr:$src), (LBu addr:$src)>;
def : Pat<(extloadi16 addr:$src), (LHu addr:$src)>;
// peepholes
def : Pat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
// brcond patterns
// direct match equal/notequal zero branches
def : Pat<(brcond (setne CPURegs:$lhs, 0), bb:$dst),
(BNE CPURegs:$lhs, ZERO, bb:$dst)>;
def : Pat<(brcond (seteq CPURegs:$lhs, 0), bb:$dst),
(BEQ CPURegs:$lhs, ZERO, bb:$dst)>;
def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BGEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
(BEQ (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BGEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BGTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BGTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
(BEQ (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setge CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
(BEQ (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setuge CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
(BEQ (SLTiu CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BLEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
(BEQ (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BLEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
(BEQ (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setlt CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
(BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
(BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BNE (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BNE (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BLTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
(BLTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>;
// generic brcond pattern
def : Pat<(brcond CPURegs:$cond, bb:$dst),
(BNE CPURegs:$cond, ZERO, bb:$dst)>;
// setcc patterns, only matched when there
// is no brcond following a setcc operation
// select patterns
def : Pat<(select (setge CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F),
(MOVZ CPURegs:$F, CPURegs:$T, (SLT CPURegs:$lhs, CPURegs:$rhs))>;
def : Pat<(select (setuge CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F),
(MOVZ CPURegs:$F, CPURegs:$T, (SLTu CPURegs:$lhs, CPURegs:$rhs))>;
def : Pat<(select (setge CPURegs:$lhs, immSExt16:$rhs), CPURegs:$T, CPURegs:$F),
(MOVZ CPURegs:$F, CPURegs:$T, (SLTi CPURegs:$lhs, immSExt16:$rhs))>;
def : Pat<(select (setuge CPURegs:$lh, immSExt16:$rh), CPURegs:$T, CPURegs:$F),
(MOVZ CPURegs:$F, CPURegs:$T, (SLTiu CPURegs:$lh, immSExt16:$rh))>;
def : Pat<(select (setle CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F),
(MOVZ CPURegs:$F, CPURegs:$T, (SLT CPURegs:$rhs, CPURegs:$lhs))>;
def : Pat<(select (setule CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F),
(MOVZ CPURegs:$F, CPURegs:$T, (SLTu CPURegs:$rhs, CPURegs:$lhs))>;
def : Pat<(select (seteq CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F),
(MOVZ CPURegs:$F, CPURegs:$T, (XOR CPURegs:$lhs, CPURegs:$rhs))>;
def : Pat<(select (setne CPURegs:$lhs, CPURegs:$rhs), CPURegs:$T, CPURegs:$F),
(MOVN CPURegs:$F, CPURegs:$T, (XOR CPURegs:$lhs, CPURegs:$rhs))>;
def : Pat<(select CPURegs:$cond, CPURegs:$T, CPURegs:$F),
(MOVN CPURegs:$F, CPURegs:$T, CPURegs:$cond)>;
// setcc patterns
def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs),
(SLTu (XOR CPURegs:$lhs, CPURegs:$rhs), 1)>;
def : Pat<(setne CPURegs:$lhs, CPURegs:$rhs),
(SLTu ZERO, (XOR CPURegs:$lhs, CPURegs:$rhs))>;
def : Pat<(setle CPURegs:$lhs, CPURegs:$rhs),
(XORi (SLT CPURegs:$rhs, CPURegs:$lhs), 1)>;
def : Pat<(setule CPURegs:$lhs, CPURegs:$rhs),
@ -637,18 +694,10 @@ def : Pat<(setge CPURegs:$lhs, CPURegs:$rhs),
def : Pat<(setuge CPURegs:$lhs, CPURegs:$rhs),
(XORi (SLTu CPURegs:$lhs, CPURegs:$rhs), 1)>;
def : Pat<(setne CPURegs:$lhs, CPURegs:$rhs),
(OR (SLT CPURegs:$lhs, CPURegs:$rhs),
(SLT CPURegs:$rhs, CPURegs:$lhs))>;
def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs),
(XORi (OR (SLT CPURegs:$lhs, CPURegs:$rhs),
(SLT CPURegs:$rhs, CPURegs:$lhs)), 1)>;
def : Pat<(setge CPURegs:$lhs, immSExt16:$rhs),
(XORi (SLTi CPURegs:$lhs, immSExt16:$rhs), 1)>;
def : Pat<(setuge CPURegs:$lhs, immZExt16:$rhs),
(XORi (SLTiu CPURegs:$lhs, immZExt16:$rhs), 1)>;
def : Pat<(setuge CPURegs:$lhs, immSExt16:$rhs),
(XORi (SLTiu CPURegs:$lhs, immSExt16:$rhs), 1)>;
//===----------------------------------------------------------------------===//
// Floating Point Support

View File

@ -58,6 +58,8 @@ MipsSubtarget::MipsSubtarget(const TargetMachine &TM, const Module &M,
HasVFPU = true; // Enables Allegrex Vector FPU (not supported yet)
HasSEInReg = true;
HasBitCount = true;
HasSwap = true;
HasCondMov = true;
}
// Abicall is the default for O32 ABI and is ignored