X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsInstrInfo.td;h=5337c9fb816a2d7b08e507309d496a2318f900f1;hb=00667a54f21f2d58382ac2eed973706332ed5817;hp=89e8ee26ea12aabad5e0c2b154560678cc0ac223;hpb=65ad452536526fe9a80023abc3703a7cc7987858;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 89e8ee26ea1..5337c9fb816 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -21,12 +21,16 @@ 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>]>; // Call -def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain, - SDNPOutFlag]>; +def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, + [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag, + SDNPVariadic]>; // Hi and Lo nodes are used to handle global addresses. Used on // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol @@ -48,11 +52,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 +70,14 @@ def HasBitCount : Predicate<"Subtarget.hasBitCount()">; // 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"; @@ -73,21 +86,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. @@ -96,19 +109,19 @@ 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 // since load and store instructions from stack used it. -def addr : ComplexPattern; +def addr : ComplexPattern; //===----------------------------------------------------------------------===// // Instructions specific format @@ -143,6 +156,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> : @@ -204,7 +225,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), @@ -280,13 +301,12 @@ 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, F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, - F14, F15, F16, F17, F18, F19], Uses = [GP] in { + Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, + K0, K1, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9], Uses = [GP] in { class JumpLink op, string instr_asm>: FJ< op, (outs), - (ins calltarget:$target), + (ins calltarget:$target, variable_ops), !strconcat(instr_asm, "\t$target"), [(MipsJmpLink imm:$target)], IIBranch>; @@ -295,14 +315,14 @@ let isCall=1, hasDelaySlot=1, FR< op, func, (outs), - (ins CPURegs:$rs), + (ins CPURegs:$rs, variable_ops), !strconcat(instr_asm, "\t$rs"), [(MipsJmpLink CPURegs:$rs)], IIBranch>; class BranchLink: FI< 0x1, (outs), - (ins CPURegs:$rs, brtarget:$target), + (ins CPURegs:$rs, brtarget:$target, variable_ops), !strconcat(instr_asm, "\t$rs, $target"), [], IIBranch>; } @@ -352,6 +372,18 @@ class SignExtInReg 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 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,17 +518,32 @@ 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 { - 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], Constraints = "$F = $dst" in { + def MOVN : CondMov<0x0a, "movn", MIPS_CMOV_NZERO>; + def MOVZ : CondMov<0x0b, "movz", MIPS_CMOV_ZERO>; } /// No operation @@ -546,8 +593,8 @@ def : Pat<(MipsJmpLink (i32 tglobaladdr:$dst)), (JAL tglobaladdr:$dst)>; def : Pat<(MipsJmpLink (i32 texternalsym:$dst)), (JAL texternalsym:$dst)>; -def : Pat<(MipsJmpLink CPURegs:$dst), - (JALR CPURegs:$dst)>; +//def : Pat<(MipsJmpLink CPURegs:$dst), +// (JALR CPURegs:$dst)>; // hi/lo relocs def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>; @@ -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)>; - -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), @@ -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