summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index d21881fd99c..787c035df10 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -89,6 +89,7 @@ private:
bool parseRegister(OperandVector &Operands);
bool parseSymbolicImmVal(const MCExpr *&ImmVal);
bool parseNeonVectorList(OperandVector &Operands);
+ bool parseOptionalMulVl(OperandVector &Operands);
bool parseOperand(OperandVector &Operands, bool isCondCode,
bool invertCondCode);
@@ -1371,6 +1372,13 @@ public:
Inst.addOperand(MCOperand::createImm(MCE->getValue()));
}
+ template <int Scale>
+ void addImmScaledOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
+ Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
+ }
+
template <typename T>
void addLogicalImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
@@ -3049,6 +3057,29 @@ AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
return MatchOperand_Success;
}
+bool AArch64AsmParser::parseOptionalMulVl(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
+
+ // Some SVE instructions have a decoration after the immediate, i.e.
+ // "mul vl". We parse them here and add tokens, which must be present in the
+ // asm string in the tablegen instruction.
+ if (!Parser.getTok().getString().equals_lower("mul") ||
+ !Parser.getLexer().peekTok().getString().equals_lower("vl"))
+ return true;
+
+ SMLoc S = getLoc();
+ Operands.push_back(
+ AArch64Operand::CreateToken("mul", false, S, getContext()));
+ Parser.Lex(); // Eat the "mul"
+
+ S = getLoc();
+ Operands.push_back(
+ AArch64Operand::CreateToken("vl", false, S, getContext()));
+ Parser.Lex(); // Eat the "vl"
+
+ return false;
+}
+
/// parseOperand - Parse a arm instruction operand. For now this parses the
/// operand regardless of the mnemonic.
bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
@@ -3102,6 +3133,10 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
if (!parseRegister(Operands))
return false;
+ // See if this is a "mul vl" decoration used by SVE instructions.
+ if (!parseOptionalMulVl(Operands))
+ return false;
+
// This could be an optional "shift" or "extend" operand.
OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
// We can only continue if no tokens were eaten.
@@ -3610,6 +3645,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
return Error(Loc, "index must be an integer in range [-32, 31].");
case Match_InvalidMemoryIndexedSImm5:
return Error(Loc, "index must be an integer in range [-16, 15].");
+ case Match_InvalidMemoryIndexed1SImm4:
+ return Error(Loc, "index must be an integer in range [-8, 7].");
case Match_InvalidMemoryIndexedSImm9:
return Error(Loc, "index must be an integer in range [-256, 255].");
case Match_InvalidMemoryIndexedSImm10:
@@ -4124,10 +4161,11 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidMemoryXExtend32:
case Match_InvalidMemoryXExtend64:
case Match_InvalidMemoryXExtend128:
- case Match_InvalidMemoryIndexedSImm6:
+ case Match_InvalidMemoryIndexed1SImm4:
case Match_InvalidMemoryIndexed4SImm7:
case Match_InvalidMemoryIndexed8SImm7:
case Match_InvalidMemoryIndexed16SImm7:
+ case Match_InvalidMemoryIndexedSImm6:
case Match_InvalidMemoryIndexedSImm5:
case Match_InvalidMemoryIndexedSImm9:
case Match_InvalidMemoryIndexedSImm10:
OpenPOWER on IntegriCloud