Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1956,6 +1956,17 @@ if (SrcReg != Mips::NoRegister) UseSrcReg = true; + bool UseAT = false; + unsigned ATReg = 0; + if (UseSrcReg && (DstReg == SrcReg)) { + UseAT = true; + // At this point we need AT to perform the expansions and we exit if it is + // not available. + ATReg = getATReg(IDLoc); + if (!ATReg) + return true; + } + if (!Is32BitSym) { // If it's a 64-bit architecture, expand to: // la d,sym => lui d,highest(sym) @@ -1968,31 +1979,31 @@ const MCExpr *HigherExpr = evaluateRelocExpr(SymExpr, "higher"); tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(DstReg)); + tmpInst.addOperand(MCOperand::createReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::createExpr(HighestExpr)); Instructions.push_back(tmpInst); - createLShiftOri<0>(MCOperand::createExpr(HigherExpr), DstReg, SMLoc(), - Instructions); - createLShiftOri<16>(MCOperand::createExpr(HiExpr), DstReg, SMLoc(), - Instructions); - createLShiftOri<16>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(), - Instructions); + createLShiftOri<0>(MCOperand::createExpr(HigherExpr), + UseAT ? ATReg : DstReg, SMLoc(), Instructions); + createLShiftOri<16>(MCOperand::createExpr(HiExpr), UseAT ? ATReg : DstReg, + SMLoc(), Instructions); + createLShiftOri<16>(MCOperand::createExpr(LoExpr), UseAT ? ATReg : 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(DstReg)); + tmpInst.addOperand(MCOperand::createReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::createExpr(HiExpr)); Instructions.push_back(tmpInst); - createLShiftOri<0>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(), - Instructions); + createLShiftOri<0>(MCOperand::createExpr(LoExpr), UseAT ? ATReg : DstReg, + SMLoc(), Instructions); } if (UseSrcReg) - createAddu(DstReg, DstReg, SrcReg, Instructions); + createAddu(DstReg, UseAT ? ATReg : DstReg, SrcReg, Instructions); return false; } Index: test/MC/Mips/mips-expansions.s =================================================================== --- test/MC/Mips/mips-expansions.s +++ test/MC/Mips/mips-expansions.s @@ -104,6 +104,52 @@ # CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 # CHECK: addu $8, $8, $9 # encoding: [0x21,0x40,0x09,0x01] +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol+1) # encoding: [0x01'A',A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: lui $1, %hi(symbol+1) # encoding: [0x01'A',A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol-32766) # encoding: [0x02'A',0x80'A',0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: lui $1, %hi(symbol+1) # encoding: [0x01'A',A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol+2) # encoding: [0x02'A',A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: lui $1, %hi(symbol+1) # encoding: [0x01'A',A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol+4369) # encoding: [0x11'A',0x11'A',0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol-1) # encoding: [0xff'A',0xff'A',0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: lui $1, %hi(symbol-1) # encoding: [0xff'A',0xff'A',0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol+32766) # encoding: [0xfe'A',0x7f'A',0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: lui $1, %hi(symbol-1) # encoding: [0xff'A',0xff'A',0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol-2) # encoding: [0xfe'A',0xff'A',0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: lui $1, %hi(symbol-1) # encoding: [0xff'A',0xff'A',0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %lo(symbol-4369) # encoding: [0xef'A',0xee'A',0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] + # CHECK: lui $10, %hi(symbol) # encoding: [A,A,0x0a,0x3c] # CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 # CHECK: addu $10, $10, $4 # encoding: [0x21,0x50,0x44,0x01] @@ -168,6 +214,16 @@ la $8, symbol-65538($9) la $8, symbol-0x11111($9) + la $8, symbol($8) + la $8, symbol+1($8) + la $8, symbol+32770($8) + la $8, symbol+65538($8) + la $8, symbol+0x11111($8) + la $8, symbol-1($8) + la $8, symbol-32770($8) + la $8, symbol-65538($8) + la $8, symbol-0x11111($8) + .set noat lw $t2, symbol($a0) .set at