Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -186,7 +186,6 @@ OperandMatchResultTy parseAnyRegister(OperandVector &Operands); OperandMatchResultTy parseImm(OperandVector &Operands); OperandMatchResultTy parseJumpTarget(OperandVector &Operands); - OperandMatchResultTy parseInvNum(OperandVector &Operands); OperandMatchResultTy parseRegisterPair(OperandVector &Operands); OperandMatchResultTy parseMovePRegPair(OperandVector &Operands); OperandMatchResultTy parseRegisterList(OperandVector &Operands); @@ -1147,6 +1146,15 @@ addConstantUImmOperands(Inst, N); } + template + void addInvConstantSImmOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + int64_t Imm = getConstantImm(); + Imm = SignExtend64(Imm); + Imm = 0 - Imm; + Inst.addOperand(MCOperand::createImm(Imm)); + } + template void addConstantSImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); @@ -5790,25 +5798,6 @@ } OperandMatchResultTy -MipsAsmParser::parseInvNum(OperandVector &Operands) { - MCAsmParser &Parser = getParser(); - const MCExpr *IdVal; - // If the first token is '$' we may have register operand. - if (Parser.getTok().is(AsmToken::Dollar)) - return MatchOperand_NoMatch; - SMLoc S = Parser.getTok().getLoc(); - if (getParser().parseExpression(IdVal)) - return MatchOperand_ParseFail; - const MCConstantExpr *MCE = dyn_cast(IdVal); - assert(MCE && "Unexpected MCExpr type."); - int64_t Val = MCE->getValue(); - SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(MipsOperand::CreateImm( - MCConstantExpr::create(0 - Val, getContext()), S, E, *this)); - return MatchOperand_Success; -} - -OperandMatchResultTy MipsAsmParser::parseRegisterList(OperandVector &Operands) { MCAsmParser &Parser = getParser(); SmallVector Regs; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -1035,18 +1035,19 @@ let DiagnosticType = "MemSImm16"; } -def MipsInvertedImmoperand : AsmOperandClass { - let Name = "InvNum"; - let RenderMethod = "addImmOperands"; - let ParserMethod = "parseInvNum"; +def MipsInvertedSImm16Operand : AsmOperandClass { + let Name = "InvSImm16_Relaxed"; + let SuperClasses = [SImm16AsmOperandClass]; + let RenderMethod = "addInvConstantSImmOperands<16>"; + let PredicateMethod = "isConstantSImm<16>"; } def InvertedImOperand : Operand { - let ParserMatchClass = MipsInvertedImmoperand; + let ParserMatchClass = MipsInvertedSImm16Operand; } def InvertedImOperand64 : Operand { - let ParserMatchClass = MipsInvertedImmoperand; + let ParserMatchClass = MipsInvertedSImm16Operand; } class mem_generic : Operand { Index: test/MC/Mips/macro-aliases-invalid.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-aliases-invalid.s @@ -0,0 +1,21 @@ +# RUN: not llvm-mc -arch=mips -mcpu=mips32r2 %s 2>%t1 +# RUN: FileCheck %s < %t1 + +# Check that subu only rejects any non-constant values. + +.globl end + subu $4, $4, %lo($start) # CHECK: error: invalid operand for instruction + subu $4, $4, $start # CHECK: error: invalid operand for instruction + subu $4, $4, %hi(end) # CHECK: error: invalid operand for instruction + subu $4, $4, end + 4 # CHECK: error: invalid operand for instruction + subu $4, $4, end # CHECK: error: invalid operand for instruction + subu $4, $4, sp # CHECK: error: invalid operand for instruction + + subu $4, %lo($start) # CHECK: error: invalid operand for instruction + subu $4, $start # CHECK: error: invalid operand for instruction + subu $4, %hi(end) # CHECK: error: invalid operand for instruction + subu $4, end + 4 # CHECK: error: invalid operand for instruction + subu $4, end # CHECK: error: invalid operand for instruction + subu $4, sp # CHECK: error: invalid operand for instruction + +$start: Index: test/MC/Mips/macro-aliases.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-aliases.s @@ -0,0 +1,35 @@ +# RUN: llvm-mc -arch=mips -mcpu=mips32r2 %s -show-inst | FileCheck %s + +# Test that subu accepts constant operands and inverts them when +# rendering the operand. + + subu $4, $4, 4 # CHECK: ADDiu + # CHECK; Imm:-4 + subu $gp, $gp, 4 # CHECK: ADDiu + # CHECK; Imm:-4 + subu $sp, $sp, 4 # CHECK: ADDiu + # CHECK; Imm:-4 + subu $4, $4, -4 # CHECK: ADDiu + # CHECK; Imm:4 + subu $gp, $gp, -4 # CHECK: ADDiu + # CHECK; Imm:4 + subu $sp, $sp, -4 # CHECK: ADDiu + # CHECK; Imm:4 + subu $sp, $sp, -(4 + 4) # CHECK: ADDiu + # CHECK: Imm:8 + + subu $4, 8 # CHECK: ADDiu + # CHECK; Imm:-8 + subu $gp, 8 # CHECK: ADDiu + # CHECK; Imm:-8 + subu $sp, 8 # CHECK: ADDiu + # CHECK; Imm:-8 + subu $4, -8 # CHECK: ADDiu + # CHECK; Imm:8 + subu $gp, -8 # CHECK: ADDiu + # CHECK; Imm:8 + subu $sp, -8 # CHECK: ADDiu + # CHECK; Imm:8 + subu $sp, -(4 + 4) # CHECK: ADDiu + # CHECK: Imm:8 +