40#define DEBUG_TYPE "wasm-asm-parser"
49 enum KindTy { Token,
Integer,
Float, Symbol, BrList, CatchList } Kind;
51 SMLoc StartLoc, EndLoc;
70 std::vector<unsigned> List;
80 std::vector<CaLOpElem> List;
92 WebAssemblyOperand(SMLoc Start, SMLoc End, TokOp
T)
93 : Kind(Token), StartLoc(
Start), EndLoc(End), Tok(
T) {}
94 WebAssemblyOperand(SMLoc Start, SMLoc End, IntOp
I)
95 : Kind(Integer), StartLoc(
Start), EndLoc(End),
Int(
I) {}
96 WebAssemblyOperand(SMLoc Start, SMLoc End, FltOp
F)
97 : Kind(Float), StartLoc(
Start), EndLoc(End), Flt(
F) {}
98 WebAssemblyOperand(SMLoc Start, SMLoc End, SymOp S)
99 : Kind(Symbol), StartLoc(
Start), EndLoc(End), Sym(S) {}
100 WebAssemblyOperand(SMLoc Start, SMLoc End, BrLOp
B)
101 : Kind(BrList), StartLoc(
Start), EndLoc(End), BrL(
B) {}
102 WebAssemblyOperand(SMLoc Start, SMLoc End, CaLOp
C)
103 : Kind(CatchList), StartLoc(
Start), EndLoc(End), CaL(
C) {}
105 ~WebAssemblyOperand()
override {
112 bool isToken()
const override {
return Kind == Token; }
113 bool isImm()
const override {
return Kind == Integer || Kind == Symbol; }
114 bool isFPImm()
const {
return Kind == Float; }
115 bool isMem()
const override {
return false; }
116 bool isReg()
const override {
return false; }
117 bool isBrList()
const {
return Kind == BrList; }
118 bool isCatchList()
const {
return Kind == CatchList; }
120 MCRegister
getReg()
const override {
130 SMLoc getStartLoc()
const override {
return StartLoc; }
131 SMLoc getEndLoc()
const override {
return EndLoc; }
133 void addRegOperands(MCInst &,
unsigned)
const {
138 void addImmOperands(MCInst &Inst,
unsigned N)
const {
139 assert(
N == 1 &&
"Invalid number of operands!");
142 else if (Kind == Symbol)
148 void addFPImmf32Operands(MCInst &Inst,
unsigned N)
const {
149 assert(
N == 1 &&
"Invalid number of operands!");
157 void addFPImmf64Operands(MCInst &Inst,
unsigned N)
const {
158 assert(
N == 1 &&
"Invalid number of operands!");
165 void addBrListOperands(MCInst &Inst,
unsigned N)
const {
166 assert(
N == 1 && isBrList() &&
"Invalid BrList!");
167 for (
auto Br : BrL.List)
171 void addCatchListOperands(MCInst &Inst,
unsigned N)
const {
172 assert(
N == 1 && isCatchList() &&
"Invalid CatchList!");
174 for (
auto Ca : CaL.List) {
183 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
186 OS <<
"Tok:" << Tok.Tok;
189 OS <<
"Int:" <<
Int.Val;
192 OS <<
"Flt:" << Flt.Val;
195 OS <<
"Sym:" << Sym.Exp;
198 OS <<
"BrList:" << BrL.List.size();
201 OS <<
"CaList:" << CaL.List.size();
215 auto *Sym =
static_cast<MCSymbolWasm *
>(Ctx.lookupSymbol(Name));
217 if (!Sym->isFunctionTable())
218 Ctx.reportError(
SMLoc(),
"symbol is not a wasm funcref table");
220 Sym =
static_cast<MCSymbolWasm *
>(Ctx.getOrCreateSymbol(Name));
245 } CurrentState = FileStart;
261 wasm::WasmSignature Sig;
263 std::vector<Nested> NestingStack;
265 MCSymbolWasm *DefaultFunctionTable =
nullptr;
266 MCSymbol *LastFunctionLabel =
nullptr;
270 WebAssemblyAsmTypeCheck TC;
275 WebAssemblyAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
276 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
277 : MCTargetAsmParser(
Options, STI, MII), Parser(Parser),
278 Lexer(Parser.getLexer()), Is64(STI.getTargetTriple().isArch64Bit()),
279 TC(Parser, MII, Is64), SkipTypeCheck(
Options.MCNoTypeCheck) {
280 FeatureBitset FBS = ComputeAvailableFeatures(STI.
getFeatureBits());
283 if (FBS.
test(WebAssembly::FeatureBulkMemory)) {
284 FBS.
set(WebAssembly::FeatureBulkMemoryOpt);
287 if (FBS.
test(WebAssembly::FeatureReferenceTypes)) {
288 FBS.
set(WebAssembly::FeatureCallIndirectOverlong);
291 setAvailableFeatures(FBS);
294 auto &
SM = Parser.getSourceManager();
296 SM.getBufferInfo(
SM.getMainFileID()).Buffer->getBufferIdentifier();
297 if (BufferName ==
"<inline asm>")
298 SkipTypeCheck =
true;
301 void Initialize(MCAsmParser &Parser)
override {
305 getContext(),
"__indirect_function_table", Is64);
308 DefaultFunctionTable->setOmitFromLinkingSection();
311#define GET_ASSEMBLER_HEADER
312#include "WebAssemblyGenAsmMatcher.inc"
318 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
319 SMLoc &EndLoc)
override {
323 bool error(
const Twine &Msg,
const AsmToken &Tok) {
327 bool error(
const Twine &Msg, SMLoc Loc = SMLoc()) {
328 return Parser.Error(Loc.isValid() ? Loc : Lexer.getTok().getLoc(), Msg);
331 std::pair<StringRef, StringRef> nestingString(NestingType NT) {
334 return {
"function",
"end_function"};
336 return {
"block",
"end_block"};
338 return {
"loop",
"end_loop"};
340 return {
"try",
"end_try/delegate"};
342 return {
"catch_all",
"end_try"};
344 return {
"try_table",
"end_try_table"};
346 return {
"if",
"end_if"};
348 return {
"else",
"end_if"};
354 void push(NestingType NT, wasm::WasmSignature Sig = wasm::WasmSignature()) {
355 NestingStack.push_back({
NT, Sig});
358 bool pop(StringRef Ins, NestingType NT1, NestingType NT2 = Undefined) {
359 if (NestingStack.empty())
360 return error(Twine(
"End of block construct with no start: ") + Ins);
361 auto Top = NestingStack.back();
362 if (Top.NT != NT1 && Top.NT != NT2)
363 return error(Twine(
"Block construct type mismatch, expected: ") +
364 nestingString(Top.NT).second +
", instead got: " + Ins);
365 TC.setLastSig(Top.Sig);
366 NestingStack.pop_back();
372 bool popAndPushWithSameSignature(StringRef Ins, NestingType PopNT,
373 NestingType PushNT) {
374 if (NestingStack.empty())
375 return error(Twine(
"End of block construct with no start: ") + Ins);
376 auto Sig = NestingStack.back().Sig;
383 bool ensureEmptyNestingStack(SMLoc Loc = SMLoc()) {
384 auto Err = !NestingStack.empty();
385 while (!NestingStack.empty()) {
386 error(Twine(
"Unmatched block construct(s) at function end: ") +
387 nestingString(NestingStack.back().NT).first,
389 NestingStack.pop_back();
395 auto Ok = Lexer.is(Kind);
403 return error(std::string(
"Expected ") + KindName +
", instead got: ",
408 StringRef expectIdent() {
410 error(
"Expected identifier, got: ", Lexer.getTok());
413 auto Name = Lexer.getTok().getString();
418 bool parseRegTypeList(SmallVectorImpl<wasm::ValType> &Types) {
422 return error(
"unknown type: ", Lexer.getTok());
431 void parseSingleInteger(
bool IsNegative,
OperandVector &Operands) {
432 auto &
Int = Lexer.getTok();
433 int64_t Val =
Int.getIntVal();
436 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
437 Int.getLoc(),
Int.getEndLoc(), WebAssemblyOperand::IntOp{Val}));
441 bool parseSingleFloat(
bool IsNegative,
OperandVector &Operands) {
442 auto &Flt = Lexer.getTok();
444 if (Flt.getString().getAsDouble(Val,
false))
445 return error(
"Cannot parse real: ", Flt);
448 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
449 Flt.getLoc(), Flt.getEndLoc(), WebAssemblyOperand::FltOp{Val}));
454 bool parseSpecialFloatMaybe(
bool IsNegative,
OperandVector &Operands) {
457 auto &Flt = Lexer.getTok();
458 auto S = Flt.getString();
460 if (S.compare_insensitive(
"infinity") == 0) {
461 Val = std::numeric_limits<double>::infinity();
462 }
else if (S.compare_insensitive(
"nan") == 0) {
463 Val = std::numeric_limits<double>::quiet_NaN();
469 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
470 Flt.getLoc(), Flt.getEndLoc(), WebAssemblyOperand::FltOp{Val}));
476 auto &Tok = Lexer.getTok();
480 Order = StringSwitch<int64_t>(S)
486 return error(
"memory ordering requires relaxed-atomics feature: ",
493 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
498 bool checkForP2AlignIfLoadStore(
OperandVector &Operands, StringRef InstName) {
500 auto IsLoadStore = InstName.
contains(
".load") ||
503 auto IsAtomic = InstName.
contains(
"atomic.");
504 if (IsLoadStore || IsAtomic) {
507 auto Id = expectIdent();
509 return error(
"Expected p2align, instead got: " + Id);
513 return error(
"Expected integer constant");
514 parseSingleInteger(
false, Operands);
519 auto IsLoadStoreLane = InstName.
contains(
"_lane");
520 if (IsLoadStoreLane && Operands.
size() == 4)
526 auto Tok = Lexer.getTok();
527 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
534 void addBlockTypeOperand(
OperandVector &Operands, SMLoc NameLoc,
536 if (
BT == WebAssembly::BlockType::Void) {
537 TC.setLastSig(wasm::WasmSignature{});
541 NestingStack.back().Sig = Sig;
543 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
544 NameLoc, NameLoc, WebAssemblyOperand::IntOp{
static_cast<int64_t
>(
BT)}));
547 bool parseLimits(wasm::WasmLimits *Limits) {
548 auto Tok = Lexer.getTok();
550 return error(
"Expected integer constant, instead got: ", Tok);
558 auto Tok = Lexer.getTok();
560 return error(
"Expected integer constant, instead got: ", Tok);
569 bool parseFunctionTableOperand(std::unique_ptr<WebAssemblyOperand> *
Op) {
577 auto &Tok = Lexer.getTok();
582 *
Op = std::make_unique<WebAssemblyOperand>(
589 *
Op = std::make_unique<WebAssemblyOperand>(
590 SMLoc(), SMLoc(), WebAssemblyOperand::SymOp{Val});
597 *
Op = std::make_unique<WebAssemblyOperand>(SMLoc(), SMLoc(),
598 WebAssemblyOperand::IntOp{0});
602 bool parseInstruction(ParseInstructionInfo & , StringRef Name,
612 auto &Sep = Lexer.getTok();
613 if (Sep.getLoc().getPointer() !=
Name.end() ||
617 Name = StringRef(
Name.begin(),
Name.size() + Sep.getString().size());
620 auto &
Id = Lexer.getTok();
622 Id.getLoc().getPointer() !=
Name.end())
623 return error(
"Incomplete instruction name: ", Id);
624 Name = StringRef(
Name.begin(),
Name.size() +
Id.getString().size());
629 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
631 WebAssemblyOperand::TokOp{Name}));
635 bool ExpectBlockType =
false;
636 bool ExpectFuncType =
false;
637 bool ExpectCatchList =
false;
638 std::unique_ptr<WebAssemblyOperand> FunctionTable;
639 if (Name ==
"block") {
641 ExpectBlockType =
true;
642 }
else if (Name ==
"loop") {
644 ExpectBlockType =
true;
645 }
else if (Name ==
"try") {
647 ExpectBlockType =
true;
648 }
else if (Name ==
"if") {
650 ExpectBlockType =
true;
651 }
else if (Name ==
"else") {
652 if (popAndPushWithSameSignature(Name, If, Else))
654 }
else if (Name ==
"catch") {
655 if (popAndPushWithSameSignature(Name, Try, Try))
657 }
else if (Name ==
"catch_all") {
658 if (popAndPushWithSameSignature(Name, Try, CatchAll))
660 }
else if (Name ==
"try_table") {
662 ExpectBlockType =
true;
663 ExpectCatchList =
true;
664 }
else if (Name ==
"end_if") {
665 if (pop(Name, If, Else))
667 }
else if (Name ==
"end_try") {
668 if (pop(Name, Try, CatchAll))
670 }
else if (Name ==
"end_try_table") {
671 if (pop(Name, TryTable))
673 }
else if (Name ==
"delegate") {
676 }
else if (Name ==
"end_loop") {
679 }
else if (Name ==
"end_block") {
680 if (pop(Name, Block))
682 }
else if (Name ==
"end_function") {
683 ensureLocals(getStreamer());
684 CurrentState = EndFunction;
685 if (pop(Name, Function) || ensureEmptyNestingStack())
687 }
else if (Name ==
"call_indirect" || Name ==
"return_call_indirect") {
691 if (parseFunctionTableOperand(&FunctionTable))
693 ExpectFuncType =
true;
694 }
else if (Name ==
"ref.test") {
697 ExpectFuncType =
true;
700 if (
Name.contains(
"atomic.")) {
701 if (addMemOrderOrDefault(Operands))
706 auto PeekCatchList = [&]() {
709 AsmToken NextTok = Lexer.peekTok();
715 if (ExpectFuncType ||
722 auto Loc = Parser.getTok();
724 if (parseSignature(Signature))
727 TC.setLastSig(*Signature);
729 NestingStack.back().Sig = *Signature;
730 ExpectBlockType =
false;
733 auto *WasmSym =
static_cast<MCSymbolWasm *
>(Sym);
734 WasmSym->setSignature(Signature);
738 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
739 Loc.getLoc(), Loc.getEndLoc(), WebAssemblyOperand::SymOp{Expr}));
749 if (ExpectCatchList && PeekCatchList()) {
750 if (ExpectBlockType) {
751 ExpectBlockType =
false;
752 addBlockTypeOperand(Operands, NameLoc, WebAssembly::BlockType::Void);
754 if (parseCatchList(Operands))
756 ExpectCatchList =
false;
760 auto &Tok = Lexer.getTok();
763 if (!parseSpecialFloatMaybe(
false, Operands))
765 auto &
Id = Lexer.getTok();
766 if (ExpectBlockType) {
769 if (
BT == WebAssembly::BlockType::Invalid)
770 return error(
"Unknown block type: ", Id);
771 addBlockTypeOperand(Operands, NameLoc,
BT);
772 ExpectBlockType =
false;
776 if (ExpectCatchList && PeekCatchList()) {
777 if (parseCatchList(Operands))
779 ExpectCatchList =
false;
786 if (Parser.parseExpression(Val, End))
787 return error(
"Cannot parse symbol: ", Lexer.getTok());
788 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
789 Start, End, WebAssemblyOperand::SymOp{Val}));
790 if (checkForP2AlignIfLoadStore(Operands, Name))
798 parseSingleInteger(
true, Operands);
799 if (checkForP2AlignIfLoadStore(Operands, Name))
802 if (parseSingleFloat(
true, Operands))
804 }
else if (!parseSpecialFloatMaybe(
true, Operands)) {
806 return error(
"Expected numeric constant instead got: ",
811 parseSingleInteger(
false, Operands);
812 if (checkForP2AlignIfLoadStore(Operands, Name))
816 if (parseSingleFloat(
false, Operands))
822 auto Op = std::make_unique<WebAssemblyOperand>(
826 Op->BrL.List.push_back(Lexer.getTok().getIntVal());
836 return error(
"Unexpected token in operand: ", Tok);
849 addBlockTypeOperand(Operands, NameLoc, WebAssembly::BlockType::Void);
852 Operands.
push_back(std::make_unique<WebAssemblyOperand>(
853 NameLoc, NameLoc, WebAssemblyOperand::CaLOp{}));
856 Operands.
push_back(std::move(FunctionTable));
861 bool parseSignature(wasm::WasmSignature *Signature) {
864 if (parseRegTypeList(Signature->
Params))
872 if (parseRegTypeList(Signature->
Returns))
880 auto Op = std::make_unique<WebAssemblyOperand>(
881 Lexer.getTok().getLoc(), SMLoc(), WebAssemblyOperand::CaLOp{});
888 auto CatchStr = expectIdent();
889 if (CatchStr.empty())
891 uint8_t CatchOpcode =
892 StringSwitch<uint8_t>(CatchStr)
898 if (CatchOpcode == 0xff)
900 "Expected catch/catch_ref/catch_all/catch_all_ref, instead got: " +
903 const MCExpr *
Tag =
nullptr;
906 if (Parser.parseExpression(
Tag))
907 return error(
"Cannot parse symbol: ", Lexer.getTok());
910 auto &DestTok = Lexer.getTok();
912 return error(
"Expected integer constant, instead got: ", DestTok);
913 unsigned Dest = DestTok.getIntVal();
916 EndLoc = Lexer.getTok().getEndLoc();
920 Op->CaL.List.push_back({CatchOpcode,
Tag, Dest});
928 bool checkDataSection() {
929 if (CurrentState != DataSection) {
930 auto *WS =
static_cast<const MCSectionWasm *
>(
931 getStreamer().getCurrentSectionOnly());
932 if (WS && WS->isText())
933 return error(
"data directive must occur in a data segment: ",
936 CurrentState = DataSection;
943 ParseStatus parseDirective(AsmToken DirectiveID)
override {
945 auto &Out = getStreamer();
947 reinterpret_cast<WebAssemblyTargetStreamer &
>(*Out.getTargetStreamer());
948 auto &Ctx = Out.getContext();
950 if (DirectiveID.
getString() ==
".globaltype") {
951 auto SymName = expectIdent();
956 auto TypeTok = Lexer.getTok();
962 return error(
"Unknown type in .globaltype directive: ", TypeTok);
968 TypeTok = Lexer.getTok();
969 auto Id = expectIdent();
972 if (Id ==
"immutable")
976 return error(
"Unknown type in .globaltype modifier: ", TypeTok);
982 WasmSym->setGlobalType(wasm::WasmGlobalType{uint8_t(*
Type), Mutable});
984 TOut.emitGlobalType(WasmSym);
988 if (DirectiveID.
getString() ==
".tabletype") {
990 auto SymName = expectIdent();
996 auto ElemTypeTok = Lexer.getTok();
997 auto ElemTypeName = expectIdent();
998 if (ElemTypeName.empty())
1000 std::optional<wasm::ValType> ElemType =
1003 return error(
"Unknown type in .tabletype directive: ", ElemTypeTok);
1005 wasm::WasmLimits Limits = defaultLimits();
1017 wasm::WasmTableType
Type = {*ElemType, Limits};
1018 WasmSym->setTableType(
Type);
1019 TOut.emitTableType(WasmSym);
1023 if (DirectiveID.
getString() ==
".functype") {
1029 auto SymName = expectIdent();
1030 if (SymName.empty())
1034 if (WasmSym->isDefined()) {
1045 if (CurrentState != FunctionLabel) {
1047 if (ensureEmptyNestingStack())
1051 CurrentState = FunctionStart;
1052 LastFunctionLabel = WasmSym;
1055 if (parseSignature(Signature))
1057 if (CurrentState == FunctionStart)
1058 TC.funcDecl(*Signature);
1059 WasmSym->setSignature(Signature);
1061 TOut.emitFunctionType(WasmSym);
1066 if (DirectiveID.
getString() ==
".export_name") {
1067 auto SymName = expectIdent();
1068 if (SymName.empty())
1072 auto ExportName = expectIdent();
1073 if (ExportName.empty())
1078 TOut.emitExportName(WasmSym, ExportName);
1082 if (DirectiveID.
getString() ==
".import_module") {
1083 auto SymName = expectIdent();
1084 if (SymName.empty())
1088 auto ImportModule = expectIdent();
1089 if (ImportModule.empty())
1094 TOut.emitImportModule(WasmSym, ImportModule);
1098 if (DirectiveID.
getString() ==
".import_name") {
1099 auto SymName = expectIdent();
1100 if (SymName.empty())
1104 auto ImportName = expectIdent();
1105 if (ImportName.empty())
1110 TOut.emitImportName(WasmSym, ImportName);
1114 if (DirectiveID.
getString() ==
".tagtype") {
1115 auto SymName = expectIdent();
1116 if (SymName.empty())
1121 if (parseRegTypeList(Signature->
Params))
1123 WasmSym->setSignature(Signature);
1125 TOut.emitTagType(WasmSym);
1130 if (DirectiveID.
getString() ==
".local") {
1131 if (CurrentState != FunctionStart)
1132 return error(
".local directive should follow the start of a function: ",
1135 if (parseRegTypeList(Locals))
1137 TC.localDecl(Locals);
1138 TOut.emitLocal(Locals);
1139 CurrentState = FunctionLocals;
1143 if (DirectiveID.
getString() ==
".int8" ||
1147 if (checkDataSection())
1151 if (Parser.parseExpression(Val, End))
1152 return error(
"Cannot parse .int expression: ", Lexer.getTok());
1155 Out.emitValue(Val, NumBits / 8, End);
1159 if (DirectiveID.
getString() ==
".asciz") {
1160 if (checkDataSection())
1163 if (Parser.parseEscapedString(S))
1164 return error(
"Cannot parse string constant: ", Lexer.getTok());
1165 Out.emitBytes(StringRef(S.c_str(), S.length() + 1));
1173 void ensureLocals(MCStreamer &Out) {
1174 if (CurrentState == FunctionStart) {
1178 auto &TOut =
reinterpret_cast<WebAssemblyTargetStreamer &
>(
1181 CurrentState = FunctionLocals;
1185 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned & ,
1187 uint64_t &ErrorInfo,
1188 bool MatchingInlineAsm)
override {
1191 FeatureBitset MissingFeatures;
1192 unsigned MatchResult = MatchInstructionImpl(
1193 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm);
1194 switch (MatchResult) {
1195 case Match_Success: {
1203 for (
unsigned E =
Desc.getNumOperands();
I <
E; ++
I) {
1206 if (
Op.getImm() == -1) {
1212 assert(
I < 2 &&
"Default p2align set but operand not found");
1219 static_cast<uint16_t
>(Inst.
getOpcode()));
1225 TC.typeCheck(IDLoc, Inst, Operands);
1227 if (CurrentState == EndFunction) {
1228 onEndOfFunction(IDLoc);
1230 CurrentState = Instructions;
1234 case Match_MissingFeature: {
1235 assert(MissingFeatures.
count() > 0 &&
"Expected missing features");
1236 SmallString<128> Message;
1237 raw_svector_ostream OS(Message);
1238 OS <<
"instruction requires:";
1239 for (
unsigned I = 0,
E = MissingFeatures.
size();
I !=
E; ++
I)
1240 if (MissingFeatures.
test(
I))
1242 return Parser.Error(IDLoc, Message);
1244 case Match_MnemonicFail:
1245 return Parser.Error(IDLoc,
"invalid instruction");
1246 case Match_NearMisses:
1247 return Parser.Error(IDLoc,
"ambiguous instruction");
1248 case Match_InvalidTiedOperand:
1249 case Match_InvalidOperand: {
1250 SMLoc ErrorLoc = IDLoc;
1251 if (ErrorInfo != ~0ULL) {
1252 if (ErrorInfo >= Operands.
size())
1253 return Parser.Error(IDLoc,
"too few operands for instruction");
1254 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
1255 if (ErrorLoc == SMLoc())
1258 return Parser.Error(ErrorLoc,
"invalid operand for instruction");
1264 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override {
1266 auto *CWS =
static_cast<const MCSectionWasm *
>(
1267 getStreamer().getCurrentSectionOnly());
1271 auto *WasmSym =
static_cast<MCSymbolWasm *
>(
Symbol);
1276 "Wasm doesn\'t support data symbols in text sections");
1283 auto SymName =
Symbol->getName();
1284 if (SymName.starts_with(
".L"))
1291 std::string SecName = (
".text." + SymName).str();
1293 auto *Group = CWS->getGroup();
1299 WasmSym->setComdat(
true);
1302 getStreamer().switchSection(WS);
1307 if (WasmSym->isFunction()) {
1317 ensureEmptyNestingStack(IDLoc);
1318 CurrentState = FunctionLabel;
1319 LastFunctionLabel =
Symbol;
1324 void onEndOfFunction(SMLoc ErrorLoc) {
1326 TC.endOfFunction(ErrorLoc,
true);
1331 void onEndOfFile()
override { ensureEmptyNestingStack(); }
1342#define GET_REGISTER_MATCHER
1343#define GET_SUBTARGET_FEATURE_NAME
1344#define GET_MATCHER_IMPLEMENTATION
1345#include "WebAssemblyGenAsmMatcher.inc"
1349 for (
auto &ME : MatchTable0) {
1350 if (ME.Opcode ==
Opc) {
1351 return ME.getMnemonic();
1354 assert(
false &&
"mnemonic not found");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static constexpr unsigned SM(unsigned Version)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyAsmParser()
StringRef getMnemonic(unsigned Opc)
static const char * getSubtargetFeatureName(uint64_t Val)
This file is part of the WebAssembly Assembler.
This file contains the declaration of the WebAssemblyMCAsmInfo class.
This file provides WebAssembly-specific target descriptions.
This file contains the declaration of the WebAssembly-specific type parsing utility functions.
This file registers the WebAssembly target.
This file declares WebAssembly-specific target streamer classes.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
constexpr bool test(unsigned I) const
constexpr size_t size() const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Context object for machine code objects.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI wasm::WasmSignature * createWasmSignature()
Allocates and returns a new WasmSignature instance (with empty parameter and return type lists).
StringRef allocateString(StringRef s)
Allocates a copy of the given string on the allocator managed by this context and returns the result.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createSFPImm(uint32_t Val)
static MCOperand createImm(int64_t Val)
static MCOperand createDFPImm(uint64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NonUniqueID
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
bool checkFeatures(StringRef FS) const
Check whether the subtarget features are enabled/disabled as per the provided string,...
const FeatureBitset & getFeatureBits() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
void setFunctionTable(bool is64)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static constexpr StatusTy Failure
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
static SectionKind getText()
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
LLVM_ABI void clear()
Clears function-level state.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
@ C
The default llvm calling convention, compatible with C.
int32_t getWasm64Opcode(uint32_t Opcode)
MCSymbolWasm * getOrCreateFunctionTableSymbol(MCContext &Ctx, const WebAssemblySubtarget *Subtarget)
Returns the __indirect_function_table, for use in call_indirect and in function bitcasts.
BlockType parseBlockType(StringRef Type)
BlockType
Used as immediate MachineOperands for block signatures.
@ OPERAND_P2ALIGN
p2align immediate for load and store address alignment.
unsigned GetDefaultP2AlignAny(unsigned Opc)
Return the default p2align value for a load or store with the given opcode.
std::optional< wasm::ValType > parseType(StringRef Type)
Context & getContext() const
@ WASM_OPCODE_CATCH_ALL_REF
@ WASM_LIMITS_FLAG_HAS_MAX
@ WASM_SYMBOL_TYPE_GLOBAL
@ WASM_SYMBOL_TYPE_FUNCTION
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
Target & getTheWebAssemblyTarget32()
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
Target & getTheWebAssemblyTarget64()
To bit_cast(const From &from) noexcept
DWARFExpression::Operation Op
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
SmallVector< ValType, 1 > Returns
SmallVector< ValType, 4 > Params