Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -261,6 +261,11 @@ uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSynciR6(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -1163,6 +1168,21 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeSynciR6(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Immediate = SignExtend32<16>(Insn & 0xffff); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Immediate)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -124,6 +124,80 @@ let Inst{9-0} = funct; } +class PAUSE_FM_MMR6 op> : MMR6Arch { + bits<32> Inst; + + let Inst{31-26} = 0; + let Inst{25-21} = 0; + let Inst{20-16} = 0; + let Inst{15-11} = op; + let Inst{10-6} = 0; + let Inst{5-0} = 0; +} + +class READ_REGISTER_FM_MMR6 funct> { + bits<5> rt; + bits<5> rd; + bits<32> Inst; + + let Inst{31-26} = 0; + let Inst{25-21} = rt; + let Inst{20-16} = rd; + let Inst{15-6} = funct; + let Inst{5-0} = 0b111100; +} + +class POOL32A_RDHWR_FM_MMR6 { + bits<5> rt; + bits<5> rs; + bits<3> sel; + bits<32> Inst; + + let Inst{31-26} = 0; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-14} = 0; + let Inst{13-11} = sel; + let Inst{10} = 0; + let Inst{9-0} = 0b0111000000; +} + +class SYNC_FM_MMR6 { + bits<5> stype; + + bits<32> Inst; + + let Inst{31-26} = 0; + let Inst{25-21} = 0; + let Inst{20-16} = stype; + let Inst{15-6} = 0b0110101101; + let Inst{5-0} = 0b111100; +} + +class SYNCI_FM_MMR6 { + bits<21> addr; + bits<5> base = addr{20-16}; + bits<16> immediate = addr{15-0}; + + bits<32> Inst; + + let Inst{31-26} = 0b010000; + let Inst{25-21} = 0b01100; + let Inst{20-16} = base; + let Inst{15-0} = immediate; +} + +class SDBBP_FM_MMR6 { + bits<10> code_; + + bits<32> Inst; + + let Inst{31-26} = 0; + let Inst{25-16} = code_; + let Inst{15-6} = 0b1101101101; + let Inst{5-0} = 0b111100; +} + class POOL32A_2R_FM_MMR6 funct> : MipsR6Inst { bits<5> rs; bits<5> rt; Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -68,6 +68,14 @@ class SUBU_MMR6_ENC : ARITH_FM_MMR6<"subu", 0x1d0>; class SW_MMR6_ENC : SW32_FM_MMR6<"sw", 0x3e>; class SWE_MMR6_ENC : POOL32C_SWE_FM_MMR6<"swe", 0x18, 0xa, 0x7>; +class PAUSE_MMR6_ENC : PAUSE_FM_MMR6<"pause", 0b00101>; +class RDHWR_MMR6_ENC : POOL32A_RDHWR_FM_MMR6; +class WAIT_MMR6_ENC : WAIT_FM_MM, MMR6Arch<"wait">; +class SSNOP_MMR6_ENC : BARRIER_FM_MM<0x1>, MMR6Arch<"ssnop">; +class SYNC_MMR6_ENC : SYNC_FM_MMR6; +class SYNCI_MMR6_ENC : SYNCI_FM_MMR6, MMR6Arch<"synci">; +class RDPGPR_MMR6_ENC : READ_REGISTER_FM_MMR6<0b1110000101>; +class SDBBP_MMR6_ENC : SDBBP_FM_MM, MMR6Arch<"sdbbp">; class XOR_MMR6_ENC : ARITH_FM_MMR6<"xor", 0x310>; class XORI_MMR6_ENC : ADDI_FM_MMR6<"xori", 0x1c>; @@ -286,6 +294,20 @@ class SELEQZ_MMR6_DESC : SELEQNE_Z_MMR6_DESC_BASE<"seleqz", GPR32Opnd>; class SELNEZ_MMR6_DESC : SELEQNE_Z_MMR6_DESC_BASE<"selnez", GPR32Opnd>; +class PAUSE_MMR6_DESC : Barrier<"pause">; +class RDHWR_MMR6_DESC_BASE : MMR6Arch<"rdhwr">, MipsR6Inst { + dag OutOperandList = (outs CPURegOperand:$rt); + dag InOperandList = (ins RO:$rs, ImmOpnd:$sel); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sel"); + list Pattern = []; + InstrItinClass Itinerary = II_RDHWR; + Format Form = FrmR; +} +class RDHWR_MMR6_DESC : RDHWR_MMR6_DESC_BASE<"rdhwr", GPR32Opnd, HWRegsOpnd, + uimm3>; +class WAIT_MMR6_DESC : WaitMM<"wait">; +class SSNOP_MMR6_DESC : Barrier<"ssnop">; class SLL_MMR6_DESC : shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL>; class DIV_MMR6_DESC : ArithLogicR<"div", GPR32Opnd>; class DIVU_MMR6_DESC : ArithLogicR<"divu", GPR32Opnd>; @@ -311,6 +333,36 @@ class SW_MMR6_DESC : Store<"sw", GPR32Opnd>; class SWE_MMR6_DESC : SWE_MMR6_DESC_BASE<"swe", GPR32Opnd, mem_simm9gpr>; +class SYNC_MMR6_DESC_BASE : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs); + dag InOperandList = (ins i32imm:$stype); + string AsmString = !strconcat(instr_asm, "\t$stype"); + list Pattern = [(MipsSync imm:$stype)]; + InstrItinClass Itinerary = NoItinerary; + bit HasSideEffects = 1; +} +class SYNC_MMR6_DESC : SYNC_MMR6_DESC_BASE<"sync">; + +class SYNCI_MMR6_DESC_BASE : SYNCI_FT { + let DecoderMethod = "DecodeSynciR6"; +} +class SYNCI_MMR6_DESC : SYNCI_MMR6_DESC_BASE<"synci">; + +class RDPGPR_MMR6_DESC_BASE : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs GPROpnd:$rt); + dag InOperandList = (ins GPROpnd:$rd); + string AsmString = !strconcat(instr_asm, "\t$rt, $rd"); +} +class RDPGPR_MMR6_DESC : RDPGPR_MMR6_DESC_BASE<"rdpgpr", GPR32Opnd>; + +class SDBBP_MMR6_DESC_BASE : MipsR6Inst { + dag OutOperandList = (outs); + dag InOperandList = (ins uimm20:$code_); + string AsmString = !strconcat(instr_asm, "\t$code_"); + list Pattern = []; +} +class SDBBP_MMR6_DESC : SDBBP_MMR6_DESC_BASE<"sdbbp">; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -380,6 +432,14 @@ def SLL_MMR6 : StdMMR6Rel, SLL_MMR6_DESC, SLL_MMR6_ENC, ISA_MICROMIPS32R6; def SUB_MMR6 : StdMMR6Rel, SUB_MMR6_DESC, SUB_MMR6_ENC, ISA_MICROMIPS32R6; def SUBU_MMR6 : StdMMR6Rel, SUBU_MMR6_DESC, SUBU_MMR6_ENC, ISA_MICROMIPS32R6; +def PAUSE_MMR6 : StdMMR6Rel, PAUSE_MMR6_DESC, PAUSE_MMR6_ENC, ISA_MICROMIPS32R6; +def RDHWR_MMR6 : R6MMR6Rel, RDHWR_MMR6_DESC, RDHWR_MMR6_ENC, ISA_MICROMIPS32R6; +def WAIT_MMR6 : StdMMR6Rel, WAIT_MMR6_DESC, WAIT_MMR6_ENC, ISA_MICROMIPS32R6; +def SSNOP_MMR6 : StdMMR6Rel, SSNOP_MMR6_DESC, SSNOP_MMR6_ENC, ISA_MICROMIPS32R6; +def SYNC_MMR6 : StdMMR6Rel, SYNC_MMR6_DESC, SYNC_MMR6_ENC, ISA_MICROMIPS32R6; +def SYNCI_MMR6 : StdMMR6Rel, SYNCI_MMR6_DESC, SYNCI_MMR6_ENC, ISA_MICROMIPS32R6; +def RDPGPR_MMR6 : R6MMR6Rel, RDPGPR_MMR6_DESC, RDPGPR_MMR6_ENC, ISA_MICROMIPS32R6; +def SDBBP_MMR6 : R6MMR6Rel, SDBBP_MMR6_DESC, SDBBP_MMR6_ENC, ISA_MICROMIPS32R6; def XOR_MMR6 : StdMMR6Rel, XOR_MMR6_DESC, XOR_MMR6_ENC, ISA_MICROMIPS32R6; def XORI_MMR6 : StdMMR6Rel, XORI_MMR6_DESC, XORI_MMR6_ENC, ISA_MICROMIPS32R6; let DecoderMethod = "DecodeMemMMImm16" in { @@ -398,3 +458,7 @@ def : MipsInstAlias<"ei", (EI_MMR6 ZERO), 1>, ISA_MICROMIPS32R6; def : MipsInstAlias<"nop", (SLL_MMR6 ZERO, ZERO, 0), 1>, ISA_MICROMIPS32R6; +def : MipsInstAlias<"sync", (SYNC_MMR6 0), 1>, ISA_MICROMIPS32R6; +def : MipsInstAlias<"sdbbp", (SDBBP_MMR6 0), 1>, ISA_MICROMIPS32R6; +def : MipsInstAlias<"rdhwr $rt, $rs", + (RDHWR_MMR6 GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MICROMIPS32R6; Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -867,10 +867,13 @@ def TLBP_MM : MMRel, TLB<"tlbp">, COP0_TLB_FM_MM<0x0d>; def TLBR_MM : MMRel, TLB<"tlbr">, COP0_TLB_FM_MM<0x4d>; def TLBWI_MM : MMRel, TLB<"tlbwi">, COP0_TLB_FM_MM<0x8d>; - def TLBWR_MM : MMRel, TLB<"tlbwr">, COP0_TLB_FM_MM<0xcd>; - + def TLBWR_MM : MMRel, StdMMR6Rel, TLB<"tlbwr">, COP0_TLB_FM_MM<0xcd>; def SDBBP_MM : MMRel, SYS_FT<"sdbbp">, SDBBP_FM_MM; - def RDHWR_MM : MMRel, ReadHardware, RDHWR_FM_MM; +} + +let DecoderNamespace = "MicroMips" in { + def RDHWR_MM : MMRel, R6MMR6Rel, ReadHardware, + RDHWR_FM_MM, ISA_MICROMIPS32R2; } let Predicates = [InMicroMips] in { Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -725,7 +725,9 @@ def RINT_D : RINT_D_ENC, RINT_D_DESC, ISA_MIPS32R6, HARDFLOAT; def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6, HARDFLOAT; def SC_R6 : SC_R6_ENC, SC_R6_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { def SDBBP_R6 : SDBBP_R6_ENC, SDBBP_R6_DESC, ISA_MIPS32R6; +} def SDC2_R6 : SDC2_R6_ENC, SDC2_R6_DESC, ISA_MIPS32R6; def SELEQZ : R6MMR6Rel, SELEQZ_ENC, SELEQZ_DESC, ISA_MIPS32R6, GPR_32; def SELEQZ_D : SELEQZ_D_ENC, SELEQZ_D_DESC, ISA_MIPS32R6, HARDFLOAT; @@ -743,7 +745,9 @@ // //===----------------------------------------------------------------------===// +let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"sdbbp", (SDBBP_R6 0)>, ISA_MIPS32R6; +} def : MipsInstAlias<"jr $rs", (JALR ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS32R6; //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -261,6 +261,9 @@ class ISA_MICROMIPS64R6 { list InsnPredicates = [HasMicroMips64r6]; } +class ISA_MICROMIPS32R2 { + list InsnPredicates = [InMicroMips, NotMips32r6]; +} // The portions of MIPS-III that were also added to MIPS32 class INSN_MIPS3_32 { list InsnPredicates = [HasMips3_32]; } @@ -1268,8 +1271,8 @@ } } -def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32; -def SYNCI : MMRel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2; +def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32; +def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2; def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2; def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2; @@ -1495,9 +1498,9 @@ 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; def PseudoUDIV : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; - +let AdditionalPredicates = [NotInMicroMips] in { def RDHWR : MMRel, ReadHardware, RDHWR_FM; - +} def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>; def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>; @@ -1509,9 +1512,9 @@ class Barrier : InstSE<(outs), (ins), asmstr, [], NoItinerary, FrmOther, asmstr>; -def SSNOP : MMRel, Barrier<"ssnop">, BARRIER_FM<1>; +def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop">, BARRIER_FM<1>; def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>; -def PAUSE : MMRel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2; +def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2; // JR_HB and JALR_HB are defined here using the new style naming // scheme because some of this code is shared with Mips32r6InstrInfo.td Index: test/MC/Disassembler/Mips/micromips32r6.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6.txt +++ test/MC/Disassembler/Mips/micromips32r6.txt @@ -122,6 +122,30 @@ 0x00 0xa4 0x19 0xd0 # CHECK: subu $3, $4, $5 +0x00 0x00 0x28 0x00 # CHECK: pause + +0x00 0xbd 0x11 0xc0 # CHECK: rdhwr $5, $29, 2 + +0x00 0xbd 0x01 0xc0 # CHECK: rdhwr $5, $29 + +0x00 0x00 0x93 0x7c # CHECK: wait + +0x00 0x11 0x93 0x7c # CHECK: wait 17 + +0x00 0x00 0x08 0x00 # CHECK: ssnop + +0x00 0x00 0x6b 0x7c # CHECK: sync + +0x00 0x11 0x6b 0x7c # CHECK: sync 17 + +0x41 0x85 0x00 0x08 # CHECK: synci 8($5) + +0x00 0x69 0xe1 0x7c # CHECK: rdpgpr $3, $9 + +0x00 0x00 0xdb 0x7c # CHECK: sdbbp + +0x00 0x22 0xdb 0x7c # CHECK: sdbbp 34 + 0x00 0xa4 0x1b 0x10 # CHECK: xor $3, $4, $5 0x70 0x64 0x04 0xd2 # CHECK: xori $3, $4, 1234 Index: test/MC/Mips/micromips-control-instructions.s =================================================================== --- test/MC/Mips/micromips-control-instructions.s +++ test/MC/Mips/micromips-control-instructions.s @@ -11,10 +11,7 @@ #------------------------------------------------------------------------------ # CHECK-EL: sdbbp # encoding: [0x00,0x00,0x7c,0xdb] # CHECK-EL: sdbbp 34 # encoding: [0x22,0x00,0x7c,0xdb] -# CHECK-EL: .set push -# CHECK-EL: .set mips32r2 -# CHECK-EL: rdhwr $5, $29 -# CHECK-EL: .set pop # encoding: [0xbd,0x00,0x3c,0x6b] +# CHECK-EL: rdhwr $5, $29 # encoding: [0xbd,0x00,0x3c,0x6b] # 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,0x00,0x08] @@ -44,10 +41,7 @@ #------------------------------------------------------------------------------ # CHECK-EB: sdbbp # encoding: [0x00,0x00,0xdb,0x7c] # CHECK-EB: sdbbp 34 # encoding: [0x00,0x22,0xdb,0x7c] -# CHECK-EB: .set push -# CHECK-EB: .set mips32r2 -# CHECK-EB: rdhwr $5, $29 -# CHECK-EB: .set pop # encoding: [0x00,0xbd,0x6b,0x3c] +# CHECK-EB: rdhwr $5, $29 # encoding: [0x00,0xbd,0x6b,0x3c] # 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,0x08,0x00] Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -65,6 +65,19 @@ sll $4, $3, 7 # CHECK: sll $4, $3, 7 # encoding: [0x00,0x83,0x38,0x00] sub $3, $4, $5 # CHECK: sub $3, $4, $5 # encoding: [0x00,0xa4,0x19,0x90] subu $3, $4, $5 # CHECK: subu $3, $4, $5 # encoding: [0x00,0xa4,0x19,0xd0] + pause # CHECK: pause # encoding: [0x00,0x00,0x28,0x00] + rdhwr $5, $29, 2 # CHECK: rdhwr $5, $29, 2 # encoding: [0x00,0xbd,0x11,0xc0] + rdhwr $5, $29, 0 # CHECK: rdhwr $5, $29 # encoding: [0x00,0xbd,0x01,0xc0] + rdhwr $5, $29 # CHECK: rdhwr $5, $29 # encoding: [0x00,0xbd,0x01,0xc0] + wait # CHECK: wait # encoding: [0x00,0x00,0x93,0x7c] + wait 17 # CHECK: wait 17 # encoding: [0x00,0x11,0x93,0x7c] + ssnop # CHECK: ssnop # encoding: [0x00,0x00,0x08,0x00] + sync # CHECK: sync # encoding: [0x00,0x00,0x6b,0x7c] + sync 17 # CHECK: sync 17 # encoding: [0x00,0x11,0x6b,0x7c] + synci 8($5) # CHECK: synci 8($5) # encoding: [0x41,0x85,0x00,0x08] + rdpgpr $3, $9 # CHECK: $3, $9 # encoding: [0x00,0x69,0xe1,0x7c] + sdbbp # CHECK: sdbbp # encoding: [0x00,0x00,0xdb,0x7c] + sdbbp 34 # CHECK: sdbbp 34 # encoding: [0x00,0x22,0xdb,0x7c] xor $3, $4, $5 # CHECK: xor $3, $4, $5 # encoding: [0x00,0xa4,0x1b,0x10] xori $3, $4, 1234 # CHECK: xori $3, $4, 1234 # encoding: [0x70,0x64,0x04,0xd2] sw $5, 4($6) # CHECK: sw $5, 4($6) # encoding: [0xf8,0xa6,0x00,0x04]