xref: /llvm-project/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp (revision a8e1135baa9074f7c088c8e1999561f88699b56e)
1 //===-- WebAssemblyMCTargetDesc.cpp - WebAssembly Target Descriptions -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file provides WebAssembly-specific target descriptions.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
15 #include "MCTargetDesc/WebAssemblyInstPrinter.h"
16 #include "MCTargetDesc/WebAssemblyMCAsmInfo.h"
17 #include "MCTargetDesc/WebAssemblyTargetStreamer.h"
18 #include "TargetInfo/WebAssemblyTargetInfo.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/MC/TargetRegistry.h"
23 #include "llvm/Support/ErrorHandling.h"
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "wasm-mc-target-desc"
27 
28 #define GET_INSTRINFO_MC_DESC
29 #define ENABLE_INSTR_PREDICATE_VERIFIER
30 #include "WebAssemblyGenInstrInfo.inc"
31 
32 #define GET_SUBTARGETINFO_MC_DESC
33 #include "WebAssemblyGenSubtargetInfo.inc"
34 
35 #define GET_REGINFO_MC_DESC
36 #include "WebAssemblyGenRegisterInfo.inc"
37 
38 // Exception handling & setjmp-longjmp handling related options.
39 
40 // Emscripten's asm.js-style exception handling
41 cl::opt<bool> WebAssembly::WasmEnableEmEH(
42     "enable-emscripten-cxx-exceptions",
43     cl::desc("WebAssembly Emscripten-style exception handling"),
44     cl::init(false));
45 // Emscripten's asm.js-style setjmp/longjmp handling
46 cl::opt<bool> WebAssembly::WasmEnableEmSjLj(
47     "enable-emscripten-sjlj",
48     cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),
49     cl::init(false));
50 // Exception handling using wasm EH instructions
51 cl::opt<bool>
52     WebAssembly::WasmEnableEH("wasm-enable-eh",
53                               cl::desc("WebAssembly exception handling"));
54 // setjmp/longjmp handling using wasm EH instrutions
55 cl::opt<bool> WebAssembly::WasmEnableSjLj(
56     "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));
57 // If true, use the legacy Wasm EH proposal:
58 // https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md
59 // And if false, use the standardized Wasm EH proposal:
60 // https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
61 // Currently set to true by default because not all major web browsers turn on
62 // the new standard proposal by default, but will later change to false.
63 cl::opt<bool> WebAssembly::WasmUseLegacyEH(
64     "wasm-use-legacy-eh", cl::desc("WebAssembly exception handling (legacy)"),
65     cl::init(true));
66 
67 static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/,
68                                   const Triple &TT,
69                                   const MCTargetOptions &Options) {
70   return new WebAssemblyMCAsmInfo(TT, Options);
71 }
72 
73 static MCInstrInfo *createMCInstrInfo() {
74   auto *X = new MCInstrInfo();
75   InitWebAssemblyMCInstrInfo(X);
76   return X;
77 }
78 
79 static MCRegisterInfo *createMCRegisterInfo(const Triple & /*T*/) {
80   auto *X = new MCRegisterInfo();
81   InitWebAssemblyMCRegisterInfo(X, 0);
82   return X;
83 }
84 
85 static MCInstPrinter *createMCInstPrinter(const Triple & /*T*/,
86                                           unsigned SyntaxVariant,
87                                           const MCAsmInfo &MAI,
88                                           const MCInstrInfo &MII,
89                                           const MCRegisterInfo &MRI) {
90   assert(SyntaxVariant == 0 && "WebAssembly only has one syntax variant");
91   return new WebAssemblyInstPrinter(MAI, MII, MRI);
92 }
93 
94 static MCCodeEmitter *createCodeEmitter(const MCInstrInfo &MCII,
95                                         MCContext &Ctx) {
96   return createWebAssemblyMCCodeEmitter(MCII, Ctx);
97 }
98 
99 static MCAsmBackend *createAsmBackend(const Target & /*T*/,
100                                       const MCSubtargetInfo &STI,
101                                       const MCRegisterInfo & /*MRI*/,
102                                       const MCTargetOptions & /*Options*/) {
103   return createWebAssemblyAsmBackend(STI.getTargetTriple());
104 }
105 
106 static MCSubtargetInfo *createMCSubtargetInfo(const Triple &TT, StringRef CPU,
107                                               StringRef FS) {
108   return createWebAssemblyMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
109 }
110 
111 static MCTargetStreamer *
112 createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
113   return new WebAssemblyTargetWasmStreamer(S);
114 }
115 
116 static MCTargetStreamer *
117 createAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
118                         MCInstPrinter * /*InstPrint*/) {
119   return new WebAssemblyTargetAsmStreamer(S, OS);
120 }
121 
122 static MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) {
123   return new WebAssemblyTargetNullStreamer(S);
124 }
125 
126 // Force static initialization.
127 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTargetMC() {
128   for (Target *T :
129        {&getTheWebAssemblyTarget32(), &getTheWebAssemblyTarget64()}) {
130     // Register the MC asm info.
131     RegisterMCAsmInfoFn X(*T, createMCAsmInfo);
132 
133     // Register the MC instruction info.
134     TargetRegistry::RegisterMCInstrInfo(*T, createMCInstrInfo);
135 
136     // Register the MC register info.
137     TargetRegistry::RegisterMCRegInfo(*T, createMCRegisterInfo);
138 
139     // Register the MCInstPrinter.
140     TargetRegistry::RegisterMCInstPrinter(*T, createMCInstPrinter);
141 
142     // Register the MC code emitter.
143     TargetRegistry::RegisterMCCodeEmitter(*T, createCodeEmitter);
144 
145     // Register the ASM Backend.
146     TargetRegistry::RegisterMCAsmBackend(*T, createAsmBackend);
147 
148     // Register the MC subtarget info.
149     TargetRegistry::RegisterMCSubtargetInfo(*T, createMCSubtargetInfo);
150 
151     // Register the object target streamer.
152     TargetRegistry::RegisterObjectTargetStreamer(*T,
153                                                  createObjectTargetStreamer);
154     // Register the asm target streamer.
155     TargetRegistry::RegisterAsmTargetStreamer(*T, createAsmTargetStreamer);
156     // Register the null target streamer.
157     TargetRegistry::RegisterNullTargetStreamer(*T, createNullTargetStreamer);
158   }
159 }
160