diff options
Diffstat (limited to 'lib/Target/Mips/MicroMipsInstrInfo.td')
-rw-r--r-- | lib/Target/Mips/MicroMipsInstrInfo.td | 360 |
1 files changed, 222 insertions, 138 deletions
diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 99f0f446deab..f27370f57fa0 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -1,23 +1,8 @@ -def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>; +def addrimm11 : ComplexPattern<iPTR, 2, "selectIntAddr11MM", [frameindex]>; +def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddr12MM", [frameindex]>; +def addrimm16 : ComplexPattern<iPTR, 2, "selectIntAddr16MM", [frameindex]>; def addrimm4lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrLSL2MM", [frameindex]>; -def simm4 : Operand<i32> { - let DecoderMethod = "DecodeSimm4"; -} -def simm7 : Operand<i32>; -def li_simm7 : Operand<i32> { - let DecoderMethod = "DecodeLiSimm7"; -} - -def simm12 : Operand<i32> { - let DecoderMethod = "DecodeSimm12"; -} - -def uimm6_lsl2 : Operand<i32> { - let EncoderMethod = "getUImm6Lsl2Encoding"; - let DecoderMethod = "DecodeUImm6Lsl2"; -} - def simm9_addiusp : Operand<i32> { let EncoderMethod = "getSImm9AddiuspValue"; let DecoderMethod = "DecodeSimm9SP"; @@ -60,9 +45,15 @@ def MicroMipsMemGPRMM16AsmOperand : AsmOperandClass { let PredicateMethod = "isMemWithGRPMM16Base"; } +// Define the classes of pointers used by microMIPS. +// The numbers must match those in MipsRegisterInfo::MipsPtrClass. +def ptr_gpr16mm_rc : PointerLikeRegClass<1>; +def ptr_sp_rc : PointerLikeRegClass<2>; +def ptr_gp_rc : PointerLikeRegClass<3>; + class mem_mm_4_generic : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops GPRMM16, simm4); + let MIOperandInfo = (ops ptr_gpr16mm_rc, simm4); let OperandType = "OPERAND_MEMORY"; let ParserMatchClass = MicroMipsMemGPRMM16AsmOperand; } @@ -86,32 +77,48 @@ def MicroMipsMemSPAsmOperand : AsmOperandClass { let PredicateMethod = "isMemWithUimmWordAlignedOffsetSP<7>"; } +def MicroMipsMemGPAsmOperand : AsmOperandClass { + let Name = "MicroMipsMemGP"; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithSimmWordAlignedOffsetGP<9>"; +} + def mem_mm_sp_imm5_lsl2 : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops GPR32:$base, simm5:$offset); + let MIOperandInfo = (ops ptr_sp_rc:$base, simm5:$offset); let OperandType = "OPERAND_MEMORY"; let ParserMatchClass = MicroMipsMemSPAsmOperand; let EncoderMethod = "getMemEncodingMMSPImm5Lsl2"; } -def mem_mm_gp_imm7_lsl2 : Operand<i32> { +def mem_mm_gp_simm7_lsl2 : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops GPRMM16:$base, simm7:$offset); + let MIOperandInfo = (ops ptr_gp_rc:$base, simm7_lsl2:$offset); let OperandType = "OPERAND_MEMORY"; + let ParserMatchClass = MicroMipsMemGPAsmOperand; let EncoderMethod = "getMemEncodingMMGPImm7Lsl2"; } def mem_mm_9 : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops GPR32, simm9); + let MIOperandInfo = (ops ptr_rc, simm9); let EncoderMethod = "getMemEncodingMMImm9"; - let ParserMatchClass = MipsMemAsmOperand; + let ParserMatchClass = MipsMemSimm9AsmOperand; + let OperandType = "OPERAND_MEMORY"; +} + +def mem_mm_11 : Operand<i32> { + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops GPR32, simm11); + let EncoderMethod = "getMemEncodingMMImm11"; + let ParserMatchClass = MipsMemSimm11AsmOperand; let OperandType = "OPERAND_MEMORY"; } def mem_mm_12 : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops GPR32, simm12); + let MIOperandInfo = (ops ptr_rc, simm12); let EncoderMethod = "getMemEncodingMMImm12"; let ParserMatchClass = MipsMemAsmOperand; let OperandType = "OPERAND_MEMORY"; @@ -119,9 +126,9 @@ def mem_mm_12 : Operand<i32> { def mem_mm_16 : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops GPR32, simm16); + let MIOperandInfo = (ops ptr_rc, simm16); let EncoderMethod = "getMemEncodingMMImm16"; - let ParserMatchClass = MipsMemAsmOperand; + let ParserMatchClass = MipsMemSimm16AsmOperand; let OperandType = "OPERAND_MEMORY"; } @@ -135,7 +142,7 @@ def MipsMemUimm4AsmOperand : AsmOperandClass { def mem_mm_4sp : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops GPR32, uimm8); + let MIOperandInfo = (ops ptr_sp_rc, uimm8); let EncoderMethod = "getMemEncodingMMImm4sp"; let ParserMatchClass = MipsMemUimm4AsmOperand; let OperandType = "OPERAND_MEMORY"; @@ -216,7 +223,7 @@ def movep_regpair : Operand<i32> { let ParserMatchClass = MovePRegPairAsmOperand; let PrintMethod = "printRegisterList"; let DecoderMethod = "DecodeMovePRegPair"; - let MIOperandInfo = (ops GPR32Opnd, GPR32Opnd); + let MIOperandInfo = (ops ptr_rc, ptr_rc); } class MovePMM16<string opstr, RegisterOperand RO> : @@ -230,6 +237,7 @@ MicroMipsInst16<(outs movep_regpair:$dst_regs), (ins RO:$rs, RO:$rt), def RegPairAsmOperand : AsmOperandClass { let Name = "RegPair"; let ParserMethod = "parseRegisterPair"; + let PredicateMethod = "isRegPair"; } def regpair : Operand<i32> { @@ -237,12 +245,12 @@ def regpair : Operand<i32> { let ParserMatchClass = RegPairAsmOperand; let PrintMethod = "printRegisterPair"; let DecoderMethod = "DecodeRegPairOperand"; - let MIOperandInfo = (ops GPR32Opnd, GPR32Opnd); + let MIOperandInfo = (ops ptr_rc, ptr_rc); } class StorePairMM<string opstr, InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> : - InstSE<(outs), (ins regpair:$rt, mem_mm_12:$addr), + InstSE<(outs), (ins regpair:$rt, mem_simm12:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let mayStore = 1; @@ -250,7 +258,7 @@ class StorePairMM<string opstr, InstrItinClass Itin = NoItinerary, class LoadPairMM<string opstr, InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> : - InstSE<(outs regpair:$rt), (ins mem_mm_12:$addr), + InstSE<(outs regpair:$rt), (ins mem_simm12:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let mayLoad = 1; @@ -264,7 +272,7 @@ class LLBaseMM<string opstr, RegisterOperand RO> : } class LLEBaseMM<string opstr, RegisterOperand RO> : - InstSE<(outs RO:$rt), (ins mem_mm_12:$addr), + InstSE<(outs RO:$rt), (ins mem_simm9:$addr), !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { let DecoderMethod = "DecodeMemMMImm9"; let mayLoad = 1; @@ -279,7 +287,7 @@ class SCBaseMM<string opstr, RegisterOperand RO> : } class SCEBaseMM<string opstr, RegisterOperand RO> : - InstSE<(outs RO:$dst), (ins RO:$rt, mem_mm_12:$addr), + InstSE<(outs RO:$dst), (ins RO:$rt, mem_simm9:$addr), !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { let DecoderMethod = "DecodeMemMMImm9"; let mayStore = 1; @@ -287,10 +295,10 @@ class SCEBaseMM<string opstr, RegisterOperand RO> : } class LoadMM<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag, - InstrItinClass Itin = NoItinerary> : - InstSE<(outs RO:$rt), (ins mem_mm_12:$addr), + InstrItinClass Itin = NoItinerary, DAGOperand MO = mem_mm_12> : + InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set RO:$rt, (OpNode addrimm12:$addr))], Itin, FrmI> { + [(set RO:$rt, (OpNode addrimm12:$addr))], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let canFoldAsLoad = 1; let mayLoad = 1; @@ -615,7 +623,7 @@ def SH16_MM : StoreMM16<"sh16", GPRMM16OpndZero, GPRMM16Opnd, truncstorei16, LOAD_STORE_FM_MM16<0x2a>; def SW16_MM : StoreMM16<"sw16", GPRMM16OpndZero, GPRMM16Opnd, store, II_SW, mem_mm_4_lsl2>, LOAD_STORE_FM_MM16<0x3a>; -def LWGP_MM : LoadGPMM16<"lw", GPRMM16Opnd, II_LW, mem_mm_gp_imm7_lsl2>, +def LWGP_MM : LoadGPMM16<"lw", GPRMM16Opnd, II_LW, mem_mm_gp_simm7_lsl2>, LOAD_GP_FM_MM16<0x19>; def LWSP_MM : LoadSPMM16<"lw", GPR32Opnd, II_LW, mem_mm_sp_imm5_lsl2>, LOAD_STORE_SP_FM_MM16<0x12>; @@ -629,7 +637,7 @@ def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>; def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>; def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>; def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16; -def LI16_MM : LoadImmMM16<"li16", li_simm7, GPRMM16Opnd>, LI_FM_MM16, +def LI16_MM : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>, LI_FM_MM16, IsAsCheapAsAMove; def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>, ISA_MICROMIPS32_NOT_MIPS32R6; @@ -677,11 +685,11 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { SLTI_FM_MM<0x2c>; def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd>, ADDI_FM_MM<0x34>; - def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd>, - ADDI_FM_MM<0x14>; - def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd>, - ADDI_FM_MM<0x1c>; - def LUi_MM : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM_MM; + def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, + or>, ADDI_FM_MM<0x14>; + def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, + immZExt16, xor>, ADDI_FM_MM<0x1c>; + def LUi_MM : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM_MM; def LEA_ADDiu_MM : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM_MM<0xc>; @@ -709,9 +717,9 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def MULTu_MM : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, MULT_FM_MM<0x26c>; def SDIV_MM : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, - MULT_FM_MM<0x2ac>; + MULT_FM_MM<0x2ac>, ISA_MIPS1_NOT_32R6_64R6; def UDIV_MM : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, - MULT_FM_MM<0x2ec>; + MULT_FM_MM<0x2ec>, ISA_MIPS1_NOT_32R6_64R6; /// Arithmetic Instructions with PC and Immediate def ADDIUPC_MM : AddImmUPC<"addiupc", GPRMM16Opnd>, ADDIUPC_FM_MM; @@ -730,16 +738,24 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def SRAV_MM : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV>, SRLV_FM_MM<0x90, 0>; def ROTR_MM : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR>, - SRA_FM_MM<0xc0, 0>; + SRA_FM_MM<0xc0, 0> { + list<dag> Pattern = [(set GPR32Opnd:$rd, + (rotr GPR32Opnd:$rt, immZExt5:$shamt))]; + } def ROTRV_MM : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV>, - SRLV_FM_MM<0xd0, 0>; + SRLV_FM_MM<0xd0, 0> { + list<dag> Pattern = [(set GPR32Opnd:$rd, + (rotr GPR32Opnd:$rt, GPR32Opnd:$rs))]; + } /// Load and Store Instructions - aligned let DecoderMethod = "DecodeMemMMImm16" in { - def LB_MM : Load<"lb", GPR32Opnd>, MMRel, LW_FM_MM<0x7>; - def LBu_MM : Load<"lbu", GPR32Opnd>, MMRel, LW_FM_MM<0x5>; - def LH_MM : Load<"lh", GPR32Opnd>, MMRel, LW_FM_MM<0xf>; - def LHu_MM : Load<"lhu", GPR32Opnd>, MMRel, LW_FM_MM<0xd>; + def LB_MM : LoadMemory<"lb", GPR32Opnd, mem_mm_16>, MMRel, LW_FM_MM<0x7>; + def LBu_MM : LoadMemory<"lbu", GPR32Opnd, mem_mm_16>, MMRel, LW_FM_MM<0x5>; + def LH_MM : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH, + addrDefault>, MMRel, LW_FM_MM<0xf>; + def LHu_MM : LoadMemory<"lhu", GPR32Opnd, mem_simm16, zextloadi16, II_LHU>, + MMRel, LW_FM_MM<0xd>; def LW_MM : Load<"lw", GPR32Opnd>, MMRel, LW_FM_MM<0x3f>; def SB_MM : Store<"sb", GPR32Opnd>, MMRel, LW_FM_MM<0x6>; def SH_MM : Store<"sh", GPR32Opnd>, MMRel, LW_FM_MM<0xe>; @@ -749,19 +765,22 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { let DecoderMethod = "DecodeMemMMImm9" in { def LBE_MM : Load<"lbe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x4>; def LBuE_MM : Load<"lbue", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x0>; - def LHE_MM : Load<"lhe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x5>; - def LHuE_MM : Load<"lhue", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x1>; - def LWE_MM : Load<"lwe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x7>; - def SBE_MM : Store<"sbe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x4>; - def SHE_MM : Store<"she", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x5>; - def SWE_MM : StoreMemory<"swe", GPR32Opnd, mem_simm9gpr>, + def LHE_MM : LoadMemory<"lhe", GPR32Opnd, mem_simm9>, + POOL32C_LHUE_FM_MM<0x18, 0x6, 0x5>; + def LHuE_MM : LoadMemory<"lhue", GPR32Opnd, mem_simm9>, + POOL32C_LHUE_FM_MM<0x18, 0x6, 0x1>; + def LWE_MM : LoadMemory<"lwe", GPR32Opnd, mem_simm9>, + POOL32C_LHUE_FM_MM<0x18, 0x6, 0x7>; + def SBE_MM : StoreMemory<"sbe", GPR32Opnd, mem_simm9>, + POOL32C_LHUE_FM_MM<0x18, 0xa, 0x4>; + def SHE_MM : StoreMemory<"she", GPR32Opnd, mem_simm9>, + POOL32C_LHUE_FM_MM<0x18, 0xa, 0x5>; + def SWE_MM : StoreMemory<"swe", GPR32Opnd, mem_simm9>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x7>; } def LWXS_MM : LoadWordIndexedScaledMM<"lwxs", GPR32Opnd>, LWXS_FM_MM<0x118>; - def LWU_MM : LoadMM<"lwu", GPR32Opnd, zextloadi32, II_LWU>, LL_FM_MM<0xe>; - /// Load and Store Instructions - unaligned def LWL_MM : LoadLeftRightMM<"lwl", MipsLWL, GPR32Opnd, mem_mm_12>, LWL_FM_MM<0x0>; @@ -772,13 +791,13 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def SWR_MM : StoreLeftRightMM<"swr", MipsSWR, GPR32Opnd, mem_mm_12>, LWL_FM_MM<0x9>; let DecoderMethod = "DecodeMemMMImm9" in { - def LWLE_MM : LoadLeftRightMM<"lwle", MipsLWL, GPR32Opnd, mem_mm_12>, + def LWLE_MM : LoadLeftRightMM<"lwle", MipsLWL, GPR32Opnd, mem_mm_9>, POOL32C_STEVA_LDEVA_FM_MM<0x6, 0x2>; - def LWRE_MM : LoadLeftRightMM<"lwre", MipsLWR, GPR32Opnd, mem_mm_12>, + def LWRE_MM : LoadLeftRightMM<"lwre", MipsLWR, GPR32Opnd, mem_mm_9>, POOL32C_STEVA_LDEVA_FM_MM<0x6, 0x3>; - def SWLE_MM : StoreLeftRightMM<"swle", MipsSWL, GPR32Opnd, mem_mm_12>, + def SWLE_MM : StoreLeftRightMM<"swle", MipsSWL, GPR32Opnd, mem_mm_9>, POOL32C_STEVA_LDEVA_FM_MM<0xa, 0x0>; - def SWRE_MM : StoreLeftRightMM<"swre", MipsSWR, GPR32Opnd, mem_mm_12>, + def SWRE_MM : StoreLeftRightMM<"swre", MipsSWR, GPR32Opnd, mem_mm_9>, POOL32C_STEVA_LDEVA_FM_MM<0xa, 0x1>, ISA_MIPS1_NOT_32R6_64R6; } @@ -845,10 +864,10 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def WSBH_MM : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM_MM<0x1ec>, ISA_MIPS32R2; // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction - def EXT_MM : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, - MipsExt>, EXT_FM_MM<0x2c>; - def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, - EXT_FM_MM<0x0c>; + def EXT_MM : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, immZExt5, + immZExt5Plus1, MipsExt>, EXT_FM_MM<0x2c>; + def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, uimm5_inssize_plus1, + MipsIns>, EXT_FM_MM<0x0c>; /// Jump Instructions let DecoderMethod = "DecodeJumpTargetMM" in { @@ -857,7 +876,8 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def JAL_MM : MMRel, JumpLink<"jal", calltarget_mm>, J_FM_MM<0x3d>; def JALX_MM : MMRel, JumpLink<"jalx", calltarget>, J_FM_MM<0x3c>; } - def JR_MM : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>; + def JR_MM : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>, + ISA_MICROMIPS32_NOT_MIPS32R6; def JALR_MM : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM_MM<0x03c>; /// Jump Instructions - Short Delay Slot @@ -891,7 +911,7 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { /// Control Instructions def SYNC_MM : MMRel, SYNC_FT<"sync">, SYNC_FM_MM; def BREAK_MM : MMRel, BRK_FT<"break">, BRK_FM_MM; - def SYSCALL_MM : MMRel, SYS_FT<"syscall">, SYS_FM_MM; + def SYSCALL_MM : MMRel, SYS_FT<"syscall", uimm10>, SYS_FM_MM; def WAIT_MM : WaitMM<"wait">, WAIT_FM_MM; def ERET_MM : MMRel, ER_FT<"eret">, ER_FM_MM<0x3cd>; def DERET_MM : MMRel, ER_FT<"deret">, ER_FM_MM<0x38d>; @@ -901,12 +921,12 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { ISA_MIPS32R2; /// Trap Instructions - def TEQ_MM : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM_MM<0x0>; - def TGE_MM : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM_MM<0x08>; - def TGEU_MM : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM_MM<0x10>; - def TLT_MM : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM_MM<0x20>; - def TLTU_MM : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM_MM<0x28>; - def TNE_MM : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM_MM<0x30>; + def TEQ_MM : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm4>, TEQ_FM_MM<0x0>; + def TGE_MM : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm4>, TEQ_FM_MM<0x08>; + def TGEU_MM : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm4>, TEQ_FM_MM<0x10>; + def TLT_MM : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm4>, TEQ_FM_MM<0x20>; + def TLTU_MM : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm4>, TEQ_FM_MM<0x28>; + def TNE_MM : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm4>, TEQ_FM_MM<0x30>; def TEQI_MM : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM_MM<0x0e>; def TGEI_MM : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM_MM<0x09>; @@ -931,9 +951,9 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { let DecoderMethod = "DecodePrefeOpMM" in { def PREFE_MM : MMRel, CacheOp<"prefe", mem_mm_9>, - CACHE_PREFE_FM_MM<0x18, 0x2>; + CACHE_PREFE_FM_MM<0x18, 0x2>; def CACHEE_MM : MMRel, CacheOp<"cachee", mem_mm_9>, - CACHE_PREFE_FM_MM<0x18, 0x3>; + CACHE_PREFE_FM_MM<0x18, 0x3>; } def SSNOP_MM : MMRel, Barrier<"ssnop">, BARRIER_FM_MM<0x1>; def EHB_MM : MMRel, Barrier<"ehb">, BARRIER_FM_MM<0x3>; @@ -944,7 +964,7 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def TLBWI_MM : MMRel, TLB<"tlbwi">, COP0_TLB_FM_MM<0x8d>; def TLBWR_MM : MMRel, TLB<"tlbwr">, COP0_TLB_FM_MM<0xcd>; - def SDBBP_MM : MMRel, SYS_FT<"sdbbp">, SDBBP_FM_MM; + def SDBBP_MM : MMRel, SYS_FT<"sdbbp", uimm10>, SDBBP_FM_MM; def PREFX_MM : PrefetchIndexed<"prefx">, POOL32F_PREFX_FM_MM<0x15, 0x1A0>; } @@ -952,54 +972,80 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { let DecoderNamespace = "MicroMips" in { def RDHWR_MM : MMRel, R6MMR6Rel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM_MM, ISA_MICROMIPS32_NOT_MIPS32R6; + def LWU_MM : MMRel, LoadMM<"lwu", GPR32Opnd, zextloadi32, II_LWU, + mem_simm12>, LL_FM_MM<0xe>, + ISA_MICROMIPS32_NOT_MIPS32R6; } -let Predicates = [InMicroMips] in { - //===----------------------------------------------------------------------===// // MicroMips arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// -def : MipsPat<(i32 immLi16:$imm), - (LI16_MM immLi16:$imm)>; -def : MipsPat<(i32 immSExt16:$imm), - (ADDiu_MM ZERO, immSExt16:$imm)>; -def : MipsPat<(i32 immZExt16:$imm), - (ORi_MM ZERO, immZExt16:$imm)>; -def : MipsPat<(not GPR32:$in), - (NOR_MM GPR32Opnd:$in, ZERO)>; - -def : MipsPat<(add GPRMM16:$src, immSExtAddiur2:$imm), - (ADDIUR2_MM GPRMM16:$src, immSExtAddiur2:$imm)>; -def : MipsPat<(add GPR32:$src, immSExtAddius5:$imm), - (ADDIUS5_MM GPR32:$src, immSExtAddius5:$imm)>; -def : MipsPat<(add GPR32:$src, immSExt16:$imm), - (ADDiu_MM GPR32:$src, immSExt16:$imm)>; - -def : MipsPat<(and GPRMM16:$src, immZExtAndi16:$imm), - (ANDI16_MM GPRMM16:$src, immZExtAndi16:$imm)>; -def : MipsPat<(and GPR32:$src, immZExt16:$imm), - (ANDi_MM GPR32:$src, immZExt16:$imm)>; - -def : MipsPat<(shl GPRMM16:$src, immZExt2Shift:$imm), - (SLL16_MM GPRMM16:$src, immZExt2Shift:$imm)>; -def : MipsPat<(shl GPR32:$src, immZExt5:$imm), - (SLL_MM GPR32:$src, immZExt5:$imm)>; - -def : MipsPat<(srl GPRMM16:$src, immZExt2Shift:$imm), - (SRL16_MM GPRMM16:$src, immZExt2Shift:$imm)>; -def : MipsPat<(srl GPR32:$src, immZExt5:$imm), - (SRL_MM GPR32:$src, immZExt5:$imm)>; - -def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr), - (SW16_MM GPRMM16:$src, addrimm4lsl2:$addr)>; -def : MipsPat<(store GPR32:$src, addr:$addr), - (SW_MM GPR32:$src, addr:$addr)>; - -def : MipsPat<(load addrimm4lsl2:$addr), - (LW16_MM addrimm4lsl2:$addr)>; -def : MipsPat<(load addr:$addr), - (LW_MM addr:$addr)>; +let Predicates = [InMicroMips] in { + def : MipsPat<(i32 immLi16:$imm), + (LI16_MM immLi16:$imm)>; + def : MipsPat<(i32 immSExt16:$imm), + (ADDiu_MM ZERO, immSExt16:$imm)>; + def : MipsPat<(i32 immZExt16:$imm), + (ORi_MM ZERO, immZExt16:$imm)>; + + def : MipsPat<(not GPRMM16:$in), + (NOT16_MM GPRMM16:$in)>; + def : MipsPat<(not GPR32:$in), + (NOR_MM GPR32Opnd:$in, ZERO)>; + + def : MipsPat<(add GPRMM16:$src, immSExtAddiur2:$imm), + (ADDIUR2_MM GPRMM16:$src, immSExtAddiur2:$imm)>; + def : MipsPat<(add GPR32:$src, immSExtAddius5:$imm), + (ADDIUS5_MM GPR32:$src, immSExtAddius5:$imm)>; + def : MipsPat<(add GPR32:$src, immSExt16:$imm), + (ADDiu_MM GPR32:$src, immSExt16:$imm)>; + + def : MipsPat<(and GPRMM16:$src, immZExtAndi16:$imm), + (ANDI16_MM GPRMM16:$src, immZExtAndi16:$imm)>; + def : MipsPat<(and GPR32:$src, immZExt16:$imm), + (ANDi_MM GPR32:$src, immZExt16:$imm)>; + + def : MipsPat<(shl GPRMM16:$src, immZExt2Shift:$imm), + (SLL16_MM GPRMM16:$src, immZExt2Shift:$imm)>; + def : MipsPat<(shl GPR32:$src, immZExt5:$imm), + (SLL_MM GPR32:$src, immZExt5:$imm)>; + def : MipsPat<(shl GPR32:$lhs, GPR32:$rhs), + (SLLV_MM GPR32:$lhs, GPR32:$rhs)>; + + def : MipsPat<(srl GPRMM16:$src, immZExt2Shift:$imm), + (SRL16_MM GPRMM16:$src, immZExt2Shift:$imm)>; + def : MipsPat<(srl GPR32:$src, immZExt5:$imm), + (SRL_MM GPR32:$src, immZExt5:$imm)>; + def : MipsPat<(srl GPR32:$lhs, GPR32:$rhs), + (SRLV_MM GPR32:$lhs, GPR32:$rhs)>; + + def : MipsPat<(sra GPR32:$src, immZExt5:$imm), + (SRA_MM GPR32:$src, immZExt5:$imm)>; + def : MipsPat<(sra GPR32:$lhs, GPR32:$rhs), + (SRAV_MM GPR32:$lhs, GPR32:$rhs)>; + + def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr), + (SW16_MM GPRMM16:$src, addrimm4lsl2:$addr)>; + def : MipsPat<(store GPR32:$src, addr:$addr), + (SW_MM GPR32:$src, addr:$addr)>; + + def : MipsPat<(load addrimm4lsl2:$addr), + (LW16_MM addrimm4lsl2:$addr)>; + def : MipsPat<(load addr:$addr), + (LW_MM addr:$addr)>; + def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs), + (SUBu_MM GPR32:$lhs, GPR32:$rhs)>; +} + +let AddedComplexity = 40 in { + def : MipsPat<(i32 (sextloadi16 addrRegImm:$a)), + (LH_MM addrRegImm:$a)>; +} +def : MipsPat<(atomic_load_16 addr:$a), + (LH_MM addr:$a)>; +def : MipsPat<(i32 (extloadi16 addr:$src)), + (LHu_MM addr:$src)>; //===----------------------------------------------------------------------===// // MicroMips instruction aliases @@ -1011,24 +1057,62 @@ class UncondBranchMMPseudo<string opstr> : def B_MM_Pseudo : UncondBranchMMPseudo<"b">, ISA_MICROMIPS; +let Predicates = [InMicroMips] in { + def SDIV_MM_Pseudo : MultDivPseudo<SDIV_MM, ACC64, GPR32Opnd, MipsDivRem, + II_DIV, 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; + def UDIV_MM_Pseudo : MultDivPseudo<UDIV_MM, ACC64, GPR32Opnd, MipsDivRemU, + II_DIVU, 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; + def : MipsInstAlias<"wait", (WAIT_MM 0x0), 1>; def : MipsInstAlias<"nop", (SLL_MM ZERO, ZERO, 0), 1>; def : MipsInstAlias<"nop", (MOVE16_MM ZERO, ZERO), 1>; -} - -let Predicates = [InMicroMips] in { -def : MipsInstAlias<"ei", (EI_MM ZERO), 1>, ISA_MIPS32R2; -def : MipsInstAlias<"di", (DI_MM ZERO), 1>, ISA_MIPS32R2; -def : MipsInstAlias<"teq $rs, $rt", - (TEQ_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; -def : MipsInstAlias<"tge $rs, $rt", - (TGE_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; -def : MipsInstAlias<"tgeu $rs, $rt", - (TGEU_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; -def : MipsInstAlias<"tlt $rs, $rt", - (TLT_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; -def : MipsInstAlias<"tltu $rs, $rt", - (TLTU_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; -def : MipsInstAlias<"tne $rs, $rt", - (TNE_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; + def : MipsInstAlias<"ei", (EI_MM ZERO), 1>, ISA_MIPS32R2; + def : MipsInstAlias<"di", (DI_MM ZERO), 1>, ISA_MIPS32R2; + def : MipsInstAlias<"teq $rs, $rt", + (TEQ_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; + def : MipsInstAlias<"tge $rs, $rt", + (TGE_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; + def : MipsInstAlias<"tgeu $rs, $rt", + (TGEU_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; + def : MipsInstAlias<"tlt $rs, $rt", + (TLT_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; + def : MipsInstAlias<"tltu $rs, $rt", + (TLTU_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; + def : MipsInstAlias<"tne $rs, $rt", + (TNE_MM GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; + def : MipsInstAlias<"sll $rd, $rt, $rs", + (SLLV_MM GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; + def : MipsInstAlias<"sra $rd, $rt, $rs", + (SRAV_MM GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; + def : MipsInstAlias<"srl $rd, $rt, $rs", + (SRLV_MM GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; + def : MipsInstAlias<"sll $rd, $rt", + (SLLV_MM GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>; + def : MipsInstAlias<"sra $rd, $rt", + (SRAV_MM GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>; + def : MipsInstAlias<"srl $rd, $rt", + (SRLV_MM GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>; + def : MipsInstAlias<"sll $rd, $shamt", + (SLL_MM GPR32Opnd:$rd, GPR32Opnd:$rd, uimm5:$shamt), 0>; + def : MipsInstAlias<"sra $rd, $shamt", + (SRA_MM GPR32Opnd:$rd, GPR32Opnd:$rd, uimm5:$shamt), 0>; + def : MipsInstAlias<"srl $rd, $shamt", + (SRL_MM GPR32Opnd:$rd, GPR32Opnd:$rd, uimm5:$shamt), 0>; + def : MipsInstAlias<"rotr $rt, $imm", + (ROTR_MM GPR32Opnd:$rt, GPR32Opnd:$rt, uimm5:$imm), 0>; + def : MipsInstAlias<"syscall", (SYSCALL_MM 0), 1>; + def : MipsInstAlias<"and $rs, $rt, $imm", + (ANDi_MM GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; + def : MipsInstAlias<"and $rs, $imm", + (ANDi_MM GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>; + def : MipsInstAlias<"or $rs, $rt, $imm", + (ORi_MM GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; + def : MipsInstAlias<"or $rs, $imm", + (ORi_MM GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>; + def : MipsInstAlias<"xor $rs, $rt, $imm", + (XORi_MM GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; + def : MipsInstAlias<"xor $rs, $imm", + (XORi_MM GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>; + def : MipsInstAlias<"not $rt, $rs", + (NOR_MM GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>; } |