summaryrefslogtreecommitdiff
path: root/lib/Target/Mips/AsmParser
diff options
context:
space:
mode:
authorMatheus Almeida <matheus.almeida@imgtec.com>2013-11-18 12:32:49 +0000
committerMatheus Almeida <matheus.almeida@imgtec.com>2013-11-18 12:32:49 +0000
commit95adf91f29980e374bf094e15bc3f2764ef9baf4 (patch)
tree96d3e0751088d9406351c72e4d6eff646098f0e2 /lib/Target/Mips/AsmParser
parentf56f1dfecc04078dd76121cf06dae4024372f329 (diff)
downloadllvm-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.cpp62
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 =