diff options
author | Matheus Almeida <matheus.almeida@imgtec.com> | 2013-11-18 12:32:49 +0000 |
---|---|---|
committer | Matheus Almeida <matheus.almeida@imgtec.com> | 2013-11-18 12:32:49 +0000 |
commit | 95adf91f29980e374bf094e15bc3f2764ef9baf4 (patch) | |
tree | 96d3e0751088d9406351c72e4d6eff646098f0e2 /lib/Target/Mips/AsmParser | |
parent | f56f1dfecc04078dd76121cf06dae4024372f329 (diff) | |
download | llvm-95adf91f29980e374bf094e15bc3f2764ef9baf4.tar.gz llvm-95adf91f29980e374bf094e15bc3f2764ef9baf4.tar.bz2 llvm-95adf91f29980e374bf094e15bc3f2764ef9baf4.tar.xz |
[mips][msa] Fix immediate value of LSA instruction as it was being wrongly encoded.
The immediate field should be encoded as "imm - 1" as the CPU always adds one to that field.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195004 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/AsmParser')
-rw-r--r-- | lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 89e2b3b022..cdae6c2f37 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -157,7 +157,10 @@ class MipsAsmParser : public MCTargetAsmParser { MipsAsmParser::OperandMatchResultTy parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands); - bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands, + MipsAsmParser::OperandMatchResultTy + parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands); + + bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind); bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &, @@ -299,7 +302,8 @@ private: k_PostIndexRegister, k_Register, k_PtrReg, - k_Token + k_Token, + k_LSAImm } Kind; MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} @@ -374,6 +378,7 @@ public: bool isMem() const { return Kind == k_Memory; } bool isPtrReg() const { return Kind == k_PtrReg; } bool isInvNum() const { return Kind == k_Immediate; } + bool isLSAImm() const { return Kind == k_LSAImm; } StringRef getToken() const { assert(Kind == k_Token && "Invalid access!"); @@ -396,7 +401,7 @@ public: } const MCExpr *getImm() const { - assert((Kind == k_Immediate) && "Invalid access!"); + assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!"); return Imm.Val; } @@ -443,8 +448,16 @@ public: return Op; } - static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S, - SMLoc E) { + static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) { + MipsOperand *Op = new MipsOperand(k_LSAImm); + Op->Imm.Val = Val; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; + } + + static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, + SMLoc S, SMLoc E) { MipsOperand *Op = new MipsOperand(k_Memory); Op->Mem.Base = Base; Op->Mem.Off = Off; @@ -2058,6 +2071,45 @@ MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { return MatchOperand_Success; } +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { + switch (getLexer().getKind()) { + default: + return MatchOperand_NoMatch; + case AsmToken::LParen: + case AsmToken::Plus: + case AsmToken::Minus: + case AsmToken::Integer: + break; + } + + const MCExpr *Expr; + SMLoc S = Parser.getTok().getLoc(); + + if (getParser().parseExpression(Expr)) + return MatchOperand_ParseFail; + + int64_t Val; + if (!Expr->EvaluateAsAbsolute(Val)) { + Error(S, "expected immediate value"); + return MatchOperand_ParseFail; + } + + // The LSA instruction allows a 2-bit unsigned immediate. For this reason + // and because the CPU always adds one to the immediate field, the allowed + // range becomes 1..4. We'll only check the range here and will deal + // with the addition/subtraction when actually decoding/encoding + // the instruction. + if (Val < 1 || Val > 4) { + Error(S, "immediate not in range (1..4)"); + return MatchOperand_ParseFail; + } + + Operands.push_back(MipsOperand::CreateLSAImm(Expr, S, + Parser.getTok().getLoc())); + return MatchOperand_Success; +} + MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { MCSymbolRefExpr::VariantKind VK = |