40#define DEBUG_TYPE "wasm-asm-parser"
59 SMLoc StartLoc, EndLoc;
78 std::vector<unsigned> List;
88 std::vector<CaLOpElem> List;
92 std::vector<uint8_t> List;
105 WebAssemblyOperand(SMLoc Start, SMLoc
End, TokOp
T)
106 : Kind(Token), StartLoc(
Start), EndLoc(
End), Tok(
T) {}
107 WebAssemblyOperand(SMLoc Start, SMLoc
End, IntOp
I)
108 : Kind(Integer), StartLoc(
Start), EndLoc(
End),
Int(
I) {}
109 WebAssemblyOperand(SMLoc Start, SMLoc
End, FltOp
F)
110 : Kind(Float), StartLoc(
Start), EndLoc(
End), Flt(
F) {}
111 WebAssemblyOperand(SMLoc Start, SMLoc
End, SymOp S)
112 : Kind(Symbol), StartLoc(
Start), EndLoc(
End), Sym(S) {}
113 WebAssemblyOperand(SMLoc Start, SMLoc
End, BrLOp
B)
114 : Kind(BrList), StartLoc(
Start), EndLoc(
End), BrL(
B) {}
115 WebAssemblyOperand(SMLoc Start, SMLoc
End, CaLOp
C)
116 : Kind(CatchList), StartLoc(
Start), EndLoc(
End), CaL(
C) {}
117 WebAssemblyOperand(SMLoc Start, SMLoc
End, TyLOp
T)
118 : Kind(TypeList), StartLoc(
Start), EndLoc(
End), TyL(
T) {}
120 ~WebAssemblyOperand()
override {
129 bool isToken()
const override {
return Kind == Token; }
130 bool isImm()
const override {
return Kind == Integer || Kind == Symbol; }
131 bool isFPImm()
const {
return Kind == Float; }
132 bool isMem()
const override {
return false; }
133 bool isReg()
const override {
return false; }
134 bool isBrList()
const {
return Kind == BrList; }
135 bool isCatchList()
const {
return Kind == CatchList; }
136 bool isTypeList()
const {
return Kind == TypeList; }
138 MCRegister
getReg()
const override {
148 SMLoc getStartLoc()
const override {
return StartLoc; }
149 SMLoc getEndLoc()
const override {
return EndLoc; }
151 void addRegOperands(MCInst &,
unsigned)
const {
156 void addImmOperands(MCInst &Inst,
unsigned N)
const {
157 assert(
N == 1 &&
"Invalid number of operands!");
160 else if (Kind == Symbol)
166 void addFPImmf32Operands(MCInst &Inst,
unsigned N)
const {
167 assert(
N == 1 &&
"Invalid number of operands!");
175 void addFPImmf64Operands(MCInst &Inst,
unsigned N)
const {
176 assert(
N == 1 &&
"Invalid number of operands!");
183 void addBrListOperands(MCInst &Inst,
unsigned N)
const {
184 assert(
N == 1 && isBrList() &&
"Invalid BrList!");
185 for (
auto Br : BrL.List)
189 void addCatchListOperands(MCInst &Inst,
unsigned N)
const {
190 assert(
N == 1 && isCatchList() &&
"Invalid CatchList!");
192 for (
auto Ca : CaL.List) {
201 void addTypeListOperands(MCInst &Inst,
unsigned N)
const {
202 assert(
N == 1 && isTypeList() &&
"Invalid TypeList!");
204 for (
auto Ty : TyL.List)
208 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
211 OS <<
"Tok:" << Tok.Tok;
214 OS <<
"Int:" <<
Int.Val;
217 OS <<
"Flt:" << Flt.Val;
220 OS <<
"Sym:" << Sym.Exp;
223 OS <<
"BrList:" << BrL.List.size();
226 OS <<
"CaList:" << CaL.List.size();
229 OS <<
"TyList:" << TyL.List.size();
243 auto *Sym =
static_cast<MCSymbolWasm *
>(Ctx.lookupSymbol(Name));
245 if (!Sym->isFunctionTable())
246 Ctx.reportError(
SMLoc(),
"symbol is not a wasm funcref table");
248 Sym =
static_cast<MCSymbolWasm *
>(Ctx.getOrCreateSymbol(Name));
273 } CurrentState = FileStart;
289 wasm::WasmSignature Sig;
291 std::vector<Nested> NestingStack;
293 MCSymbolWasm *DefaultFunctionTable =
nullptr;
294 MCSymbol *LastFunctionLabel =
nullptr;
298 WebAssemblyAsmTypeCheck TC;
303 WebAssemblyAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
304 const MCInstrInfo &MII)
305 : MCTargetAsmParser(STI, MII), Parser(Parser), Lexer(Parser.getLexer()),
306 Is64(STI.getTargetTriple().isArch64Bit()), TC(Parser, MII, Is64),
307 SkipTypeCheck(Parser.
getContext().getTargetOptions().MCNoTypeCheck) {
308 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
311 auto &SM = Parser.getSourceManager();
313 SM.getBufferInfo(SM.getMainFileID()).Buffer->getBufferIdentifier();
314 if (BufferName ==
"<inline asm>")
315 SkipTypeCheck =
true;
318 void Initialize(MCAsmParser &Parser)
override {
322 getContext(),
"__indirect_function_table", Is64);
325 DefaultFunctionTable->setOmitFromLinkingSection();
328#define GET_ASSEMBLER_HEADER
329#include "WebAssemblyGenAsmMatcher.inc"
335 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
336 SMLoc &EndLoc)
override {
340 bool error(
const Twine &
Msg,
const AsmToken &Tok) {
344 bool error(
const Twine &
Msg, SMLoc Loc = SMLoc()) {
345 return Parser.Error(Loc.isValid() ? Loc : Lexer.getTok().getLoc(),
Msg);
348 std::pair<StringRef, StringRef> nestingString(NestingType NT) {
351 return {
"function",
"end_function"};
353 return {
"block",
"end_block"};
355 return {
"loop",
"end_loop"};
357 return {
"try",
"end_try/delegate"};
359 return {
"catch_all",
"end_try"};
361 return {
"try_table",
"end_try_table"};
363 return {
"if",
"end_if"};
365 return {
"else",
"end_if"};
371 void push(NestingType NT, wasm::WasmSignature Sig = wasm::WasmSignature()) {
372 NestingStack.push_back({
NT, Sig});
375 bool pop(StringRef Ins, NestingType NT1, NestingType NT2 = Undefined) {
376 if (NestingStack.empty())
377 return error(Twine(
"End of block construct with no start: ") + Ins);
378 auto Top = NestingStack.back();
379 if (Top.NT != NT1 && Top.NT != NT2)
380 return error(Twine(
"Block construct type mismatch, expected: ") +
381 nestingString(Top.NT).second +
", instead got: " + Ins);
382 TC.setLastSig(Top.Sig);
383 NestingStack.pop_back();
389 bool popAndPushWithSameSignature(StringRef Ins, NestingType PopNT,
390 NestingType PushNT) {
391 if (NestingStack.empty())
392 return error(Twine(
"End of block construct with no start: ") + Ins);
393 auto Sig = NestingStack.back().Sig;
400 bool ensureEmptyNestingStack(SMLoc Loc = SMLoc()) {
401 auto Err = !NestingStack.empty();
402 while (!NestingStack.empty()) {
403 error(Twine(
"Unmatched block construct(s) at function end: ") +
404 nestingString(NestingStack.back().NT).first,
406 NestingStack.pop_back();
412 auto Ok = Lexer.is(Kind);
420 return error(std::string(
"Expected ") + KindName +
", instead got: ",
425 StringRef expectIdent() {
427 error(
"Expected identifier, got: ", Lexer.getTok());
430 auto Name = Lexer.getTok().getString();
435 StringRef expectStringOrIdent() {
437 auto Str = Lexer.getTok().getStringContents();
442 auto Name = Lexer.getTok().getString();
446 error(
"Expected string or identifier, got: ", Lexer.getTok());
450 bool parseRegTypeList(SmallVectorImpl<wasm::ValType> &Types) {
452 auto Type = WebAssembly::parseType(Lexer.getTok().getString());
454 return error(
"unknown type: ", Lexer.getTok());
464 auto &
Int = Lexer.getTok();
465 int64_t Val =
Int.getIntVal();
468 Operands.push_back(std::make_unique<WebAssemblyOperand>(
469 Int.getLoc(),
Int.getEndLoc(), WebAssemblyOperand::IntOp{Val}));
474 auto &Flt = Lexer.getTok();
476 if (Flt.getString().getAsDouble(Val,
false))
477 return error(
"Cannot parse real: ", Flt);
480 Operands.push_back(std::make_unique<WebAssemblyOperand>(
481 Flt.getLoc(), Flt.getEndLoc(), WebAssemblyOperand::FltOp{Val}));
489 auto &Flt = Lexer.getTok();
490 auto S = Flt.getString();
492 if (S.compare_insensitive(
"infinity") == 0) {
493 Val = std::numeric_limits<double>::infinity();
494 }
else if (S.compare_insensitive(
"nan") == 0) {
495 Val = std::numeric_limits<double>::quiet_NaN();
501 Operands.push_back(std::make_unique<WebAssemblyOperand>(
502 Flt.getLoc(), Flt.getEndLoc(), WebAssemblyOperand::FltOp{Val}));
508 auto &Tok = Lexer.getTok();
512 Order = StringSwitch<int64_t>(S)
519 "memory ordering requires acquire-release-atomics feature: ",
526 Operands.push_back(std::make_unique<WebAssemblyOperand>(
533 auto IsLoadStore = InstName.
contains(
".load") ||
536 auto IsAtomic = InstName.
contains(
"atomic.");
537 if (IsLoadStore || IsAtomic) {
540 auto Id = expectIdent();
542 return error(
"Expected p2align, instead got: " + Id);
546 return error(
"Expected integer constant");
547 parseSingleInteger(
false,
Operands);
552 auto IsLoadStoreLane = InstName.
contains(
"_lane");
553 if (IsLoadStoreLane &&
Operands.size() == 4)
559 auto Tok = Lexer.getTok();
560 Operands.push_back(std::make_unique<WebAssemblyOperand>(
568 WebAssembly::BlockType
BT) {
569 if (
BT == WebAssembly::BlockType::Void) {
570 TC.setLastSig(wasm::WasmSignature{});
574 NestingStack.back().Sig = Sig;
576 Operands.push_back(std::make_unique<WebAssemblyOperand>(
577 NameLoc, NameLoc, WebAssemblyOperand::IntOp{
static_cast<int64_t
>(
BT)}));
580 bool parseLimits(wasm::WasmLimits *Limits) {
581 auto Tok = Lexer.getTok();
583 return error(
"Expected integer constant, instead got: ", Tok);
591 auto Tok = Lexer.getTok();
593 return error(
"Expected integer constant, instead got: ", Tok);
602 bool parseFunctionTableOperand(std::unique_ptr<WebAssemblyOperand> *
Op) {
610 auto &Tok = Lexer.getTok();
615 *
Op = std::make_unique<WebAssemblyOperand>(
622 *
Op = std::make_unique<WebAssemblyOperand>(
623 SMLoc(), SMLoc(), WebAssemblyOperand::SymOp{Val});
630 *
Op = std::make_unique<WebAssemblyOperand>(SMLoc(), SMLoc(),
631 WebAssemblyOperand::IntOp{0});
635 bool parseInstruction(ParseInstructionInfo & , StringRef Name,
645 auto &Sep = Lexer.getTok();
646 if (Sep.getLoc().getPointer() !=
Name.end() ||
650 Name = StringRef(
Name.begin(),
Name.size() + Sep.getString().size());
653 auto &
Id = Lexer.getTok();
655 Id.getLoc().getPointer() !=
Name.end())
656 return error(
"Incomplete instruction name: ", Id);
657 Name = StringRef(
Name.begin(),
Name.size() +
Id.getString().size());
662 Operands.push_back(std::make_unique<WebAssemblyOperand>(
664 WebAssemblyOperand::TokOp{Name}));
668 bool ExpectBlockType =
false;
669 bool ExpectFuncType =
false;
670 bool ExpectCatchList =
false;
671 std::unique_ptr<WebAssemblyOperand> FunctionTable;
672 if (Name ==
"block") {
674 ExpectBlockType =
true;
675 }
else if (Name ==
"loop") {
677 ExpectBlockType =
true;
678 }
else if (Name ==
"try") {
680 ExpectBlockType =
true;
681 }
else if (Name ==
"if") {
683 ExpectBlockType =
true;
684 }
else if (Name ==
"else") {
685 if (popAndPushWithSameSignature(Name, If, Else))
687 }
else if (Name ==
"catch") {
688 if (popAndPushWithSameSignature(Name, Try, Try))
690 }
else if (Name ==
"catch_all") {
691 if (popAndPushWithSameSignature(Name, Try, CatchAll))
693 }
else if (Name ==
"try_table") {
695 ExpectBlockType =
true;
696 ExpectCatchList =
true;
697 }
else if (Name ==
"end_if") {
698 if (pop(Name, If, Else))
700 }
else if (Name ==
"end_try") {
701 if (pop(Name, Try, CatchAll))
703 }
else if (Name ==
"end_try_table") {
704 if (pop(Name, TryTable))
706 }
else if (Name ==
"delegate") {
709 }
else if (Name ==
"end_loop") {
712 }
else if (Name ==
"end_block") {
713 if (pop(Name, Block))
715 }
else if (Name ==
"end_function") {
716 ensureLocals(getStreamer());
717 CurrentState = EndFunction;
718 if (pop(Name, Function) || ensureEmptyNestingStack())
720 }
else if (Name ==
"call_indirect" || Name ==
"return_call_indirect") {
724 if (parseFunctionTableOperand(&FunctionTable))
726 ExpectFuncType =
true;
727 }
else if (Name ==
"call_ref" || Name ==
"return_call_ref") {
730 ExpectFuncType =
true;
731 }
else if (Name ==
"ref.test") {
734 ExpectFuncType =
true;
735 }
else if (Name ==
"ref.cast") {
738 ExpectFuncType =
true;
739 }
else if (Name ==
"select") {
743 auto Op = std::make_unique<WebAssemblyOperand>(
744 Lexer.getLoc(), Lexer.getLoc(), WebAssemblyOperand::TyLOp{});
746 auto &
Id = Lexer.getTok();
747 auto Ty = WebAssembly::parseType(
Id.getString());
749 return error(
"unknown value type in select operand list: ", Id);
750 Op->TyL.List.push_back(
static_cast<uint8_t
>(*Ty));
751 Op->EndLoc =
Id.getEndLoc();
757 if (
Name.contains(
"atomic.")) {
763 auto PeekCatchList = [&]() {
766 AsmToken NextTok = Lexer.peekTok();
772 if (ExpectFuncType ||
779 auto Loc = Parser.getTok();
784 TC.setLastSig(*Signature);
786 NestingStack.back().Sig = *Signature;
787 ExpectBlockType =
false;
790 auto *WasmSym =
static_cast<MCSymbolWasm *
>(Sym);
791 WasmSym->setSignature(Signature);
795 Operands.push_back(std::make_unique<WebAssemblyOperand>(
796 Loc.getLoc(), Loc.getEndLoc(), WebAssemblyOperand::SymOp{Expr}));
806 if (ExpectCatchList && PeekCatchList()) {
807 if (ExpectBlockType) {
808 ExpectBlockType =
false;
809 addBlockTypeOperand(
Operands, NameLoc, WebAssembly::BlockType::Void);
813 ExpectCatchList =
false;
817 auto &Tok = Lexer.getTok();
820 if (!parseSpecialFloatMaybe(
false,
Operands))
822 auto &
Id = Lexer.getTok();
823 if (ExpectBlockType) {
825 auto BT = WebAssembly::parseBlockType(
Id.getString());
826 if (
BT == WebAssembly::BlockType::Invalid)
827 return error(
"Unknown block type: ", Id);
829 ExpectBlockType =
false;
833 if (ExpectCatchList && PeekCatchList()) {
836 ExpectCatchList =
false;
843 if (Parser.parseExpression(Val,
End))
844 return error(
"Cannot parse symbol: ", Lexer.getTok());
845 Operands.push_back(std::make_unique<WebAssemblyOperand>(
846 Start,
End, WebAssemblyOperand::SymOp{Val}));
847 if (checkForP2AlignIfLoadStore(
Operands, Name))
856 if (checkForP2AlignIfLoadStore(
Operands, Name))
859 if (parseSingleFloat(
true,
Operands))
861 }
else if (!parseSpecialFloatMaybe(
true,
Operands)) {
863 return error(
"Expected numeric constant instead got: ",
868 parseSingleInteger(
false,
Operands);
869 if (checkForP2AlignIfLoadStore(
Operands, Name))
873 if (parseSingleFloat(
false,
Operands))
879 auto Op = std::make_unique<WebAssemblyOperand>(
883 Op->BrL.List.push_back(Lexer.getTok().getIntVal());
893 return error(
"Unexpected token in operand: ", Tok);
906 addBlockTypeOperand(
Operands, NameLoc, WebAssembly::BlockType::Void);
909 Operands.push_back(std::make_unique<WebAssemblyOperand>(
910 NameLoc, NameLoc, WebAssemblyOperand::CaLOp{}));
913 Operands.push_back(std::move(FunctionTable));
921 if (parseRegTypeList(Signature->
Params))
929 if (parseRegTypeList(Signature->
Returns))
937 auto Op = std::make_unique<WebAssemblyOperand>(
938 Lexer.getTok().getLoc(), SMLoc(), WebAssemblyOperand::CaLOp{});
945 auto CatchStr = expectIdent();
946 if (CatchStr.empty())
948 uint8_t CatchOpcode =
949 StringSwitch<uint8_t>(CatchStr)
955 if (CatchOpcode == 0xff)
957 "Expected catch/catch_ref/catch_all/catch_all_ref, instead got: " +
960 const MCExpr *
Tag =
nullptr;
963 if (Parser.parseExpression(
Tag))
964 return error(
"Cannot parse symbol: ", Lexer.getTok());
967 auto &DestTok = Lexer.getTok();
969 return error(
"Expected integer constant, instead got: ", DestTok);
970 unsigned Dest = DestTok.getIntVal();
973 EndLoc = Lexer.getTok().getEndLoc();
977 Op->CaL.List.push_back({CatchOpcode,
Tag, Dest});
985 bool checkDataSection() {
986 if (CurrentState != DataSection) {
987 auto *WS =
static_cast<const MCSectionWasm *
>(
988 getStreamer().getCurrentSectionOnly());
989 if (WS && WS->isText())
990 return error(
"data directive must occur in a data segment: ",
993 CurrentState = DataSection;
1000 ParseStatus parseDirective(AsmToken DirectiveID)
override {
1002 auto &
Out = getStreamer();
1004 reinterpret_cast<WebAssemblyTargetStreamer &
>(*
Out.getTargetStreamer());
1005 auto &Ctx =
Out.getContext();
1007 if (DirectiveID.
getString() ==
".globaltype") {
1008 auto SymName = expectIdent();
1009 if (SymName.empty())
1013 auto TypeTok = Lexer.getTok();
1017 auto Type = WebAssembly::parseType(TypeName);
1019 return error(
"Unknown type in .globaltype directive: ", TypeTok);
1023 bool Mutable =
true;
1025 TypeTok = Lexer.getTok();
1026 auto Id = expectIdent();
1029 if (Id ==
"immutable")
1033 return error(
"Unknown type in .globaltype modifier: ", TypeTok);
1039 WasmSym->setGlobalType(wasm::WasmGlobalType{uint8_t(*
Type), Mutable});
1041 TOut.emitGlobalType(WasmSym);
1045 if (DirectiveID.
getString() ==
".tabletype") {
1047 auto SymName = expectIdent();
1048 if (SymName.empty())
1053 auto ElemTypeTok = Lexer.getTok();
1054 auto ElemTypeName = expectIdent();
1055 if (ElemTypeName.empty())
1057 std::optional<wasm::ValType> ElemType =
1058 WebAssembly::parseType(ElemTypeName);
1060 return error(
"Unknown type in .tabletype directive: ", ElemTypeTok);
1062 wasm::WasmLimits Limits = defaultLimits();
1074 wasm::WasmTableType
Type = {*ElemType, Limits};
1075 WasmSym->setTableType(
Type);
1076 TOut.emitTableType(WasmSym);
1080 if (DirectiveID.
getString() ==
".functype") {
1086 auto SymName = expectIdent();
1087 if (SymName.empty())
1091 if (WasmSym->isDefined()) {
1102 if (CurrentState != FunctionLabel) {
1104 if (ensureEmptyNestingStack())
1108 CurrentState = FunctionStart;
1109 LastFunctionLabel = WasmSym;
1114 if (CurrentState == FunctionStart)
1115 TC.funcDecl(*Signature);
1116 WasmSym->setSignature(Signature);
1118 TOut.emitFunctionType(WasmSym);
1123 if (DirectiveID.
getString() ==
".export_name") {
1124 auto SymName = expectIdent();
1125 if (SymName.empty())
1129 auto ExportName = expectStringOrIdent();
1130 if (ExportName.empty())
1135 TOut.emitExportName(WasmSym, ExportName);
1139 if (DirectiveID.
getString() ==
".import_module") {
1140 auto SymName = expectIdent();
1141 if (SymName.empty())
1145 auto ImportModule = expectStringOrIdent();
1146 if (ImportModule.empty())
1151 TOut.emitImportModule(WasmSym, ImportModule);
1155 if (DirectiveID.
getString() ==
".import_name") {
1156 auto SymName = expectIdent();
1157 if (SymName.empty())
1161 StringRef ImportName = expectStringOrIdent();
1162 if (ImportName.
empty())
1167 TOut.emitImportName(WasmSym, ImportName);
1171 if (DirectiveID.
getString() ==
".tagtype") {
1172 auto SymName = expectIdent();
1173 if (SymName.empty())
1178 if (parseRegTypeList(Signature->
Params))
1180 WasmSym->setSignature(Signature);
1182 TOut.emitTagType(WasmSym);
1187 if (DirectiveID.
getString() ==
".local") {
1188 if (CurrentState != FunctionStart)
1189 return error(
".local directive should follow the start of a function: ",
1192 if (parseRegTypeList(Locals))
1194 TC.localDecl(Locals);
1195 TOut.emitLocal(Locals);
1196 CurrentState = FunctionLocals;
1200 if (DirectiveID.
getString() ==
".int8" ||
1204 if (checkDataSection())
1208 if (Parser.parseExpression(Val,
End))
1209 return error(
"Cannot parse .int expression: ", Lexer.getTok());
1212 Out.emitValue(Val, NumBits / 8,
End);
1216 if (DirectiveID.
getString() ==
".asciz") {
1217 if (checkDataSection())
1220 if (Parser.parseEscapedString(S))
1221 return error(
"Cannot parse string constant: ", Lexer.getTok());
1222 Out.emitBytes(StringRef(S.c_str(), S.length() + 1));
1230 void ensureLocals(MCStreamer &Out) {
1231 if (CurrentState == FunctionStart) {
1235 auto &TOut =
reinterpret_cast<WebAssemblyTargetStreamer &
>(
1236 *
Out.getTargetStreamer());
1238 CurrentState = FunctionLocals;
1242 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned & ,
1245 bool MatchingInlineAsm)
override {
1248 FeatureBitset MissingFeatures;
1249 unsigned MatchResult = MatchInstructionImpl(
1250 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm);
1251 switch (MatchResult) {
1252 case Match_Success: {
1256 auto Align = WebAssembly::GetDefaultP2AlignAny(Inst.
getOpcode());
1260 for (
unsigned E =
Desc.getNumOperands();
I <
E; ++
I) {
1261 if (
Desc.operands()[
I].OperandType == WebAssembly::OPERAND_P2ALIGN) {
1263 if (
Op.getImm() == -1) {
1269 assert(
I < 2 &&
"Default p2align set but operand not found");
1275 auto Opc64 = WebAssembly::getWasm64Opcode(
1276 static_cast<uint16_t
>(Inst.
getOpcode()));
1282 TC.typeCheck(IDLoc, Inst,
Operands);
1283 Out.emitInstruction(Inst, getSTI());
1284 if (CurrentState == EndFunction) {
1285 onEndOfFunction(IDLoc);
1287 CurrentState = Instructions;
1291 case Match_MissingFeature: {
1292 assert(MissingFeatures.
count() > 0 &&
"Expected missing features");
1293 SmallString<128> Message;
1294 raw_svector_ostream OS(Message);
1295 OS <<
"instruction requires:";
1296 for (
unsigned I = 0,
E = MissingFeatures.
size();
I !=
E; ++
I)
1297 if (MissingFeatures.
test(
I))
1299 return Parser.Error(IDLoc, Message);
1301 case Match_MnemonicFail:
1302 return Parser.Error(IDLoc,
"invalid instruction");
1303 case Match_NearMisses:
1304 return Parser.Error(IDLoc,
"ambiguous instruction");
1305 case Match_InvalidTiedOperand:
1306 case Match_InvalidOperand: {
1307 SMLoc ErrorLoc = IDLoc;
1308 if (ErrorInfo != ~0ULL) {
1310 return Parser.Error(IDLoc,
"too few operands for instruction");
1311 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
1312 if (ErrorLoc == SMLoc())
1315 return Parser.Error(ErrorLoc,
"invalid operand for instruction");
1321 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override {
1323 auto *CWS =
static_cast<const MCSectionWasm *
>(
1324 getStreamer().getCurrentSectionOnly());
1328 auto *WasmSym =
static_cast<MCSymbolWasm *
>(
Symbol);
1333 "Wasm doesn\'t support data symbols in text sections");
1340 auto SymName =
Symbol->getName();
1341 if (SymName.starts_with(
".L"))
1348 std::string SecName = (
".text." + SymName).str();
1350 auto *Group = CWS->getGroup();
1356 WasmSym->setComdat(
true);
1359 getStreamer().switchSection(WS);
1364 if (WasmSym->isFunction()) {
1374 ensureEmptyNestingStack(IDLoc);
1375 CurrentState = FunctionLabel;
1376 LastFunctionLabel =
Symbol;
1381 void onEndOfFunction(SMLoc ErrorLoc) {
1383 TC.endOfFunction(ErrorLoc,
true);
1388 void onEndOfFile()
override { ensureEmptyNestingStack(); }
1399#define GET_REGISTER_MATCHER
1400#define GET_SUBTARGET_FEATURE_NAME
1401#define GET_MATCHER_IMPLEMENTATION
1402#include "WebAssemblyGenAsmMatcher.inc"
1406 for (
auto &ME : MatchTable0) {
1407 if (ME.Opcode ==
Opc) {
1408 return ME.getMnemonic();
1411 assert(
false &&
"mnemonic not found");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 Error parseSignature(Metadata *MD, SmallVectorImpl< SemanticSignatureElement > &Out, ModuleSignatureInfo &Info, Triple::EnvironmentType Stage, IOType IO, const VersionTuple &ShaderModelVersion, bool Native16, unsigned &Extent)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
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
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()
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.
constexpr bool empty() const
Check if the string is empty.
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.
#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.
MCSymbolWasm * getOrCreateFunctionTableSymbol(MCContext &Ctx, const WebAssemblySubtarget *Subtarget)
Returns the __indirect_function_table, for use in call_indirect and in function bitcasts.
@ 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
@ End
Run the machine verifier once, at the end of the pipeline.
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
SmallVector< ValType, 1 > Returns
SmallVector< ValType, 4 > Params