Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -186,6 +186,10 @@ bool Is32BitImm, SMLoc IDLoc, SmallVectorImpl &Instructions); + bool loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg, + unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc, + SmallVectorImpl &Instructions); + bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc, SmallVectorImpl &Instructions); @@ -197,10 +201,6 @@ bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions); - void expandLoadAddressSym(const MCOperand &DstRegOp, const MCOperand &SymOp, - bool Is32BitSym, SMLoc IDLoc, - SmallVectorImpl &Instructions); - void expandMemInst(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions, bool isLoad, bool isImmOpnd); @@ -1916,10 +1916,9 @@ assert((ImmOp.isImm() || ImmOp.isExpr()) && "expected immediate operand kind"); if (!ImmOp.isImm()) { - expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions); - - unsigned DstReg = DstRegOp.getReg(); - createAddu(DstReg, DstReg, SrcRegOp.getReg(), Instructions); + if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), SrcRegOp.getReg(), + Is32BitImm, IDLoc, Instructions)) + return true; return false; } @@ -1941,7 +1940,10 @@ assert((ImmOp.isImm() || ImmOp.isExpr()) && "expected immediate operand kind"); if (!ImmOp.isImm()) { - expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions); + if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Mips::NoRegister, + Is32BitImm, IDLoc, Instructions)) + return true; + return false; } @@ -1952,19 +1954,22 @@ return false; } -void MipsAsmParser::expandLoadAddressSym( - const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym, - SMLoc IDLoc, SmallVectorImpl &Instructions) { +bool MipsAsmParser::loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg, + unsigned SrcReg, bool Is32BitSym, + SMLoc IDLoc, + SmallVectorImpl &Instructions) { warnIfNoMacro(IDLoc); if (Is32BitSym && isABI_N64()) Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol"); MCInst tmpInst; - unsigned RegNo = DstRegOp.getReg(); + const MCExpr *HiExpr = evaluateRelocExpr(SymExpr, "hi"); + const MCExpr *LoExpr = evaluateRelocExpr(SymExpr, "lo"); - const MCExpr *HiExpr = evaluateRelocExpr(SymOp.getExpr(), "hi"); - const MCExpr *LoExpr = evaluateRelocExpr(SymOp.getExpr(), "lo"); + bool UseSrcReg = false; + if (SrcReg != Mips::NoRegister) + UseSrcReg = true; if (!Is32BitSym) { // If it's a 64-bit architecture, expand to: @@ -1974,32 +1979,37 @@ // ori d,d,hi16(sym) // dsll d,d,16 // ori d,d,lo16(sym) - const MCExpr *HighestExpr = evaluateRelocExpr(SymOp.getExpr(), "highest"); - const MCExpr *HigherExpr = evaluateRelocExpr(SymOp.getExpr(), "higher"); + const MCExpr *HighestExpr = evaluateRelocExpr(SymExpr, "highest"); + const MCExpr *HigherExpr = evaluateRelocExpr(SymExpr, "higher"); tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(RegNo)); + tmpInst.addOperand(MCOperand::createReg(DstReg)); tmpInst.addOperand(MCOperand::createExpr(HighestExpr)); Instructions.push_back(tmpInst); - createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(), + createLShiftOri<0>(MCOperand::createExpr(HigherExpr), DstReg, SMLoc(), Instructions); - createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(), + createLShiftOri<16>(MCOperand::createExpr(HiExpr), DstReg, SMLoc(), Instructions); - createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(), + createLShiftOri<16>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(), Instructions); } else { // Otherwise, expand to: // la d,sym => lui d,hi16(sym) // ori d,d,lo16(sym) tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(RegNo)); + tmpInst.addOperand(MCOperand::createReg(DstReg)); tmpInst.addOperand(MCOperand::createExpr(HiExpr)); Instructions.push_back(tmpInst); - createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(), + createLShiftOri<0>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(), Instructions); } + + if (UseSrcReg) + createAddu(DstReg, DstReg, SrcReg, Instructions); + + return false; } bool MipsAsmParser::expandUncondBranchMMPseudo(