Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -186,9 +186,9 @@ bool Is32BitImm, SMLoc IDLoc, SmallVectorImpl &Instructions); - bool loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg, - bool Is32BitSym, SMLoc IDLoc, - SmallVectorImpl &Instructions); + bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg, + unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc, + SmallVectorImpl &Instructions); bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc, SmallVectorImpl &Instructions); @@ -1909,18 +1909,20 @@ 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 (loadAndAddSymbolAddress(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 +1941,9 @@ assert((ImmOp.isImm() || ImmOp.isExpr()) && "expected immediate operand kind"); if (!ImmOp.isImm()) { - if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc, - Instructions)) + if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), + Mips::NoRegister, Is32BitImm, IDLoc, + Instructions)) return true; return false; @@ -1953,9 +1956,9 @@ return false; } -bool MipsAsmParser::loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg, - bool Is32BitSym, SMLoc IDLoc, - SmallVectorImpl &Instructions) { +bool MipsAsmParser::loadAndAddSymbolAddress( + const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym, + SMLoc IDLoc, SmallVectorImpl &Instructions) { warnIfNoMacro(IDLoc); if (Is32BitSym && isABI_N64()) @@ -2007,6 +2010,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