Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1181,6 +1181,15 @@ Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535)) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::CACHE: + case Mips::PREF: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + UImm = Opnd.getImm(); + if (!isIntN(5, UImm)) + return Error(IDLoc, "immediate operand value out of range"); + break; } } Index: lib/Target/Mips/MicroMipsInstrFormats.td =================================================================== --- lib/Target/Mips/MicroMipsInstrFormats.td +++ lib/Target/Mips/MicroMipsInstrFormats.td @@ -768,3 +768,29 @@ let Inst{20-16} = rs; let Inst{15-0} = offset; } + +class CACHE_PREF_FM_MM op, bits<4> funct> : MMArch { + bits<21> addr; + bits<5> hint; + bits<5> base = addr{20-16}; + bits<12> offset = addr{11-0}; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = hint; + let Inst{20-16} = base; + let Inst{15-12} = funct; + let Inst{11-0} = offset; +} + +class BARRIER_FM_MM op> : MMArch { + bits<32> Inst; + + let Inst{31-26} = 0x0; + let Inst{25-21} = 0x0; + let Inst{20-16} = 0x0; + let Inst{15-11} = op; + let Inst{10-6} = 0x0; + let Inst{5-0} = 0x0; +} Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -550,6 +550,14 @@ /// Load-linked, Store-conditional def LL_MM : LLBaseMM<"ll", GPR32Opnd>, LL_FM_MM<0x3>; def SC_MM : SCBaseMM<"sc", GPR32Opnd>, LL_FM_MM<0xb>; + + def CACHE_MM : MMRel, CacheOp<"cache", mem_mm_12, GPR32Opnd>, + CACHE_PREF_FM_MM<0x08, 0x6>; + def PREF_MM : MMRel, CacheOp<"pref", mem_mm_12, GPR32Opnd>, + CACHE_PREF_FM_MM<0x18, 0x2>; + def SSNOP_MM : MMRel, Barrier<"ssnop">, BARRIER_FM_MM<0x1>; + def EHB_MM : MMRel, Barrier<"ehb">, BARRIER_FM_MM<0x2>; + def PAUSE_MM : MMRel, Barrier<"pause">, BARRIER_FM_MM<0x5>; } //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -1417,11 +1417,12 @@ class CacheOp : InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint), - !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther>; + !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther, + instr_asm>; -def CACHE : CacheOp<"cache", mem, GPR32Opnd>, CACHEOP_FM<0b101111>, +def CACHE : MMRel, CacheOp<"cache", mem, GPR32Opnd>, CACHEOP_FM<0b101111>, INSN_MIPS3_32_NOT_32R6_64R6; -def PREF : CacheOp<"pref", mem, GPR32Opnd>, CACHEOP_FM<0b110011>, +def PREF : MMRel, CacheOp<"pref", mem, GPR32Opnd>, CACHEOP_FM<0b110011>, INSN_MIPS3_32_NOT_32R6_64R6; //===----------------------------------------------------------------------===// Index: test/MC/Mips/micromips-control-instructions.s =================================================================== --- test/MC/Mips/micromips-control-instructions.s +++ test/MC/Mips/micromips-control-instructions.s @@ -9,6 +9,11 @@ #------------------------------------------------------------------------------ # Little endian #------------------------------------------------------------------------------ +# CHECK-EL: cache 1, 8($5) # encoding: [0x25,0x20,0x08,0x60] +# CHECK-EL: pref 1, 8($5) # encoding: [0x25,0x60,0x08,0x20] +# CHECK-EL: ssnop # encoding: [0x00,0x00,0x40,0x00] +# CHECK-EL: ehb # encoding: [0x00,0x00,0xc0,0x00] +# CHECK-EL: pause # encoding: [0x00,0x00,0x40,0x01] # CHECK-EL: break # encoding: [0x00,0x00,0x07,0x00] # CHECK-EL: break 7 # encoding: [0x07,0x00,0x07,0x00] # CHECK-EL: break 7, 5 # encoding: [0x07,0x00,0x47,0x01] @@ -27,6 +32,11 @@ #------------------------------------------------------------------------------ # Big endian #------------------------------------------------------------------------------ +# CHECK-EB: cache 1, 8($5) # encoding: [0x20,0x25,0x60,0x08] +# CHECK-EB: pref 1, 8($5) # encoding: [0x60,0x25,0x20,0x08] +# CHECK-EB: ssnop # encoding: [0x00,0x00,0x00,0x40] +# CHECK-EB: ehb # encoding: [0x00,0x00,0x00,0xc0] +# CHECK-EB: pause # encoding: [0x00,0x00,0x01,0x40] # CHECK-EB: break # encoding: [0x00,0x00,0x00,0x07] # CHECK-EB: break 7 # encoding: [0x00,0x07,0x00,0x07] # CHECK-EB: break 7, 5 # encoding: [0x00,0x07,0x01,0x47] @@ -43,6 +53,11 @@ # CHECK-EB: wait # encoding: [0x00,0x00,0x93,0x7c] # CHECK-EB: wait 17 # encoding: [0x00,0x11,0x93,0x7c] + cache 1, 8($5) + pref 1, 8($5) + ssnop + ehb + pause break break 7 break 7,5 Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -29,3 +29,5 @@ addiur1sp $7, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range addiur2 $9, $7, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction addiur2 $6, $7, 10 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + cache 256, 8($5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + pref 256, 8($5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range