X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsInstrInfo.td;h=e39fd690fb900b4a77e27a46e4cf632ff4c20626;hb=bec8cee98120d48bc94f08d8921d8f5d6ad0ac9a;hp=44495ff134acdc854d5ba2cdb608c17729056640;hpb=2ef99c5dff1ab9612f2d65e38f725d809672d2fd;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 44495ff134a..e39fd690fb9 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -168,8 +168,6 @@ def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">, AssemblerPredicate<"FeatureMips64r2">; def IsN64 : Predicate<"Subtarget.isABI_N64()">, AssemblerPredicate<"FeatureN64">; -def NotN64 : Predicate<"!Subtarget.isABI_N64()">, - AssemblerPredicate<"!FeatureN64">; def InMips16Mode : Predicate<"Subtarget.inMips16Mode()">, AssemblerPredicate<"FeatureMips16">; def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">, @@ -179,7 +177,7 @@ def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">, def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">, AssemblerPredicate<"FeatureMips32">; def HasStdEnc : Predicate<"Subtarget.hasStandardEncoding()">, - AssemblerPredicate<"!FeatureMips16,!FeatureMicroMips">; + AssemblerPredicate<"!FeatureMips16">; def NotDSP : Predicate<"!Subtarget.hasDSP()">; def InMicroMips : Predicate<"Subtarget.inMicroMipsMode()">, AssemblerPredicate<"FeatureMicroMips">; @@ -187,6 +185,7 @@ def NotInMicroMips : Predicate<"!Subtarget.inMicroMipsMode()">, AssemblerPredicate<"!FeatureMicroMips">; def IsLE : Predicate<"Subtarget.isLittle()">; def IsBE : Predicate<"!Subtarget.isLittle()">; +def IsNotNaCl : Predicate<"!Subtarget.isTargetNaCl()">; class MipsPat : Pat { let Predicates = [HasStdEnc]; @@ -278,6 +277,9 @@ def uimm16 : Operand { let PrintMethod = "printUnsignedImm"; } +def pcrel16 : Operand { +} + def MipsMemAsmOperand : AsmOperandClass { let Name = "Mem"; let ParserMethod = "parseMemOperand"; @@ -299,8 +301,7 @@ def InvertedImOperand : Operand { let ParserMatchClass = MipsInvertedImmoperand; } -// Address operand -def mem : Operand { +class mem_generic : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops ptr_rc, simm16); let EncoderMethod = "getMemEncoding"; @@ -308,6 +309,14 @@ def mem : Operand { let OperandType = "OPERAND_MEMORY"; } +// Address operand +def mem : mem_generic; + +// MSA specific address operand +def mem_msa : mem_generic { + let EncoderMethod = "getMSAMemEncoding"; +} + def mem_ea : Operand { let PrintMethod = "printMemOperandEA"; let MIOperandInfo = (ops ptr_rc, simm16); @@ -426,9 +435,9 @@ class ArithLogicI : +class MArithR : InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), - !strconcat(opstr, "\t$rs, $rt"), [], IIImult, FrmR, opstr> { + !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> { let Defs = [HI0, LO0]; let Uses = [HI0, LO0]; let isCommutable = isComm; @@ -438,28 +447,30 @@ class MArithR : class LogicNOR: InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], IIArith, FrmR, opstr> { + [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> { let isCommutable = 1; } // Shifts class shift_rotate_imm : InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt), !strconcat(opstr, "\t$rd, $rt, $shamt"), - [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], IIArith, FrmR, opstr>; + [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr>; -class shift_rotate_reg: InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs), !strconcat(opstr, "\t$rd, $rt, $rs"), - [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], IIArith, FrmR, opstr>; + [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR, + opstr>; // Load Upper Imediate class LoadUpper: InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"), - [], IIArith, FrmI, opstr>, IsAsCheapAsAMove { + [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove { let neverHasSideEffects = 1; let isReMaterializable = 1; } @@ -501,21 +512,24 @@ class StoreLeftRight : - InstSE<(outs), (ins RO:$rs, RO:$rt, brtarget:$offset), +class CBranch : + InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset), !strconcat(opstr, "\t$rs, $rt, $offset"), [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch, - FrmI> { + FrmI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; let Defs = [AT]; } -class CBranchZero : - InstSE<(outs), (ins RO:$rs, brtarget:$offset), +class CBranchZero : + InstSE<(outs), (ins RO:$rs, opnd:$offset), !strconcat(opstr, "\t$rs, $offset"), - [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, FrmI> { + [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, + FrmI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; @@ -527,20 +541,20 @@ class SetCC_R : InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))], - IIslt, FrmR, opstr>; + II_SLT_SLTU, FrmR, opstr>; class SetCC_I: InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))], - IIslt, FrmI, opstr>; + II_SLTI_SLTIU, FrmI, opstr>; // Jump class JumpFJ : + SDPatternOperator targetoperator, string bopstr> : InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), - [(operator targetoperator:$target)], IIBranch, FrmJ> { + [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> { let isTerminator=1; let isBarrier=1; let hasDelaySlot = 1; @@ -562,17 +576,20 @@ class UncondBranch : // Base class for indirect branch and return instruction classes. let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in -class JumpFR: - InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch, FrmR>; +class JumpFR: + InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch, + FrmR, opstr>; // Indirect branch -class IndirectBranch: JumpFR { +class IndirectBranch : + JumpFR { let isBranch = 1; let isIndirectBranch = 1; } // Return instruction -class RetBase: JumpFR { +class RetBase: JumpFR { let isReturn = 1; let isCodeGenOnly = 1; let hasCtrlDep = 1; @@ -581,9 +598,9 @@ class RetBase: JumpFR { // Jump and Link (Call) let isCall=1, hasDelaySlot=1, Defs = [RA] in { - class JumpLink : - InstSE<(outs), (ins calltarget:$target), !strconcat(opstr, "\t$target"), - [(MipsJmpLink imm:$target)], IIBranch, FrmJ> { + class JumpLink : + InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), + [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> { let DecoderMethod = "DecodeJumpTarget"; } @@ -594,14 +611,26 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in { class JumpLinkReg: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [], IIBranch, FrmR>; + [], IIBranch, FrmR, opstr>; - class BGEZAL_FT : - InstSE<(outs), (ins RO:$rs, brtarget:$offset), - !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI>; + class BGEZAL_FT : + InstSE<(outs), (ins RO:$rs, opnd:$offset), + !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>; } +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, + hasExtraSrcRegAllocReq = 1, Defs = [AT] in { + class TailCall : + PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>, + PseudoInstExpansion<(JumpInst jmptarget:$target)>; + + class TailCallReg : + PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>, + PseudoInstExpansion<(JRInst ResRO:$rs)>; +} + class BAL_BR_Pseudo : PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>, PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> { @@ -615,45 +644,42 @@ class BAL_BR_Pseudo : // Syscall class SYS_FT : InstSE<(outs), (ins uimm20:$code_), - !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI>; + !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>; // Break class BRK_FT : InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2), - !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary, FrmOther>; + !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary, + FrmOther, opstr>; // (D)Eret class ER_FT : InstSE<(outs), (ins), - opstr, [], NoItinerary, FrmOther>; + opstr, [], NoItinerary, FrmOther, opstr>; // Interrupts class DEI_FT : InstSE<(outs RO:$rt), (ins), - !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther>; + !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>; // Wait class WAIT_FT : - InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther> { - let Inst{31-26} = 0x10; - let Inst{25} = 1; - let Inst{24-6} = 0; - let Inst{5-0} = 0x20; -} + InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>; // Sync let hasSideEffects = 1 in -class SYNC_FT : +class SYNC_FT : InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)], - NoItinerary, FrmOther>; + NoItinerary, FrmOther, opstr>; let hasSideEffects = 1 in class TEQ_FT : InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_), - !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary, FrmI>; + !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary, + FrmI, opstr>; class TEQI_FT : InstSE<(outs), (ins RO:$rs, uimm16:$imm16), - !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther>; + !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>; // Mul, Div class Mult DefRegs> : @@ -680,12 +706,13 @@ class MultDivPseudo +class MAddSubPseudo : PseudoSE<(outs ACC64:$ac), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin), [(set ACC64:$ac, (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))], - IIImult>, + itin>, PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> { string Constraints = "$acin = $ac"; } @@ -700,21 +727,22 @@ class Div : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo), - [(set DstRC:$rd, (OpNode SrcRC:$hilo))], IIHiLo>; + [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>; class MoveFromLOHI: - InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, FrmR, - opstr> { + InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO, + FrmR, opstr> { let Uses = [UseReg]; let neverHasSideEffects = 1; } class PseudoMTLOHI : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi), - [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))], IIHiLo>; + [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))], + II_MTHI_MTLO>; class MoveToLOHI DefRegs>: - InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo, + InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO, FrmR, opstr> { let Defs = DefRegs; let neverHasSideEffects = 1; @@ -722,7 +750,8 @@ class MoveToLOHI DefRegs>: class EffectiveAddress : InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set RO:$rt, addr:$addr)], NoItinerary, FrmI> { + [(set RO:$rt, addr:$addr)], NoItinerary, FrmI, + !strconcat(opstr, "_lea")> { let isCodeGenOnly = 1; let DecoderMethod = "DecodeMem"; } @@ -730,19 +759,20 @@ class EffectiveAddress : // Count Leading Ones/Zeros in Word class CountLeading0: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz RO:$rs))], IIArith, FrmR, opstr>, + [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>, Requires<[HasBitCount, HasStdEnc]>; class CountLeading1: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz (not RO:$rs)))], IIArith, FrmR, opstr>, + [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>, Requires<[HasBitCount, HasStdEnc]>; // Sign Extend in Register. -class SignExtInReg : +class SignExtInReg : InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), - [(set RO:$rd, (sext_inreg RO:$rt, vt))], IIseb, FrmR, opstr> { + [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr> { let Predicates = [HasSEInReg, HasStdEnc]; } @@ -757,7 +787,7 @@ class SubwordSwap: // Read Hardware class ReadHardware : InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [], - IIArith, FrmR>; + II_RDHWR, FrmR>; // Ext and Ins class ExtBase, ADDI_FM<0x9>, IsAsCheapAsAMove; def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>; @@ -882,130 +912,140 @@ def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>, SLTI_FM<0xa>; def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>, SLTI_FM<0xb>; -def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, IILogic, immZExt16, +def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>, ADDI_FM<0xc>; -def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, IILogic, immZExt16, +def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>, ADDI_FM<0xd>; -def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, IILogic, immZExt16, +def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>, ADDI_FM<0xe>; def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM; /// Arithmetic Instructions (3-Operand, R-Type) -def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, IIArith, add>, +def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>, ADD_FM<0, 0x21>; -def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, IIArith, sub>, +def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>, ADD_FM<0, 0x23>; let Defs = [HI0, LO0] in -def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, IIImul, mul>, +def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>, ADD_FM<0x1c, 2>; def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>; def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>; def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>; def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>; -def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, IILogic, and>, +def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>, ADD_FM<0, 0x24>; -def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, IILogic, or>, +def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>, ADD_FM<0, 0x25>; -def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, IILogic, xor>, +def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>, ADD_FM<0, 0x26>; def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>; /// Shift Instructions -def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, shl, immZExt5>, - SRA_FM<0, 0>; -def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, srl, immZExt5>, - SRA_FM<2, 0>; -def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, sra, immZExt5>, - SRA_FM<3, 0>; -def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, shl>, SRLV_FM<4, 0>; -def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, srl>, SRLV_FM<6, 0>; -def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, sra>, SRLV_FM<7, 0>; +def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl, + immZExt5>, SRA_FM<0, 0>; +def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl, + immZExt5>, SRA_FM<2, 0>; +def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra, + immZExt5>, SRA_FM<3, 0>; +def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>, + SRLV_FM<4, 0>; +def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>, + SRLV_FM<6, 0>; +def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>, + SRLV_FM<7, 0>; // Rotate Instructions let Predicates = [HasMips32r2, HasStdEnc] in { - def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, rotr, - immZExt5>, - SRA_FM<2, 1>; - def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, rotr>, + def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr, + immZExt5>, SRA_FM<2, 1>; + def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>, SRLV_FM<6, 1>; } /// Load and Store Instructions /// aligned -def LB : Load<"lb", GPR32Opnd, sextloadi8, IILoad>, MMRel, LW_FM<0x20>; -def LBu : Load<"lbu", GPR32Opnd, zextloadi8, IILoad, addrDefault>, MMRel, +def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>; +def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel, LW_FM<0x24>; -def LH : Load<"lh", GPR32Opnd, sextloadi16, IILoad, addrDefault>, MMRel, +def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel, LW_FM<0x21>; -def LHu : Load<"lhu", GPR32Opnd, zextloadi16, IILoad>, MMRel, LW_FM<0x25>; -def LW : Load<"lw", GPR32Opnd, load, IILoad, addrDefault>, MMRel, +def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>; +def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel, LW_FM<0x23>; -def SB : Store<"sb", GPR32Opnd, truncstorei8, IIStore>, MMRel, LW_FM<0x28>; -def SH : Store<"sh", GPR32Opnd, truncstorei16, IIStore>, MMRel, LW_FM<0x29>; -def SW : Store<"sw", GPR32Opnd, store, IIStore>, MMRel, LW_FM<0x2b>; +def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>; +def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>; +def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>; /// load/store left/right -def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, IILoad>, LW_FM<0x22>; -def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, IILoad>, LW_FM<0x26>; -def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, IIStore>, LW_FM<0x2a>; -def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, IIStore>, LW_FM<0x2e>; - -def SYNC : SYNC_FT, SYNC_FM; -def TEQ : TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>; -def TGE : TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>; -def TGEU : TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>; -def TLT : TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>; -def TLTU : TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>; -def TNE : TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>; - -def TEQI : TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>; -def TGEI : TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>; -def TGEIU : TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>; -def TLTI : TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>; -def TTLTIU : TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>; -def TNEI : TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>; - -def BREAK : BRK_FT<"break">, BRK_FM<0xd>; -def SYSCALL : SYS_FT<"syscall">, SYS_FM<0xc>; +let Predicates = [NotInMicroMips] in { +def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>; +def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>; +def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>; +def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>; +} + +def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM; +def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>; +def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>; +def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>; +def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>; +def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>; +def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>; + +def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>; +def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>; +def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>; +def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>; +def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>; +def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>; + +def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>; +def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>; def TRAP : TrapBase; -def ERET : ER_FT<"eret">, ER_FM<0x18>; -def DERET : ER_FT<"deret">, ER_FM<0x1f>; +def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>; +def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>; -def EI : DEI_FT<"ei", GPR32Opnd>, EI_FM<1>; -def DI : DEI_FT<"di", GPR32Opnd>, EI_FM<0>; +def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>; +def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>; -def WAIT : WAIT_FT<"wait">; +def WAIT : MMRel, WAIT_FT<"wait">, WAIT_FM; /// Load-linked, Store-conditional +let Predicates = [NotInMicroMips] in { def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>; def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>; +} /// Jump and Branch Instructions -def J : JumpFJ, FJ<2>, +def J : MMRel, JumpFJ, FJ<2>, Requires<[RelocStatic, HasStdEnc]>, IsBranch; -def JR : IndirectBranch, MTLO_FM<8>; -def BEQ : CBranch<"beq", seteq, GPR32Opnd>, BEQ_FM<4>; -def BNE : CBranch<"bne", setne, GPR32Opnd>, BEQ_FM<5>; -def BGEZ : CBranchZero<"bgez", setge, GPR32Opnd>, BGEZ_FM<1, 1>; -def BGTZ : CBranchZero<"bgtz", setgt, GPR32Opnd>, BGEZ_FM<7, 0>; -def BLEZ : CBranchZero<"blez", setle, GPR32Opnd>, BGEZ_FM<6, 0>; -def BLTZ : CBranchZero<"bltz", setlt, GPR32Opnd>, BGEZ_FM<1, 0>; +def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>; +def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>; +def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>; +def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>, + BGEZ_FM<1, 1>; +def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>, + BGEZ_FM<7, 0>; +def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>, + BGEZ_FM<6, 0>; +def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>, + BGEZ_FM<1, 0>; def B : UncondBranch; -def JAL : JumpLink<"jal">, FJ<3>; -def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM; +def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>; +def JALR : MMRel, JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM; def JALRPseudo : JumpLinkRegPseudo; -def BGEZAL : BGEZAL_FT<"bgezal", GPR32Opnd>, BGEZAL_FM<0x11>; -def BLTZAL : BGEZAL_FT<"bltzal", GPR32Opnd>, BGEZAL_FM<0x10>; +def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>; +def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>; def BAL_BR : BAL_BR_Pseudo; -def TAILCALL : JumpFJ, FJ<2>, IsTailCall; -def TAILCALL_R : JumpFR, MTLO_FM<8>, IsTailCall; +def TAILCALL : TailCall; +def TAILCALL_R : TailCallReg; -def RET : RetBase, MTLO_FM<8>; +def RET : MMRel, RetBase<"ret", GPR32Opnd>, MTLO_FM<8>; // Exception handling related node and instructions. // The conversion sequence is: @@ -1029,12 +1069,14 @@ let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in { } /// Multiply and Divide Instructions. -def MULT : MMRel, Mult<"mult", IIImult, GPR32Opnd, [HI0, LO0]>, +def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x18>; -def MULTu : MMRel, Mult<"multu", IIImult, GPR32Opnd, [HI0, LO0]>, +def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x19>; -def SDIV : Div<"div", IIIdiv, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x1a>; -def UDIV : Div<"divu", IIIdiv, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x1b>; +def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, + MULT_FM<0, 0x1a>; +def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, + MULT_FM<0, 0x1b>; def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>; def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>; @@ -1042,8 +1084,8 @@ def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>; def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>; /// Sign Ext In Register Instructions. -def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd>, SEB_FM<0x10, 0x20>; -def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd>, SEB_FM<0x18, 0x20>; +def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, SEB_FM<0x10, 0x20>; +def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>, SEB_FM<0x18, 0x20>; /// Count Leading def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>; @@ -1059,29 +1101,29 @@ def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>; // instructions. The same not happens for stack address copies, so an // add op with mem ComplexPattern is used and the stack address copy // can be matched. It's similar to Sparc LEA_ADDRi -def LEA_ADDiu : EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>; +def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>; // MADD*/MSUB* -def MADD : MMRel, MArithR<"madd", 1>, MULT_FM<0x1c, 0>; -def MADDU : MMRel, MArithR<"maddu", 1>, MULT_FM<0x1c, 1>; -def MSUB : MMRel, MArithR<"msub">, MULT_FM<0x1c, 4>; -def MSUBU : MMRel, MArithR<"msubu">, MULT_FM<0x1c, 5>; +def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>; +def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>; +def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>; +def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>; let Predicates = [HasStdEnc, NotDSP] in { -def PseudoMULT : MultDivPseudo; -def PseudoMULTu : MultDivPseudo; +def PseudoMULT : MultDivPseudo; +def PseudoMULTu : MultDivPseudo; def PseudoMFHI : PseudoMFLOHI; def PseudoMFLO : PseudoMFLOHI; def PseudoMTLOHI : PseudoMTLOHI; -def PseudoMADD : MAddSubPseudo; -def PseudoMADDU : MAddSubPseudo; -def PseudoMSUB : MAddSubPseudo; -def PseudoMSUBU : MAddSubPseudo; +def PseudoMADD : MAddSubPseudo; +def PseudoMADDU : MAddSubPseudo; +def PseudoMSUB : MAddSubPseudo; +def PseudoMSUBU : MAddSubPseudo; } -def PseudoSDIV : MultDivPseudo; -def PseudoUDIV : MultDivPseudo; def RDHWR : ReadHardware, RDHWR_FM; @@ -1399,3 +1441,4 @@ include "MipsMSAInstrInfo.td" // Micromips include "MicroMipsInstrFormats.td" include "MicroMipsInstrInfo.td" +include "MicroMipsInstrFPU.td"