Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1558,6 +1558,7 @@ if (Imm < 0 || Imm > 60 || (Imm % 4 != 0)) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::PREFX_MM: case Mips::CACHE: case Mips::PREF: Opnd = Inst.getOperand(2); Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -277,6 +277,11 @@ uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemMMImm9(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1279,6 +1284,24 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeMemMMImm9(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = SignExtend32<9>(Insn & 0x1ff); + unsigned Reg = fieldFromInstruction(Insn, 21, 5); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::CreateReg(Base)); + Inst.addOperand(MCOperand::CreateImm(Offset)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1328,7 +1351,6 @@ Inst.addOperand(MCOperand::CreateReg(Reg)); Inst.addOperand(MCOperand::CreateReg(Base)); Inst.addOperand(MCOperand::CreateImm(Offset)); - return MCDisassembler::Success; } Index: lib/Target/Mips/MicroMipsInstrFormats.td =================================================================== --- lib/Target/Mips/MicroMipsInstrFormats.td +++ lib/Target/Mips/MicroMipsInstrFormats.td @@ -389,6 +389,20 @@ let Inst{15-0} = addr{15-0}; } +class LHUE_FM_MM op, bits<4> fmt, bits<3> funct> : MMArch { + bits<5> rt; + bits<21> addr; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = rt; + let Inst{20-16} = addr{20-16}; + let Inst{15-12} = fmt; + let Inst{11-9} = funct; + let Inst{8-0} = addr{8-0}; +} + class LWL_FM_MM funct> { bits<5> rt; bits<21> addr; @@ -922,6 +936,21 @@ let Inst{11-0} = offset; } +class PREFX_FM_MM op, bits<9> funct> : MMArch { + bits<5> index; + bits<5> base; + bits<5> hint; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = index; + let Inst{20-16} = base; + let Inst{15-11} = hint; + let Inst{10-9} = 0x0; + let Inst{8-0} = funct; +} + class BARRIER_FM_MM op> : MMArch { bits<32> Inst; Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -105,6 +105,14 @@ let EncoderMethod = "getMemEncodingMMGPImm7Lsl2"; } +def mem_mm_9 : Operand { + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops GPR32, simm9); + let EncoderMethod = "getMemEncodingMMImm9"; + let ParserMatchClass = MipsMemAsmOperand; + let OperandType = "OPERAND_MEMORY"; +} + def mem_mm_12 : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops GPR32, simm12); @@ -475,6 +483,10 @@ InstSE<(outs RO:$rd), (ins PtrRC:$base, PtrRC:$index), !strconcat(opstr, "\t$rd, ${index}(${base})"), [], Itin, FrmFI>; +class PrefetchIndexed : + InstSE<(outs), (ins PtrRC:$base, PtrRC:$index, uimm5:$hint), + !strconcat(opstr, "\t$hint, ${index}(${base})"), [], NoItinerary, FrmOther>; + class AddImmUPC : InstSE<(outs RO:$rs), (ins simm23_lsl2:$imm), !strconcat(opstr, "\t$rs, $imm"), [], NoItinerary, FrmR>; @@ -701,6 +713,17 @@ def SW_MM : Store<"sw", GPR32Opnd>, MMRel, LW_FM_MM<0x3e>; } + let DecoderMethod = "DecodeMemMMImm9" in { + def LBE_MM : Load<"lbe", GPR32Opnd>, LHUE_FM_MM<0x18, 0x6, 0x4>; + def LBuE_MM : Load<"lbue", GPR32Opnd>, LHUE_FM_MM<0x18, 0x6, 0x0>; + def LHE_MM : Load<"lhe", GPR32Opnd>, LHUE_FM_MM<0x18, 0x6, 0x5>; + def LHuE_MM : Load<"lhue", GPR32Opnd>, LHUE_FM_MM<0x18, 0x6, 0x1>; + def LWE_MM : Load<"lwe", GPR32Opnd>, LHUE_FM_MM<0x18, 0x6, 0x7>; + def SBE_MM : Store<"sbe", GPR32Opnd>, LHUE_FM_MM<0x18, 0xa, 0x4>; + def SHE_MM : Store<"she", GPR32Opnd>, LHUE_FM_MM<0x18, 0xa, 0x5>; + def SWE_MM : Store<"swe", GPR32Opnd>, 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>; @@ -871,6 +894,8 @@ def SDBBP_MM : MMRel, SYS_FT<"sdbbp">, SDBBP_FM_MM; def RDHWR_MM : MMRel, ReadHardware, RDHWR_FM_MM; + + def PREFX_MM : PrefetchIndexed<"prefx">, PREFX_FM_MM<0x15, 0x1A0>; } let Predicates = [InMicroMips] in { Index: test/MC/Disassembler/Mips/micromips.txt =================================================================== --- test/MC/Disassembler/Mips/micromips.txt +++ test/MC/Disassembler/Mips/micromips.txt @@ -504,3 +504,30 @@ # CHECK: movep $5, $6, $2, $3 0x84 0x34 + +# CHECK: prefx 1, $3($5) +0x54 0x65 0x09 0xa0 + +# CHECK: lhue $4, 8($2) +0x60 0x82 0x62 0x08 + +# CHECK: lbe $4, 8($2) +0x60 0x82 0x68 0x08 + +# CHECK: lbue $4, 8($2) +0x60 0x82 0x60 0x08 + +# CHECK: lhe $4, 8($2) +0x60 0x82 0x6a 0x08 + +# CHECK: lwe $4, 8($2) +0x60 0x82 0x6e 0x08 + +# CHECK: sbe $5, 8($4) +0x60 0xa4 0xa8 0x08 + +# CHECK: she $5, 8($4) +0x60 0xa4 0xaa 0x08 + +# CHECK: swe $5, 8($4) +0x60 0xa4 0xae 0x08 Index: test/MC/Disassembler/Mips/micromips_le.txt =================================================================== --- test/MC/Disassembler/Mips/micromips_le.txt +++ test/MC/Disassembler/Mips/micromips_le.txt @@ -504,3 +504,30 @@ # CHECK: movep $5, $6, $2, $3 0x34 0x84 + +# CHECK: prefx 1, $3($5) +0x65 0x54 0xa0 0x09 + +# CHECK: lhue $4, 8($2) +0x82 0x60 0x08 0x62 + +# CHECK: lbe $4, 8($2) +0x82 0x60 0x08 0x68 + +# CHECK: lbue $4, 8($2) +0x82 0x60 0x08 0x60 + +# CHECK: lhe $4, 8($2) +0x82 0x60 0x08 0x6a + +# CHECK: lwe $4, 8($2) +0x82 0x60 0x08 0x6e + +# CHECK: sbe $5, 8($4) +0xa4 0x60 0x08 0xa8 + +# CHECK: she $5, 8($4) +0xa4 0x60 0x08 0xaa + +# CHECK: swe $5, 8($4) +0xa4 0x60 0x08 0xae Index: test/MC/Mips/micromips-control-instructions.s =================================================================== --- test/MC/Mips/micromips-control-instructions.s +++ test/MC/Mips/micromips-control-instructions.s @@ -39,6 +39,7 @@ # CHECK-EL: tlbr # encoding: [0x00,0x00,0x7c,0x13] # CHECK-EL: tlbwi # encoding: [0x00,0x00,0x7c,0x23] # CHECK-EL: tlbwr # encoding: [0x00,0x00,0x7c,0x33] +# CHECK-EL: prefx 1, $3($5) # encoding: [0x65,0x54,0xa0,0x09] #------------------------------------------------------------------------------ # Big endian #------------------------------------------------------------------------------ @@ -72,6 +73,7 @@ # CHECK-EB: tlbr # encoding: [0x00,0x00,0x13,0x7c] # CHECK-EB: tlbwi # encoding: [0x00,0x00,0x23,0x7c] # CHECK-EB: tlbwr # encoding: [0x00,0x00,0x33,0x7c] +# CHECK-EB: prefx 1, $3($5) # encoding: [0x54,0x65,0x09,0xa0] sdbbp sdbbp 34 @@ -100,3 +102,4 @@ tlbr tlbwi tlbwr + prefx 1, $3($5) Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -73,3 +73,4 @@ movep $8, $6, $2, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction movep $5, $6, $5, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction movep $5, $6, $2, $9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + prefx 33, $8($5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range Index: test/MC/Mips/micromips-loadstore-instructions.s =================================================================== --- test/MC/Mips/micromips-loadstore-instructions.s +++ test/MC/Mips/micromips-loadstore-instructions.s @@ -44,6 +44,14 @@ # CHECK-EL: swm32 $16, $17, 8($sp) # encoding: [0x5d,0x20,0x08,0xd0] # CHECK-EL: swp $16, 8($4) # encoding: [0x04,0x22,0x08,0x90] # CHECK-EL: lwp $16, 8($4) # encoding: [0x04,0x22,0x08,0x10] +# CHECK-EL: lhue $4, 8($2) # encoding: [0x82,0x60,0x08,0x62] +# CHECK-EL: lbe $4, 8($2) # encoding: [0x82,0x60,0x08,0x68] +# CHECK-EL: lbue $4, 8($2) # encoding: [0x82,0x60,0x08,0x60] +# CHECK-EL: lhe $4, 8($2) # encoding: [0x82,0x60,0x08,0x6a] +# CHECK-EL: lwe $4, 8($2) # encoding: [0x82,0x60,0x08,0x6e] +# CHECK-EL: sbe $5, 8($4) # encoding: [0xa4,0x60,0x08,0xa8] +# CHECK-EL: she $5, 8($4) # encoding: [0xa4,0x60,0x08,0xaa] +# CHECK-EL: swe $5, 8($4) # encoding: [0xa4,0x60,0x08,0xae] #------------------------------------------------------------------------------ # Big endian #------------------------------------------------------------------------------ @@ -82,6 +90,14 @@ # CHECK-EB: swm32 $16, $17, 8($sp) # encoding: [0x20,0x5d,0xd0,0x08] # CHECK-EB: swp $16, 8($4) # encoding: [0x22,0x04,0x90,0x08] # CHECK-EB: lwp $16, 8($4) # encoding: [0x22,0x04,0x10,0x08] +# CHECK-EB: lhue $4, 8($2) # encoding: [0x60,0x82,0x62,0x08] +# CHECK-EB: lbe $4, 8($2) # encoding: [0x60,0x82,0x68,0x08] +# CHECK-EB: lbue $4, 8($2) # encoding: [0x60,0x82,0x60,0x08] +# CHECK-EB: lhe $4, 8($2) # encoding: [0x60,0x82,0x6a,0x08] +# CHECK-EB: lwe $4, 8($2) # encoding: [0x60,0x82,0x6e,0x08] +# CHECK-EB: sbe $5, 8($4) # encoding: [0x60,0xa4,0xa8,0x08] +# CHECK-EB: she $5, 8($4) # encoding: [0x60,0xa4,0xaa,0x08] +# CHECK-EB: swe $5, 8($4) # encoding: [0x60,0xa4,0xae,0x08] lb $5, 8($4) lbu $6, 8($4) lh $2, 8($4) @@ -117,3 +133,11 @@ swm $16, $17, 8($sp) swp $16, 8($4) lwp $16, 8($4) + lhue $4, 8($2) + lbe $4, 8($2) + lbue $4, 8($2) + lhe $4, 8($2) + lwe $4, 8($2) + sbe $5, 8($4) + she $5, 8($4) + swe $5, 8($4) Index: test/MC/Mips/mips32r6/invalid-mips4-wrong-error.s =================================================================== --- test/MC/Mips/mips32r6/invalid-mips4-wrong-error.s +++ test/MC/Mips/mips32r6/invalid-mips4-wrong-error.s @@ -8,4 +8,3 @@ .set noat bc2tl 4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction bc2fl 4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction - prefx 0,$2($31) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction Index: test/MC/Mips/mips32r6/invalid-mips4.s =================================================================== --- test/MC/Mips/mips32r6/invalid-mips4.s +++ test/MC/Mips/mips32r6/invalid-mips4.s @@ -11,3 +11,4 @@ lwxc1 $f12,$s1($s8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled sdxc1 $f11,$10($14) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled swxc1 $f19,$12($k0) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + prefx 0,$2($31) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips64r6/invalid-mips4-wrong-error.s =================================================================== --- test/MC/Mips/mips64r6/invalid-mips4-wrong-error.s +++ test/MC/Mips/mips64r6/invalid-mips4-wrong-error.s @@ -8,4 +8,3 @@ .set noat bc2tl 4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction bc2fl 4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction - prefx 0,$2($31) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction Index: test/MC/Mips/mips64r6/invalid-mips4.s =================================================================== --- test/MC/Mips/mips64r6/invalid-mips4.s +++ test/MC/Mips/mips64r6/invalid-mips4.s @@ -14,3 +14,5 @@ lwxc1 $f12,$s1($s8) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled sdxc1 $f11,$10($14) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled swxc1 $f19,$12($k0) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + prefx 0,$2($31) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + \ No newline at end of file