Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1735,6 +1735,17 @@ MCInst tmpInst; + 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; + } + tmpInst.setLoc(IDLoc); // FIXME: gas has a special case for values that are 000...1111, which // becomes a li -1 and then a dsrl @@ -1772,23 +1783,23 @@ // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the // upper 32 bits. tmpInst.setOpcode(Mips::ORi); - tmpInst.addOperand(MCOperand::createReg(DstReg)); + tmpInst.addOperand(MCOperand::createReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::createReg(Mips::ZERO)); tmpInst.addOperand(MCOperand::createImm(Bits31To16)); tmpInst.setLoc(IDLoc); Instructions.push_back(tmpInst); // Move the value to the upper 16 bits by doing a 16-bit left shift. - createLShiftOri<16>(0, DstReg, IDLoc, Instructions); + createLShiftOri<16>(0, UseAT ? ATReg : DstReg, IDLoc, Instructions); } else { tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(DstReg)); + tmpInst.addOperand(MCOperand::createReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::createImm(Bits31To16)); Instructions.push_back(tmpInst); } - createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions); + createLShiftOri<0>(Bits15To0, UseAT ? ATReg : DstReg, IDLoc, Instructions); if (UseSrcReg) - createAddu(DstReg, DstReg, SrcReg, Instructions); + createAddu(DstReg, UseAT ? ATReg : DstReg, SrcReg, Instructions); } else if ((ImmValue & (0xffffLL << 48)) == 0) { if (Is32BitImm) { @@ -1816,14 +1827,14 @@ uint16_t Bits15To0 = ImmValue & 0xffff; tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(DstReg)); + tmpInst.addOperand(MCOperand::createReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::createImm(Bits47To32)); Instructions.push_back(tmpInst); - createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions); - createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions); + createLShiftOri<0>(Bits31To16, UseAT ? ATReg : DstReg, IDLoc, Instructions); + createLShiftOri<16>(Bits15To0, UseAT ? ATReg : DstReg, IDLoc, Instructions); if (UseSrcReg) - createAddu(DstReg, DstReg, SrcReg, Instructions); + createAddu(DstReg, UseAT ? ATReg : DstReg, SrcReg, Instructions); } else { if (Is32BitImm) { @@ -1853,22 +1864,25 @@ uint16_t Bits15To0 = ImmValue & 0xffff; tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(DstReg)); + tmpInst.addOperand(MCOperand::createReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::createImm(Bits63To48)); Instructions.push_back(tmpInst); - createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions); + createLShiftOri<0>(Bits47To32, UseAT ? ATReg : DstReg, IDLoc, Instructions); // When Bits31To16 is 0, do a left shift of 32 bits instead of doing // two left shifts of 16 bits. if (Bits31To16 == 0) { - createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions); + createLShiftOri<32>(Bits15To0, UseAT ? ATReg : DstReg, IDLoc, + Instructions); } else { - createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions); - createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions); + createLShiftOri<16>(Bits31To16, UseAT ? ATReg : DstReg, IDLoc, + Instructions); + createLShiftOri<16>(Bits15To0, UseAT ? ATReg : DstReg, IDLoc, + 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 @@ -150,6 +150,11 @@ # CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 # CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# CHECK: ori $8, $8, 20 # encoding: [0x14,0x00,0x08,0x35] +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 2 # encoding: [0x02,0x00,0x21,0x34] +# 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] @@ -224,6 +229,9 @@ la $8, symbol-65538($8) la $8, symbol-0x11111($8) + la $8, 20($8) + la $8, 65538($8) + .set noat lw $t2, symbol($a0) .set at