Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1737,6 +1737,17 @@ unsigned DstReg = DstRegOp->getReg(); 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 @@ -1764,16 +1775,16 @@ 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(Bits31To16)); Instructions.push_back(tmpInst); - createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions); + createLShiftOri<0>(Bits15To0, UseAT ? ATReg : DstReg, IDLoc, Instructions); if (UseSrcReg) { tmpInst.clear(); tmpInst.setOpcode(Mips::ADDu); tmpInst.addOperand(MCOperand::CreateReg(DstReg)); - tmpInst.addOperand(MCOperand::CreateReg(DstReg)); + tmpInst.addOperand(MCOperand::CreateReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::CreateReg(SrcReg)); Instructions.push_back(tmpInst); } @@ -1801,17 +1812,17 @@ 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) { tmpInst.clear(); tmpInst.setOpcode(Mips::ADDu); tmpInst.addOperand(MCOperand::CreateReg(DstReg)); - tmpInst.addOperand(MCOperand::CreateReg(DstReg)); + tmpInst.addOperand(MCOperand::CreateReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::CreateReg(SrcReg)); Instructions.push_back(tmpInst); } @@ -1841,26 +1852,26 @@ 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>(0, DstReg, IDLoc, Instructions); - createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions); + createLShiftOri<32>(0, UseAT ? ATReg : DstReg, IDLoc, Instructions); + createLShiftOri<0>(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) { tmpInst.clear(); tmpInst.setOpcode(Mips::ADDu); tmpInst.addOperand(MCOperand::CreateReg(DstReg)); - tmpInst.addOperand(MCOperand::CreateReg(DstReg)); + tmpInst.addOperand(MCOperand::CreateReg(UseAT ? ATReg : DstReg)); tmpInst.addOperand(MCOperand::CreateReg(SrcReg)); Instructions.push_back(tmpInst); } Index: test/MC/Mips/mips-expansions.s =================================================================== --- test/MC/Mips/mips-expansions.s +++ test/MC/Mips/mips-expansions.s @@ -148,6 +148,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] @@ -221,6 +226,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