Index: lib/Target/Mips/MicroMips64r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrFormats.td +++ lib/Target/Mips/MicroMips64r6InstrFormats.td @@ -84,3 +84,65 @@ let Inst{10-9} = 0b00; let Inst{8-0} = funct; } + +class LD_SD_32_2ROFFSET16_FM_MMR6 op> + : MMR6Arch { + bits<5> rt; + bits<21> addr; + bits<5> base = addr{20-16}; + bits<16> offset = addr{15-0}; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = rt; + let Inst{20-16} = base; + let Inst{15-0} = offset; +} + +class POOL32C_2ROFFSET12_FM_MMR6 funct> + : MMR6Arch { + bits<5> rt; + bits<21> addr; + bits<5> base = addr{20-16}; + bits<12> offset = addr{11-0}; + + bits<32> Inst; + + let Inst{31-26} = 0b011000; + let Inst{25-21} = rt; + let Inst{20-16} = base; + let Inst{15-12} = funct; + let Inst{11-0} = offset; +} + +class POOL32S_2RSA5_FM_MMR6 funct> { + bits<5> rt; + bits<5> rs; + bits<5> sa; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = sa; + let Inst{10-9} = 0b00; + let Inst{8-0} = funct; +} + +class POOL32S_3R_FM_MMR6 funct> + : MMR6Arch { + bits<5> rt; + bits<5> rs; + bits<5> rd; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = rd; + let Inst{10-9} = 0b00; + let Inst{8-0} = funct; +} Index: lib/Target/Mips/MicroMips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrInfo.td +++ lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -28,6 +28,13 @@ class DMOD_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmod", 0b101011000>; class DDIVU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddivu", 0b110011000>; class DMODU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmodu", 0b111011000>; +class LD_MM64R6_ENC : LD_SD_32_2ROFFSET16_FM_MMR6<"ld", 0b110111>; +class LLD_MM64R6_ENC : POOL32C_2ROFFSET12_FM_MMR6<"lld", 0b0111>; +class LWU_MM64R6_ENC : POOL32C_2ROFFSET12_FM_MMR6<"lwu", 0b1110>; +class SD_MM64R6_ENC : LD_SD_32_2ROFFSET16_FM_MMR6<"sd", 0b110110>; +class DSRL_MM64R6_ENC : POOL32S_2RSA5_FM_MMR6<"dsrl", 0b001000000>; +class DSRL32_MM64R6_ENC : POOL32S_2RSA5_FM_MMR6<"dsrl32", 0b001001000>; +class DSRLV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"dsrlv", 0b001010000>; //===----------------------------------------------------------------------===// // @@ -90,6 +97,38 @@ class DDIVU_MM64R6_DESC : ArithLogicR<"ddivu", GPR32Opnd>; class DMODU_MM64R6_DESC : ArithLogicR<"dmodu", GPR32Opnd>; +class LD_MM64R6_DESC : LoadMemory<"ld", GPR64Opnd, mem_mm_16, load, II_LD> { + let DecoderMethod = "DecodeMemMMImm16"; +} +class LLD_MM64R6_DESC : LLBase<"lld", GPR64Opnd> { + let DecoderMethod = "DecodeMemMMImm12"; +} +class LWU_MM64R6_DESC : LoadMM<"lwu", GPR64Opnd, zextloadi32, II_LWU>; +class SD_MM64R6_DESC : StoreMemory<"sd", GPR64Opnd, mem_mm_16, store, II_SD> { + let DecoderMethod = "DecodeMemMMImm16"; +} + +class SHIFT_ROTATE_IMM_MM64R6 + : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs RO:$rt); + dag InOperandList = (ins RO:$rs, ImmOpnd:$sa); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa"); + list Pattern = [(set RO:$rt, (OpNode RO:$rs, PF:$sa))]; + InstrItinClass Itinerary = itin; + Format Form = FrmR; + string BaseOpcode = instr_asm; +} + +class DSRL_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsrl", uimm5, + GPR64Opnd, II_DSRL, + srl, immZExt5>; +class DSRL32_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsrl32", uimm5, + GPR64Opnd, II_DSRL32>; +class DSRLV_MM64R6_DESC : shift_rotate_reg<"dsrlv", GPR64Opnd, II_DSRLV, srl>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -116,4 +155,18 @@ ISA_MICROMIPS64R6; def DMODU_MM64R6 : R6MMR6Rel, DMODU_MM64R6_DESC, DMODU_MM64R6_ENC, ISA_MICROMIPS64R6; + def LD_MM64R6 : R6MMR6Rel, LD_MM64R6_DESC, LD_MM64R6_ENC, + ISA_MICROMIPS64R6; + def LLD_MM64R6 : R6MMR6Rel, LLD_MM64R6_DESC, LLD_MM64R6_ENC, + ISA_MICROMIPS64R6; + def LWU_MM64R6 : R6MMR6Rel, LWU_MM64R6_DESC, LWU_MM64R6_ENC, + ISA_MICROMIPS64R6; + def SD_MM64R6 : R6MMR6Rel, SD_MM64R6_DESC, SD_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSRL_MM64R6 : R6MMR6Rel, DSRL_MM64R6_DESC, DSRL_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSRL32_MM64R6 : R6MMR6Rel, DSRL32_MM64R6_DESC, DSRL32_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSRLV_MM64R6 : R6MMR6Rel, DSRLV_MM64R6_DESC, DSRLV_MM64R6_ENC, + ISA_MICROMIPS64R6; } Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -138,20 +138,26 @@ /// Shift Instructions def DSLL : shift_rotate_imm<"dsll", uimm6, GPR64Opnd, II_DSLL, shl, immZExt6>, SRA_FM<0x38, 0>, ISA_MIPS3; -def DSRL : shift_rotate_imm<"dsrl", uimm6, GPR64Opnd, II_DSRL, srl, immZExt6>, - SRA_FM<0x3a, 0>, ISA_MIPS3; +let AdditionalPredicates = [NotInMicroMips] in { + def DSRL : shift_rotate_imm<"dsrl", uimm6, GPR64Opnd, II_DSRL, srl, immZExt6>, + SRA_FM<0x3a, 0>, ISA_MIPS3; +} def DSRA : shift_rotate_imm<"dsra", uimm6, GPR64Opnd, II_DSRA, sra, immZExt6>, SRA_FM<0x3b, 0>, ISA_MIPS3; def DSLLV : shift_rotate_reg<"dsllv", GPR64Opnd, II_DSLLV, shl>, SRLV_FM<0x14, 0>, ISA_MIPS3; -def DSRLV : shift_rotate_reg<"dsrlv", GPR64Opnd, II_DSRLV, srl>, - SRLV_FM<0x16, 0>, ISA_MIPS3; +let AdditionalPredicates = [NotInMicroMips] in { + def DSRLV : shift_rotate_reg<"dsrlv", GPR64Opnd, II_DSRLV, srl>, + SRLV_FM<0x16, 0>, ISA_MIPS3; +} def DSRAV : shift_rotate_reg<"dsrav", GPR64Opnd, II_DSRAV, sra>, SRLV_FM<0x17, 0>, ISA_MIPS3; def DSLL32 : shift_rotate_imm<"dsll32", uimm5, GPR64Opnd, II_DSLL32>, SRA_FM<0x3c, 0>, ISA_MIPS3; -def DSRL32 : shift_rotate_imm<"dsrl32", uimm5, GPR64Opnd, II_DSRL32>, - SRA_FM<0x3e, 0>, ISA_MIPS3; +let AdditionalPredicates = [NotInMicroMips] in { + def DSRL32 : shift_rotate_imm<"dsrl32", uimm5, GPR64Opnd, II_DSRL32>, + SRA_FM<0x3e, 0>, ISA_MIPS3; +} def DSRA32 : shift_rotate_imm<"dsra32", uimm5, GPR64Opnd, II_DSRA32>, SRA_FM<0x3f, 0>, ISA_MIPS3; @@ -178,8 +184,12 @@ } def LWu : Load<"lwu", GPR64Opnd, zextloadi32, II_LWU>, LW_FM<0x27>, ISA_MIPS3; -def LD : Load<"ld", GPR64Opnd, load, II_LD>, LW_FM<0x37>, ISA_MIPS3; -def SD : Store<"sd", GPR64Opnd, store, II_SD>, LW_FM<0x3f>, ISA_MIPS3; +let AdditionalPredicates = [NotInMicroMips] in { + def LD : LoadMemory<"ld", GPR64Opnd, mem, load, II_LD>, LW_FM<0x37>, + ISA_MIPS3; + def SD : Store<"sd", GPR64Opnd, store, II_SD>, LW_FM<0x3f>, ISA_MIPS3; +} + /// load/store left/right let isCodeGenOnly = 1 in { @@ -199,7 +209,9 @@ ISA_MIPS3_NOT_32R6_64R6; /// Load-linked, Store-conditional -def LLD : LLBase<"lld", GPR64Opnd>, LW_FM<0x34>, ISA_MIPS3_NOT_32R6_64R6; +let AdditionalPredicates = [NotInMicroMips] in { + def LLD : LLBase<"lld", GPR64Opnd>, LW_FM<0x34>, ISA_MIPS3_NOT_32R6_64R6; +} def SCD : SCBase<"scd", GPR64Opnd>, LW_FM<0x3c>, ISA_MIPS3_NOT_32R6_64R6; /// Jump and Branch Instructions @@ -622,10 +634,11 @@ def : MipsInstAlias<"dsra $rd, $rt, $rs", (DSRAV GPR64Opnd:$rd, GPR64Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS3; -def : MipsInstAlias<"dsrl $rd, $rt, $rs", - (DSRLV GPR64Opnd:$rd, GPR64Opnd:$rt, GPR32Opnd:$rs), 0>, - ISA_MIPS3; - +let AdditionalPredicates = [NotInMicroMips] in { + def : MipsInstAlias<"dsrl $rd, $rt, $rs", + (DSRLV GPR64Opnd:$rd, GPR64Opnd:$rt, GPR32Opnd:$rs), 0>, + ISA_MIPS3; +} // Two operand (implicit 0 selector) versions: def : MipsInstAlias<"dmfc0 $rt, $rd", (DMFC0 GPR64Opnd:$rt, COP0Opnd:$rd, 0), 0>; def : MipsInstAlias<"dmtc0 $rt, $rd", (DMTC0 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>; Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -100,7 +100,9 @@ def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6; def DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6; def LDPC: LDPC_ENC, LDPC_DESC, ISA_MIPS64R6; -def LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS32R6; +} def SCD_R6 : SCD_R6_ENC, SCD_R6_DESC, ISA_MIPS32R6; let DecoderNamespace = "Mips32r6_64r6_GP64" in { def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -849,6 +849,17 @@ } // Memory Load/Store +class LoadMemory : + InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> { + let DecoderMethod = "DecodeMem"; + let canFoldAsLoad = 1; + let mayLoad = 1; +} + class Load : InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), Index: test/MC/Disassembler/Mips/micromips64r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -169,3 +169,10 @@ 0x00 0x00 0xe3 0x7c # CHECK: deret 0x00 0x00 0x47 0x7c # CHECK: di 0x00 0x0f 0x47 0x7c # CHECK: di $15 +0xdc 0x82 0x00 0x05 # CHECK: ld $4, 5($2) +0x60 0x48 0x70 0x03 # CHECK: lld $2, 3($8) +0x60 0x22 0xe0 0x0a # CHECK: lwu $1, 10($2) +0xd8 0x83 0x00 0x05 # CHECK: sd $4, 5($3) +0x58 0x22 0x10 0x40 # CHECK: dsrl $1, $2, 2 +0x58 0x64 0x28 0x48 # CHECK: dsrl32 $3, $4, 5 +0x58 0x63 0x08 0x50 # CHECK: dsrlv $1, $3, $3 Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -91,3 +91,4 @@ jraddiusp 33 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected both 7-bit unsigned immediate and multiple of 4 jraddiusp 125 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected both 7-bit unsigned immediate and multiple of 4 jraddiusp 132 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected both 7-bit unsigned immediate and multiple of 4 + lwu $32, 4096($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips64r6/invalid.s =================================================================== --- test/MC/Mips/micromips64r6/invalid.s +++ test/MC/Mips/micromips64r6/invalid.s @@ -143,3 +143,7 @@ swm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + ld $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lld $32, 4096($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lwu $32, 4096($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sd $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips64r6/valid.s =================================================================== --- test/MC/Mips/micromips64r6/valid.s +++ test/MC/Mips/micromips64r6/valid.s @@ -150,5 +150,11 @@ di # CHECK: di # encoding: [0x00,0x00,0x47,0x7c] di $0 # CHECK: di # encoding: [0x00,0x00,0x47,0x7c] di $15 # CHECK: di $15 # encoding: [0x00,0x0f,0x47,0x7c] - + ld $4, 5($2) # CHECK: ld $4, 5($2) # encoding: [0xdc,0x82,0x00,0x05] + lld $2, 3($8) # CHECK: lld $2, 3($8) # encoding: [0x60,0x48,0x70,0x03] + lwu $1, 10($2) # CHECK: lwu $1, 10($2) # encoding: [0x60,0x22,0xe0,0x0a] + sd $4, 5($3) # CHECK: sd $4, 5($3) # encoding: [0xd8,0x83,0x00,0x05] + dsrl $1, $2, 2 # CHECK: dsrl $1, $2, 2 # encoding: [0x58,0x22,0x10,0x40] + dsrl32 $3, $4, 5 # CHECK: dsrl32 $3, $4, 5 # encoding: [0x58,0x64,0x28,0x48] + dsrlv $1, $3, $3 # CHECK: dsrlv $1, $3, $3 # encoding: [0x58,0x63,0x08,0x50] 1: Index: test/MC/Mips/mips64r3/invalid.s =================================================================== --- test/MC/Mips/mips64r3/invalid.s +++ test/MC/Mips/mips64r3/invalid.s @@ -14,3 +14,4 @@ jalr.hb $31, $31 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different pref -1, 255($7) # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate pref 32, 255($7) # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate + sd $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/mips64r5/invalid.s =================================================================== --- test/MC/Mips/mips64r5/invalid.s +++ test/MC/Mips/mips64r5/invalid.s @@ -14,3 +14,4 @@ jalr.hb $31, $31 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different pref -1, 255($7) # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate pref 32, 255($7) # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate + sd $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/mips64r6/invalid.s =================================================================== --- test/MC/Mips/mips64r6/invalid.s +++ test/MC/Mips/mips64r6/invalid.s @@ -43,3 +43,9 @@ lsa $2, $3, $4, 5 # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4 pref -1, 255($7) # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate pref 32, 255($7) # CHECK: :[[@LINE]]:14: error: expected 5-bit unsigned immediate + ld $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lld $32, 4096($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sd $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + dsrl $32, $32, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + dsrl32 $32, $32, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + dsrlv $32, $32, $32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction