diff options
author | Wouter van Oortmerssen <aardappel@gmail.com> | 2018-12-17 22:04:44 +0000 |
---|---|---|
committer | Wouter van Oortmerssen <aardappel@gmail.com> | 2018-12-17 22:04:44 +0000 |
commit | d3c544aa6ec94aaf143a092cbd1058890863c7dc (patch) | |
tree | 7ef64c5f8edde9082a3382f14c783dc7a6aa380d /llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | |
parent | 8c9d7729916c143fac07ea69acfff3cb13458278 (diff) | |
download | bcm5719-llvm-d3c544aa6ec94aaf143a092cbd1058890863c7dc.tar.gz bcm5719-llvm-d3c544aa6ec94aaf143a092cbd1058890863c7dc.zip |
[WebAssembly] Fix assembler parsing of br_table.
Summary:
We use `variable_ops` in the tablegen defs to denote the list of
branch targets in `br_table`, but unlike other uses of `variable_ops`
(e.g. call) the these branch targets need to actually be encoded in the
instruction. The existing tables for `variable_ops` cause not operands
to be accepted by the assembly matcher.
Following the example of ARM:
https://github.com/llvm-mirror/llvm/blob/2cc0a7da876c1d8c32775b0119e1e15aaa759b9e/lib/Target/ARM/ARMInstrInfo.td#L550-L555
we introduce a new operand type to capture this list, and we use the
same {} syntax as ARM as well to differentiate them from regular
integer operands.
Also removed definition and use of TSFlags in tablegen defs, since
`br_table` now has a non-variable_ops immediate operand, so the
previous logic of only the variable_ops arguments being labels didn't
make sense anymore.
Reviewers: dschuff, aheejin, sunfish
Subscribers: javed.absar, sbc100, jgravelle-google, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D55401
llvm-svn: 349405
Diffstat (limited to 'llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 9688090cab7..f463aeaf827 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -38,7 +38,7 @@ namespace { /// WebAssemblyOperand - Instances of this class represent the operands in a /// parsed WASM machine instruction. struct WebAssemblyOperand : public MCParsedAsmOperand { - enum KindTy { Token, Integer, Float, Symbol } Kind; + enum KindTy { Token, Integer, Float, Symbol, BrList } Kind; SMLoc StartLoc, EndLoc; @@ -58,11 +58,16 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { const MCExpr *Exp; }; + struct BrLOp { + std::vector<unsigned> List; + }; + union { struct TokOp Tok; struct IntOp Int; struct FltOp Flt; struct SymOp Sym; + struct BrLOp BrL; }; WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, TokOp T) @@ -73,6 +78,13 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { : Kind(K), StartLoc(Start), EndLoc(End), Flt(F) {} WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, SymOp S) : Kind(K), StartLoc(Start), EndLoc(End), Sym(S) {} + WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End) + : Kind(K), StartLoc(Start), EndLoc(End), BrL() {} + + ~WebAssemblyOperand() { + if (isBrList()) + BrL.~BrLOp(); + } bool isToken() const override { return Kind == Token; } bool isImm() const override { @@ -80,6 +92,7 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { } bool isMem() const override { return false; } bool isReg() const override { return false; } + bool isBrList() const { return Kind == BrList; } unsigned getReg() const override { llvm_unreachable("Assembly inspects a register operand"); @@ -111,6 +124,12 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { llvm_unreachable("Should be immediate or symbol!"); } + void addBrListOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && isBrList() && "Invalid BrList!"); + for (auto Br : BrL.List) + Inst.addOperand(MCOperand::createImm(Br)); + } + void print(raw_ostream &OS) const override { switch (Kind) { case Token: @@ -125,6 +144,9 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { case Symbol: OS << "Sym:" << Sym.Exp; break; + case BrList: + OS << "BrList:" << BrL.List.size(); + break; } } }; @@ -340,6 +362,21 @@ public: Parser.Lex(); break; } + case AsmToken::LCurly: { + Parser.Lex(); + auto Op = make_unique<WebAssemblyOperand>( + WebAssemblyOperand::BrList, Tok.getLoc(), Tok.getEndLoc()); + if (!Lexer.is(AsmToken::RCurly)) + for (;;) { + Op->BrL.List.push_back(Lexer.getTok().getIntVal()); + expect(AsmToken::Integer, "integer"); + if (!isNext(AsmToken::Comma)) + break; + } + expect(AsmToken::RCurly, "}"); + Operands.push_back(std::move(Op)); + break; + } default: return error("Unexpected token in operand: ", Tok); } |