llvm.org GIT mirror llvm / 22d1d41
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272748 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 4 years ago
2 changed file(s) with 77 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
157157 };
158158
159159 bool isToken() const override {
160 return Kind == Token;
160 if (Kind == Token)
161 return true;
162
163 if (Kind != Expression || !Expr)
164 return false;
165
166 // When parsing operands, we can't always tell if something was meant to be
167 // a token, like 'gds', or an expression that references a global variable.
168 // In this case, we assume the string is an expression, and if we need to
169 // interpret is a token, then we treat the symbol name as the token.
170 return isa(Expr);
161171 }
162172
163173 bool isImm() const override {
245255 }
246256
247257 bool isSSrc32() const {
248 return isImm() || isSCSrc32();
258 return isImm() || isSCSrc32() || isExpr();
249259 }
250260
251261 bool isSSrc64() const {
295305 bool isSMRDLiteralOffset() const;
296306 bool isDPPCtrl() const;
297307
308 StringRef getExpressionAsToken() const {
309 assert(isExpr());
310 const MCSymbolRefExpr *S = cast(Expr);
311 return S->getSymbol().getName();
312 }
313
314
298315 StringRef getToken() const {
316 assert(isToken());
317
318 if (Kind == Expression)
319 return getExpressionAsToken();
320
299321 return StringRef(Tok.Data, Tok.Length);
300322 }
301323
373395 void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
374396 if (isRegKind())
375397 addRegOperands(Inst, N);
398 else if (isExpr())
399 Inst.addOperand(MCOperand::createExpr(Expr));
376400 else
377401 addImmOperands(Inst, N);
378402 }
14471471 return ResTy;
14481472
14491473 if (getLexer().getKind() == AsmToken::Identifier) {
1474 // If this identifier is a symbol, we want to create an expression for it.
1475 // It is a little difficult to distinguish between a symbol name, and
1476 // an instruction flag like 'gds'. In order to do this, we parse
1477 // all tokens as expressions and then treate the symbol name as the token
1478 // string when we want to interpret the operand as a token.
14501479 const auto &Tok = Parser.getTok();
1480 SMLoc S = Tok.getLoc();
1481 const MCExpr *Expr = nullptr;
1482 if (!Parser.parseExpression(Expr)) {
1483 Operands.push_back(AMDGPUOperand::CreateExpr(Expr, S));
1484 return MatchOperand_Success;
1485 }
1486
14511487 Operands.push_back(AMDGPUOperand::CreateToken(Tok.getString(), Tok.getLoc()));
14521488 Parser.Lex();
14531489 return MatchOperand_Success;
27732809 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
27742810 case MCK_offen:
27752811 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
2812 case MCK_SSrc32:
2813 // When operands have expression values, they will return true for isToken,
2814 // because it is not possible to distinguish between a token and an
2815 // expression at parse time. MatchInstructionImpl() will always try to
2816 // match an operand as a token, when isToken returns true, and when the
2817 // name of the expression is not a valid token, the match will fail,
2818 // so we need to handle it here.
2819 return Operand.isSSrc32() ? Match_Success : Match_InvalidOperand;
27762820 default: return Match_InvalidOperand;
27772821 }
27782822 }
0 // RUN: llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s | FileCheck %s --check-prefix=VI
1
2
3 .globl global
4 .globl gds
5
6 // Parse a global expression
7 s_mov_b32 s0, global
8 // VI: s_mov_b32 s0, global ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
9 // VI-NEXT: ; fixup A - offset: 4, value: global, kind: FK_PCRel_4
10
11 // Use a token with the same name as a global
12 ds_gws_init v2 gds
13 // VI: ds_gws_init v2 gds ; encoding: [0x00,0x00,0x33,0xd8,0x02,0x00,0x00,0x00]
14
15 // Use a global with the same name as a token
16 s_mov_b32 s0, gds
17 // VI: s_mov_b32 s0, gds ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
18 // VI-NEXT: ; fixup A - offset: 4, value: gds, kind: FK_PCRel_4
19
20 // Use a binary expression
21 s_mov_b32 s0, gds+4
22 // VI: s_mov_b32 s0, gds+4 ; encoding: [0xff,0x00,0x80,0xbe,A,A,A,A]
23 // VI-NEXT: ; fixup A - offset: 4, value: gds+4, kind: FK_PCRel_4
24
25 // Consecutive instructions with no blank line in between to make sure we
26 // don't call Lex() too many times.
27 s_add_u32 s0, s0, global+4
28 s_addc_u32 s1, s1, 0
29 // VI: s_add_u32 s0, s0, global+4
30 // VI: s_addc_u32 s1, s1, 0