Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1127,6 +1127,15 @@ if (Imm < -8 || Imm > 7) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::ADDIUSP_MM: + Opnd = Inst.getOperand(0); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) || + Imm % 4 != 0) + 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,12 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + // getSImm9AddiuspValue - Return binary encoding of the microMIPS addiusp + // instruction immediate operand. + unsigned getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getBranchTargetOpValue - Return binary encoding of the branch // target operand. If the machine operand requires relocation, // record the relocation and return zero. 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:: +getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) { + unsigned binary = (MO.getImm() >> 2) & 0x0000ffff; + return (((binary & 0x8000) >> 7) | (binary & 0x00ff)); + } + + return 0; +} + +unsigned MipsMCCodeEmitter:: getExprOpValue(const MCExpr *Expr,SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { int64_t Res; Index: lib/Target/Mips/MicroMipsInstrFormats.td =================================================================== --- lib/Target/Mips/MicroMipsInstrFormats.td +++ lib/Target/Mips/MicroMipsInstrFormats.td @@ -53,6 +53,16 @@ let Inst{0} = 0; } +class ADDIUSP_FM_MM16 { + bits<9> imm; + + bits<16> Inst; + + let Inst{15-10} = 0x13; + let Inst{9-1} = imm; + let Inst{0} = 1; +} + class MOVE_FM_MM16 funct> { bits<5> rs; bits<5> rd; Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -10,6 +10,10 @@ let EncoderMethod = "getUImm5Lsl2Encoding"; } +def simm9_addiusp : Operand { + let EncoderMethod = "getSImm9AddiuspValue"; +} + def mem_mm_12 : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops GPR32, simm12); @@ -93,6 +97,10 @@ let isCommutable = 1; } +class AddImmUSP : + MicroMipsInst16<(outs), (ins simm9_addiusp:$imm), + !strconcat(opstr, "\t$imm"), [], NoItinerary, FrmI>; + class MoveFromHILOMM : MicroMipsInst16<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO, FrmR> { @@ -175,6 +183,7 @@ } 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>; def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>; def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>; 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 @@ -10,6 +10,7 @@ # Little endian #------------------------------------------------------------------------------ # CHECK-EL: addius5 $7, -2 # encoding: [0xfc,0x4c] +# CHECK-EL: addiusp -16 # encoding: [0xf9,0x4f] # CHECK-EL: mfhi $9 # encoding: [0x09,0x46] # CHECK-EL: mflo $9 # encoding: [0x49,0x46] # CHECK-EL: move $25, $1 # encoding: [0x21,0x0f] @@ -25,6 +26,7 @@ # Big endian #------------------------------------------------------------------------------ # CHECK-EB: addius5 $7, -2 # encoding: [0x4c,0xfc] +# CHECK-EB: addiusp -16 # encoding: [0x4f,0xf9] # CHECK-EB: mfhi $9 # encoding: [0x46,0x09] # CHECK-EB: mflo $9 # encoding: [0x46,0x49] # CHECK-EB: move $25, $1 # encoding: [0x0f,0x21] @@ -38,6 +40,7 @@ # CHECK-EB: move $zero, $zero # encoding: [0x0c,0x00] addius5 $7, -2 + addiusp -16 mfhi $9 mflo $9 move $25, $1 Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -2,3 +2,4 @@ # RUN: FileCheck %s < %t1 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