mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-14 07:09:08 +00:00
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 llvm-svn: 272748
This commit is contained in:
parent
996b690cdd
commit
f545457356
@ -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(OperandVector &Operands, StringRef Mnemonic) {
|
||||
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::validateTargetOperandClass(MCParsedAsmOperand &Op,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
31
test/MC/AMDGPU/expressions.s
Normal file
31
test/MC/AMDGPU/expressions.s
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user