WebAssemblyMCTargetDesc.h revision 360784
1//==- WebAssemblyMCTargetDesc.h - WebAssembly Target Descriptions -*- C++ -*-=//
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#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
15#define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
16
17#include "../WebAssemblySubtarget.h"
18#include "llvm/BinaryFormat/Wasm.h"
19#include "llvm/MC/MCInstrDesc.h"
20#include "llvm/Support/DataTypes.h"
21#include <memory>
22
23namespace llvm {
24
25class MCAsmBackend;
26class MCCodeEmitter;
27class MCContext;
28class MCInstrInfo;
29class MCObjectTargetWriter;
30class MCSubtargetInfo;
31class MVT;
32class Target;
33class Triple;
34class raw_pwrite_stream;
35
36MCCodeEmitter *createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII);
37
38MCAsmBackend *createWebAssemblyAsmBackend(const Triple &TT);
39
40std::unique_ptr<MCObjectTargetWriter>
41createWebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten);
42
43namespace WebAssembly {
44enum OperandType {
45  /// Basic block label in a branch construct.
46  OPERAND_BASIC_BLOCK = MCOI::OPERAND_FIRST_TARGET,
47  /// Local index.
48  OPERAND_LOCAL,
49  /// Global index.
50  OPERAND_GLOBAL,
51  /// 32-bit integer immediates.
52  OPERAND_I32IMM,
53  /// 64-bit integer immediates.
54  OPERAND_I64IMM,
55  /// 32-bit floating-point immediates.
56  OPERAND_F32IMM,
57  /// 64-bit floating-point immediates.
58  OPERAND_F64IMM,
59  /// 8-bit vector lane immediate
60  OPERAND_VEC_I8IMM,
61  /// 16-bit vector lane immediate
62  OPERAND_VEC_I16IMM,
63  /// 32-bit vector lane immediate
64  OPERAND_VEC_I32IMM,
65  /// 64-bit vector lane immediate
66  OPERAND_VEC_I64IMM,
67  /// 32-bit unsigned function indices.
68  OPERAND_FUNCTION32,
69  /// 32-bit unsigned memory offsets.
70  OPERAND_OFFSET32,
71  /// p2align immediate for load and store address alignment.
72  OPERAND_P2ALIGN,
73  /// signature immediate for block/loop.
74  OPERAND_SIGNATURE,
75  /// type signature immediate for call_indirect.
76  OPERAND_TYPEINDEX,
77  /// Event index.
78  OPERAND_EVENT,
79  /// A list of branch targets for br_list.
80  OPERAND_BRLIST,
81};
82} // end namespace WebAssembly
83
84namespace WebAssemblyII {
85
86/// Target Operand Flag enum.
87enum TOF {
88  MO_NO_FLAG = 0,
89
90  // On a symbol operand this indicates that the immediate is a wasm global
91  // index.  The value of the wasm global will be set to the symbol address at
92  // runtime.  This adds a level of indirection similar to the GOT on native
93  // platforms.
94  MO_GOT,
95
96  // On a symbol operand this indicates that the immediate is the symbol
97  // address relative the __memory_base wasm global.
98  // Only applicable to data symbols.
99  MO_MEMORY_BASE_REL,
100
101  // On a symbol operand this indicates that the immediate is the symbol
102  // address relative the __table_base wasm global.
103  // Only applicable to function symbols.
104  MO_TABLE_BASE_REL,
105};
106
107} // end namespace WebAssemblyII
108
109} // end namespace llvm
110
111// Defines symbolic names for WebAssembly registers. This defines a mapping from
112// register name to register number.
113//
114#define GET_REGINFO_ENUM
115#include "WebAssemblyGenRegisterInfo.inc"
116
117// Defines symbolic names for the WebAssembly instructions.
118//
119#define GET_INSTRINFO_ENUM
120#include "WebAssemblyGenInstrInfo.inc"
121
122namespace llvm {
123namespace WebAssembly {
124
125/// Used as immediate MachineOperands for block signatures
126enum class BlockType : unsigned {
127  Invalid = 0x00,
128  Void = 0x40,
129  I32 = unsigned(wasm::ValType::I32),
130  I64 = unsigned(wasm::ValType::I64),
131  F32 = unsigned(wasm::ValType::F32),
132  F64 = unsigned(wasm::ValType::F64),
133  V128 = unsigned(wasm::ValType::V128),
134  Exnref = unsigned(wasm::ValType::EXNREF),
135  // Multivalue blocks (and other non-void blocks) are only emitted when the
136  // blocks will never be exited and are at the ends of functions (see
137  // WebAssemblyCFGStackify::fixEndsAtEndOfFunction). They also are never made
138  // to pop values off the stack, so the exact multivalue signature can always
139  // be inferred from the return type of the parent function in MCInstLower.
140  Multivalue = 0xffff,
141};
142
143/// Instruction opcodes emitted via means other than CodeGen.
144static const unsigned Nop = 0x01;
145static const unsigned End = 0x0b;
146
147wasm::ValType toValType(const MVT &Ty);
148
149/// Return the default p2align value for a load or store with the given opcode.
150inline unsigned GetDefaultP2AlignAny(unsigned Opc) {
151  switch (Opc) {
152  case WebAssembly::LOAD8_S_I32:
153  case WebAssembly::LOAD8_S_I32_S:
154  case WebAssembly::LOAD8_U_I32:
155  case WebAssembly::LOAD8_U_I32_S:
156  case WebAssembly::LOAD8_S_I64:
157  case WebAssembly::LOAD8_S_I64_S:
158  case WebAssembly::LOAD8_U_I64:
159  case WebAssembly::LOAD8_U_I64_S:
160  case WebAssembly::ATOMIC_LOAD8_U_I32:
161  case WebAssembly::ATOMIC_LOAD8_U_I32_S:
162  case WebAssembly::ATOMIC_LOAD8_U_I64:
163  case WebAssembly::ATOMIC_LOAD8_U_I64_S:
164  case WebAssembly::STORE8_I32:
165  case WebAssembly::STORE8_I32_S:
166  case WebAssembly::STORE8_I64:
167  case WebAssembly::STORE8_I64_S:
168  case WebAssembly::ATOMIC_STORE8_I32:
169  case WebAssembly::ATOMIC_STORE8_I32_S:
170  case WebAssembly::ATOMIC_STORE8_I64:
171  case WebAssembly::ATOMIC_STORE8_I64_S:
172  case WebAssembly::ATOMIC_RMW8_U_ADD_I32:
173  case WebAssembly::ATOMIC_RMW8_U_ADD_I32_S:
174  case WebAssembly::ATOMIC_RMW8_U_ADD_I64:
175  case WebAssembly::ATOMIC_RMW8_U_ADD_I64_S:
176  case WebAssembly::ATOMIC_RMW8_U_SUB_I32:
177  case WebAssembly::ATOMIC_RMW8_U_SUB_I32_S:
178  case WebAssembly::ATOMIC_RMW8_U_SUB_I64:
179  case WebAssembly::ATOMIC_RMW8_U_SUB_I64_S:
180  case WebAssembly::ATOMIC_RMW8_U_AND_I32:
181  case WebAssembly::ATOMIC_RMW8_U_AND_I32_S:
182  case WebAssembly::ATOMIC_RMW8_U_AND_I64:
183  case WebAssembly::ATOMIC_RMW8_U_AND_I64_S:
184  case WebAssembly::ATOMIC_RMW8_U_OR_I32:
185  case WebAssembly::ATOMIC_RMW8_U_OR_I32_S:
186  case WebAssembly::ATOMIC_RMW8_U_OR_I64:
187  case WebAssembly::ATOMIC_RMW8_U_OR_I64_S:
188  case WebAssembly::ATOMIC_RMW8_U_XOR_I32:
189  case WebAssembly::ATOMIC_RMW8_U_XOR_I32_S:
190  case WebAssembly::ATOMIC_RMW8_U_XOR_I64:
191  case WebAssembly::ATOMIC_RMW8_U_XOR_I64_S:
192  case WebAssembly::ATOMIC_RMW8_U_XCHG_I32:
193  case WebAssembly::ATOMIC_RMW8_U_XCHG_I32_S:
194  case WebAssembly::ATOMIC_RMW8_U_XCHG_I64:
195  case WebAssembly::ATOMIC_RMW8_U_XCHG_I64_S:
196  case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I32:
197  case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I32_S:
198  case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64:
199  case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64_S:
200  case WebAssembly::LOAD_SPLAT_v8x16:
201  case WebAssembly::LOAD_SPLAT_v8x16_S:
202    return 0;
203  case WebAssembly::LOAD16_S_I32:
204  case WebAssembly::LOAD16_S_I32_S:
205  case WebAssembly::LOAD16_U_I32:
206  case WebAssembly::LOAD16_U_I32_S:
207  case WebAssembly::LOAD16_S_I64:
208  case WebAssembly::LOAD16_S_I64_S:
209  case WebAssembly::LOAD16_U_I64:
210  case WebAssembly::LOAD16_U_I64_S:
211  case WebAssembly::ATOMIC_LOAD16_U_I32:
212  case WebAssembly::ATOMIC_LOAD16_U_I32_S:
213  case WebAssembly::ATOMIC_LOAD16_U_I64:
214  case WebAssembly::ATOMIC_LOAD16_U_I64_S:
215  case WebAssembly::STORE16_I32:
216  case WebAssembly::STORE16_I32_S:
217  case WebAssembly::STORE16_I64:
218  case WebAssembly::STORE16_I64_S:
219  case WebAssembly::ATOMIC_STORE16_I32:
220  case WebAssembly::ATOMIC_STORE16_I32_S:
221  case WebAssembly::ATOMIC_STORE16_I64:
222  case WebAssembly::ATOMIC_STORE16_I64_S:
223  case WebAssembly::ATOMIC_RMW16_U_ADD_I32:
224  case WebAssembly::ATOMIC_RMW16_U_ADD_I32_S:
225  case WebAssembly::ATOMIC_RMW16_U_ADD_I64:
226  case WebAssembly::ATOMIC_RMW16_U_ADD_I64_S:
227  case WebAssembly::ATOMIC_RMW16_U_SUB_I32:
228  case WebAssembly::ATOMIC_RMW16_U_SUB_I32_S:
229  case WebAssembly::ATOMIC_RMW16_U_SUB_I64:
230  case WebAssembly::ATOMIC_RMW16_U_SUB_I64_S:
231  case WebAssembly::ATOMIC_RMW16_U_AND_I32:
232  case WebAssembly::ATOMIC_RMW16_U_AND_I32_S:
233  case WebAssembly::ATOMIC_RMW16_U_AND_I64:
234  case WebAssembly::ATOMIC_RMW16_U_AND_I64_S:
235  case WebAssembly::ATOMIC_RMW16_U_OR_I32:
236  case WebAssembly::ATOMIC_RMW16_U_OR_I32_S:
237  case WebAssembly::ATOMIC_RMW16_U_OR_I64:
238  case WebAssembly::ATOMIC_RMW16_U_OR_I64_S:
239  case WebAssembly::ATOMIC_RMW16_U_XOR_I32:
240  case WebAssembly::ATOMIC_RMW16_U_XOR_I32_S:
241  case WebAssembly::ATOMIC_RMW16_U_XOR_I64:
242  case WebAssembly::ATOMIC_RMW16_U_XOR_I64_S:
243  case WebAssembly::ATOMIC_RMW16_U_XCHG_I32:
244  case WebAssembly::ATOMIC_RMW16_U_XCHG_I32_S:
245  case WebAssembly::ATOMIC_RMW16_U_XCHG_I64:
246  case WebAssembly::ATOMIC_RMW16_U_XCHG_I64_S:
247  case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I32:
248  case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I32_S:
249  case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64:
250  case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64_S:
251  case WebAssembly::LOAD_SPLAT_v16x8:
252  case WebAssembly::LOAD_SPLAT_v16x8_S:
253    return 1;
254  case WebAssembly::LOAD_I32:
255  case WebAssembly::LOAD_I32_S:
256  case WebAssembly::LOAD_F32:
257  case WebAssembly::LOAD_F32_S:
258  case WebAssembly::STORE_I32:
259  case WebAssembly::STORE_I32_S:
260  case WebAssembly::STORE_F32:
261  case WebAssembly::STORE_F32_S:
262  case WebAssembly::LOAD32_S_I64:
263  case WebAssembly::LOAD32_S_I64_S:
264  case WebAssembly::LOAD32_U_I64:
265  case WebAssembly::LOAD32_U_I64_S:
266  case WebAssembly::STORE32_I64:
267  case WebAssembly::STORE32_I64_S:
268  case WebAssembly::ATOMIC_LOAD_I32:
269  case WebAssembly::ATOMIC_LOAD_I32_S:
270  case WebAssembly::ATOMIC_LOAD32_U_I64:
271  case WebAssembly::ATOMIC_LOAD32_U_I64_S:
272  case WebAssembly::ATOMIC_STORE_I32:
273  case WebAssembly::ATOMIC_STORE_I32_S:
274  case WebAssembly::ATOMIC_STORE32_I64:
275  case WebAssembly::ATOMIC_STORE32_I64_S:
276  case WebAssembly::ATOMIC_RMW_ADD_I32:
277  case WebAssembly::ATOMIC_RMW_ADD_I32_S:
278  case WebAssembly::ATOMIC_RMW32_U_ADD_I64:
279  case WebAssembly::ATOMIC_RMW32_U_ADD_I64_S:
280  case WebAssembly::ATOMIC_RMW_SUB_I32:
281  case WebAssembly::ATOMIC_RMW_SUB_I32_S:
282  case WebAssembly::ATOMIC_RMW32_U_SUB_I64:
283  case WebAssembly::ATOMIC_RMW32_U_SUB_I64_S:
284  case WebAssembly::ATOMIC_RMW_AND_I32:
285  case WebAssembly::ATOMIC_RMW_AND_I32_S:
286  case WebAssembly::ATOMIC_RMW32_U_AND_I64:
287  case WebAssembly::ATOMIC_RMW32_U_AND_I64_S:
288  case WebAssembly::ATOMIC_RMW_OR_I32:
289  case WebAssembly::ATOMIC_RMW_OR_I32_S:
290  case WebAssembly::ATOMIC_RMW32_U_OR_I64:
291  case WebAssembly::ATOMIC_RMW32_U_OR_I64_S:
292  case WebAssembly::ATOMIC_RMW_XOR_I32:
293  case WebAssembly::ATOMIC_RMW_XOR_I32_S:
294  case WebAssembly::ATOMIC_RMW32_U_XOR_I64:
295  case WebAssembly::ATOMIC_RMW32_U_XOR_I64_S:
296  case WebAssembly::ATOMIC_RMW_XCHG_I32:
297  case WebAssembly::ATOMIC_RMW_XCHG_I32_S:
298  case WebAssembly::ATOMIC_RMW32_U_XCHG_I64:
299  case WebAssembly::ATOMIC_RMW32_U_XCHG_I64_S:
300  case WebAssembly::ATOMIC_RMW_CMPXCHG_I32:
301  case WebAssembly::ATOMIC_RMW_CMPXCHG_I32_S:
302  case WebAssembly::ATOMIC_RMW32_U_CMPXCHG_I64:
303  case WebAssembly::ATOMIC_RMW32_U_CMPXCHG_I64_S:
304  case WebAssembly::ATOMIC_NOTIFY:
305  case WebAssembly::ATOMIC_NOTIFY_S:
306  case WebAssembly::ATOMIC_WAIT_I32:
307  case WebAssembly::ATOMIC_WAIT_I32_S:
308  case WebAssembly::LOAD_SPLAT_v32x4:
309  case WebAssembly::LOAD_SPLAT_v32x4_S:
310    return 2;
311  case WebAssembly::LOAD_I64:
312  case WebAssembly::LOAD_I64_S:
313  case WebAssembly::LOAD_F64:
314  case WebAssembly::LOAD_F64_S:
315  case WebAssembly::STORE_I64:
316  case WebAssembly::STORE_I64_S:
317  case WebAssembly::STORE_F64:
318  case WebAssembly::STORE_F64_S:
319  case WebAssembly::ATOMIC_LOAD_I64:
320  case WebAssembly::ATOMIC_LOAD_I64_S:
321  case WebAssembly::ATOMIC_STORE_I64:
322  case WebAssembly::ATOMIC_STORE_I64_S:
323  case WebAssembly::ATOMIC_RMW_ADD_I64:
324  case WebAssembly::ATOMIC_RMW_ADD_I64_S:
325  case WebAssembly::ATOMIC_RMW_SUB_I64:
326  case WebAssembly::ATOMIC_RMW_SUB_I64_S:
327  case WebAssembly::ATOMIC_RMW_AND_I64:
328  case WebAssembly::ATOMIC_RMW_AND_I64_S:
329  case WebAssembly::ATOMIC_RMW_OR_I64:
330  case WebAssembly::ATOMIC_RMW_OR_I64_S:
331  case WebAssembly::ATOMIC_RMW_XOR_I64:
332  case WebAssembly::ATOMIC_RMW_XOR_I64_S:
333  case WebAssembly::ATOMIC_RMW_XCHG_I64:
334  case WebAssembly::ATOMIC_RMW_XCHG_I64_S:
335  case WebAssembly::ATOMIC_RMW_CMPXCHG_I64:
336  case WebAssembly::ATOMIC_RMW_CMPXCHG_I64_S:
337  case WebAssembly::ATOMIC_WAIT_I64:
338  case WebAssembly::ATOMIC_WAIT_I64_S:
339  case WebAssembly::LOAD_SPLAT_v64x2:
340  case WebAssembly::LOAD_SPLAT_v64x2_S:
341  case WebAssembly::LOAD_EXTEND_S_v8i16:
342  case WebAssembly::LOAD_EXTEND_S_v8i16_S:
343  case WebAssembly::LOAD_EXTEND_U_v8i16:
344  case WebAssembly::LOAD_EXTEND_U_v8i16_S:
345  case WebAssembly::LOAD_EXTEND_S_v4i32:
346  case WebAssembly::LOAD_EXTEND_S_v4i32_S:
347  case WebAssembly::LOAD_EXTEND_U_v4i32:
348  case WebAssembly::LOAD_EXTEND_U_v4i32_S:
349  case WebAssembly::LOAD_EXTEND_S_v2i64:
350  case WebAssembly::LOAD_EXTEND_S_v2i64_S:
351  case WebAssembly::LOAD_EXTEND_U_v2i64:
352  case WebAssembly::LOAD_EXTEND_U_v2i64_S:
353    return 3;
354  case WebAssembly::LOAD_V128:
355  case WebAssembly::LOAD_V128_S:
356  case WebAssembly::STORE_V128:
357  case WebAssembly::STORE_V128_S:
358    return 4;
359  default:
360    return -1;
361  }
362}
363
364inline unsigned GetDefaultP2Align(unsigned Opc) {
365  auto Align = GetDefaultP2AlignAny(Opc);
366  if (Align == -1U) {
367    llvm_unreachable("Only loads and stores have p2align values");
368  }
369  return Align;
370}
371
372inline bool isArgument(unsigned Opc) {
373  switch (Opc) {
374  case WebAssembly::ARGUMENT_i32:
375  case WebAssembly::ARGUMENT_i32_S:
376  case WebAssembly::ARGUMENT_i64:
377  case WebAssembly::ARGUMENT_i64_S:
378  case WebAssembly::ARGUMENT_f32:
379  case WebAssembly::ARGUMENT_f32_S:
380  case WebAssembly::ARGUMENT_f64:
381  case WebAssembly::ARGUMENT_f64_S:
382  case WebAssembly::ARGUMENT_v16i8:
383  case WebAssembly::ARGUMENT_v16i8_S:
384  case WebAssembly::ARGUMENT_v8i16:
385  case WebAssembly::ARGUMENT_v8i16_S:
386  case WebAssembly::ARGUMENT_v4i32:
387  case WebAssembly::ARGUMENT_v4i32_S:
388  case WebAssembly::ARGUMENT_v2i64:
389  case WebAssembly::ARGUMENT_v2i64_S:
390  case WebAssembly::ARGUMENT_v4f32:
391  case WebAssembly::ARGUMENT_v4f32_S:
392  case WebAssembly::ARGUMENT_v2f64:
393  case WebAssembly::ARGUMENT_v2f64_S:
394  case WebAssembly::ARGUMENT_exnref:
395  case WebAssembly::ARGUMENT_exnref_S:
396    return true;
397  default:
398    return false;
399  }
400}
401
402inline bool isCopy(unsigned Opc) {
403  switch (Opc) {
404  case WebAssembly::COPY_I32:
405  case WebAssembly::COPY_I32_S:
406  case WebAssembly::COPY_I64:
407  case WebAssembly::COPY_I64_S:
408  case WebAssembly::COPY_F32:
409  case WebAssembly::COPY_F32_S:
410  case WebAssembly::COPY_F64:
411  case WebAssembly::COPY_F64_S:
412  case WebAssembly::COPY_V128:
413  case WebAssembly::COPY_V128_S:
414  case WebAssembly::COPY_EXNREF:
415  case WebAssembly::COPY_EXNREF_S:
416    return true;
417  default:
418    return false;
419  }
420}
421
422inline bool isTee(unsigned Opc) {
423  switch (Opc) {
424  case WebAssembly::TEE_I32:
425  case WebAssembly::TEE_I32_S:
426  case WebAssembly::TEE_I64:
427  case WebAssembly::TEE_I64_S:
428  case WebAssembly::TEE_F32:
429  case WebAssembly::TEE_F32_S:
430  case WebAssembly::TEE_F64:
431  case WebAssembly::TEE_F64_S:
432  case WebAssembly::TEE_V128:
433  case WebAssembly::TEE_V128_S:
434  case WebAssembly::TEE_EXNREF:
435  case WebAssembly::TEE_EXNREF_S:
436    return true;
437  default:
438    return false;
439  }
440}
441
442inline bool isCallDirect(unsigned Opc) {
443  switch (Opc) {
444  case WebAssembly::CALL_VOID:
445  case WebAssembly::CALL_VOID_S:
446  case WebAssembly::CALL_i32:
447  case WebAssembly::CALL_i32_S:
448  case WebAssembly::CALL_i64:
449  case WebAssembly::CALL_i64_S:
450  case WebAssembly::CALL_f32:
451  case WebAssembly::CALL_f32_S:
452  case WebAssembly::CALL_f64:
453  case WebAssembly::CALL_f64_S:
454  case WebAssembly::CALL_v16i8:
455  case WebAssembly::CALL_v16i8_S:
456  case WebAssembly::CALL_v8i16:
457  case WebAssembly::CALL_v8i16_S:
458  case WebAssembly::CALL_v4i32:
459  case WebAssembly::CALL_v4i32_S:
460  case WebAssembly::CALL_v2i64:
461  case WebAssembly::CALL_v2i64_S:
462  case WebAssembly::CALL_v4f32:
463  case WebAssembly::CALL_v4f32_S:
464  case WebAssembly::CALL_v2f64:
465  case WebAssembly::CALL_v2f64_S:
466  case WebAssembly::CALL_exnref:
467  case WebAssembly::CALL_exnref_S:
468  case WebAssembly::RET_CALL:
469  case WebAssembly::RET_CALL_S:
470    return true;
471  default:
472    return false;
473  }
474}
475
476inline bool isCallIndirect(unsigned Opc) {
477  switch (Opc) {
478  case WebAssembly::CALL_INDIRECT_VOID:
479  case WebAssembly::CALL_INDIRECT_VOID_S:
480  case WebAssembly::CALL_INDIRECT_i32:
481  case WebAssembly::CALL_INDIRECT_i32_S:
482  case WebAssembly::CALL_INDIRECT_i64:
483  case WebAssembly::CALL_INDIRECT_i64_S:
484  case WebAssembly::CALL_INDIRECT_f32:
485  case WebAssembly::CALL_INDIRECT_f32_S:
486  case WebAssembly::CALL_INDIRECT_f64:
487  case WebAssembly::CALL_INDIRECT_f64_S:
488  case WebAssembly::CALL_INDIRECT_v16i8:
489  case WebAssembly::CALL_INDIRECT_v16i8_S:
490  case WebAssembly::CALL_INDIRECT_v8i16:
491  case WebAssembly::CALL_INDIRECT_v8i16_S:
492  case WebAssembly::CALL_INDIRECT_v4i32:
493  case WebAssembly::CALL_INDIRECT_v4i32_S:
494  case WebAssembly::CALL_INDIRECT_v2i64:
495  case WebAssembly::CALL_INDIRECT_v2i64_S:
496  case WebAssembly::CALL_INDIRECT_v4f32:
497  case WebAssembly::CALL_INDIRECT_v4f32_S:
498  case WebAssembly::CALL_INDIRECT_v2f64:
499  case WebAssembly::CALL_INDIRECT_v2f64_S:
500  case WebAssembly::CALL_INDIRECT_exnref:
501  case WebAssembly::CALL_INDIRECT_exnref_S:
502  case WebAssembly::RET_CALL_INDIRECT:
503  case WebAssembly::RET_CALL_INDIRECT_S:
504    return true;
505  default:
506    return false;
507  }
508}
509
510/// Returns the operand number of a callee, assuming the argument is a call
511/// instruction.
512inline unsigned getCalleeOpNo(unsigned Opc) {
513  switch (Opc) {
514  case WebAssembly::CALL_VOID:
515  case WebAssembly::CALL_VOID_S:
516  case WebAssembly::CALL_INDIRECT_VOID:
517  case WebAssembly::CALL_INDIRECT_VOID_S:
518  case WebAssembly::RET_CALL:
519  case WebAssembly::RET_CALL_S:
520  case WebAssembly::RET_CALL_INDIRECT:
521  case WebAssembly::RET_CALL_INDIRECT_S:
522    return 0;
523  case WebAssembly::CALL_i32:
524  case WebAssembly::CALL_i32_S:
525  case WebAssembly::CALL_i64:
526  case WebAssembly::CALL_i64_S:
527  case WebAssembly::CALL_f32:
528  case WebAssembly::CALL_f32_S:
529  case WebAssembly::CALL_f64:
530  case WebAssembly::CALL_f64_S:
531  case WebAssembly::CALL_v16i8:
532  case WebAssembly::CALL_v16i8_S:
533  case WebAssembly::CALL_v8i16:
534  case WebAssembly::CALL_v8i16_S:
535  case WebAssembly::CALL_v4i32:
536  case WebAssembly::CALL_v4i32_S:
537  case WebAssembly::CALL_v2i64:
538  case WebAssembly::CALL_v2i64_S:
539  case WebAssembly::CALL_v4f32:
540  case WebAssembly::CALL_v4f32_S:
541  case WebAssembly::CALL_v2f64:
542  case WebAssembly::CALL_v2f64_S:
543  case WebAssembly::CALL_exnref:
544  case WebAssembly::CALL_exnref_S:
545  case WebAssembly::CALL_INDIRECT_i32:
546  case WebAssembly::CALL_INDIRECT_i32_S:
547  case WebAssembly::CALL_INDIRECT_i64:
548  case WebAssembly::CALL_INDIRECT_i64_S:
549  case WebAssembly::CALL_INDIRECT_f32:
550  case WebAssembly::CALL_INDIRECT_f32_S:
551  case WebAssembly::CALL_INDIRECT_f64:
552  case WebAssembly::CALL_INDIRECT_f64_S:
553  case WebAssembly::CALL_INDIRECT_v16i8:
554  case WebAssembly::CALL_INDIRECT_v16i8_S:
555  case WebAssembly::CALL_INDIRECT_v8i16:
556  case WebAssembly::CALL_INDIRECT_v8i16_S:
557  case WebAssembly::CALL_INDIRECT_v4i32:
558  case WebAssembly::CALL_INDIRECT_v4i32_S:
559  case WebAssembly::CALL_INDIRECT_v2i64:
560  case WebAssembly::CALL_INDIRECT_v2i64_S:
561  case WebAssembly::CALL_INDIRECT_v4f32:
562  case WebAssembly::CALL_INDIRECT_v4f32_S:
563  case WebAssembly::CALL_INDIRECT_v2f64:
564  case WebAssembly::CALL_INDIRECT_v2f64_S:
565  case WebAssembly::CALL_INDIRECT_exnref:
566  case WebAssembly::CALL_INDIRECT_exnref_S:
567    return 1;
568  default:
569    llvm_unreachable("Not a call instruction");
570  }
571}
572
573inline bool isMarker(unsigned Opc) {
574  switch (Opc) {
575  case WebAssembly::BLOCK:
576  case WebAssembly::BLOCK_S:
577  case WebAssembly::END_BLOCK:
578  case WebAssembly::END_BLOCK_S:
579  case WebAssembly::LOOP:
580  case WebAssembly::LOOP_S:
581  case WebAssembly::END_LOOP:
582  case WebAssembly::END_LOOP_S:
583  case WebAssembly::TRY:
584  case WebAssembly::TRY_S:
585  case WebAssembly::END_TRY:
586  case WebAssembly::END_TRY_S:
587    return true;
588  default:
589    return false;
590  }
591}
592
593} // end namespace WebAssembly
594} // end namespace llvm
595
596#endif
597