Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1216,6 +1216,16 @@ if (Imm < 0 || Imm > 60 || (Imm % 4 != 0)) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::ADDIUR1SP_MM: + Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (OffsetToAlignment(Imm, 4LL)) + return Error(IDLoc, "misaligned immediate operand value"); + if (Imm < 0 || Imm > 255) + return Error(IDLoc, "immediate operand value out of range"); + break; } } Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -80,6 +80,10 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getSImm9AddiuspValue - Return binary encoding of the microMIPS addiusp // instruction immediate operand. unsigned getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -364,6 +364,20 @@ } unsigned MipsMCCodeEmitter:: +getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) { + unsigned Value = MO.getImm(); + return Value >> 2; + } + + return 0; +} + +unsigned MipsMCCodeEmitter:: getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { Index: lib/Target/Mips/MicroMipsInstrFormats.td =================================================================== --- lib/Target/Mips/MicroMipsInstrFormats.td +++ lib/Target/Mips/MicroMipsInstrFormats.td @@ -157,6 +157,18 @@ let Inst{4-0} = imm; } +class ADDIUR1SP_FM_MM16 { + bits<3> rd; + bits<6> imm; + + bits<16> Inst; + + let Inst{15-10} = 0x1b; + let Inst{9-7} = rd; + let Inst{6-1} = imm; + let Inst{0} = 1; +} + //===----------------------------------------------------------------------===// // MicroMIPS 32-bit Instruction Formats //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -14,6 +14,10 @@ let EncoderMethod = "getUImm5Lsl2Encoding"; } +def uimm6_lsl2 : Operand { + let EncoderMethod = "getUImm6Lsl2Encoding"; +} + def simm9_addiusp : Operand { let EncoderMethod = "getSImm9AddiuspValue"; } @@ -172,6 +176,10 @@ let mayStore = 1; } +class AddImmUR1SP : + MicroMipsInst16<(outs RO:$rd), (ins uimm6_lsl2:$imm), + !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmR>; + class AddImmUSP : MicroMipsInst16<(outs), (ins simm9_addiusp:$imm), !strconcat(opstr, "\t$imm"), [], NoItinerary, FrmI>; @@ -285,6 +293,7 @@ LOAD_STORE_FM_MM16<0x2a>; def SW16_MM : StoreMM16<"sw16", GPRMM16OpndZero, GPRMM16Opnd, store, II_SW, mem_mm_4_lsl2, addrimm6>, LOAD_STORE_FM_MM16<0x3a>; +def ADDIUR1SP_MM : AddImmUR1SP<"addiur1sp", GPRMM16Opnd>, ADDIUR1SP_FM_MM16; def ADDIUS5_MM : AddImmUS5<"addius5", GPR32Opnd>, ADDIUS5_FM_MM16; def ADDIUSP_MM : AddImmUSP<"addiusp">, ADDIUSP_FM_MM16; def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>; Index: test/MC/Mips/micromips-16-bit-instructions.s =================================================================== --- test/MC/Mips/micromips-16-bit-instructions.s +++ test/MC/Mips/micromips-16-bit-instructions.s @@ -24,6 +24,7 @@ # CHECK-EL: sh16 $4, 8($17) # encoding: [0x14,0xaa] # CHECK-EL: sw16 $4, 4($17) # encoding: [0x11,0xea] # CHECK-EL: sw16 $zero, 4($17) # encoding: [0x11,0xe8] +# CHECK-EL: addiur1sp $7, 4 # encoding: [0x83,0x6f] # CHECK-EL: addius5 $7, -2 # encoding: [0xfc,0x4c] # CHECK-EL: addiusp -16 # encoding: [0xf9,0x4f] # CHECK-EL: mfhi $9 # encoding: [0x09,0x46] @@ -55,6 +56,7 @@ # CHECK-EB: sh16 $4, 8($17) # encoding: [0xaa,0x14] # CHECK-EB: sw16 $4, 4($17) # encoding: [0xea,0x11] # CHECK-EB: sw16 $zero, 4($17) # encoding: [0xe8,0x11] +# CHECK-EB: addiur1sp $7, 4 # encoding: [0x6f,0x83] # CHECK-EB: addius5 $7, -2 # encoding: [0x4c,0xfc] # CHECK-EB: addiusp -16 # encoding: [0x4f,0xf9] # CHECK-EB: mfhi $9 # encoding: [0x46,0x09] @@ -84,6 +86,7 @@ sh16 $4, 8($17) sw16 $4, 4($17) sw16 $0, 4($17) + addiur1sp $7, 4 addius5 $7, -2 addiusp -16 mfhi $9 Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -1,6 +1,9 @@ # RUN: not llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips 2>%t1 # RUN: FileCheck %s < %t1 + addiur1sp $7, 260 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + addiur1sp $7, 241 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: misaligned immediate operand value + addiur1sp $8, 240 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction addius5 $7, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range addiusp 1032 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range addu16 $6, $14, $4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction