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(Val: 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(Val: 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 | // Whether we use the new exnref Wasm EH proposal adopted on Oct 2023. |
58 | // Should be used with -wasm-enable-eh. |
59 | // Currently set to false by default, but will later change to true and then |
60 | // later can be removed after the legacy WAsm EH instructions are removed. |
61 | cl::opt<bool> WebAssembly::WasmEnableExnref( |
62 | "wasm-enable-exnref" , cl::desc("WebAssembly exception handling (exnref)" ), |
63 | cl::init(Val: false)); |
64 | |
65 | static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/, |
66 | const Triple &TT, |
67 | const MCTargetOptions &Options) { |
68 | return new WebAssemblyMCAsmInfo(TT, Options); |
69 | } |
70 | |
71 | static MCInstrInfo *createMCInstrInfo() { |
72 | auto *X = new MCInstrInfo(); |
73 | InitWebAssemblyMCInstrInfo(II: X); |
74 | return X; |
75 | } |
76 | |
77 | static MCRegisterInfo *createMCRegisterInfo(const Triple & /*T*/) { |
78 | auto *X = new MCRegisterInfo(); |
79 | InitWebAssemblyMCRegisterInfo(RI: X, RA: 0); |
80 | return X; |
81 | } |
82 | |
83 | static MCInstPrinter *createMCInstPrinter(const Triple & /*T*/, |
84 | unsigned SyntaxVariant, |
85 | const MCAsmInfo &MAI, |
86 | const MCInstrInfo &MII, |
87 | const MCRegisterInfo &MRI) { |
88 | assert(SyntaxVariant == 0 && "WebAssembly only has one syntax variant" ); |
89 | return new WebAssemblyInstPrinter(MAI, MII, MRI); |
90 | } |
91 | |
92 | static MCCodeEmitter *createCodeEmitter(const MCInstrInfo &MCII, |
93 | MCContext &Ctx) { |
94 | return createWebAssemblyMCCodeEmitter(MCII, Ctx); |
95 | } |
96 | |
97 | static MCAsmBackend *createAsmBackend(const Target & /*T*/, |
98 | const MCSubtargetInfo &STI, |
99 | const MCRegisterInfo & /*MRI*/, |
100 | const MCTargetOptions & /*Options*/) { |
101 | return createWebAssemblyAsmBackend(TT: STI.getTargetTriple()); |
102 | } |
103 | |
104 | static MCSubtargetInfo *createMCSubtargetInfo(const Triple &TT, StringRef CPU, |
105 | StringRef FS) { |
106 | return createWebAssemblyMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); |
107 | } |
108 | |
109 | static MCTargetStreamer * |
110 | createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { |
111 | return new WebAssemblyTargetWasmStreamer(S); |
112 | } |
113 | |
114 | static MCTargetStreamer * |
115 | createAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, |
116 | MCInstPrinter * /*InstPrint*/) { |
117 | return new WebAssemblyTargetAsmStreamer(S, OS); |
118 | } |
119 | |
120 | static MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) { |
121 | return new WebAssemblyTargetNullStreamer(S); |
122 | } |
123 | |
124 | // Force static initialization. |
125 | extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTargetMC() { |
126 | for (Target *T : |
127 | {&getTheWebAssemblyTarget32(), &getTheWebAssemblyTarget64()}) { |
128 | // Register the MC asm info. |
129 | RegisterMCAsmInfoFn X(*T, createMCAsmInfo); |
130 | |
131 | // Register the MC instruction info. |
132 | TargetRegistry::RegisterMCInstrInfo(T&: *T, Fn: createMCInstrInfo); |
133 | |
134 | // Register the MC register info. |
135 | TargetRegistry::RegisterMCRegInfo(T&: *T, Fn: createMCRegisterInfo); |
136 | |
137 | // Register the MCInstPrinter. |
138 | TargetRegistry::RegisterMCInstPrinter(T&: *T, Fn: createMCInstPrinter); |
139 | |
140 | // Register the MC code emitter. |
141 | TargetRegistry::RegisterMCCodeEmitter(T&: *T, Fn: createCodeEmitter); |
142 | |
143 | // Register the ASM Backend. |
144 | TargetRegistry::RegisterMCAsmBackend(T&: *T, Fn: createAsmBackend); |
145 | |
146 | // Register the MC subtarget info. |
147 | TargetRegistry::RegisterMCSubtargetInfo(T&: *T, Fn: createMCSubtargetInfo); |
148 | |
149 | // Register the object target streamer. |
150 | TargetRegistry::RegisterObjectTargetStreamer(T&: *T, |
151 | Fn: createObjectTargetStreamer); |
152 | // Register the asm target streamer. |
153 | TargetRegistry::RegisterAsmTargetStreamer(T&: *T, Fn: createAsmTargetStreamer); |
154 | // Register the null target streamer. |
155 | TargetRegistry::RegisterNullTargetStreamer(T&: *T, Fn: createNullTargetStreamer); |
156 | } |
157 | } |
158 | |