1 //==- WebAssemblyMCTargetDesc.h - WebAssembly Target Descriptions -*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file provides WebAssembly-specific target descriptions.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
16 #define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
17 
18 #include "llvm/BinaryFormat/Wasm.h"
19 #include "llvm/MC/MCInstrDesc.h"
20 #include "llvm/Support/DataTypes.h"
21 
22 namespace llvm {
23 
24 class MCAsmBackend;
25 class MCCodeEmitter;
26 class MCContext;
27 class MCInstrInfo;
28 class MCObjectWriter;
29 class MCSubtargetInfo;
30 class MVT;
31 class Target;
32 class Triple;
33 class raw_pwrite_stream;
34 
35 Target &getTheWebAssemblyTarget32();
36 Target &getTheWebAssemblyTarget64();
37 
38 MCCodeEmitter *createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII);
39 
40 MCAsmBackend *createWebAssemblyAsmBackend(const Triple &TT);
41 
42 MCObjectWriter *createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS,
43                                                  bool Is64Bit, uint8_t OSABI);
44 
45 MCObjectWriter *createWebAssemblyWasmObjectWriter(raw_pwrite_stream &OS,
46                                                   bool Is64Bit);
47 
48 namespace WebAssembly {
49 enum OperandType {
50   /// Basic block label in a branch construct.
51   OPERAND_BASIC_BLOCK = MCOI::OPERAND_FIRST_TARGET,
52   /// Local index.
53   OPERAND_LOCAL,
54   /// Global index.
55   OPERAND_GLOBAL,
56   /// 32-bit integer immediates.
57   OPERAND_I32IMM,
58   /// 64-bit integer immediates.
59   OPERAND_I64IMM,
60   /// 32-bit floating-point immediates.
61   OPERAND_F32IMM,
62   /// 64-bit floating-point immediates.
63   OPERAND_F64IMM,
64   /// 32-bit unsigned function indices.
65   OPERAND_FUNCTION32,
66   /// 32-bit unsigned memory offsets.
67   OPERAND_OFFSET32,
68   /// p2align immediate for load and store address alignment.
69   OPERAND_P2ALIGN,
70   /// signature immediate for block/loop.
71   OPERAND_SIGNATURE,
72   /// type signature immediate for call_indirect.
73   OPERAND_TYPEINDEX,
74 };
75 } // end namespace WebAssembly
76 
77 namespace WebAssemblyII {
78 enum {
79   // For variadic instructions, this flag indicates whether an operand
80   // in the variable_ops range is an immediate value.
81   VariableOpIsImmediate = (1 << 0),
82   // For immediate values in the variable_ops range, this flag indicates
83   // whether the value represents a control-flow label.
84   VariableOpImmediateIsLabel = (1 << 1)
85 };
86 } // end namespace WebAssemblyII
87 
88 } // end namespace llvm
89 
90 // Defines symbolic names for WebAssembly registers. This defines a mapping from
91 // register name to register number.
92 //
93 #define GET_REGINFO_ENUM
94 #include "WebAssemblyGenRegisterInfo.inc"
95 
96 // Defines symbolic names for the WebAssembly instructions.
97 //
98 #define GET_INSTRINFO_ENUM
99 #include "WebAssemblyGenInstrInfo.inc"
100 
101 #define GET_SUBTARGETINFO_ENUM
102 #include "WebAssemblyGenSubtargetInfo.inc"
103 
104 namespace llvm {
105 namespace WebAssembly {
106 
107 /// Return the default p2align value for a load or store with the given opcode.
108 inline unsigned GetDefaultP2Align(unsigned Opcode) {
109   switch (Opcode) {
110   case WebAssembly::LOAD8_S_I32:
111   case WebAssembly::LOAD8_U_I32:
112   case WebAssembly::LOAD8_S_I64:
113   case WebAssembly::LOAD8_U_I64:
114   case WebAssembly::ATOMIC_LOAD8_U_I32:
115   case WebAssembly::ATOMIC_LOAD8_U_I64:
116   case WebAssembly::STORE8_I32:
117   case WebAssembly::STORE8_I64:
118     return 0;
119   case WebAssembly::LOAD16_S_I32:
120   case WebAssembly::LOAD16_U_I32:
121   case WebAssembly::LOAD16_S_I64:
122   case WebAssembly::LOAD16_U_I64:
123   case WebAssembly::ATOMIC_LOAD16_U_I32:
124   case WebAssembly::ATOMIC_LOAD16_U_I64:
125   case WebAssembly::STORE16_I32:
126   case WebAssembly::STORE16_I64:
127     return 1;
128   case WebAssembly::LOAD_I32:
129   case WebAssembly::LOAD_F32:
130   case WebAssembly::STORE_I32:
131   case WebAssembly::STORE_F32:
132   case WebAssembly::LOAD32_S_I64:
133   case WebAssembly::LOAD32_U_I64:
134   case WebAssembly::STORE32_I64:
135   case WebAssembly::ATOMIC_LOAD_I32:
136   case WebAssembly::ATOMIC_LOAD32_U_I64:
137     return 2;
138   case WebAssembly::LOAD_I64:
139   case WebAssembly::LOAD_F64:
140   case WebAssembly::STORE_I64:
141   case WebAssembly::STORE_F64:
142   case WebAssembly::ATOMIC_LOAD_I64:
143     return 3;
144   default:
145     llvm_unreachable("Only loads and stores have p2align values");
146   }
147 }
148 
149 /// The operand number of the load or store address in load/store instructions.
150 static const unsigned LoadAddressOperandNo = 3;
151 static const unsigned StoreAddressOperandNo = 2;
152 
153 /// The operand number of the load or store p2align in load/store instructions.
154 static const unsigned LoadP2AlignOperandNo = 1;
155 static const unsigned StoreP2AlignOperandNo = 0;
156 
157 /// This is used to indicate block signatures.
158 enum class ExprType {
159   Void    = -0x40,
160   I32     = -0x01,
161   I64     = -0x02,
162   F32     = -0x03,
163   F64     = -0x04,
164   I8x16   = -0x05,
165   I16x8   = -0x06,
166   I32x4   = -0x07,
167   F32x4   = -0x08,
168   B8x16   = -0x09,
169   B16x8   = -0x0a,
170   B32x4   = -0x0b
171 };
172 
173 /// Instruction opcodes emitted via means other than CodeGen.
174 static const unsigned Nop = 0x01;
175 static const unsigned End = 0x0b;
176 
177 wasm::ValType toValType(const MVT &Ty);
178 
179 } // end namespace WebAssembly
180 } // end namespace llvm
181 
182 #endif
183