Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -2643,8 +2643,21 @@ return MipsMCExpr::create(VK, Expr, getContext()); const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); - const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); - Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext()); + // If the RHS is a constant and we are subtracting it, switch the + // MCBinaryExpr to be the addition of the negated RHS constant with the + // unchanged LHS. + if (BE->getOpcode() == MCBinaryExpr::Sub && + isa(BE->getRHS())) { + const MCConstantExpr *OldRExp = cast(BE->getRHS()); + const MCExpr *NewRExp = + MCConstantExpr::create(-OldRExp->getValue(), getContext()); + + const MCExpr *RExp = evaluateRelocExpr(NewRExp, RelocStr); + Res = MCBinaryExpr::create(MCBinaryExpr::Add, LExp, RExp, getContext()); + } else { + const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); + Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext()); + } return Res; } Index: test/MC/Mips/mips-expansions.s =================================================================== --- test/MC/Mips/mips-expansions.s +++ test/MC/Mips/mips-expansions.s @@ -58,6 +58,26 @@ # CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 # CHECK: ori $8, $8, %lo(symbol+4369) # encoding: [0x11'A',0x11'A',0x08,0x35] # CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 + la $8, symbol-1 +# CHECK: lui $8, %hi(symbol) # encoding: [A,A,0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %lo(symbol-1) # encoding: [0xff'A',0xff'A',0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 + la $8, symbol-32770 +# CHECK: lui $8, %hi(symbol-1) # encoding: [0xff'A',0xff'A',0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %lo(symbol+32766) # encoding: [0xfe'A',0x7f'A',0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 + la $8, symbol-65538 +# CHECK: lui $8, %hi(symbol-1) # encoding: [0xff'A',0xff'A',0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %lo(symbol-2) # encoding: [0xfe'A',0xff'A',0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 + la $8, symbol-0x11111 +# CHECK: lui $8, %hi(symbol-1) # encoding: [0xff'A',0xff'A',0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %lo(symbol-4369) # encoding: [0xef'A',0xee'A',0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 # LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst(): .set noat