aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index cb4eddf..16a5d68 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "AMDKernelCodeT.h"
+#include "MCTargetDesc/AMDGPUMCExpr.h"
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "MCTargetDesc/AMDGPUTargetStreamer.h"
#include "SIDefines.h"
@@ -1816,6 +1817,7 @@ private:
public:
void onBeginOfFile() override;
+ bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
ParseStatus parseCustomOperand(OperandVector &Operands, unsigned MCK);
@@ -8277,6 +8279,59 @@ void AMDGPUAsmParser::onBeginOfFile() {
getTargetStreamer().EmitDirectiveAMDGCNTarget();
}
+/// Parse AMDGPU specific expressions.
+///
+/// expr ::= or(expr, ...) |
+/// max(expr, ...)
+///
+bool AMDGPUAsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+ using AGVK = AMDGPUVariadicMCExpr::VariadicKind;
+
+ if (isToken(AsmToken::Identifier)) {
+ StringRef TokenId = getTokenStr();
+ AGVK VK = StringSwitch<AGVK>(TokenId)
+ .Case("max", AGVK::AGVK_Max)
+ .Case("or", AGVK::AGVK_Or)
+ .Default(AGVK::AGVK_None);
+
+ if (VK != AGVK::AGVK_None && peekToken().is(AsmToken::LParen)) {
+ SmallVector<const MCExpr *, 4> Exprs;
+ uint64_t CommaCount = 0;
+ lex(); // Eat 'max'/'or'
+ lex(); // Eat '('
+ while (true) {
+ if (trySkipToken(AsmToken::RParen)) {
+ if (Exprs.empty()) {
+ Error(getToken().getLoc(),
+ "empty " + Twine(TokenId) + " expression");
+ return true;
+ }
+ if (CommaCount + 1 != Exprs.size()) {
+ Error(getToken().getLoc(),
+ "mismatch of commas in " + Twine(TokenId) + " expression");
+ return true;
+ }
+ Res = AMDGPUVariadicMCExpr::create(VK, Exprs, getContext());
+ return false;
+ }
+ const MCExpr *Expr;
+ if (getParser().parseExpression(Expr, EndLoc))
+ return true;
+ Exprs.push_back(Expr);
+ bool LastTokenWasComma = trySkipToken(AsmToken::Comma);
+ if (LastTokenWasComma)
+ CommaCount++;
+ if (!LastTokenWasComma && !isToken(AsmToken::RParen)) {
+ Error(getToken().getLoc(),
+ "unexpected token in " + Twine(TokenId) + " expression");
+ return true;
+ }
+ }
+ }
+ }
+ return getParser().parsePrimaryExpr(Res, EndLoc, nullptr);
+}
+
ParseStatus AMDGPUAsmParser::parseOModSI(OperandVector &Operands) {
StringRef Name = getTokenStr();
if (Name == "mul") {