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 /// 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 #include <memory> 22 23 namespace llvm { 24 25 class MCAsmBackend; 26 class MCCodeEmitter; 27 class MCContext; 28 class MCInstrInfo; 29 class MCObjectTargetWriter; 30 class MCSubtargetInfo; 31 class MVT; 32 class Target; 33 class Triple; 34 class raw_pwrite_stream; 35 36 Target &getTheWebAssemblyTarget32(); 37 Target &getTheWebAssemblyTarget64(); 38 39 MCCodeEmitter *createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII); 40 41 MCAsmBackend *createWebAssemblyAsmBackend(const Triple &TT); 42 43 std::unique_ptr<MCObjectTargetWriter> 44 createWebAssemblyWasmObjectWriter(bool Is64Bit); 45 46 namespace WebAssembly { 47 enum OperandType { 48 /// Basic block label in a branch construct. 49 OPERAND_BASIC_BLOCK = MCOI::OPERAND_FIRST_TARGET, 50 /// Local index. 51 OPERAND_LOCAL, 52 /// Global index. 53 OPERAND_GLOBAL, 54 /// 32-bit integer immediates. 55 OPERAND_I32IMM, 56 /// 64-bit integer immediates. 57 OPERAND_I64IMM, 58 /// 32-bit floating-point immediates. 59 OPERAND_F32IMM, 60 /// 64-bit floating-point immediates. 61 OPERAND_F64IMM, 62 /// 8-bit vector lane immediate 63 OPERAND_VEC_I8IMM, 64 /// 16-bit vector lane immediate 65 OPERAND_VEC_I16IMM, 66 /// 32-bit vector lane immediate 67 OPERAND_VEC_I32IMM, 68 /// 64-bit vector lane immediate 69 OPERAND_VEC_I64IMM, 70 /// 32-bit unsigned function indices. 71 OPERAND_FUNCTION32, 72 /// 32-bit unsigned memory offsets. 73 OPERAND_OFFSET32, 74 /// p2align immediate for load and store address alignment. 75 OPERAND_P2ALIGN, 76 /// signature immediate for block/loop. 77 OPERAND_SIGNATURE, 78 /// type signature immediate for call_indirect. 79 OPERAND_TYPEINDEX, 80 /// Event index. 81 OPERAND_EVENT, 82 /// A list of branch targets for br_list. 83 OPERAND_BRLIST, 84 }; 85 } // end namespace WebAssembly 86 87 namespace WebAssemblyII { 88 89 /// Target Operand Flag enum. 90 enum TOF { 91 MO_NO_FLAG = 0, 92 93 // Flags to indicate the type of the symbol being referenced 94 MO_SYMBOL_FUNCTION = 0x1, 95 MO_SYMBOL_GLOBAL = 0x2, 96 MO_SYMBOL_EVENT = 0x4, 97 MO_SYMBOL_MASK = 0x7, 98 }; 99 } // end namespace WebAssemblyII 100 101 } // end namespace llvm 102 103 // Defines symbolic names for WebAssembly registers. This defines a mapping from 104 // register name to register number. 105 // 106 #define GET_REGINFO_ENUM 107 #include "WebAssemblyGenRegisterInfo.inc" 108 109 // Defines symbolic names for the WebAssembly instructions. 110 // 111 #define GET_INSTRINFO_ENUM 112 #include "WebAssemblyGenInstrInfo.inc" 113 114 #define GET_SUBTARGETINFO_ENUM 115 #include "WebAssemblyGenSubtargetInfo.inc" 116 117 namespace llvm { 118 namespace WebAssembly { 119 120 /// Return the default p2align value for a load or store with the given opcode. 121 inline unsigned GetDefaultP2Align(unsigned Opcode) { 122 switch (Opcode) { 123 case WebAssembly::LOAD8_S_I32: 124 case WebAssembly::LOAD8_S_I32_S: 125 case WebAssembly::LOAD8_U_I32: 126 case WebAssembly::LOAD8_U_I32_S: 127 case WebAssembly::LOAD8_S_I64: 128 case WebAssembly::LOAD8_S_I64_S: 129 case WebAssembly::LOAD8_U_I64: 130 case WebAssembly::LOAD8_U_I64_S: 131 case WebAssembly::ATOMIC_LOAD8_U_I32: 132 case WebAssembly::ATOMIC_LOAD8_U_I32_S: 133 case WebAssembly::ATOMIC_LOAD8_U_I64: 134 case WebAssembly::ATOMIC_LOAD8_U_I64_S: 135 case WebAssembly::STORE8_I32: 136 case WebAssembly::STORE8_I32_S: 137 case WebAssembly::STORE8_I64: 138 case WebAssembly::STORE8_I64_S: 139 case WebAssembly::ATOMIC_STORE8_I32: 140 case WebAssembly::ATOMIC_STORE8_I32_S: 141 case WebAssembly::ATOMIC_STORE8_I64: 142 case WebAssembly::ATOMIC_STORE8_I64_S: 143 case WebAssembly::ATOMIC_RMW8_U_ADD_I32: 144 case WebAssembly::ATOMIC_RMW8_U_ADD_I32_S: 145 case WebAssembly::ATOMIC_RMW8_U_ADD_I64: 146 case WebAssembly::ATOMIC_RMW8_U_ADD_I64_S: 147 case WebAssembly::ATOMIC_RMW8_U_SUB_I32: 148 case WebAssembly::ATOMIC_RMW8_U_SUB_I32_S: 149 case WebAssembly::ATOMIC_RMW8_U_SUB_I64: 150 case WebAssembly::ATOMIC_RMW8_U_SUB_I64_S: 151 case WebAssembly::ATOMIC_RMW8_U_AND_I32: 152 case WebAssembly::ATOMIC_RMW8_U_AND_I32_S: 153 case WebAssembly::ATOMIC_RMW8_U_AND_I64: 154 case WebAssembly::ATOMIC_RMW8_U_AND_I64_S: 155 case WebAssembly::ATOMIC_RMW8_U_OR_I32: 156 case WebAssembly::ATOMIC_RMW8_U_OR_I32_S: 157 case WebAssembly::ATOMIC_RMW8_U_OR_I64: 158 case WebAssembly::ATOMIC_RMW8_U_OR_I64_S: 159 case WebAssembly::ATOMIC_RMW8_U_XOR_I32: 160 case WebAssembly::ATOMIC_RMW8_U_XOR_I32_S: 161 case WebAssembly::ATOMIC_RMW8_U_XOR_I64: 162 case WebAssembly::ATOMIC_RMW8_U_XOR_I64_S: 163 case WebAssembly::ATOMIC_RMW8_U_XCHG_I32: 164 case WebAssembly::ATOMIC_RMW8_U_XCHG_I32_S: 165 case WebAssembly::ATOMIC_RMW8_U_XCHG_I64: 166 case WebAssembly::ATOMIC_RMW8_U_XCHG_I64_S: 167 case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I32: 168 case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I32_S: 169 case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64: 170 case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64_S: 171 return 0; 172 case WebAssembly::LOAD16_S_I32: 173 case WebAssembly::LOAD16_S_I32_S: 174 case WebAssembly::LOAD16_U_I32: 175 case WebAssembly::LOAD16_U_I32_S: 176 case WebAssembly::LOAD16_S_I64: 177 case WebAssembly::LOAD16_S_I64_S: 178 case WebAssembly::LOAD16_U_I64: 179 case WebAssembly::LOAD16_U_I64_S: 180 case WebAssembly::ATOMIC_LOAD16_U_I32: 181 case WebAssembly::ATOMIC_LOAD16_U_I32_S: 182 case WebAssembly::ATOMIC_LOAD16_U_I64: 183 case WebAssembly::ATOMIC_LOAD16_U_I64_S: 184 case WebAssembly::STORE16_I32: 185 case WebAssembly::STORE16_I32_S: 186 case WebAssembly::STORE16_I64: 187 case WebAssembly::STORE16_I64_S: 188 case WebAssembly::ATOMIC_STORE16_I32: 189 case WebAssembly::ATOMIC_STORE16_I32_S: 190 case WebAssembly::ATOMIC_STORE16_I64: 191 case WebAssembly::ATOMIC_STORE16_I64_S: 192 case WebAssembly::ATOMIC_RMW16_U_ADD_I32: 193 case WebAssembly::ATOMIC_RMW16_U_ADD_I32_S: 194 case WebAssembly::ATOMIC_RMW16_U_ADD_I64: 195 case WebAssembly::ATOMIC_RMW16_U_ADD_I64_S: 196 case WebAssembly::ATOMIC_RMW16_U_SUB_I32: 197 case WebAssembly::ATOMIC_RMW16_U_SUB_I32_S: 198 case WebAssembly::ATOMIC_RMW16_U_SUB_I64: 199 case WebAssembly::ATOMIC_RMW16_U_SUB_I64_S: 200 case WebAssembly::ATOMIC_RMW16_U_AND_I32: 201 case WebAssembly::ATOMIC_RMW16_U_AND_I32_S: 202 case WebAssembly::ATOMIC_RMW16_U_AND_I64: 203 case WebAssembly::ATOMIC_RMW16_U_AND_I64_S: 204 case WebAssembly::ATOMIC_RMW16_U_OR_I32: 205 case WebAssembly::ATOMIC_RMW16_U_OR_I32_S: 206 case WebAssembly::ATOMIC_RMW16_U_OR_I64: 207 case WebAssembly::ATOMIC_RMW16_U_OR_I64_S: 208 case WebAssembly::ATOMIC_RMW16_U_XOR_I32: 209 case WebAssembly::ATOMIC_RMW16_U_XOR_I32_S: 210 case WebAssembly::ATOMIC_RMW16_U_XOR_I64: 211 case WebAssembly::ATOMIC_RMW16_U_XOR_I64_S: 212 case WebAssembly::ATOMIC_RMW16_U_XCHG_I32: 213 case WebAssembly::ATOMIC_RMW16_U_XCHG_I32_S: 214 case WebAssembly::ATOMIC_RMW16_U_XCHG_I64: 215 case WebAssembly::ATOMIC_RMW16_U_XCHG_I64_S: 216 case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I32: 217 case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I32_S: 218 case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64: 219 case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64_S: 220 return 1; 221 case WebAssembly::LOAD_I32: 222 case WebAssembly::LOAD_I32_S: 223 case WebAssembly::LOAD_F32: 224 case WebAssembly::LOAD_F32_S: 225 case WebAssembly::STORE_I32: 226 case WebAssembly::STORE_I32_S: 227 case WebAssembly::STORE_F32: 228 case WebAssembly::STORE_F32_S: 229 case WebAssembly::LOAD32_S_I64: 230 case WebAssembly::LOAD32_S_I64_S: 231 case WebAssembly::LOAD32_U_I64: 232 case WebAssembly::LOAD32_U_I64_S: 233 case WebAssembly::STORE32_I64: 234 case WebAssembly::STORE32_I64_S: 235 case WebAssembly::ATOMIC_LOAD_I32: 236 case WebAssembly::ATOMIC_LOAD_I32_S: 237 case WebAssembly::ATOMIC_LOAD32_U_I64: 238 case WebAssembly::ATOMIC_LOAD32_U_I64_S: 239 case WebAssembly::ATOMIC_STORE_I32: 240 case WebAssembly::ATOMIC_STORE_I32_S: 241 case WebAssembly::ATOMIC_STORE32_I64: 242 case WebAssembly::ATOMIC_STORE32_I64_S: 243 case WebAssembly::ATOMIC_RMW_ADD_I32: 244 case WebAssembly::ATOMIC_RMW_ADD_I32_S: 245 case WebAssembly::ATOMIC_RMW32_U_ADD_I64: 246 case WebAssembly::ATOMIC_RMW32_U_ADD_I64_S: 247 case WebAssembly::ATOMIC_RMW_SUB_I32: 248 case WebAssembly::ATOMIC_RMW_SUB_I32_S: 249 case WebAssembly::ATOMIC_RMW32_U_SUB_I64: 250 case WebAssembly::ATOMIC_RMW32_U_SUB_I64_S: 251 case WebAssembly::ATOMIC_RMW_AND_I32: 252 case WebAssembly::ATOMIC_RMW_AND_I32_S: 253 case WebAssembly::ATOMIC_RMW32_U_AND_I64: 254 case WebAssembly::ATOMIC_RMW32_U_AND_I64_S: 255 case WebAssembly::ATOMIC_RMW_OR_I32: 256 case WebAssembly::ATOMIC_RMW_OR_I32_S: 257 case WebAssembly::ATOMIC_RMW32_U_OR_I64: 258 case WebAssembly::ATOMIC_RMW32_U_OR_I64_S: 259 case WebAssembly::ATOMIC_RMW_XOR_I32: 260 case WebAssembly::ATOMIC_RMW_XOR_I32_S: 261 case WebAssembly::ATOMIC_RMW32_U_XOR_I64: 262 case WebAssembly::ATOMIC_RMW32_U_XOR_I64_S: 263 case WebAssembly::ATOMIC_RMW_XCHG_I32: 264 case WebAssembly::ATOMIC_RMW_XCHG_I32_S: 265 case WebAssembly::ATOMIC_RMW32_U_XCHG_I64: 266 case WebAssembly::ATOMIC_RMW32_U_XCHG_I64_S: 267 case WebAssembly::ATOMIC_RMW_CMPXCHG_I32: 268 case WebAssembly::ATOMIC_RMW_CMPXCHG_I32_S: 269 case WebAssembly::ATOMIC_RMW32_U_CMPXCHG_I64: 270 case WebAssembly::ATOMIC_RMW32_U_CMPXCHG_I64_S: 271 case WebAssembly::ATOMIC_NOTIFY: 272 case WebAssembly::ATOMIC_NOTIFY_S: 273 case WebAssembly::ATOMIC_WAIT_I32: 274 case WebAssembly::ATOMIC_WAIT_I32_S: 275 return 2; 276 case WebAssembly::LOAD_I64: 277 case WebAssembly::LOAD_I64_S: 278 case WebAssembly::LOAD_F64: 279 case WebAssembly::LOAD_F64_S: 280 case WebAssembly::STORE_I64: 281 case WebAssembly::STORE_I64_S: 282 case WebAssembly::STORE_F64: 283 case WebAssembly::STORE_F64_S: 284 case WebAssembly::ATOMIC_LOAD_I64: 285 case WebAssembly::ATOMIC_LOAD_I64_S: 286 case WebAssembly::ATOMIC_STORE_I64: 287 case WebAssembly::ATOMIC_STORE_I64_S: 288 case WebAssembly::ATOMIC_RMW_ADD_I64: 289 case WebAssembly::ATOMIC_RMW_ADD_I64_S: 290 case WebAssembly::ATOMIC_RMW_SUB_I64: 291 case WebAssembly::ATOMIC_RMW_SUB_I64_S: 292 case WebAssembly::ATOMIC_RMW_AND_I64: 293 case WebAssembly::ATOMIC_RMW_AND_I64_S: 294 case WebAssembly::ATOMIC_RMW_OR_I64: 295 case WebAssembly::ATOMIC_RMW_OR_I64_S: 296 case WebAssembly::ATOMIC_RMW_XOR_I64: 297 case WebAssembly::ATOMIC_RMW_XOR_I64_S: 298 case WebAssembly::ATOMIC_RMW_XCHG_I64: 299 case WebAssembly::ATOMIC_RMW_XCHG_I64_S: 300 case WebAssembly::ATOMIC_RMW_CMPXCHG_I64: 301 case WebAssembly::ATOMIC_RMW_CMPXCHG_I64_S: 302 case WebAssembly::ATOMIC_WAIT_I64: 303 case WebAssembly::ATOMIC_WAIT_I64_S: 304 return 3; 305 case WebAssembly::LOAD_v16i8: 306 case WebAssembly::LOAD_v16i8_S: 307 case WebAssembly::LOAD_v8i16: 308 case WebAssembly::LOAD_v8i16_S: 309 case WebAssembly::LOAD_v4i32: 310 case WebAssembly::LOAD_v4i32_S: 311 case WebAssembly::LOAD_v2i64: 312 case WebAssembly::LOAD_v2i64_S: 313 case WebAssembly::LOAD_v4f32: 314 case WebAssembly::LOAD_v4f32_S: 315 case WebAssembly::LOAD_v2f64: 316 case WebAssembly::LOAD_v2f64_S: 317 case WebAssembly::STORE_v16i8: 318 case WebAssembly::STORE_v16i8_S: 319 case WebAssembly::STORE_v8i16: 320 case WebAssembly::STORE_v8i16_S: 321 case WebAssembly::STORE_v4i32: 322 case WebAssembly::STORE_v4i32_S: 323 case WebAssembly::STORE_v2i64: 324 case WebAssembly::STORE_v2i64_S: 325 case WebAssembly::STORE_v4f32: 326 case WebAssembly::STORE_v4f32_S: 327 case WebAssembly::STORE_v2f64: 328 case WebAssembly::STORE_v2f64_S: 329 return 4; 330 default: 331 llvm_unreachable("Only loads and stores have p2align values"); 332 } 333 } 334 335 /// The operand number of the load or store address in load/store instructions. 336 static const unsigned LoadAddressOperandNo = 3; 337 static const unsigned StoreAddressOperandNo = 2; 338 339 /// The operand number of the load or store p2align in load/store instructions. 340 static const unsigned LoadP2AlignOperandNo = 1; 341 static const unsigned StoreP2AlignOperandNo = 0; 342 343 /// This is used to indicate block signatures. 344 enum class ExprType : unsigned { 345 Void = 0x40, 346 I32 = 0x7F, 347 I64 = 0x7E, 348 F32 = 0x7D, 349 F64 = 0x7C, 350 V128 = 0x7B, 351 ExceptRef = 0x68, 352 Invalid = 0x00 353 }; 354 355 /// Instruction opcodes emitted via means other than CodeGen. 356 static const unsigned Nop = 0x01; 357 static const unsigned End = 0x0b; 358 359 wasm::ValType toValType(const MVT &Ty); 360 361 } // end namespace WebAssembly 362 } // end namespace llvm 363 364 #endif 365