X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsInstrInfo.td;h=46cf43e422db90935e0e0c217f06b9ebcb8cac80;hb=2045c47affc0d1462a815175e420f9d6bd3f35c6;hp=ddf18d88ac7bfa332b22e524133d74b23ac9fe9b;hpb=91ef849e6cb01a019dc50ed4e95c058e01616062;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index ddf18d88ac7..46cf43e422d 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -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,10 +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 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. @@ -60,10 +69,14 @@ def HasSEInReg : Predicate<"Subtarget.hasSEInReg()">; // Instruction operand types def brtarget : Operand; def calltarget : Operand; -def uimm16 : Operand; def simm16 : Operand; def shamt : Operand; +// Unsigned Operand +def uimm16 : Operand { + let PrintMethod = "printUnsignedImm"; +} + // Address operand def mem : Operand { let PrintMethod = "printMemOperand"; @@ -72,21 +85,21 @@ def mem : Operand { // Transformation Function - get the lower 16 bits. def LO16 : SDNodeXFormgetValue() & 0xFFFF); + return getI32Imm((unsigned)N->getZExtValue() & 0xFFFF); }]>; // Transformation Function - get the higher 16 bits. def HI16 : SDNodeXFormgetValue() >> 16); + return getI32Imm((unsigned)N->getZExtValue() >> 16); }]>; // Node immediate fits as 16-bit sign extended on target immediate. // e.g. addi, andi def immSExt16 : PatLeaf<(imm), [{ if (N->getValueType(0) == MVT::i32) - return (int32_t)N->getValue() == (short)N->getValue(); + return (int32_t)N->getZExtValue() == (short)N->getZExtValue(); else - return (int64_t)N->getValue() == (short)N->getValue(); + return (int64_t)N->getZExtValue() == (short)N->getZExtValue(); }]>; // Node immediate fits as 16-bit zero extended on target immediate. @@ -95,14 +108,14 @@ def immSExt16 : PatLeaf<(imm), [{ // e.g. addiu, sltiu def immZExt16 : PatLeaf<(imm), [{ if (N->getValueType(0) == MVT::i32) - return (uint32_t)N->getValue() == (unsigned short)N->getValue(); + return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue(); else - return (uint64_t)N->getValue() == (unsigned short)N->getValue(); + return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue(); }], LO16>; // shamt field must fit in 5 bits. def immZExt5 : PatLeaf<(imm), [{ - return N->getValue() == ((N->getValue()) & 0x1f) ; + return N->getZExtValue() == ((N->getZExtValue()) & 0x1f) ; }]>; // Mips Address Mode! SDNode frameindex could possibily be a match @@ -142,6 +155,14 @@ class ArithI 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 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 func, string instr_asm> : @@ -203,7 +224,7 @@ class LoadUpper op, string instr_asm>: [], IIAlu>; // Memory Load/Store -let isSimpleLoad = 1, hasDelaySlot = 1 in +let canFoldAsLoad = 1, hasDelaySlot = 1 in class LoadM op, string instr_asm, PatFrag OpNode>: FI< op, (outs CPURegs:$dst), @@ -279,8 +300,9 @@ class JumpFR op, bits<6> func, string instr_asm>: // Jump and Link (Call) let isCall=1, hasDelaySlot=1, // All calls clobber the non-callee saved registers... - Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, - T3, T4, T5, T6, T7, T8, T9, K0, K1], Uses = [GP] in { + Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, + K0, K1, F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, + F14, F15, F16, F17, F18, F19], Uses = [GP] in { class JumpLink op, string instr_asm>: FJ< op, (outs), @@ -331,15 +353,6 @@ class MoveToLOHI func, string instr_asm>: !strconcat(instr_asm, "\t$src"), [], IIHiLo>; -// Count Leading Ones/Zeros in Word -class CountLeading func, string instr_asm>: - FR< 0x1c, - func, - (outs CPURegs:$dst), - (ins CPURegs:$src), - !strconcat(instr_asm, "\t$dst, $src"), - [], IIAlu>; - class EffectiveAddress : FI<0x09, (outs CPURegs:$dst), @@ -347,11 +360,30 @@ class EffectiveAddress : instr_asm, [(set CPURegs:$dst, addr:$addr)], IIAlu>; +// Count Leading Ones/Zeros in Word +class CountLeading func, string instr_asm, SDNode CountOp>: + FR< 0x1c, func, (outs CPURegs:$dst), (ins CPURegs:$src), + !strconcat(instr_asm, "\t$dst, $src"), + [(set CPURegs:$dst, (CountOp CPURegs:$src))], IIAlu>; + +// Sign Extend in Register. class SignExtInReg func, string instr_asm, ValueType vt>: FR< 0x3f, func, (outs CPURegs:$dst), (ins CPURegs:$src), !strconcat(instr_asm, "\t$dst, $src"), [(set CPURegs:$dst, (sext_inreg CPURegs:$src, vt))], NoItinerary>; +// Byte Swap +class ByteSwap 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 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 @@ -361,10 +393,10 @@ class SignExtInReg func, string instr_asm, ValueType vt>: let Defs = [SP], Uses = [SP] in { def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins uimm16:$amt), "!ADJCALLSTACKDOWN $amt", - [(callseq_start imm:$amt)]>; + [(callseq_start timm:$amt)]>; def ADJCALLSTACKUP : MipsPseudo<(outs), (ins uimm16:$amt1, uimm16:$amt2), "!ADJCALLSTACKUP $amt1", - [(callseq_end imm:$amt1, imm:$amt2)]>; + [(callseq_end timm:$amt1, timm:$amt2)]>; } // Some assembly macros need to avoid pseudoinstructions and assembler @@ -385,7 +417,7 @@ def CPRESTORE : MipsPseudo<(outs), (ins uimm16:$loc), ".cprestore\t$loc\n", []>; // operation. The solution is to create a Mips pseudo SELECT_CC instruction // (MipsSelectCC), use LowerSELECT_CC to generate this instruction and finally // replace it for real supported nodes into EmitInstrWithCustomInserter -let usesCustomDAGSchedInserter = 1 in { +let usesCustomInserter = 1 in { class PseudoSelCC: MipsPseudo<(outs RC:$dst), (ins CPURegs:$CmpRes, RC:$T, RC:$F), asmstr, [(set RC:$dst, (MipsSelectCC CPURegs:$CmpRes, RC:$T, RC:$F))]>; @@ -402,10 +434,10 @@ def Select_CC : PseudoSelCC; //===----------------------------------------------------------------------===// /// 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>; @@ -486,13 +518,34 @@ let Uses = [LO] in /// Sign Ext In Register Instructions. let Predicates = [HasSEInReg] in { - let shamt = 0x10, rs = 0 in + let shamt = 0x10, rs = 0 in def SEB : SignExtInReg<0x21, "seb", i8>; - let shamt = 0x18, rs = 0 in + let shamt = 0x18, rs = 0 in def SEH : SignExtInReg<0x20, "seh", i16>; } +/// Count Leading +let Predicates = [HasBitCount] in { + 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 let addr=0 in def NOP : FJ<0, (outs), (ins), "nop", [], IIAlu>; @@ -503,13 +556,6 @@ let addr=0 in // can be matched. It's similar to Sparc LEA_ADDRi def LEA_ADDiu : EffectiveAddress<"addiu\t$dst, ${addr:stackloc}">; -// Count Leading -// CLO/CLZ are part of the newer MIPS32(tm) instruction -// set and not older Mips I keep this for future use -// though. -//def CLO : CountLeading<0x21, "clo">; -//def CLZ : CountLeading<0x20, "clz">; - // MADD*/MSUB* are not part of MipsI either. //def MADD : MArithR<0x00, "madd">; //def MADDU : MArithR<0x01, "maddu">; @@ -574,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)>; - -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 + (BEQ (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>; + 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), @@ -638,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