Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1854,7 +1854,7 @@ Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); Base = getReg(Decoder, Mips::GPR32RegClassID, Base); - if (Inst.getOpcode() == Mips::SCE_MM) + if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6) Inst.addOperand(MCOperand::createReg(Reg)); Inst.addOperand(MCOperand::createReg(Reg)); Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -1015,3 +1015,21 @@ let Inst{11} = 0; let Inst{10-0} = offset; } + +class POOL32C_LL_E_SC_E_FM_MMR6 majorFunc, + bits<3> minorFunc> + : MMR6Arch, MipsR6Inst { + bits<5> rt; + bits<21> addr; + bits<5> base = addr{20-16}; + bits<9> offset = addr{8-0}; + + bits<32> Inst; + + let Inst{31-26} = 0b011000; + let Inst{25-21} = rt; + let Inst{20-16} = base; + let Inst{15-12} = majorFunc; + let Inst{11-9} = minorFunc; + let Inst{8-0} = offset; +} Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -232,6 +232,9 @@ class LWC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"lwc2", 0b0000>; class SWC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"swc2", 0b1000>; +class LL_MMR6_ENC : POOL32C_LL_E_SC_E_FM_MMR6<"ll", 0b0011, 0b000>; +class SC_MMR6_ENC : POOL32C_LL_E_SC_E_FM_MMR6<"sc", 0b1011, 0b000>; + /// Floating Point Instructions class FADD_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"add.s", 0, 0b00110000>; class FSUB_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"sub.s", 0, 0b01110000>; @@ -826,6 +829,30 @@ class SDC2_MMR6_DESC : SDC2_SWC2_MMR6_DESC_BASE<"sdc2", II_SDC2>; class SWC2_MMR6_DESC : SDC2_SWC2_MMR6_DESC_BASE<"swc2", II_SWC2>; +class SC_MMR6_DESC_BASE { + dag OutOperandList = (outs GPR32Opnd:$dst); + dag InOperandList = (ins GPR32Opnd:$rt, mem_mm_9:$addr); + string AsmString = !strconcat(opstr, "\t$rt, $addr"); + InstrItinClass Itinerary = itin; + string BaseOpcode = opstr; + bit mayStore = 1; + string Constraints = "$rt = $dst"; + string DecoderMethod = "DecodeMemMMImm9"; +} + +class LL_MMR6_DESC_BASE { + dag OutOperandList = (outs GPR32Opnd:$rt); + dag InOperandList = (ins mem_mm_9:$addr); + string AsmString = !strconcat(opstr, "\t$rt, $addr"); + InstrItinClass Itinerary = itin; + string BaseOpcode = opstr; + bit mayLoad = 1; + string DecoderMethod = "DecodeMemMMImm9"; +} + +class SC_MMR6_DESC : SC_MMR6_DESC_BASE<"sc", II_SC>; +class LL_MMR6_DESC : LL_MMR6_DESC_BASE<"ll", II_LL>; + /// Floating Point Instructions class FARITH_MMR6_DESC_BASE, ISA_MICROMIPS32_NOT_MIPS32R6; def TNEI_MM : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM_MM<0x0c>, ISA_MICROMIPS32_NOT_MIPS32R6; -} -let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { + /// Load-linked, Store-conditional - def LL_MM : LLBaseMM<"ll", GPR32Opnd>, LL_FM_MM<0x3>; - def SC_MM : SCBaseMM<"sc", GPR32Opnd>, LL_FM_MM<0xb>; -} -let DecoderNamespace = "MicroMips" in { + def LL_MM : LLBaseMM<"ll", GPR32Opnd>, LL_FM_MM<0x3>, + ISA_MICROMIPS32_NOT_MIPS32R6; + def SC_MM : SCBaseMM<"sc", GPR32Opnd>, LL_FM_MM<0xb>, + ISA_MICROMIPS32_NOT_MIPS32R6; + def LLE_MM : MMRel, LLEBaseMM<"lle", GPR32Opnd>, LLE_FM_MM<0x6>, ISA_MICROMIPS, ASE_EVA; def SCE_MM : MMRel, SCEBaseMM<"sce", GPR32Opnd>, LLE_FM_MM<0xA>, Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -1433,8 +1433,8 @@ if (Size == 4) { if (isMicroMips) { - LL = Mips::LL_MM; - SC = Mips::SC_MM; + LL = Subtarget.hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM; + SC = Subtarget.hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM; } else { LL = Subtarget.hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6) @@ -1580,8 +1580,8 @@ unsigned LL, SC; if (isMicroMips) { - LL = Mips::LL_MM; - SC = Mips::SC_MM; + LL = Subtarget.hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM; + SC = Subtarget.hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM; } else { LL = Subtarget.hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6) : (ArePtrs64bit ? Mips::LL64 : Mips::LL); @@ -1721,8 +1721,8 @@ if (Size == 4) { if (isMicroMips) { - LL = Mips::LL_MM; - SC = Mips::SC_MM; + LL = Subtarget.hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM; + SC = Subtarget.hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM; } else { LL = Subtarget.hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6) @@ -1835,8 +1835,8 @@ unsigned LL, SC; if (isMicroMips) { - LL = Mips::LL_MM; - SC = Mips::SC_MM; + LL = Subtarget.hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM; + SC = Subtarget.hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM; } else { LL = Subtarget.hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6) : (ArePtrs64bit ? Mips::LL64 : Mips::LL); Index: lib/Target/Mips/MipsSERegisterInfo.cpp =================================================================== --- lib/Target/Mips/MipsSERegisterInfo.cpp +++ lib/Target/Mips/MipsSERegisterInfo.cpp @@ -98,6 +98,8 @@ case Mips::SC64_R6: case Mips::SCD_R6: case Mips::SC_R6: + case Mips::LL_MMR6: + case Mips::SC_MMR6: return 9; case Mips::INLINEASM: { unsigned ConstraintID = InlineAsm::getMemoryConstraintID(MO.getImm()); Index: test/MC/Disassembler/Mips/micromips32r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -351,3 +351,7 @@ 0xf4 0x40 0x00 0x40 # CHECK: blezc $2, 260 0xf6 0x10 0x00 0x80 # CHECK: bgezc $16, 516 0xd5 0x80 0x01 0x00 # CHECK: bgtzc $12, 1028 +0x60 0x44 0x30 0x08 # CHECK: ll $2, 8($4) +0x60 0x44 0xb0 0x08 # CHECK: sc $2, 8($4) +0x60 0x44 0x6c 0x08 # CHECK: lle $2, 8($4) +0x60 0x44 0xac 0x08 # CHECK: sce $2, 8($4) Index: test/MC/Mips/micromips32r6/invalid-wrong-error.s =================================================================== --- test/MC/Mips/micromips32r6/invalid-wrong-error.s +++ test/MC/Mips/micromips32r6/invalid-wrong-error.s @@ -28,4 +28,7 @@ lwl $4, 1($5) # CHECK: :[[@LINE]]:11: error: invalid operand for instruction swr $4, 1($5) # CHECK: :[[@LINE]]:11: error: invalid operand for instruction swl $4, 1($5) # CHECK: :[[@LINE]]:11: error: invalid operand for instruction - + sc $4, 512($5) # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled + sc $4, -513($5) # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled + ll $4, 512($5) # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled + ll $4, -513($5) # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/micromips32r6/invalid.s =================================================================== --- test/MC/Mips/micromips32r6/invalid.s +++ test/MC/Mips/micromips32r6/invalid.s @@ -154,6 +154,10 @@ sra $3, 32 # CHECK: :[[@LINE]]:11: error: expected 5-bit unsigned immediate srl $3, -1 # CHECK: :[[@LINE]]:11: error: expected 5-bit unsigned immediate srl $3, 32 # CHECK: :[[@LINE]]:11: error: expected 5-bit unsigned immediate + ll $33, 8($5) # CHECK: :[[@LINE]]:6: error: invalid register number + ll $4, 8($33) # CHECK: :[[@LINE]]:12: error: invalid register number + ll $4, 512($5) # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled + ll $4, -513($5) # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled lle $33, 8($5) # CHECK: :[[@LINE]]:7: error: invalid register number lle $4, 8($33) # CHECK: :[[@LINE]]:13: error: invalid register number lle $4, 512($5) # CHECK: :[[@LINE]]:11: error: expected memory with 9-bit signed offset @@ -166,6 +170,10 @@ sbe $4, 8($33) # CHECK: :[[@LINE]]:13: error: invalid register number sbe $4, 512($5) # CHECK: :[[@LINE]]:11: error: expected memory with 9-bit signed offset sbe $4, -513($5) # CHECK: :[[@LINE]]:11: error: expected memory with 9-bit signed offset + sc $33, 8($5) # CHECK: :[[@LINE]]:6: error: invalid register number + sc $4, 8($33) # CHECK: :[[@LINE]]:12: error: invalid register number + sc $4, 512($5) # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled + sc $4, -513($5) # CHECK: :[[@LINE]]:3: error: instruction requires a CPU feature not currently enabled sce $33, 8($5) # CHECK: :[[@LINE]]:7: error: invalid register number sce $4, 8($33) # CHECK: :[[@LINE]]:13: error: invalid register number sce $4, 512($5) # CHECK: :[[@LINE]]:11: error: expected memory with 9-bit signed offset Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -74,6 +74,7 @@ lwm $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22] lwm16 $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22] ll $2, 8($4) # CHECK: ll $2, 8($4) # encoding: [0x60,0x44,0x30,0x08] + # CHECK-NEXT: #