X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsInstrInfo.td;h=cbc8e2fcb8f7e9ec7619d92f46dcdf957bf608a3;hb=1af10ebe4d42672a5ef8cb2e8c7af16589ffc0b5;hp=e358775cb2ec8231ed59026daad33e11be76e4e0;hpb=8007133f3e6073688f494b2060488b14fc9834fa;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index e358775cb2e..cbc8e2fcb8f 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -146,61 +146,71 @@ def MipsSDR : SDNode<"MipsISD::SDR", SDTStore, //===----------------------------------------------------------------------===// // Mips Instruction Predicate Definitions. //===----------------------------------------------------------------------===// -def HasMips2 : Predicate<"Subtarget.hasMips2()">, +def HasMips2 : Predicate<"Subtarget->hasMips2()">, AssemblerPredicate<"FeatureMips2">; -def HasMips3_32 : Predicate<"Subtarget.hasMips3_32()">, +def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">, AssemblerPredicate<"FeatureMips3_32">; -def HasMips3_32r2 : Predicate<"Subtarget.hasMips3_32r2()">, +def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">, AssemblerPredicate<"FeatureMips3_32r2">; -def HasMips3 : Predicate<"Subtarget.hasMips3()">, +def HasMips3 : Predicate<"Subtarget->hasMips3()">, AssemblerPredicate<"FeatureMips3">; -def HasMips4_32 : Predicate<"Subtarget.hasMips4_32()">, +def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">, AssemblerPredicate<"FeatureMips4_32">; -def HasMips4_32r2 : Predicate<"Subtarget.hasMips4_32r2()">, +def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">, + AssemblerPredicate<"!FeatureMips4_32">; +def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">, AssemblerPredicate<"FeatureMips4_32r2">; -def HasMips5_32r2 : Predicate<"Subtarget.hasMips5_32r2()">, +def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">, AssemblerPredicate<"FeatureMips5_32r2">; -def HasMips32 : Predicate<"Subtarget.hasMips32()">, +def HasMips32 : Predicate<"Subtarget->hasMips32()">, AssemblerPredicate<"FeatureMips32">; -def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">, +def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">, AssemblerPredicate<"FeatureMips32r2">; -def HasMips32r6 : Predicate<"Subtarget.hasMips32r6()">, +def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">, + AssemblerPredicate<"FeatureMips32r5">; +def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">, AssemblerPredicate<"FeatureMips32r6">; -def NotMips32r6 : Predicate<"!Subtarget.hasMips32r6()">, +def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">, AssemblerPredicate<"!FeatureMips32r6">; -def IsGP64bit : Predicate<"Subtarget.isGP64bit()">, +def IsGP64bit : Predicate<"Subtarget->isGP64bit()">, AssemblerPredicate<"FeatureGP64Bit">; -def IsGP32bit : Predicate<"!Subtarget.isGP64bit()">, +def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">, AssemblerPredicate<"!FeatureGP64Bit">; -def HasMips64 : Predicate<"Subtarget.hasMips64()">, +def HasMips64 : Predicate<"Subtarget->hasMips64()">, AssemblerPredicate<"FeatureMips64">; -def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">, +def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">, AssemblerPredicate<"FeatureMips64r2">; -def HasMips64r6 : Predicate<"Subtarget.hasMips64r6()">, +def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">, AssemblerPredicate<"FeatureMips64r6">; -def NotMips64r6 : Predicate<"!Subtarget.hasMips64r6()">, +def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">, AssemblerPredicate<"!FeatureMips64r6">; -def IsN64 : Predicate<"Subtarget.isABI_N64()">, - AssemblerPredicate<"FeatureN64">; -def InMips16Mode : Predicate<"Subtarget.inMips16Mode()">, +def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">, + AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">; +def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">, + AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">; +def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">, AssemblerPredicate<"FeatureMips16">; -def HasCnMips : Predicate<"Subtarget.hasCnMips()">, +def HasCnMips : Predicate<"Subtarget->hasCnMips()">, AssemblerPredicate<"FeatureCnMips">; -def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">, - AssemblerPredicate<"FeatureMips32">; -def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">, - AssemblerPredicate<"FeatureMips32">; +def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">; +def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">; def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">; -def HasStdEnc : Predicate<"Subtarget.hasStandardEncoding()">, +def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">, AssemblerPredicate<"!FeatureMips16">; -def NotDSP : Predicate<"!Subtarget.hasDSP()">; -def InMicroMips : Predicate<"Subtarget.inMicroMipsMode()">, +def NotDSP : Predicate<"!Subtarget->hasDSP()">; +def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">, AssemblerPredicate<"FeatureMicroMips">; -def NotInMicroMips : Predicate<"!Subtarget.inMicroMipsMode()">, +def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">, AssemblerPredicate<"!FeatureMicroMips">; -def IsLE : Predicate<"Subtarget.isLittle()">; -def IsBE : Predicate<"!Subtarget.isLittle()">; -def IsNotNaCl : Predicate<"!Subtarget.isTargetNaCl()">; +def IsLE : Predicate<"Subtarget->isLittle()">; +def IsBE : Predicate<"!Subtarget->isLittle()">; +def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">; +def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">; +def HasEVA : Predicate<"Subtarget->hasEVA()">, + AssemblerPredicate<"FeatureEVA,FeatureMips32r2">; +def HasMSA : Predicate<"Subtarget->hasMSA()">, + AssemblerPredicate<"FeatureMSA">; + //===----------------------------------------------------------------------===// // Mips GPR size adjectives. @@ -220,6 +230,9 @@ class GPR_64 { list GPRPredicates = [IsGP64bit]; } // subtractive predicate will hopefully keep us under the 32 predicate // limit long enough to develop an alternative way to handle P1||P2 // predicates. +class ISA_MIPS1_NOT_4_32 { + list InsnPredicates = [NotMips4_32]; +} class ISA_MIPS1_NOT_32R6_64R6 { list InsnPredicates = [NotMips32r6, NotMips64r6]; } @@ -239,14 +252,36 @@ class ISA_MIPS32R2 { list InsnPredicates = [HasMips32r2]; } class ISA_MIPS32R2_NOT_32R6_64R6 { list InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6]; } +class ISA_MIPS32R5 { list InsnPredicates = [HasMips32r5]; } class ISA_MIPS64 { list InsnPredicates = [HasMips64]; } +class ISA_MIPS64_NOT_64R6 { + list InsnPredicates = [HasMips64, NotMips64r6]; +} class ISA_MIPS64R2 { list InsnPredicates = [HasMips64r2]; } class ISA_MIPS32R6 { list InsnPredicates = [HasMips32r6]; } class ISA_MIPS64R6 { list InsnPredicates = [HasMips64r6]; } +class ISA_MICROMIPS { list InsnPredicates = [InMicroMips]; } +class ISA_MICROMIPS32R6 { + list InsnPredicates = [HasMicroMips32r6]; +} +class ISA_MICROMIPS64R6 { + list InsnPredicates = [HasMicroMips64r6]; +} + +class INSN_EVA { list InsnPredicates = [HasEVA]; } +class INSN_EVA_NOT_32R6_64R6 { + list InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA]; +} // The portions of MIPS-III that were also added to MIPS32 class INSN_MIPS3_32 { list InsnPredicates = [HasMips3_32]; } +// The portions of MIPS-III that were also added to MIPS32 but were removed in +// MIPS32r6 and MIPS64r6. +class INSN_MIPS3_32_NOT_32R6_64R6 { + list InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6]; +} + // The portions of MIPS-III that were also added to MIPS32 class INSN_MIPS3_32R2 { list InsnPredicates = [HasMips3_32r2]; } @@ -256,11 +291,31 @@ class INSN_MIPS4_32_NOT_32R6_64R6 { list InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6]; } -// The portions of MIPS-IV that were also added to MIPS32R2 -class INSN_MIPS4_32R2 { list InsnPredicates = [HasMips4_32r2]; } +// The portions of MIPS-IV that were also added to MIPS32r2 but were removed in +// MIPS32r6 and MIPS64r6. +class INSN_MIPS4_32R2_NOT_32R6_64R6 { + list InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6]; +} + +// The portions of MIPS-V that were also added to MIPS32r2 but were removed in +// MIPS32r6 and MIPS64r6. +class INSN_MIPS5_32R2_NOT_32R6_64R6 { + list InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6]; +} + +class ASE_MSA { + list InsnPredicates = [HasMSA]; +} + +class ASE_MSA64 { + list InsnPredicates = [HasMSA, HasMips64]; +} -// The portions of MIPS-V that were also added to MIPS32R2 -class INSN_MIPS5_32R2 { list InsnPredicates = [HasMips5_32r2]; } +// Class used for separating microMIPSr6 and microMIPS (r3) instruction. +// It can be used only on instructions that doesn't inherit PredicateControl. +class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl { + let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6]; +} //===----------------------------------------------------------------------===// @@ -301,7 +356,7 @@ class IsAsCheapAsAMove { } class NeverHasSideEffects { - bit neverHasSideEffects = 1; + bit hasSideEffects = 0; } //===----------------------------------------------------------------------===// @@ -316,7 +371,7 @@ include "MipsInstrFormats.td" def MipsJumpTargetAsmOperand : AsmOperandClass { let Name = "JumpTarget"; - let ParserMethod = "ParseJumpTarget"; + let ParserMethod = "parseJumpTarget"; let PredicateMethod = "isImm"; let RenderMethod = "addImmOperands"; } @@ -337,7 +392,11 @@ def calltarget : Operand { let ParserMatchClass = MipsJumpTargetAsmOperand; } +def imm64: Operand; + +def simm9 : Operand; def simm10 : Operand; +def simm11 : Operand; def simm16 : Operand { let DecoderMethod= "DecodeSimm16"; @@ -352,6 +411,7 @@ def simm19_lsl2 : Operand { def simm18_lsl3 : Operand { let EncoderMethod = "getSimm18Lsl3Encoding"; let DecoderMethod = "DecodeSimm18Lsl3"; + let ParserMatchClass = MipsJumpTargetAsmOperand; } def simm20 : Operand { @@ -360,7 +420,15 @@ def simm20 : Operand { def uimm20 : Operand { } +def MipsUImm10AsmOperand : AsmOperandClass { + let Name = "UImm10"; + let RenderMethod = "addImmOperands"; + let ParserMethod = "parseImm"; + let PredicateMethod = "isUImm<10>"; +} + def uimm10 : Operand { + let ParserMatchClass = MipsUImm10AsmOperand; } def simm16_64 : Operand { @@ -401,6 +469,38 @@ def MipsMemAsmOperand : AsmOperandClass { let ParserMethod = "parseMemOperand"; } +def MipsMemSimm9AsmOperand : AsmOperandClass { + let Name = "MemOffsetSimm9"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithSimmOffset<9>"; +} + +def MipsMemSimm9GPRAsmOperand : AsmOperandClass { + let Name = "MemOffsetSimm9GPR"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithSimmOffsetGPR<9>"; +} + +def MipsMemSimm11AsmOperand : AsmOperandClass { + let Name = "MemOffsetSimm11"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithSimmOffset<11>"; +} + +def MipsMemSimm16AsmOperand : AsmOperandClass { + let Name = "MemOffsetSimm16"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithSimmOffset<16>"; +} + def MipsInvertedImmoperand : AsmOperandClass { let Name = "InvNum"; let RenderMethod = "addImmOperands"; @@ -432,6 +532,30 @@ def mem_msa : mem_generic { let EncoderMethod = "getMSAMemEncoding"; } +def mem_simm9 : mem_generic { + let MIOperandInfo = (ops ptr_rc, simm9); + let EncoderMethod = "getMemEncoding"; + let ParserMatchClass = MipsMemSimm9AsmOperand; +} + +def mem_simm9gpr : mem_generic { + let MIOperandInfo = (ops ptr_rc, simm9); + let EncoderMethod = "getMemEncoding"; + let ParserMatchClass = MipsMemSimm9GPRAsmOperand; +} + +def mem_simm11 : mem_generic { + let MIOperandInfo = (ops ptr_rc, simm11); + let EncoderMethod = "getMemEncoding"; + let ParserMatchClass = MipsMemSimm11AsmOperand; +} + +def mem_simm16 : mem_generic { + let MIOperandInfo = (ops ptr_rc, simm16); + let EncoderMethod = "getMemEncoding"; + let ParserMatchClass = MipsMemSimm16AsmOperand; +} + def mem_ea : Operand { let PrintMethod = "printMemOperandEA"; let MIOperandInfo = (ops ptr_rc, simm16); @@ -590,11 +714,11 @@ class shift_rotate_reg; -// Load Upper Imediate +// Load Upper Immediate class LoadUpper: InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"), [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove { - let neverHasSideEffects = 1; + let hasSideEffects = 0; let isReMaterializable = 1; } @@ -608,14 +732,19 @@ class Load : - InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMem"; let mayStore = 1; } +class Store : + StoreMemory; + // Load/Store Left/Right let canFoldAsLoad = 1 in class LoadLeftRight : + InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> { + let DecoderMethod = "DecodeFMem2"; + let mayLoad = 1; +} + +class SW_FT2 : + InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> { + let DecoderMethod = "DecodeFMem2"; + let mayStore = 1; +} + +// COP3 Load/Store +class LW_FT3 : + InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> { + let DecoderMethod = "DecodeFMem3"; + let mayLoad = 1; +} + +class SW_FT3 : + InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> { + let DecoderMethod = "DecodeFMem3"; + let mayStore = 1; +} + // Conditional Branch class CBranch : + RegisterOperand RO, bit DelaySlot = 1> : 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, + [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC, FrmI, opstr> { let isBranch = 1; let isTerminator = 1; - let hasDelaySlot = 1; + let hasDelaySlot = DelaySlot; let Defs = [AT]; } class CBranchZero : + RegisterOperand RO, bit DelaySlot = 1> : InstSE<(outs), (ins RO:$rs, opnd:$offset), !strconcat(opstr, "\t$rs, $offset"), - [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, + [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ, FrmI, opstr> { let isBranch = 1; let isTerminator = 1; - let hasDelaySlot = 1; + let hasDelaySlot = DelaySlot; let Defs = [AT]; } @@ -677,7 +840,7 @@ class SetCC_I : InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), - [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> { + [(operator targetoperator:$target)], II_J, FrmJ, bopstr> { let isTerminator=1; let isBarrier=1; let hasDelaySlot = 1; @@ -687,7 +850,7 @@ class JumpFJ : - PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], IIBranch>, + PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>, PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> { let isBranch = 1; let isTerminator = 1; @@ -701,61 +864,55 @@ class UncondBranch : let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in class JumpFR: - InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch, + InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR, FrmR, opstr>; // Indirect branch -class IndirectBranch : - JumpFR { +class IndirectBranch : JumpFR { let isBranch = 1; let isIndirectBranch = 1; } -// Return instruction -class RetBase: JumpFR { - let isReturn = 1; - let isCodeGenOnly = 1; - let hasCtrlDep = 1; - let hasExtraSrcRegAllocReq = 1; -} - // Jump and Link (Call) let isCall=1, hasDelaySlot=1, Defs = [RA] in { class JumpLink : InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), - [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> { + [(MipsJmpLink imm:$target)], II_JAL, FrmJ, opstr> { let DecoderMethod = "DecodeJumpTarget"; } class JumpLinkRegPseudo: - PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>, + PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>, PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>; class JumpLinkReg: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [], IIBranch, FrmR>; + [], II_JALR, FrmR, opstr>; - class BGEZAL_FT : + class BGEZAL_FT : InstSE<(outs), (ins RO:$rs, opnd:$offset), - !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>; + !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> { + let hasDelaySlot = DelaySlot; + } } let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, hasExtraSrcRegAllocReq = 1, Defs = [AT] in { class TailCall : - PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>, + PseudoSE<(outs), (ins calltarget:$target), [], II_J>, PseudoInstExpansion<(JumpInst jmptarget:$target)>; class TailCallReg : - PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>, + PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>, PseudoInstExpansion<(JRInst ResRO:$rs)>; } class BAL_BR_Pseudo : - PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>, + PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>, PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> { let isBranch = 1; let isTerminator = 1; @@ -794,6 +951,13 @@ class SYNC_FT : InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)], NoItinerary, FrmOther, opstr>; +class SYNCI_FT : + InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [], + NoItinerary, FrmOther, opstr> { + let hasSideEffects = 1; + let DecoderMethod = "DecodeSyncI"; +} + let hasSideEffects = 1 in class TEQ_FT : InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_), @@ -810,7 +974,7 @@ class Mult { let isCommutable = 1; let Defs = DefRegs; - let neverHasSideEffects = 1; + let hasSideEffects = 0; } // Pseudo multiply/divide instruction with explicit accumulator register @@ -856,7 +1020,7 @@ class MoveFromLOHI: InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO, FrmR, opstr> { let Uses = [UseReg]; - let neverHasSideEffects = 1; + let hasSideEffects = 0; } class PseudoMTLOHI @@ -868,7 +1032,7 @@ class MoveToLOHI DefRegs>: InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO, FrmR, opstr> { let Defs = DefRegs; - let neverHasSideEffects = 1; + let hasSideEffects = 0; } class EffectiveAddress : @@ -895,23 +1059,24 @@ class SignExtInReg; // Subword Swap -class SubwordSwap: - InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], - NoItinerary, FrmR, opstr> { - let neverHasSideEffects = 1; +class SubwordSwap: + InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin, + FrmR, opstr> { + let hasSideEffects = 0; } // Read Hardware class ReadHardware : InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [], - II_RDHWR, FrmR>; + II_RDHWR, FrmR, "rdhwr">; // Ext and Ins class ExtBase: InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size), !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], NoItinerary, + [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT, FrmR, opstr>, ISA_MIPS32R2; class InsBase, ISA_MIPS32R2 { + II_INS, FrmR, opstr>, ISA_MIPS32R2 { let Constraints = "$src = $rt"; } @@ -948,8 +1113,12 @@ class SCBase : let Constraints = "$rt = $dst"; } -class MFC3OP : - InstSE<(outs RO:$rt, RO:$rd, uimm16:$sel), (ins), +class MFC3OP : + InstSE<(outs RO:$rt), (ins RD:$rd, uimm16:$sel), + !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>; + +class MTC3OP : + InstSE<(outs RO:$rd), (ins RD:$rt, uimm16:$sel), !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>; class TrapBase @@ -1030,51 +1199,60 @@ def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst), //===----------------------------------------------------------------------===// /// Arithmetic Instructions (ALU Immediate) -def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16, - add>, +let AdditionalPredicates = [NotInMicroMips] in { +def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16, GPR32Opnd, + II_ADDIU, immSExt16, add>, ADDI_FM<0x9>, IsAsCheapAsAMove; +} def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6; 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, II_ANDI, immZExt16, - and>, +let AdditionalPredicates = [NotInMicroMips] in { +def ANDi : MMRel, StdMMR6Rel, + ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>, ADDI_FM<0xc>; -def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, - or>, +} +def ORi : MMRel, StdMMR6Rel, + ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>, ADDI_FM<0xd>; -def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, - xor>, +def XORi : MMRel, StdMMR6Rel, + ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>, ADDI_FM<0xe>; def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM; - +let AdditionalPredicates = [NotInMicroMips] in { /// Arithmetic Instructions (3-Operand, R-Type) -def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>, +def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>, ADD_FM<0, 0x21>; 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, II_MUL, mul>, ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6; -def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>; +def ADD : MMRel, StdMMR6Rel, 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, II_AND, and>, +let AdditionalPredicates = [NotInMicroMips] in { +def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>, ADD_FM<0, 0x24>; -def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>, +def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>, ADD_FM<0, 0x25>; -def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>, +def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>, ADD_FM<0, 0x26>; -def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>; +} +def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>; /// Shift Instructions +let AdditionalPredicates = [NotInMicroMips] in { 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>, @@ -1099,11 +1277,16 @@ def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel, def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel, LW_FM<0x21>; def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>; -def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel, +let AdditionalPredicates = [NotInMicroMips] in { +def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel, LW_FM<0x23>; -def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>; +} +def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, + LW_FM<0x28>; def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>; +let AdditionalPredicates = [NotInMicroMips] in { def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>; +} /// load/store left/right let EncodingPredicates = [], // FIXME: Lack of HasStdEnc is probably a bug @@ -1118,13 +1301,39 @@ def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>, ISA_MIPS1_NOT_32R6_64R6; } -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>; +let AdditionalPredicates = [NotInMicroMips] in { +// COP2 Memory Instructions +def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>, + ISA_MIPS1_NOT_32R6_64R6; +def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>, + ISA_MIPS1_NOT_32R6_64R6; +def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>, + ISA_MIPS2_NOT_32R6_64R6; +def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>, + ISA_MIPS2_NOT_32R6_64R6; + +// COP3 Memory Instructions +let DecoderNamespace = "COP3_" in { + def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>; + def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>; + def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>, + ISA_MIPS2; + def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>, + ISA_MIPS2; +} +} + +def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32; +def SYNCI : MMRel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2; + +let AdditionalPredicates = [NotInMicroMips] in { + def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2; + def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2; + def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2; + def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2; + def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2; + def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2; +} def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>, ISA_MIPS2_NOT_32R6_64R6; @@ -1139,14 +1348,22 @@ def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>, def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>, ISA_MIPS2_NOT_32R6_64R6; -def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>; +let AdditionalPredicates = [NotInMicroMips] in { +def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>; +} def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>; def TRAP : TrapBase; +def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6; -def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>, INSN_MIPS3_32; -def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>, ISA_MIPS32; +let AdditionalPredicates = [NotInMicroMips] in { +def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18, 0x0>, INSN_MIPS3_32; +def ERETNC : MMRel, ER_FT<"eretnc">, ER_FM<0x18, 0x1>, ISA_MIPS32R5; +} +def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f, 0x0>, ISA_MIPS32; -def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2; +let AdditionalPredicates = [NotInMicroMips] in { +def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2; +} def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2; let EncodingPredicates = [], // FIXME: Lack of HasStdEnc is probably a bug @@ -1154,8 +1371,8 @@ let EncodingPredicates = [], // FIXME: Lack of HasStdEnc is probably def WAIT : WAIT_FT<"wait">, WAIT_FM; /// Load-linked, Store-conditional -def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2; -def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2; +def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6; +def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6; } /// Jump and Branch Instructions @@ -1163,15 +1380,27 @@ def J : MMRel, JumpFJ, FJ<2>, AdditionalRequires<[RelocStatic]>, IsBranch; def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>; def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>; +def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>, + BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6; def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>; +def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>, + BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6; def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>, BGEZ_FM<1, 1>; +def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>, + BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6; def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>, BGEZ_FM<7, 0>; +def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>, + BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6; def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>, BGEZ_FM<6, 0>; +def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>, + BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6; def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>, BGEZ_FM<1, 0>; +def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>, + BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6; def B : UncondBranch; def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>; @@ -1180,15 +1409,50 @@ let AdditionalPredicates = [NotInMicroMips] in { def JALRPseudo : JumpLinkRegPseudo; } -// FIXME: JALX really requires either MIPS16 or microMIPS in addition to MIPS32. -def JALX : JumpLink<"jalx", calltarget>, FJ<0x1D>, ISA_MIPS32_NOT_32R6_64R6; -def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>; -def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>; +def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>, + ISA_MIPS32_NOT_32R6_64R6; +def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>, + ISA_MIPS1_NOT_32R6_64R6; +def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>, + BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6; +def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>, + ISA_MIPS1_NOT_32R6_64R6; +def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>, + BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6; def BAL_BR : BAL_BR_Pseudo; def TAILCALL : TailCall; def TAILCALL_R : TailCallReg; -def RET : MMRel, RetBase<"ret", GPR32Opnd>, MTLO_FM<8>; +// Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64 +// then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA. +class PseudoIndirectBranchBase : + MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)], + II_IndirectBranchPseudo> { + let isTerminator=1; + let isBarrier=1; + let hasDelaySlot = 1; + let isBranch = 1; + let isIndirectBranch = 1; +} + +def PseudoIndirectBranch : PseudoIndirectBranchBase; + +// Return instructions are matched as a RetRA instruction, then are expanded +// into PseudoReturn/PseudoReturn64 after register allocation. Finally, +// MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the +// ISA. +class PseudoReturnBase : MipsPseudo<(outs), (ins RO:$rs), + [], II_ReturnPseudo> { + let isTerminator = 1; + let isBarrier = 1; + let hasDelaySlot = 1; + let isReturn = 1; + let isCodeGenOnly = 1; + let hasCtrlDep = 1; + let hasExtraSrcRegAllocReq = 1; +} + +def PseudoReturn : PseudoReturnBase; // Exception handling related node and instructions. // The conversion sequence is: @@ -1234,17 +1498,20 @@ def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>, } /// Sign Ext In Register Instructions. -def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, +def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, SEB_FM<0x10, 0x20>, ISA_MIPS32R2; -def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>, +def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>, SEB_FM<0x18, 0x20>, ISA_MIPS32R2; /// Count Leading -def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>, ISA_MIPS32; -def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>, ISA_MIPS32; +def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>, + ISA_MIPS32_NOT_32R6_64R6; +def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>, + ISA_MIPS32_NOT_32R6_64R6; /// Word Swap Bytes Within Halfwords -def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2; +def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>, + ISA_MIPS32R2; /// No operation. def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>; @@ -1288,22 +1555,22 @@ def PseudoSDIV : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; -def RDHWR : ReadHardware, RDHWR_FM; +def RDHWR : MMRel, ReadHardware, RDHWR_FM; def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>; def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>; /// Move Control Registers From/To CPU Registers -def MFC0 : MFC3OP<"mfc0", GPR32Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32; -def MTC0 : MFC3OP<"mtc0", GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32; -def MFC2 : MFC3OP<"mfc2", GPR32Opnd>, MFC3OP_FM<0x12, 0>; -def MTC2 : MFC3OP<"mtc2", GPR32Opnd>, MFC3OP_FM<0x12, 4>; +def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32; +def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32; +def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>; +def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>; class Barrier : InstSE<(outs), (ins), asmstr, [], NoItinerary, - FrmOther>; -def SSNOP : Barrier<"ssnop">, BARRIER_FM<1>; -def EHB : Barrier<"ehb">, BARRIER_FM<3>; -def PAUSE : Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2; + FrmOther, asmstr>; +def SSNOP : MMRel, Barrier<"ssnop">, BARRIER_FM<1>; +def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>; +def PAUSE : MMRel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2; // JR_HB and JALR_HB are defined here using the new style naming // scheme because some of this code is shared with Mips32r6InstrInfo.td @@ -1346,33 +1613,57 @@ def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6; def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32; class TLB : InstSE<(outs), (ins), asmstr, [], NoItinerary, - FrmOther>; -def TLBP : TLB<"tlbp">, COP0_TLB_FM<0x08>; -def TLBR : TLB<"tlbr">, COP0_TLB_FM<0x01>; -def TLBWI : TLB<"tlbwi">, COP0_TLB_FM<0x02>; -def TLBWR : TLB<"tlbwr">, COP0_TLB_FM<0x06>; + FrmOther, asmstr>; +def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>; +def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>; +def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>; +def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>; + +class CacheOp : + InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint), + !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther, + instr_asm> { + let DecoderMethod = "DecodeCacheOp"; +} + +def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>, + INSN_MIPS3_32_NOT_32R6_64R6; +def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>, + INSN_MIPS3_32_NOT_32R6_64R6; //===----------------------------------------------------------------------===// // Instruction aliases //===----------------------------------------------------------------------===// def : MipsInstAlias<"move $dst, $src", - (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>, + (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>, + GPR_32 { + let AdditionalPredicates = [NotInMicroMips]; +} +def : MipsInstAlias<"move $dst, $src", + (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>, GPR_32 { let AdditionalPredicates = [NotInMicroMips]; } -def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>; +def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>, + ISA_MIPS1_NOT_32R6_64R6; def : MipsInstAlias<"addu $rs, $rt, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; +def : MipsInstAlias<"addu $rs, $imm", + (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>; def : MipsInstAlias<"add $rs, $rt, $imm", - (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; + (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>, + ISA_MIPS1_NOT_32R6_64R6; +def : MipsInstAlias<"add $rs, $imm", + (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>, + ISA_MIPS1_NOT_32R6_64R6; def : MipsInstAlias<"and $rs, $rt, $imm", (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; +def : MipsInstAlias<"and $rs, $imm", + (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>; def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>; let Predicates = [NotInMicroMips] in { def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>; } -def : MipsInstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>; -def : MipsInstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>; def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32; def : MipsInstAlias<"not $rt, $rs", (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>; @@ -1388,41 +1679,60 @@ def : MipsInstAlias<"sltu $rt, $rs, $imm", (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>; def : MipsInstAlias<"xor $rs, $rt, $imm", (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; +def : MipsInstAlias<"xor $rs, $imm", + (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>; def : MipsInstAlias<"or $rs, $rt, $imm", (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; +def : MipsInstAlias<"or $rs, $imm", + (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>; +let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>; -def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; -def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; -def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; -def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; +} +def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>; +def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>; +def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>; +def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>; +let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>; +} def : MipsInstAlias<"bnez $rs,$offset", (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; +def : MipsInstAlias<"bnezl $rs,$offset", + (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; def : MipsInstAlias<"beqz $rs,$offset", (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; +def : MipsInstAlias<"beqzl $rs,$offset", + (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; def : MipsInstAlias<"syscall", (SYSCALL 0), 1>; - + def : MipsInstAlias<"break", (BREAK 0, 0), 1>; def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>; -def : MipsInstAlias<"ei", (EI ZERO), 1>; -def : MipsInstAlias<"di", (DI ZERO), 1>; - -def : MipsInstAlias<"teq $rs, $rt", (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; -def : MipsInstAlias<"tge $rs, $rt", (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; -def : MipsInstAlias<"tgeu $rs, $rt", (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), - 1>; -def : MipsInstAlias<"tlt $rs, $rt", (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; -def : MipsInstAlias<"tltu $rs, $rt", (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), - 1>; -def : MipsInstAlias<"tne $rs, $rt", (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; +let AdditionalPredicates = [NotInMicroMips] in { +def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2; +} +def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2; +let AdditionalPredicates = [NotInMicroMips] in { + def : MipsInstAlias<"teq $rs, $rt", + (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; + def : MipsInstAlias<"tge $rs, $rt", + (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; + def : MipsInstAlias<"tgeu $rs, $rt", + (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; + def : MipsInstAlias<"tlt $rs, $rt", + (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; + def : MipsInstAlias<"tltu $rs, $rt", + (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; + def : MipsInstAlias<"tne $rs, $rt", + (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; +} def : MipsInstAlias<"sll $rd, $rt, $rs", (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; def : MipsInstAlias<"sub, $rd, $rs, $imm", (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs, - InvertedImOperand:$imm), 0>; + InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6; def : MipsInstAlias<"sub $rs, $imm", (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm), - 0>; + 0>, ISA_MIPS1_NOT_32R6_64R6; def : MipsInstAlias<"subu, $rd, $rs, $imm", (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs, InvertedImOperand:$imm), 0>; @@ -1432,24 +1742,88 @@ def : MipsInstAlias<"sra $rd, $rt, $rs", (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; def : MipsInstAlias<"srl $rd, $rt, $rs", (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; +def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6; +def : MipsInstAlias<"sync", + (SYNC 0), 1>, ISA_MIPS2; //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions //===----------------------------------------------------------------------===// -class LoadImm32< string instr_asm, Operand Od, RegisterOperand RO> : +class LoadImmediate32 : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadImm32Reg : LoadImm32<"li", uimm5, GPR32Opnd>; +def LoadImm32 : LoadImmediate32<"li", uimm5, GPR32Opnd>; -class LoadAddress : +class LoadAddressFromReg32 : MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(instr_asm, "\t$rt, $addr")> ; -def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>; +def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>; -class LoadAddressImm : +class LoadAddressFromImm32 : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadAddr32Imm : LoadAddressImm<"la", uimm5, GPR32Opnd>; +def LoadAddrImm32 : LoadAddressFromImm32<"la", uimm5, GPR32Opnd>; + +def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs), + "jal\t$rd, $rs"> ; +def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs), + "jal\t$rs"> ; + +let hasDelaySlot = 1 in { +def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), + (ins imm64:$imm64, brtarget:$offset), + "bne\t$rt, $imm64, $offset">; +def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), + (ins imm64:$imm64, brtarget:$offset), + "beq\t$rt, $imm64, $offset">; + +class CondBranchPseudo : + MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, + brtarget:$offset), + !strconcat(instr_asm, "\t$rs, $rt, $offset")>; +} + +def BLT : CondBranchPseudo<"blt">; +def BLE : CondBranchPseudo<"ble">; +def BGE : CondBranchPseudo<"bge">; +def BGT : CondBranchPseudo<"bgt">; +def BLTU : CondBranchPseudo<"bltu">; +def BLEU : CondBranchPseudo<"bleu">; +def BGEU : CondBranchPseudo<"bgeu">; +def BGTU : CondBranchPseudo<"bgtu">; +def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6; +def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6; +def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6; +def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6; +def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6; +def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6; +def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6; +def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6; + +// FIXME: Predicates are removed because instructions are matched regardless of +// predicates, because PredicateControl was not in the hierarchy. This was +// done to emit more precise error message from expansion function. +// Once the tablegen-erated errors are made better, this needs to be fixed and +// predicates needs to be restored. + +def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "div\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6; + +def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6; + +def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6; + +def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6; + +def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), + "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6; + +def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), + "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6; //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions @@ -1463,10 +1837,12 @@ class StoreRegImmPat : MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>; // Small immediates +let AdditionalPredicates = [NotInMicroMips] in { def : MipsPat<(i32 immSExt16:$in), (ADDiu ZERO, imm:$in)>; def : MipsPat<(i32 immZExt16:$in), (ORi ZERO, imm:$in)>; +} def : MipsPat<(i32 immLow16Zero:$in), (LUi (HI16 imm:$in))>; @@ -1484,6 +1860,16 @@ let AdditionalPredicates = [NotDSP] in { (ADDiu GPR32:$src, imm:$imm)>; } +// Support multiplication for pre-Mips32 targets that don't have +// the MUL instruction. +def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs), + (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>, + ISA_MIPS1_NOT_32R6_64R6; + +// SYNC +def : MipsPat<(MipsSync (i32 immz)), + (SYNC 0)>, ISA_MIPS2; + // Call def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)), (JAL tglobaladdr:$dst)>; @@ -1541,9 +1927,11 @@ def : WrapperPat; def : WrapperPat; def : WrapperPat; +let AdditionalPredicates = [NotInMicroMips] in { // Mips does not have "not", so we expand our way def : MipsPat<(not GPR32:$in), (NOR GPR32Opnd:$in, ZERO)>; +} // extended loads def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>; @@ -1646,7 +2034,9 @@ def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>; let AddedComplexity = 40 in { def : LoadRegImmPat; def : LoadRegImmPat; + let AdditionalPredicates = [NotInMicroMips] in { def : LoadRegImmPat; + } } //===----------------------------------------------------------------------===// @@ -1674,7 +2064,19 @@ include "MipsDSPInstrInfo.td" include "MipsMSAInstrFormats.td" include "MipsMSAInstrInfo.td" +// EVA +include "MipsEVAInstrFormats.td" +include "MipsEVAInstrInfo.td" + // Micromips include "MicroMipsInstrFormats.td" include "MicroMipsInstrInfo.td" include "MicroMipsInstrFPU.td" + +// Micromips r6 +include "MicroMips32r6InstrFormats.td" +include "MicroMips32r6InstrInfo.td" + +// Micromips64 r6 +include "MicroMips64r6InstrFormats.td" +include "MicroMips64r6InstrInfo.td"