23 #include "llvm/IR/IntrinsicsWebAssembly.h"
31 #define DEBUG_TYPE "wasm-isel"
50 return "WebAssembly Instruction Selection";
55 "********** Function: "
63 void PreprocessISelDAG()
override;
67 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
68 std::vector<SDValue> &OutOps)
override;
71 #include "WebAssemblyGenDAGISel.inc"
78 void WebAssemblyDAGToDAGISel::PreprocessISelDAG() {
96 ? MF.createExternalSymbolName(
"__cpp_exception")
97 : MF.createExternalSymbolName(
"__c_longjmp");
103 if (Node->isMachineOpcode()) {
109 MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
110 auto GlobalGetIns = PtrVT ==
MVT::i64 ? WebAssembly::GLOBAL_GET_I64
111 : WebAssembly::GLOBAL_GET_I32;
116 switch (Node->getOpcode()) {
121 uint64_t SyncScopeID = Node->getConstantOperandVal(2);
123 switch (SyncScopeID) {
128 Fence = CurDAG->getMachineNode(WebAssembly::COMPILER_FENCE,
137 Fence = CurDAG->getMachineNode(
149 ReplaceNode(Node, Fence);
150 CurDAG->RemoveDeadNode(Node);
155 unsigned IntNo = Node->getConstantOperandVal(0);
157 case Intrinsic::wasm_tls_size: {
159 GlobalGetIns,
DL, PtrVT,
160 CurDAG->getTargetExternalSymbol(
"__tls_size", PtrVT));
161 ReplaceNode(Node, TLSSize);
165 case Intrinsic::wasm_tls_align: {
167 GlobalGetIns,
DL, PtrVT,
168 CurDAG->getTargetExternalSymbol(
"__tls_align", PtrVT));
169 ReplaceNode(Node, TLSAlign);
177 unsigned IntNo = Node->getConstantOperandVal(1);
178 const auto &TLI = CurDAG->getTargetLoweringInfo();
179 MVT PtrVT = TLI.getPointerTy(CurDAG->getDataLayout());
181 case Intrinsic::wasm_tls_base: {
184 CurDAG->getTargetExternalSymbol(
"__tls_base", PtrVT),
185 Node->getOperand(0));
186 ReplaceNode(Node, TLSBase);
190 case Intrinsic::wasm_catch: {
191 int Tag = Node->getConstantOperandVal(2);
194 CurDAG->getMachineNode(WebAssembly::CATCH,
DL,
203 ReplaceNode(Node, Catch);
211 unsigned IntNo = Node->getConstantOperandVal(1);
213 case Intrinsic::wasm_throw: {
214 int Tag = Node->getConstantOperandVal(2);
217 CurDAG->getMachineNode(WebAssembly::THROW,
DL,
224 ReplaceNode(Node, Throw);
232 case WebAssemblyISD::RET_CALL: {
238 for (
size_t i = 1;
i < Node->getNumOperands(); ++
i) {
241 Op =
Op->getOperand(0);
246 Ops.push_back(Node->getOperand(0));
248 CurDAG->getMachineNode(WebAssembly::CALL_PARAMS,
DL,
MVT::Glue, Ops);
251 ? WebAssembly::CALL_RESULTS
252 : WebAssembly::RET_CALL_RESULTS;
256 CurDAG->getMachineNode(
Results,
DL, Node->getVTList(),
Link);
257 ReplaceNode(Node, CallResults);
269 bool WebAssemblyDAGToDAGISel::SelectInlineAsmMemoryOperand(
270 const SDValue &
Op,
unsigned ConstraintID, std::vector<SDValue> &OutOps) {
271 switch (ConstraintID) {
275 OutOps.push_back(
Op);
288 return new WebAssemblyDAGToDAGISel(
TM, OptLevel);