Index: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1758,7 +1758,7 @@ tmpInst.addOperand(MCOperand::createReg(SrcReg)); tmpInst.addOperand(MCOperand::createImm(ImmValue)); Instructions.push_back(tmpInst); - } else if ((ImmValue & 0xffffffff) == ImmValue) { + } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) { if (!AssemblerOptions.back()->isMacro()) Warning(IDLoc, "macro instruction expanded into multiple instructions"); @@ -1768,10 +1768,23 @@ uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff; uint16_t Bits15To0 = ImmValue & 0xffff; - tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(DstReg)); - tmpInst.addOperand(MCOperand::createImm(Bits31To16)); - Instructions.push_back(tmpInst); + if (!Is32BitImm && !isInt<32>(ImmValue)) { + // 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(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); + } else { + tmpInst.setOpcode(Mips::LUi); + tmpInst.addOperand(MCOperand::createReg(DstReg)); + tmpInst.addOperand(MCOperand::createImm(Bits31To16)); + Instructions.push_back(tmpInst); + } createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions); if (UseSrcReg) Index: llvm/trunk/test/MC/Mips/mips-expansions.s =================================================================== --- llvm/trunk/test/MC/Mips/mips-expansions.s +++ llvm/trunk/test/MC/Mips/mips-expansions.s @@ -11,6 +11,8 @@ # CHECK: addiu $8, $zero, -8 # encoding: [0xf8,0xff,0x08,0x24] # CHECK: lui $9, 1 # encoding: [0x01,0x00,0x09,0x3c] # CHECK-NOT: ori $9, $9, 0 # encoding: [0x00,0x00,0x29,0x35] +# CHECK: lui $10, 65519 # encoding: [0xef,0xff,0x0a,0x3c] +# CHECK: ori $10, $10, 61423 # encoding: [0xef,0xef,0x4a,0x35] # CHECK: ori $4, $zero, 20 # encoding: [0x14,0x00,0x04,0x34] # CHECK: lui $7, 1 # encoding: [0x01,0x00,0x07,0x3c] @@ -61,6 +63,7 @@ li $7,65538 li $8, ~7 li $9, 0x10000 + li $10, ~(0x101010) la $a0, 20 la $7,65538 Index: llvm/trunk/test/MC/Mips/mips64-expansions.s =================================================================== --- llvm/trunk/test/MC/Mips/mips64-expansions.s +++ llvm/trunk/test/MC/Mips/mips64-expansions.s @@ -178,3 +178,18 @@ # CHECK: ori $8, $8, 65534 # encoding: [0xfe,0xff,0x08,0x35] # CHECK: dsll $8, $8, 16 # encoding: [0x38,0x44,0x08,0x00] # CHECK: ori $8, $8, 65535 # encoding: [0xff,0xff,0x08,0x35] + +# Check that signed negative 32-bit immediates are loaded correctly: + li $10, ~(0x101010) +# CHECK: lui $10, 65519 # encoding: [0xef,0xff,0x0a,0x3c] +# CHECK: ori $10, $10, 61423 # encoding: [0xef,0xef,0x4a,0x35] +# CHECK-NOT: dsll + + dli $10, ~(0x202020) +# CHECK: lui $10, 65503 # encoding: [0xdf,0xff,0x0a,0x3c] +# CHECK: ori $10, $10, 57311 # encoding: [0xdf,0xdf,0x4a,0x35] +# CHECK-NOT: dsll + + dli $9, 0x80000000 +# CHECK: ori $9, $zero, 32768 # encoding: [0x00,0x80,0x09,0x34] +# CHECK: dsll $9, $9, 16 # encoding: [0x38,0x4c,0x09,0x00]