Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1053,8 +1053,21 @@ } static std::unique_ptr - CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { + CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser, bool IsNegated = false) { auto Op = make_unique(k_Immediate, Parser); + const MCConstantExpr *ValCstExpr = static_cast(Val); + int64_t ValInt = ValCstExpr->getValue(); + + // We don't clear the upper 32 bits for 16-bit negated values. + if (IsNegated && !(ValInt < 0 && ValInt >= -32768)) { + // Clear the upper 32 bits. + uint32_t NewValInt = ValInt & 0xffffffff; + + // Replace the previous Value with our NewVal. + const MCConstantExpr *NewValConstExpr = MCConstantExpr::Create( + NewValInt, Parser.getContext()); + Val = NewValConstExpr; + } Op->Imm.Val = Val; Op->StartLoc = S; Op->EndLoc = E; @@ -2903,13 +2916,19 @@ break; } + // If the immediate was negated, we clear the upper 32 bits of the negated + // value (unless it's a 16-bit value). + bool IsNegated = false; + if (getLexer().is(AsmToken::Tilde)) + IsNegated = true; + const MCExpr *IdVal; SMLoc S = Parser.getTok().getLoc(); if (getParser().parseExpression(IdVal)) return MatchOperand_ParseFail; SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); + Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this, IsNegated)); return MatchOperand_Success; } Index: test/MC/Mips/mips-expansions.s =================================================================== --- test/MC/Mips/mips-expansions.s +++ test/MC/Mips/mips-expansions.s @@ -9,6 +9,8 @@ # CHECK: lui $7, 1 # encoding: [0x01,0x00,0x07,0x3c] # CHECK: ori $7, $7, 2 # encoding: [0x02,0x00,0xe7,0x34] # CHECK: addiu $8, $zero, -8 # encoding: [0xf8,0xff,0x08,0x24] +# CHECK: lui $10, 65519 # encoding: [0xef,0xff,0x0a,0x3c] +# CHECK: ori $10, $10, 61423 # encoding: [0xef,0xef,0x4a,0x35] # CHECK: addiu $4, $zero, 20 # encoding: [0x14,0x00,0x04,0x24] # CHECK: lui $7, 1 # encoding: [0x01,0x00,0x07,0x3c] @@ -59,6 +61,7 @@ li $6,-2345 li $7,65538 li $8, ~7 + li $10, ~(0x101010) la $a0, 20 la $7,65538 Index: test/MC/Mips/mips64-expansions.s =================================================================== --- test/MC/Mips/mips64-expansions.s +++ test/MC/Mips/mips64-expansions.s @@ -207,3 +207,13 @@ dli $t0, -100000000000000000 dli $t0, -1000000000000000000 dli $t0, -10000000000000000000 + + 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