diff options
author | Simon Dardis <simon.dardis@imgtec.com> | 2016-10-05 18:26:19 +0000 |
---|---|---|
committer | Simon Dardis <simon.dardis@imgtec.com> | 2016-10-05 18:26:19 +0000 |
commit | 299dbd6cd15807d154cc91b7748b73da5adf0bda (patch) | |
tree | 67bc9ba298c41af882b0cbc16ae2aa67f20a3fa3 /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | |
parent | 36e21a3d56d48ec16044f1cc7e4ea903bb0a1216 (diff) | |
download | bcm5719-llvm-299dbd6cd15807d154cc91b7748b73da5adf0bda.tar.gz bcm5719-llvm-299dbd6cd15807d154cc91b7748b73da5adf0bda.zip |
[mips][ias] fix li macro when values are negated with ~
The integrated assembler evaluates the expressions such as ~0x80000000 to
0xffffffff7fffffff early in the parsing process. This patch adds compatibility
with gas so that li loads the expected value (0x7fffffff) in those cases. This
only occurs iff all the upper 32bits are set and maintains existing checks by
not truncating the result down to 32 bits if any of the the upper bits are not
set.
Reviewers: dsanders, zoran.jovanovic
Differential Review: https://reviews.llvm.org/D23399
llvm-svn: 283353
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 58562f99d5f..e4b2a40fba6 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -995,7 +995,7 @@ public: void addConstantUImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); uint64_t Imm = getConstantImm() - Offset; - Imm &= (1 << Bits) - 1; + Imm &= (1ULL << Bits) - 1; Imm += Offset; Imm += AdjustOffset; Inst.addOperand(MCOperand::createImm(Imm)); @@ -1093,7 +1093,8 @@ public: bool isRegIdx() const { return Kind == k_RegisterIndex; } bool isImm() const override { return Kind == k_Immediate; } bool isConstantImm() const { - return isImm() && isa<MCConstantExpr>(getImm()); + int64_t Res; + return isImm() && getImm()->evaluateAsAbsolute(Res); } bool isConstantImmz() const { return isConstantImm() && getConstantImm() == 0; @@ -1264,7 +1265,9 @@ public: int64_t getConstantImm() const { const MCExpr *Val = getImm(); - return static_cast<const MCConstantExpr *>(Val)->getValue(); + int64_t Value = 0; + (void)Val->evaluateAsAbsolute(Value); + return Value; } MipsOperand *getMemBase() const { @@ -4051,6 +4054,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_SImm32_Relaxed: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 32-bit signed immediate"); + case Match_UImm32_Coerced: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected 32-bit immediate"); case Match_MemSImm9: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected memory with 9-bit signed offset"); |