Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -256,3 +256,17 @@ let Inst{5-0} = 0x3c; } +class SHIFT_MMR6_ENC funct, bit rotate> : MMR6Arch { + bits<5> rd; + bits<5> rt; + bits<5> shamt; + + bits<32> Inst; + + let Inst{31-26} = 0; + let Inst{25-21} = rd; + let Inst{20-16} = rt; + let Inst{15-11} = shamt; + let Inst{10} = rotate; + let Inst{9-0} = funct; +} Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -60,6 +60,7 @@ class SEH_MMR6_ENC : SIGN_EXTEND_FM_MMR6<"seh", 0b0011101100>; class SELEQZ_MMR6_ENC : POOL32A_FM_MMR6<0b0101000000>; class SELNEZ_MMR6_ENC : POOL32A_FM_MMR6<0b0110000000>; +class SLL_MMR6_ENC : SHIFT_MMR6_ENC<"sll", 0x00, 0b0>; class SUB_MMR6_ENC : ARITH_FM_MMR6<"sub", 0x190>; class SUBU_MMR6_ENC : ARITH_FM_MMR6<"subu", 0x1d0>; class XOR_MMR6_ENC : ARITH_FM_MMR6<"xor", 0x310>; @@ -262,6 +263,7 @@ class SELEQZ_MMR6_DESC : SELEQNE_Z_MMR6_DESC_BASE<"seleqz", GPR32Opnd>; class SELNEZ_MMR6_DESC : SELEQNE_Z_MMR6_DESC_BASE<"selnez", GPR32Opnd>; +class SLL_MMR6_DESC : shift_rotate_imm<"sll", uimm5opnd, GPR32Opnd, II_SLL>; class DIV_MMR6_DESC : ArithLogicR<"div", GPR32Opnd>; class DIVU_MMR6_DESC : ArithLogicR<"divu", GPR32Opnd>; class MOD_MMR6_DESC : ArithLogicR<"mod", GPR32Opnd>; @@ -355,6 +357,7 @@ ISA_MICROMIPS32R6; def SELNEZ_MMR6 : R6MMR6Rel, SELNEZ_MMR6_ENC, SELNEZ_MMR6_DESC, ISA_MICROMIPS32R6; +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 XOR_MMR6 : StdMMR6Rel, XOR_MMR6_DESC, XOR_MMR6_ENC, ISA_MICROMIPS32R6; @@ -366,3 +369,11 @@ def TLTU_MMR6 : StdMMR6Rel, TLTU_MMR6_ENC, TLTU_MMR6_DESC, ISA_MICROMIPS32R6; def TNE_MMR6 : StdMMR6Rel, TNE_MMR6_ENC, TNE_MMR6_DESC, ISA_MICROMIPS32R6; } + +//===----------------------------------------------------------------------===// +// +// MicroMips instruction aliases +// +//===----------------------------------------------------------------------===// + +def : MipsInstAlias<"nop", (SLL_MMR6 ZERO, ZERO, 0), 1>, ISA_MICROMIPS32R6; Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -694,7 +694,7 @@ def ADDIUPC_MM : AddImmUPC<"addiupc", GPRMM16Opnd>, ADDIUPC_FM_MM; /// Shift Instructions - def SLL_MM : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL>, + def SLL_MM : MMRel, shift_rotate_imm<"sll", uimm5opnd, GPR32Opnd, II_SLL>, SRA_FM_MM<0, 0>; def SRL_MM : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL>, SRA_FM_MM<0x40, 0>; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -422,6 +422,18 @@ let PrintMethod = "printUnsignedImm"; } +def MipsUImm5AsmOperand : AsmOperandClass { + let Name = "UImm5"; + let RenderMethod = "addImmOperands"; + let ParserMethod = "parseImm"; + let PredicateMethod = "isUImm<5>"; +} + +def uimm5opnd : Operand { + let PrintMethod = "printUnsignedImm"; + let ParserMatchClass = MipsUImm5AsmOperand; +} + def uimm6 : Operand { let PrintMethod = "printUnsignedImm"; } @@ -1184,7 +1196,7 @@ /// Shift Instructions let AdditionalPredicates = [NotInMicroMips] in { -def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl, +def SLL : MMRel, shift_rotate_imm<"sll", uimm5opnd, GPR32Opnd, II_SLL, shl, immZExt5>, SRA_FM<0, 0>; def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl, immZExt5>, SRA_FM<2, 0>; @@ -1608,7 +1620,9 @@ (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; def : MipsInstAlias<"or $rs, $imm", (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>; +let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>; +} def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; Index: test/MC/Disassembler/Mips/micromips32r6.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6.txt +++ test/MC/Disassembler/Mips/micromips32r6.txt @@ -72,6 +72,8 @@ 0x00 0xa4,0x18,0xd8 # CHECK: muhu $3, $4, $5 +0x00 0x00 0x00 0x00 # CHECK: nop + 0x00 0xa4 0x1a 0xd0 # CHECK: nor $3, $4, $5 0x00,0xa4,0x1a,0x90 # CHECK: or $3, $4, $5 @@ -84,6 +86,8 @@ 0x00 0x83 0x11 0x80 # CHECK: selnez $2, $3, $4 +0x00 0x83 0x38 0x00 # CHECK: sll $4, $3, 7 + 0x00 0xa4 0x19 0x90 # CHECK: sub $3, $4, $5 0x00 0xa4 0x19 0xd0 # CHECK: subu $3, $4, $5 Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -79,3 +79,6 @@ break 1024, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction wait 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction prefx 33, $8($5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + sll $33, $3, 7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $4, $34, 7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $4, $3, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips32r6/invalid.s =================================================================== --- test/MC/Mips/micromips32r6/invalid.s +++ test/MC/Mips/micromips32r6/invalid.s @@ -25,3 +25,6 @@ tlt $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction tltu $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction tne $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $33, $3, 7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $4, $34, 7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $4, $3, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -37,6 +37,7 @@ muh $3, $4, $5 # CHECK muh $3, $4, $5 # encoding: [0x00,0xa4,0x18,0x58] mulu $3, $4, $5 # CHECK mulu $3, $4, $5 # encoding: [0x00,0xa4,0x18,0x98] muhu $3, $4, $5 # CHECK muhu $3, $4, $5 # encoding: [0x00,0xa4,0x18,0xd8] + nop # CHECK: nop # encoding: [0x00,0x00,0x00,0x00] nor $3, $4, $5 # CHECK: nor $3, $4, $5 # encoding: [0x00,0xa4,0x1a,0xd0] or $3, $4, $5 # CHECK: or $3, $4, $5 # encoding: [0x00,0xa4,0x1a,0x90] ori $3, $4, 1234 # CHECK: ori $3, $4, 1234 # encoding: [0x50,0x64,0x04,0xd2] @@ -45,6 +46,8 @@ seh $3, $4 # CHECK: seh $3, $4 # encoding: [0x00,0x64,0x3b,0x3c] seleqz $2,$3,$4 # CHECK: seleqz $2, $3, $4 # encoding: [0x00,0x83,0x11,0x40] selnez $2,$3,$4 # CHECK: selnez $2, $3, $4 # encoding: [0x00,0x83,0x11,0x80] + 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] Index: test/MC/Mips/mips32r6/invalid.s =================================================================== --- test/MC/Mips/mips32r6/invalid.s +++ test/MC/Mips/mips32r6/invalid.s @@ -16,3 +16,6 @@ break 1024, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction break 7, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction break 1024, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $33, $3, 7 # ASM: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $4, $34, 7 # ASM: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $4, $3, 32 # ASM: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/mips64r6/invalid.s =================================================================== --- test/MC/Mips/mips64r6/invalid.s +++ test/MC/Mips/mips64r6/invalid.s @@ -14,3 +14,6 @@ break 1024, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction break 7, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction break 1024, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $33, $3, 7 # ASM: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $4, $34, 7 # ASM: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sll $4, $3, 32 # ASM: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction