Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1895,14 +1895,30 @@ assert((ImmOp->isImm() || ImmOp->isExpr()) && "expected immediate operand kind"); if (!ImmOp->isImm()) { - expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions); - unsigned DstReg = DstRegOp->getReg(); + unsigned SrcReg = SrcRegOp->getReg(); + + bool UseAT = false; + unsigned ATReg = 0; + MCOperand ATRegOp; + if (DstReg == SrcReg) { + // 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; + ATRegOp = MCOperand::CreateReg(ATReg); + UseAT = true; + } + + expandLoadAddressSym(UseAT ? &ATRegOp : DstRegOp, ImmOp, Is32BitImm, IDLoc, + Instructions); + MCInst TmpInst; TmpInst.setOpcode(Mips::ADDu); TmpInst.addOperand(MCOperand::CreateReg(DstReg)); - TmpInst.addOperand(MCOperand::CreateReg(DstReg)); - TmpInst.addOperand(MCOperand::CreateReg(SrcRegOp->getReg())); + TmpInst.addOperand(MCOperand::CreateReg(UseAT ? ATReg : DstReg)); + TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); Instructions.push_back(TmpInst); return false; Index: test/MC/Mips/mips-expansions.s =================================================================== --- test/MC/Mips/mips-expansions.s +++ test/MC/Mips/mips-expansions.s @@ -102,6 +102,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] @@ -165,6 +211,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