diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2013-04-30 22:37:26 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2013-04-30 22:37:26 +0000 |
commit | cd6c57917db22a3913a2cdbadfa79fed3547bdec (patch) | |
tree | 3950548bc9bb33b74cf36a92dd0c1dffff7a88c1 /lib/Target/Mips | |
parent | 86a87d9ba1faf153e0e6eaddfd3e95595c83bcb1 (diff) |
[mips] Instruction selection patterns for DSP-ASE vector select and compare
instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180820 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r-- | lib/Target/Mips/MipsDSPInstrInfo.td | 73 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsRegisterInfo.td | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEISelLowering.cpp | 63 |
5 files changed, 145 insertions, 3 deletions
diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td index 730bca7d52..6719cd54a9 100644 --- a/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/lib/Target/Mips/MipsDSPInstrInfo.td @@ -79,6 +79,8 @@ def MipsMSUBU_DSP : MipsDSPBase<"MSUBU_DSP", SDT_MipsDPA>; def MipsSHLL_DSP : MipsDSPBase<"SHLL_DSP", SDT_MipsSHIFT_DSP>; def MipsSHRA_DSP : MipsDSPBase<"SHRA_DSP", SDT_MipsSHIFT_DSP>; def MipsSHRL_DSP : MipsDSPBase<"SHRL_DSP", SDT_MipsSHIFT_DSP>; +def MipsSETCC_DSP : MipsDSPBase<"SETCC_DSP", SDTSetCC>; +def MipsSELECT_CC_DSP : MipsDSPBase<"SELECT_CC_DSP", SDTSelectCC>; // Flags. class UseAC { @@ -1237,6 +1239,26 @@ let isPseudo = 1 in { def COPY_AC_DSP : PseudoSE<(outs ACRegsDSP:$dst), (ins ACRegsDSP:$src), []>; +// Pseudo CMP and PICK instructions. +class PseudoCMP<Instruction RealInst> : + PseudoDSP<(outs DSPCC:$cmp), (ins DSPRegs:$rs, DSPRegs:$rt), []>, + PseudoInstExpansion<(RealInst DSPRegs:$rs, DSPRegs:$rt)>, NeverHasSideEffects; + +class PseudoPICK<Instruction RealInst> : + PseudoDSP<(outs DSPRegs:$rd), (ins DSPCC:$cmp, DSPRegs:$rs, DSPRegs:$rt), []>, + PseudoInstExpansion<(RealInst DSPRegs:$rd, DSPRegs:$rs, DSPRegs:$rt)>, + NeverHasSideEffects; + +def PseudoCMP_EQ_PH : PseudoCMP<CMP_EQ_PH>; +def PseudoCMP_LT_PH : PseudoCMP<CMP_LT_PH>; +def PseudoCMP_LE_PH : PseudoCMP<CMP_LE_PH>; +def PseudoCMPU_EQ_QB : PseudoCMP<CMPU_EQ_QB>; +def PseudoCMPU_LT_QB : PseudoCMP<CMPU_LT_QB>; +def PseudoCMPU_LE_QB : PseudoCMP<CMPU_LE_QB>; + +def PseudoPICK_PH : PseudoPICK<PICK_PH>; +def PseudoPICK_QB : PseudoPICK<PICK_QB>; + // Patterns. class DSPPat<dag pattern, dag result, Predicate pred = HasDSP> : Pat<pattern, result>, Requires<[pred]>; @@ -1298,6 +1320,57 @@ def : DSPShiftPat<SHLL_QB, v4i8, int_mips_shll_qb, immZExt3>; def : DSPShiftPat<SHRA_QB, v4i8, int_mips_shra_qb, immZExt3, HasDSPR2>; def : DSPShiftPat<SHRL_QB, v4i8, int_mips_shrl_qb, immZExt3>; +// SETCC/SELECT_CC patterns. +class DSPSetCCPat<Instruction Cmp, Instruction Pick, ValueType ValTy, + CondCode CC> : + DSPPat<(ValTy (MipsSETCC_DSP ValTy:$a, ValTy:$b, CC)), + (ValTy (Pick (ValTy (Cmp ValTy:$a, ValTy:$b)), + (ValTy (COPY_TO_REGCLASS (ADDiu ZERO, -1), DSPRegs)), + (ValTy ZERO)))>; + +class DSPSetCCPatInv<Instruction Cmp, Instruction Pick, ValueType ValTy, + CondCode CC> : + DSPPat<(ValTy (MipsSETCC_DSP ValTy:$a, ValTy:$b, CC)), + (ValTy (Pick (ValTy (Cmp ValTy:$a, ValTy:$b)), + (ValTy ZERO), + (ValTy (COPY_TO_REGCLASS (ADDiu ZERO, -1), DSPRegs))))>; + +class DSPSelectCCPat<Instruction Cmp, Instruction Pick, ValueType ValTy, + CondCode CC> : + DSPPat<(ValTy (MipsSELECT_CC_DSP ValTy:$a, ValTy:$b, ValTy:$c, ValTy:$d, CC)), + (ValTy (Pick (ValTy (Cmp ValTy:$a, ValTy:$b)), $c, $d))>; + +class DSPSelectCCPatInv<Instruction Cmp, Instruction Pick, ValueType ValTy, + CondCode CC> : + DSPPat<(ValTy (MipsSELECT_CC_DSP ValTy:$a, ValTy:$b, ValTy:$c, ValTy:$d, CC)), + (ValTy (Pick (ValTy (Cmp ValTy:$a, ValTy:$b)), $d, $c))>; + +def : DSPSetCCPat<PseudoCMP_EQ_PH, PseudoPICK_PH, v2i16, SETEQ>; +def : DSPSetCCPat<PseudoCMP_LT_PH, PseudoPICK_PH, v2i16, SETLT>; +def : DSPSetCCPat<PseudoCMP_LE_PH, PseudoPICK_PH, v2i16, SETLE>; +def : DSPSetCCPatInv<PseudoCMP_EQ_PH, PseudoPICK_PH, v2i16, SETNE>; +def : DSPSetCCPatInv<PseudoCMP_LT_PH, PseudoPICK_PH, v2i16, SETGE>; +def : DSPSetCCPatInv<PseudoCMP_LE_PH, PseudoPICK_PH, v2i16, SETGT>; +def : DSPSetCCPat<PseudoCMPU_EQ_QB, PseudoPICK_QB, v4i8, SETEQ>; +def : DSPSetCCPat<PseudoCMPU_LT_QB, PseudoPICK_QB, v4i8, SETULT>; +def : DSPSetCCPat<PseudoCMPU_LE_QB, PseudoPICK_QB, v4i8, SETULE>; +def : DSPSetCCPatInv<PseudoCMPU_EQ_QB, PseudoPICK_QB, v4i8, SETNE>; +def : DSPSetCCPatInv<PseudoCMPU_LT_QB, PseudoPICK_QB, v4i8, SETUGE>; +def : DSPSetCCPatInv<PseudoCMPU_LE_QB, PseudoPICK_QB, v4i8, SETUGT>; + +def : DSPSelectCCPat<PseudoCMP_EQ_PH, PseudoPICK_PH, v2i16, SETEQ>; +def : DSPSelectCCPat<PseudoCMP_LT_PH, PseudoPICK_PH, v2i16, SETLT>; +def : DSPSelectCCPat<PseudoCMP_LE_PH, PseudoPICK_PH, v2i16, SETLE>; +def : DSPSelectCCPatInv<PseudoCMP_EQ_PH, PseudoPICK_PH, v2i16, SETNE>; +def : DSPSelectCCPatInv<PseudoCMP_LT_PH, PseudoPICK_PH, v2i16, SETGE>; +def : DSPSelectCCPatInv<PseudoCMP_LE_PH, PseudoPICK_PH, v2i16, SETGT>; +def : DSPSelectCCPat<PseudoCMPU_EQ_QB, PseudoPICK_QB, v4i8, SETEQ>; +def : DSPSelectCCPat<PseudoCMPU_LT_QB, PseudoPICK_QB, v4i8, SETULT>; +def : DSPSelectCCPat<PseudoCMPU_LE_QB, PseudoPICK_QB, v4i8, SETULE>; +def : DSPSelectCCPatInv<PseudoCMPU_EQ_QB, PseudoPICK_QB, v4i8, SETNE>; +def : DSPSelectCCPatInv<PseudoCMPU_LT_QB, PseudoPICK_QB, v4i8, SETUGE>; +def : DSPSelectCCPatInv<PseudoCMPU_LE_QB, PseudoPICK_QB, v4i8, SETUGT>; + // Extr patterns. class EXTR_W_TY1_R2_Pat<SDPatternOperator OpNode, Instruction Instr> : DSPPat<(i32 (OpNode CPURegs:$rs, ACRegsDSP:$ac)), diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 8a0673feb6..611d48326e 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -200,6 +200,8 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::SHLL_DSP: return "MipsISD::SHLL_DSP"; case MipsISD::SHRA_DSP: return "MipsISD::SHRA_DSP"; case MipsISD::SHRL_DSP: return "MipsISD::SHRL_DSP"; + case MipsISD::SETCC_DSP: return "MipsISD::SETCC_DSP"; + case MipsISD::SELECT_CC_DSP: return "MipsISD::SELECT_CC_DSP"; default: return NULL; } } @@ -213,7 +215,7 @@ MipsTargetLowering(MipsTargetMachine &TM) // Mips does not have i1 type, so use i32 for // setcc operations results (slt, sgt, ...). setBooleanContents(ZeroOrOneBooleanContent); - setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? + setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); // Load extented operations for i1 types must be promoted setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index c1574fac57..5587e8f581 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -148,6 +148,10 @@ namespace llvm { SHRA_DSP, SHRL_DSP, + // DSP setcc and select_cc nodes. + SETCC_DSP, + SELECT_CC_DSP, + // Load/Store Left/Right nodes. LWL = ISD::FIRST_TARGET_MEMORY_OPCODE, LWR, diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index 30699ac421..e314e946a0 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -265,6 +265,7 @@ let Namespace = "Mips" in { def AC0_64 : ACC<0, "ac0", [LO64, HI64]>; def DSPCtrl : Register<"dspctrl">; + def DSPCCond : Register<"">; } //===----------------------------------------------------------------------===// @@ -362,6 +363,9 @@ def ACRegsDSP : RegisterClass<"Mips", [untyped], 64, (sequence "AC%u", 0, 3)> { let Size = 64; } +def DSPCC : RegisterClass<"Mips", [v4i8, v2i16], 32, (add DSPCCond)>; + +// Register Operands. def CPURegsAsmOperand : AsmOperandClass { let Name = "CPURegsAsm"; let ParserMethod = "parseCPURegs"; diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index 7e103bbef7..8544bb8910 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -56,6 +56,8 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) setTargetDAGCombine(ISD::SHL); setTargetDAGCombine(ISD::SRA); setTargetDAGCombine(ISD::SRL); + setTargetDAGCombine(ISD::SETCC); + setTargetDAGCombine(ISD::VSELECT); } if (Subtarget->hasDSPR2()) @@ -373,9 +375,57 @@ static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget); } +static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) { + bool IsV216 = (Ty == MVT::v2i16); + + switch (CC) { + case ISD::SETEQ: + case ISD::SETNE: return true; + case ISD::SETLT: + case ISD::SETLE: + case ISD::SETGT: + case ISD::SETGE: return IsV216; + case ISD::SETULT: + case ISD::SETULE: + case ISD::SETUGT: + case ISD::SETUGE: return !IsV216; + default: return false; + } +} + +static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) { + EVT Ty = N->getValueType(0); + + if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) + return SDValue(); + + if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get())) + return SDValue(); + + return DAG.getNode(MipsISD::SETCC_DSP, N->getDebugLoc(), Ty, N->getOperand(0), + N->getOperand(1), N->getOperand(2)); +} + +static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) { + EVT Ty = N->getValueType(0); + + if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) + return SDValue(); + + SDValue SetCC = N->getOperand(0); + + if (SetCC.getOpcode() != MipsISD::SETCC_DSP) + return SDValue(); + + return DAG.getNode(MipsISD::SELECT_CC_DSP, N->getDebugLoc(), Ty, + SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1), + N->getOperand(2), SetCC.getOperand(2)); +} + SDValue MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; + SDValue Val; switch (N->getOpcode()) { case ISD::ADDE: @@ -388,9 +438,18 @@ MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { return performSRACombine(N, DAG, DCI, Subtarget); case ISD::SRL: return performSRLCombine(N, DAG, DCI, Subtarget); - default: - return MipsTargetLowering::PerformDAGCombine(N, DCI); + case ISD::VSELECT: + return performVSELECTCombine(N, DAG); + case ISD::SETCC: { + Val = performSETCCCombine(N, DAG); + break; } + } + + if (Val.getNode()) + return Val; + + return MipsTargetLowering::PerformDAGCombine(N, DCI); } MachineBasicBlock * |