Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1107,6 +1107,11 @@ } template bool isScaledSImm() const { + // Operand can also be symbol in case of relocations. + // In this case we should just ignore checking of integer value. + if (isa(getImm())) { + return true; + } return isConstantImm() && isShiftedInt(getConstantImm()); } @@ -3790,6 +3795,9 @@ case Match_SImm16_Relaxed: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 16-bit signed immediate"); + case Match_SImm19_Lsl2: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected both 19-bit signed immediate and multiple of 4"); case Match_UImm20_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 20-bit unsigned immediate"); Index: lib/Target/Mips/MicroMips64r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrFormats.td +++ lib/Target/Mips/MicroMips64r6InstrFormats.td @@ -185,3 +185,46 @@ let Inst{10-9} = 0b00; let Inst{8-0} = funct; } + +class POOL32A_2R_FM_MM64R6 { + bits<5> rt; + bits<5> rd; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rt; + let Inst{20-16} = rd; + let Inst{15-12} = 0b0000; + let Inst{11-6} = 0b101100; + let Inst{5-0} = 0b111100; +} + +class POOL32S_3RSA_FM_MMR6 { + bits<5> rt; + bits<5> rs; + bits<5> rd; + bits<2> imm; + + 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} = imm; + let Inst{8-6} = 0b100; + let Inst{5-0} = 0b000100; +} + +class PCREL_1ROFFSET19_FM_MMR6 { + bits<5> rt; + bits<19> offset; + + bits<32> Inst; + + let Inst{31-26} = 0b011110; + let Inst{25-21} = rt; + let Inst{20-19} = 0b10; + let Inst{18-0} = offset; +} Index: lib/Target/Mips/MicroMips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrInfo.td +++ lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -55,6 +55,9 @@ class DSRAV_MM64R6_ENC : POOL32S_3R_FM_MMR6<0b010010000>; class DSRA_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b010000000>; class DSRA32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b010000100>; +class DBITSWAP_MM64R6_ENC : POOL32A_2R_FM_MM64R6; +class DLSA_MM64R6_ENC : POOL32S_3RSA_FM_MMR6; +class LWUPC_MM64R6_ENC : PCREL_1ROFFSET19_FM_MMR6; //===----------------------------------------------------------------------===// // @@ -242,6 +245,27 @@ class DSRA32_MM64R6_DESC : DSRA_DSRA32_MM64R6_DESC_BASE<"dsra32", uimm5, GPR64Opnd, II_DSRA32>; +class DBITSWAP_MM64R6_DESC : MMR6Arch<"dbitswap">, MipsR6Inst { + dag OutOperandList = (outs GPR64Opnd:$rd); + dag InOperandList = (ins GPR64Opnd:$rt); + string AsmString = !strconcat("dbitswap", "\t$rd, $rt"); + list Pattern = []; +} + +class DLSA_MM64R6_DESC : MMR6Arch<"dlsa">, MipsR6Inst { + dag OutOperandList = (outs GPR64Opnd:$rd); + dag InOperandList = (ins GPR64Opnd:$rt, GPR64Opnd:$rs, uimm2_plus1:$imm); + string AsmString = "dlsa\t$rt, $rs, $rd, $imm"; + list Pattern = []; +} + +class LWUPC_MM64R6_DESC : MMR6Arch<"lwupc">, MipsR6Inst { + dag OutOperandList = (outs GPR64Opnd:$rt); + dag InOperandList = (ins simm19_lsl2:$offset); + string AsmString = "lwupc\t$rt, $offset"; + list Pattern = []; +} + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -322,6 +346,12 @@ ISA_MICROMIPS64R6; def DSRA32_MM64R6 : R6MMR6Rel, DSRA32_MM64R6_DESC, DSRA32_MM64R6_ENC, ISA_MICROMIPS64R6; + def DBITSWAP_MM64R6 : R6MMR6Rel, DBITSWAP_MM64R6_DESC, DBITSWAP_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DLSA_MM64R6 : R6MMR6Rel, DLSA_MM64R6_DESC, DLSA_MM64R6_ENC, + ISA_MICROMIPS64R6; + def LWUPC_MM64R6 : R6MMR6Rel, LWUPC_MM64R6_DESC, LWUPC_MM64R6_ENC, + ISA_MICROMIPS64R6; } //===----------------------------------------------------------------------===// Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -766,7 +766,9 @@ def LSA_R6 : R6MMR6Rel, LSA_R6_ENC, LSA_R6_DESC, ISA_MIPS32R6; def LWC2_R6 : LWC2_R6_ENC, LWC2_R6_DESC, ISA_MIPS32R6; def LWPC : R6MMR6Rel, LWPC_ENC, LWPC_DESC, ISA_MIPS32R6; -def LWUPC : LWUPC_ENC, LWUPC_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def LWUPC : LWUPC_ENC, LWUPC_DESC, ISA_MIPS32R6; +} let AdditionalPredicates = [NotInMicroMips] in { def MADDF_S : MADDF_S_ENC, MADDF_S_DESC, ISA_MIPS32R6, HARDFLOAT; def MADDF_D : MADDF_D_ENC, MADDF_D_DESC, ISA_MIPS32R6, HARDFLOAT; Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -99,8 +99,9 @@ def DAHI : DAHI_ENC, DAHI_DESC, ISA_MIPS64R6; def DAUI : DAUI_ENC, DAUI_DESC, ISA_MIPS64R6; def DALIGN : DALIGN_ENC, DALIGN_DESC, ISA_MIPS64R6; + def DBITSWAP : DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6; + def DLSA_R6 : DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6; } -def DBITSWAP : DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6; def DCLO_R6 : DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6; def DCLZ_R6 : DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6; let AdditionalPredicates = [NotInMicroMips] in { @@ -109,7 +110,6 @@ def DMOD : DMOD_ENC, DMOD_DESC, ISA_MIPS64R6; def DMODU : DMODU_ENC, DMODU_DESC, ISA_MIPS64R6; } -def DLSA_R6 : DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6; let AdditionalPredicates = [NotInMicroMips] in { def DMUH: DMUH_ENC, DMUH_DESC, ISA_MIPS64R6; def DMUHU: DMUHU_ENC, DMUHU_DESC, ISA_MIPS64R6; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -406,6 +406,16 @@ let DiagnosticType = "SImm" # Bits # "_" # Offset; } +class MipsJumpTargetAsmOperandClass Supers = [], + int Shift = 0> : AsmOperandClass { + let Name = "JumpTarget" # Bits # "_" # Shift; + let RenderMethod = "addImmOperands"; + let ParserMethod = "parseJumpTarget"; + let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">"; + let SuperClasses = Supers; + let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift; +} + class ConstantUImmAsmOperandClass Supers = [], int Offset = 0> : AsmOperandClass { let Name = "ConstantUImm" # Bits # "_" # Offset; @@ -478,6 +488,13 @@ : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>; def ConstantUImm20AsmOperandClass : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>; +def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass { + let Name = "SImm19Lsl2"; + let RenderMethod = "addImmOperands"; + let PredicateMethod = "isScaledSImm<19, 2>"; + let SuperClasses = [ConstantUImm20AsmOperandClass]; + let DiagnosticType = "SImm19_Lsl2"; +} def UImm16RelaxedAsmOperandClass : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> { let Name = "UImm16_Relaxed"; @@ -604,6 +621,10 @@ let DiagnosticType = "Immz"; } +def MipsJumpTarget19Lsl2AsmOperand + : MipsJumpTargetAsmOperandClass<19, [], 2>; + + def MipsJumpTargetAsmOperand : AsmOperandClass { let Name = "JumpTarget"; let ParserMethod = "parseJumpTarget"; @@ -638,7 +659,7 @@ def simm19_lsl2 : Operand { let EncoderMethod = "getSimm19Lsl2Encoding"; let DecoderMethod = "DecodeSimm19Lsl2"; - let ParserMatchClass = MipsJumpTargetAsmOperand; + let ParserMatchClass = MipsJumpTarget19Lsl2AsmOperand; } def simm18_lsl3 : Operand { Index: test/MC/Disassembler/Mips/micromips64r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -273,3 +273,7 @@ 0x41 0x3f 0x00 0x02 # CHECK: bc1nezc $f31, 4 0x41 0x5f 0x00 0x04 # CHECK: bc2eqzc $31, 8 0x41 0x7f 0x00 0x04 # CHECK: bc2nezc $31, 8 +0x10 0x64 0x01 0x00 # CHECK: aui $3, $4, 256 +0x58 0x83 0x0b 0x3c # CHECK: dbitswap $3, $4 +0x58 0x64 0x2d 0x04 # CHECK: dlsa $3, $4, $5, 3 +0x78 0x50 0x00 0x43 # CHECK: lwupc $2, 268 Index: test/MC/Mips/micromips64r6/invalid.s =================================================================== --- test/MC/Mips/micromips64r6/invalid.s +++ test/MC/Mips/micromips64r6/invalid.s @@ -274,3 +274,11 @@ bc2nezc $31, -65537 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range bc2nezc $31, 65535 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch to misaligned address bc2nezc $31, 65536 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range + dlsa $3, $4, $5, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected immediate in range 1 .. 4 + dlsa $3, $4, $5, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected immediate in range 1 .. 4 + dlsa $3, $4, $5, 0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected immediate in range 1 .. 4 + lwupc $2, 262145 # CHECK: :[[@LINE]]:13: error: expected both 19-bit signed immediate and multiple of 4 + lwupc $2, 5 # CHECK: :[[@LINE]]:13: error: expected both 19-bit signed immediate and multiple of 4 + lwupc $2, -262145 # CHECK: :[[@LINE]]:13: error: expected both 19-bit signed immediate and multiple of 4 + aui $3, $4, 32768 # CHECK: :[[@LINE]]:15: error: expected 16-bit signed immediate + aui $3, $4, -32769 # CHECK: :[[@LINE]]:15: error: expected 16-bit signed immediate Index: test/MC/Mips/micromips64r6/valid.s =================================================================== --- test/MC/Mips/micromips64r6/valid.s +++ test/MC/Mips/micromips64r6/valid.s @@ -277,5 +277,9 @@ bc1nezc $f31, 4 # CHECK: bc1nezc $f31, 4 # encoding: [0x41,0x3f,0x00,0x02] bc2eqzc $31, 8 # CHECK: bc2eqzc $31, 8 # encoding: [0x41,0x5f,0x00,0x04] bc2nezc $31, 8 # CHECK: bc2nezc $31, 8 # encoding: [0x41,0x7f,0x00,0x04] + aui $3, $4, 256 # CHECK: aui $3, $4, 256 # encoding: [0x10,0x64,0x01,0x00] + dbitswap $3, $4 # CHECK: dbitswap $3, $4 # encoding: [0x58,0x83,0x0b,0x3c] + dlsa $3, $4, $5, 3 # CHECK: dlsa $3, $4, $5, 3 # encoding: [0x58,0x64,0x2d,0x04] + lwupc $2, 268 # CHECK: lwupc $2, 268 # encoding: [0x78,0x50,0x00,0x43] 1: