Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -187,7 +187,7 @@ SmallVectorImpl &Instructions); bool loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg, - bool Is32BitSym, SMLoc IDLoc, + unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc, SmallVectorImpl &Instructions); bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc, @@ -1909,18 +1909,19 @@ const MCOperand &DstRegOp = Inst.getOperand(0); assert(DstRegOp.isReg() && "expected register operand kind"); + const MCOperand &SrcRegOp = Inst.getOperand(1); + assert(SrcRegOp.isReg() && "expected register operand kind"); + const MCOperand &ImmOp = Inst.getOperand(2); assert((ImmOp.isImm() || ImmOp.isExpr()) && "expected immediate operand kind"); if (!ImmOp.isImm()) { - if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc, - Instructions)) + if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), SrcRegOp.getReg(), + Is32BitImm, IDLoc, Instructions)) return true; return false; } - const MCOperand &SrcRegOp = Inst.getOperand(1); - assert(SrcRegOp.isReg() && "expected register operand kind"); if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(), Is32BitImm, IDLoc, Instructions)) @@ -1939,8 +1940,8 @@ assert((ImmOp.isImm() || ImmOp.isExpr()) && "expected immediate operand kind"); if (!ImmOp.isImm()) { - if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc, - Instructions)) + if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Mips::NoRegister, + Is32BitImm, IDLoc, Instructions)) return true; return false; @@ -1954,7 +1955,8 @@ } bool MipsAsmParser::loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg, - bool Is32BitSym, SMLoc IDLoc, + unsigned SrcReg, bool Is32BitSym, + SMLoc IDLoc, SmallVectorImpl &Instructions) { warnIfNoMacro(IDLoc); @@ -2007,6 +2009,10 @@ createLShiftOri<0>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(), Instructions); } + + if (SrcReg != Mips::NoRegister) + createAddu(DstReg, DstReg, SrcReg, Instructions); + return false; } Index: test/MC/Mips/mips-expansions.s =================================================================== --- test/MC/Mips/mips-expansions.s +++ test/MC/Mips/mips-expansions.s @@ -38,6 +38,12 @@ # CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 # CHECK: ori $8, $8, %lo(symbol) # encoding: [A,A,0x08,0x35] # CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 + la $8, symbol($9) +# 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) # encoding: [A,A,0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $8, $9 # encoding: [0x21,0x40,0x09,0x01] # LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst(): .set noat