[llvm] r272748 - AMDGPU/AsmParser: Add support for parsing symbol operands

Tom Stellard via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 14 19:54:14 PDT 2016


Author: tstellar
Date: Tue Jun 14 21:54:14 2016
New Revision: 272748

URL: http://llvm.org/viewvc/llvm-project?rev=272748&view=rev
Log:
AMDGPU/AsmParser: Add support for parsing symbol operands

Summary:
We can now reference symbols directly in operands, like this:
s_mov_b32 s0, global

Reviewers: artem.tamazov, vpykhtin, SamWot, nhaustov

Subscribers: arsenm, llvm-commits, kzhuravl

Differential Revision: http://reviews.llvm.org/D21038

Added:
    llvm/trunk/test/MC/AMDGPU/expressions.s
Modified:
    llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

Modified: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp?rev=272748&r1=272747&r2=272748&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Tue Jun 14 21:54:14 2016
@@ -158,7 +158,17 @@ public:
   };
 
   bool isToken() const override {
-    return Kind == Token;
+    if (Kind == Token)
+      return true;
+
+    if (Kind != Expression || !Expr)
+      return false;
+
+    // When parsing operands, we can't always tell if something was meant to be
+    // a token, like 'gds', or an expression that references a global variable.
+    // In this case, we assume the string is an expression, and if we need to
+    // interpret is a token, then we treat the symbol name as the token.
+    return isa<MCSymbolRefExpr>(Expr);
   }
 
   bool isImm() const override {
@@ -246,7 +256,7 @@ public:
   }
 
   bool isSSrc32() const {
-    return isImm() || isSCSrc32();
+    return isImm() || isSCSrc32() || isExpr();
   }
 
   bool isSSrc64() const {
@@ -296,7 +306,19 @@ public:
   bool isSMRDLiteralOffset() const;
   bool isDPPCtrl() const;
 
+  StringRef getExpressionAsToken() const {
+    assert(isExpr());
+    const MCSymbolRefExpr *S = cast<MCSymbolRefExpr>(Expr);
+    return S->getSymbol().getName();
+  }
+
+
   StringRef getToken() const {
+    assert(isToken());
+
+    if (Kind == Expression)
+      return getExpressionAsToken();
+
     return StringRef(Tok.Data, Tok.Length);
   }
 
@@ -374,6 +396,8 @@ public:
   void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
     if (isRegKind())
       addRegOperands(Inst, N);
+    else if (isExpr())
+      Inst.addOperand(MCOperand::createExpr(Expr));
     else
       addImmOperands(Inst, N);
   }
@@ -1448,7 +1472,19 @@ AMDGPUAsmParser::parseOperand(OperandVec
     return ResTy;
 
   if (getLexer().getKind() == AsmToken::Identifier) {
+    // If this identifier is a symbol, we want to create an expression for it.
+    // It is a little difficult to distinguish between a symbol name, and
+    // an instruction flag like 'gds'.  In order to do this, we parse
+    // all tokens as expressions and then treate the symbol name as the token
+    // string when we want to interpret the operand as a token.
     const auto &Tok = Parser.getTok();
+    SMLoc S = Tok.getLoc();
+    const MCExpr *Expr = nullptr;
+    if (!Parser.parseExpression(Expr)) {
+      Operands.push_back(AMDGPUOperand::CreateExpr(Expr, S));
+      return MatchOperand_Success;
+    }
+
     Operands.push_back(AMDGPUOperand::CreateToken(Tok.getString(), Tok.getLoc()));
     Parser.Lex();
     return MatchOperand_Success;
@@ -2774,6 +2810,14 @@ unsigned AMDGPUAsmParser::validateTarget
     return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
   case MCK_offen:
     return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
+  case MCK_SSrc32:
+    // When operands have expression values, they will return true for isToken,
+    // because it is not possible to distinguish between a token and an
+    // expression at parse time. MatchInstructionImpl() will always try to
+    // match an operand as a token, when isToken returns true, and when the
+    // name of the expression is not a valid token, the match will fail,
+    // so we need to handle it here.
+    return Operand.isSSrc32() ? Match_Success : Match_InvalidOperand;
   default: return Match_InvalidOperand;
   }
 }

Added: llvm/trunk/test/MC/AMDGPU/expressions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/expressions.s?rev=272748&view=auto
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/expressions.s (added)
+++ llvm/trunk/test/MC/AMDGPU/expressions.s Tue Jun 14 21:54:14 2016
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s | FileCheck %s --check-prefix=VI
+
+
+.globl global
+.globl gds
+
+// Parse a global expression
+s_mov_b32 s0, global
+// VI: s_mov_b32 s0, global ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
+// VI-NEXT: ;   fixup A - offset: 4, value: global, kind: FK_PCRel_4
+
+// Use a token with the same name as a global
+ds_gws_init v2 gds
+// VI: ds_gws_init v2 gds ; encoding: [0x00,0x00,0x33,0xd8,0x02,0x00,0x00,0x00]
+
+// Use a global with the same name as a token
+s_mov_b32 s0, gds
+// VI: s_mov_b32 s0, gds ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
+// VI-NEXT: ;   fixup A - offset: 4, value: gds, kind: FK_PCRel_4
+
+// Use a binary expression
+s_mov_b32 s0, gds+4
+// VI: s_mov_b32 s0, gds+4 ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
+// VI-NEXT: ;   fixup A - offset: 4, value: gds+4, kind: FK_PCRel_4
+
+// Consecutive instructions with no blank line in between to make sure we
+// don't call Lex() too many times.
+s_add_u32 s0, s0, global+4
+s_addc_u32 s1, s1, 0
+// VI: s_add_u32 s0, s0, global+4
+// VI: s_addc_u32 s1, s1, 0




More information about the llvm-commits mailing list