Home | History | Annotate | Line # | Download | only in MCTargetDesc
      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 
     23 namespace llvm {
     24 
     25 class MCAsmBackend;
     26 class MCCodeEmitter;
     27 class MCInstrInfo;
     28 class MCObjectTargetWriter;
     29 class MVT;
     30 class Triple;
     31 
     32 MCCodeEmitter *createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII);
     33 
     34 MCAsmBackend *createWebAssemblyAsmBackend(const Triple &TT);
     35 
     36 std::unique_ptr<MCObjectTargetWriter>
     37 createWebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten);
     38 
     39 namespace WebAssembly {
     40 enum OperandType {
     41   /// Basic block label in a branch construct.
     42   OPERAND_BASIC_BLOCK = MCOI::OPERAND_FIRST_TARGET,
     43   /// Local index.
     44   OPERAND_LOCAL,
     45   /// Global index.
     46   OPERAND_GLOBAL,
     47   /// 32-bit integer immediates.
     48   OPERAND_I32IMM,
     49   /// 64-bit integer immediates.
     50   OPERAND_I64IMM,
     51   /// 32-bit floating-point immediates.
     52   OPERAND_F32IMM,
     53   /// 64-bit floating-point immediates.
     54   OPERAND_F64IMM,
     55   /// 8-bit vector lane immediate
     56   OPERAND_VEC_I8IMM,
     57   /// 16-bit vector lane immediate
     58   OPERAND_VEC_I16IMM,
     59   /// 32-bit vector lane immediate
     60   OPERAND_VEC_I32IMM,
     61   /// 64-bit vector lane immediate
     62   OPERAND_VEC_I64IMM,
     63   /// 32-bit unsigned function indices.
     64   OPERAND_FUNCTION32,
     65   /// 32-bit unsigned memory offsets.
     66   OPERAND_OFFSET32,
     67   /// 64-bit unsigned memory offsets.
     68   OPERAND_OFFSET64,
     69   /// p2align immediate for load and store address alignment.
     70   OPERAND_P2ALIGN,
     71   /// signature immediate for block/loop.
     72   OPERAND_SIGNATURE,
     73   /// type signature immediate for call_indirect.
     74   OPERAND_TYPEINDEX,
     75   /// Event index.
     76   OPERAND_EVENT,
     77   /// A list of branch targets for br_list.
     78   OPERAND_BRLIST,
     79   /// 32-bit unsigned table number.
     80   OPERAND_TABLE,
     81   /// heap type immediate for ref.null.
     82   OPERAND_HEAPTYPE,
     83 };
     84 } // end namespace WebAssembly
     85 
     86 namespace WebAssemblyII {
     87 
     88 /// Target Operand Flag enum.
     89 enum TOF {
     90   MO_NO_FLAG = 0,
     91 
     92   // On a symbol operand this indicates that the immediate is a wasm global
     93   // index.  The value of the wasm global will be set to the symbol address at
     94   // runtime.  This adds a level of indirection similar to the GOT on native
     95   // platforms.
     96   MO_GOT,
     97 
     98   // On a symbol operand this indicates that the immediate is the symbol
     99   // address relative the __memory_base wasm global.
    100   // Only applicable to data symbols.
    101   MO_MEMORY_BASE_REL,
    102 
    103   // On a symbol operand this indicates that the immediate is the symbol
    104   // address relative the __tls_base wasm global.
    105   // Only applicable to data symbols.
    106   MO_TLS_BASE_REL,
    107 
    108   // On a symbol operand this indicates that the immediate is the symbol
    109   // address relative the __table_base wasm global.
    110   // Only applicable to function symbols.
    111   MO_TABLE_BASE_REL,
    112 };
    113 
    114 } // end namespace WebAssemblyII
    115 
    116 } // end namespace llvm
    117 
    118 // Defines symbolic names for WebAssembly registers. This defines a mapping from
    119 // register name to register number.
    120 //
    121 #define GET_REGINFO_ENUM
    122 #include "WebAssemblyGenRegisterInfo.inc"
    123 
    124 // Defines symbolic names for the WebAssembly instructions.
    125 //
    126 #define GET_INSTRINFO_ENUM
    127 #include "WebAssemblyGenInstrInfo.inc"
    128 
    129 namespace llvm {
    130 namespace WebAssembly {
    131 
    132 /// Instruction opcodes emitted via means other than CodeGen.
    133 static const unsigned Nop = 0x01;
    134 static const unsigned End = 0x0b;
    135 
    136 /// Return the default p2align value for a load or store with the given opcode.
    137 inline unsigned GetDefaultP2AlignAny(unsigned Opc) {
    138   switch (Opc) {
    139 #define WASM_LOAD_STORE(NAME) \
    140   case WebAssembly::NAME##_A32: \
    141   case WebAssembly::NAME##_A64: \
    142   case WebAssembly::NAME##_A32_S: \
    143   case WebAssembly::NAME##_A64_S:
    144   WASM_LOAD_STORE(LOAD8_S_I32)
    145   WASM_LOAD_STORE(LOAD8_U_I32)
    146   WASM_LOAD_STORE(LOAD8_S_I64)
    147   WASM_LOAD_STORE(LOAD8_U_I64)
    148   WASM_LOAD_STORE(ATOMIC_LOAD8_U_I32)
    149   WASM_LOAD_STORE(ATOMIC_LOAD8_U_I64)
    150   WASM_LOAD_STORE(STORE8_I32)
    151   WASM_LOAD_STORE(STORE8_I64)
    152   WASM_LOAD_STORE(ATOMIC_STORE8_I32)
    153   WASM_LOAD_STORE(ATOMIC_STORE8_I64)
    154   WASM_LOAD_STORE(ATOMIC_RMW8_U_ADD_I32)
    155   WASM_LOAD_STORE(ATOMIC_RMW8_U_ADD_I64)
    156   WASM_LOAD_STORE(ATOMIC_RMW8_U_SUB_I32)
    157   WASM_LOAD_STORE(ATOMIC_RMW8_U_SUB_I64)
    158   WASM_LOAD_STORE(ATOMIC_RMW8_U_AND_I32)
    159   WASM_LOAD_STORE(ATOMIC_RMW8_U_AND_I64)
    160   WASM_LOAD_STORE(ATOMIC_RMW8_U_OR_I32)
    161   WASM_LOAD_STORE(ATOMIC_RMW8_U_OR_I64)
    162   WASM_LOAD_STORE(ATOMIC_RMW8_U_XOR_I32)
    163   WASM_LOAD_STORE(ATOMIC_RMW8_U_XOR_I64)
    164   WASM_LOAD_STORE(ATOMIC_RMW8_U_XCHG_I32)
    165   WASM_LOAD_STORE(ATOMIC_RMW8_U_XCHG_I64)
    166   WASM_LOAD_STORE(ATOMIC_RMW8_U_CMPXCHG_I32)
    167   WASM_LOAD_STORE(ATOMIC_RMW8_U_CMPXCHG_I64)
    168   WASM_LOAD_STORE(LOAD8_SPLAT)
    169   WASM_LOAD_STORE(LOAD_LANE_I8x16)
    170   WASM_LOAD_STORE(STORE_LANE_I8x16)
    171   return 0;
    172   WASM_LOAD_STORE(LOAD16_S_I32)
    173   WASM_LOAD_STORE(LOAD16_U_I32)
    174   WASM_LOAD_STORE(LOAD16_S_I64)
    175   WASM_LOAD_STORE(LOAD16_U_I64)
    176   WASM_LOAD_STORE(ATOMIC_LOAD16_U_I32)
    177   WASM_LOAD_STORE(ATOMIC_LOAD16_U_I64)
    178   WASM_LOAD_STORE(STORE16_I32)
    179   WASM_LOAD_STORE(STORE16_I64)
    180   WASM_LOAD_STORE(ATOMIC_STORE16_I32)
    181   WASM_LOAD_STORE(ATOMIC_STORE16_I64)
    182   WASM_LOAD_STORE(ATOMIC_RMW16_U_ADD_I32)
    183   WASM_LOAD_STORE(ATOMIC_RMW16_U_ADD_I64)
    184   WASM_LOAD_STORE(ATOMIC_RMW16_U_SUB_I32)
    185   WASM_LOAD_STORE(ATOMIC_RMW16_U_SUB_I64)
    186   WASM_LOAD_STORE(ATOMIC_RMW16_U_AND_I32)
    187   WASM_LOAD_STORE(ATOMIC_RMW16_U_AND_I64)
    188   WASM_LOAD_STORE(ATOMIC_RMW16_U_OR_I32)
    189   WASM_LOAD_STORE(ATOMIC_RMW16_U_OR_I64)
    190   WASM_LOAD_STORE(ATOMIC_RMW16_U_XOR_I32)
    191   WASM_LOAD_STORE(ATOMIC_RMW16_U_XOR_I64)
    192   WASM_LOAD_STORE(ATOMIC_RMW16_U_XCHG_I32)
    193   WASM_LOAD_STORE(ATOMIC_RMW16_U_XCHG_I64)
    194   WASM_LOAD_STORE(ATOMIC_RMW16_U_CMPXCHG_I32)
    195   WASM_LOAD_STORE(ATOMIC_RMW16_U_CMPXCHG_I64)
    196   WASM_LOAD_STORE(LOAD16_SPLAT)
    197   WASM_LOAD_STORE(LOAD_LANE_I16x8)
    198   WASM_LOAD_STORE(STORE_LANE_I16x8)
    199   return 1;
    200   WASM_LOAD_STORE(LOAD_I32)
    201   WASM_LOAD_STORE(LOAD_F32)
    202   WASM_LOAD_STORE(STORE_I32)
    203   WASM_LOAD_STORE(STORE_F32)
    204   WASM_LOAD_STORE(LOAD32_S_I64)
    205   WASM_LOAD_STORE(LOAD32_U_I64)
    206   WASM_LOAD_STORE(STORE32_I64)
    207   WASM_LOAD_STORE(ATOMIC_LOAD_I32)
    208   WASM_LOAD_STORE(ATOMIC_LOAD32_U_I64)
    209   WASM_LOAD_STORE(ATOMIC_STORE_I32)
    210   WASM_LOAD_STORE(ATOMIC_STORE32_I64)
    211   WASM_LOAD_STORE(ATOMIC_RMW_ADD_I32)
    212   WASM_LOAD_STORE(ATOMIC_RMW32_U_ADD_I64)
    213   WASM_LOAD_STORE(ATOMIC_RMW_SUB_I32)
    214   WASM_LOAD_STORE(ATOMIC_RMW32_U_SUB_I64)
    215   WASM_LOAD_STORE(ATOMIC_RMW_AND_I32)
    216   WASM_LOAD_STORE(ATOMIC_RMW32_U_AND_I64)
    217   WASM_LOAD_STORE(ATOMIC_RMW_OR_I32)
    218   WASM_LOAD_STORE(ATOMIC_RMW32_U_OR_I64)
    219   WASM_LOAD_STORE(ATOMIC_RMW_XOR_I32)
    220   WASM_LOAD_STORE(ATOMIC_RMW32_U_XOR_I64)
    221   WASM_LOAD_STORE(ATOMIC_RMW_XCHG_I32)
    222   WASM_LOAD_STORE(ATOMIC_RMW32_U_XCHG_I64)
    223   WASM_LOAD_STORE(ATOMIC_RMW_CMPXCHG_I32)
    224   WASM_LOAD_STORE(ATOMIC_RMW32_U_CMPXCHG_I64)
    225   WASM_LOAD_STORE(MEMORY_ATOMIC_NOTIFY)
    226   WASM_LOAD_STORE(MEMORY_ATOMIC_WAIT32)
    227   WASM_LOAD_STORE(LOAD32_SPLAT)
    228   WASM_LOAD_STORE(LOAD_ZERO_I32x4)
    229   WASM_LOAD_STORE(LOAD_LANE_I32x4)
    230   WASM_LOAD_STORE(STORE_LANE_I32x4)
    231   return 2;
    232   WASM_LOAD_STORE(LOAD_I64)
    233   WASM_LOAD_STORE(LOAD_F64)
    234   WASM_LOAD_STORE(STORE_I64)
    235   WASM_LOAD_STORE(STORE_F64)
    236   WASM_LOAD_STORE(ATOMIC_LOAD_I64)
    237   WASM_LOAD_STORE(ATOMIC_STORE_I64)
    238   WASM_LOAD_STORE(ATOMIC_RMW_ADD_I64)
    239   WASM_LOAD_STORE(ATOMIC_RMW_SUB_I64)
    240   WASM_LOAD_STORE(ATOMIC_RMW_AND_I64)
    241   WASM_LOAD_STORE(ATOMIC_RMW_OR_I64)
    242   WASM_LOAD_STORE(ATOMIC_RMW_XOR_I64)
    243   WASM_LOAD_STORE(ATOMIC_RMW_XCHG_I64)
    244   WASM_LOAD_STORE(ATOMIC_RMW_CMPXCHG_I64)
    245   WASM_LOAD_STORE(MEMORY_ATOMIC_WAIT64)
    246   WASM_LOAD_STORE(LOAD64_SPLAT)
    247   WASM_LOAD_STORE(LOAD_EXTEND_S_I16x8)
    248   WASM_LOAD_STORE(LOAD_EXTEND_U_I16x8)
    249   WASM_LOAD_STORE(LOAD_EXTEND_S_I32x4)
    250   WASM_LOAD_STORE(LOAD_EXTEND_U_I32x4)
    251   WASM_LOAD_STORE(LOAD_EXTEND_S_I64x2)
    252   WASM_LOAD_STORE(LOAD_EXTEND_U_I64x2)
    253   WASM_LOAD_STORE(LOAD_ZERO_I64x2)
    254   WASM_LOAD_STORE(LOAD_LANE_I64x2)
    255   WASM_LOAD_STORE(STORE_LANE_I64x2)
    256   return 3;
    257   WASM_LOAD_STORE(LOAD_V128)
    258   WASM_LOAD_STORE(STORE_V128)
    259     return 4;
    260   default:
    261     return -1;
    262   }
    263 #undef WASM_LOAD_STORE
    264 }
    265 
    266 inline unsigned GetDefaultP2Align(unsigned Opc) {
    267   auto Align = GetDefaultP2AlignAny(Opc);
    268   if (Align == -1U) {
    269     llvm_unreachable("Only loads and stores have p2align values");
    270   }
    271   return Align;
    272 }
    273 
    274 inline bool isArgument(unsigned Opc) {
    275   switch (Opc) {
    276   case WebAssembly::ARGUMENT_i32:
    277   case WebAssembly::ARGUMENT_i32_S:
    278   case WebAssembly::ARGUMENT_i64:
    279   case WebAssembly::ARGUMENT_i64_S:
    280   case WebAssembly::ARGUMENT_f32:
    281   case WebAssembly::ARGUMENT_f32_S:
    282   case WebAssembly::ARGUMENT_f64:
    283   case WebAssembly::ARGUMENT_f64_S:
    284   case WebAssembly::ARGUMENT_v16i8:
    285   case WebAssembly::ARGUMENT_v16i8_S:
    286   case WebAssembly::ARGUMENT_v8i16:
    287   case WebAssembly::ARGUMENT_v8i16_S:
    288   case WebAssembly::ARGUMENT_v4i32:
    289   case WebAssembly::ARGUMENT_v4i32_S:
    290   case WebAssembly::ARGUMENT_v2i64:
    291   case WebAssembly::ARGUMENT_v2i64_S:
    292   case WebAssembly::ARGUMENT_v4f32:
    293   case WebAssembly::ARGUMENT_v4f32_S:
    294   case WebAssembly::ARGUMENT_v2f64:
    295   case WebAssembly::ARGUMENT_v2f64_S:
    296   case WebAssembly::ARGUMENT_funcref:
    297   case WebAssembly::ARGUMENT_funcref_S:
    298   case WebAssembly::ARGUMENT_externref:
    299   case WebAssembly::ARGUMENT_externref_S:
    300     return true;
    301   default:
    302     return false;
    303   }
    304 }
    305 
    306 inline bool isCopy(unsigned Opc) {
    307   switch (Opc) {
    308   case WebAssembly::COPY_I32:
    309   case WebAssembly::COPY_I32_S:
    310   case WebAssembly::COPY_I64:
    311   case WebAssembly::COPY_I64_S:
    312   case WebAssembly::COPY_F32:
    313   case WebAssembly::COPY_F32_S:
    314   case WebAssembly::COPY_F64:
    315   case WebAssembly::COPY_F64_S:
    316   case WebAssembly::COPY_V128:
    317   case WebAssembly::COPY_V128_S:
    318   case WebAssembly::COPY_FUNCREF:
    319   case WebAssembly::COPY_FUNCREF_S:
    320   case WebAssembly::COPY_EXTERNREF:
    321   case WebAssembly::COPY_EXTERNREF_S:
    322     return true;
    323   default:
    324     return false;
    325   }
    326 }
    327 
    328 inline bool isTee(unsigned Opc) {
    329   switch (Opc) {
    330   case WebAssembly::TEE_I32:
    331   case WebAssembly::TEE_I32_S:
    332   case WebAssembly::TEE_I64:
    333   case WebAssembly::TEE_I64_S:
    334   case WebAssembly::TEE_F32:
    335   case WebAssembly::TEE_F32_S:
    336   case WebAssembly::TEE_F64:
    337   case WebAssembly::TEE_F64_S:
    338   case WebAssembly::TEE_V128:
    339   case WebAssembly::TEE_V128_S:
    340   case WebAssembly::TEE_FUNCREF:
    341   case WebAssembly::TEE_FUNCREF_S:
    342   case WebAssembly::TEE_EXTERNREF:
    343   case WebAssembly::TEE_EXTERNREF_S:
    344     return true;
    345   default:
    346     return false;
    347   }
    348 }
    349 
    350 inline bool isCallDirect(unsigned Opc) {
    351   switch (Opc) {
    352   case WebAssembly::CALL:
    353   case WebAssembly::CALL_S:
    354   case WebAssembly::RET_CALL:
    355   case WebAssembly::RET_CALL_S:
    356     return true;
    357   default:
    358     return false;
    359   }
    360 }
    361 
    362 inline bool isCallIndirect(unsigned Opc) {
    363   switch (Opc) {
    364   case WebAssembly::CALL_INDIRECT:
    365   case WebAssembly::CALL_INDIRECT_S:
    366   case WebAssembly::RET_CALL_INDIRECT:
    367   case WebAssembly::RET_CALL_INDIRECT_S:
    368     return true;
    369   default:
    370     return false;
    371   }
    372 }
    373 
    374 inline bool isBrTable(const MachineInstr &MI) {
    375   switch (MI.getOpcode()) {
    376   case WebAssembly::BR_TABLE_I32:
    377   case WebAssembly::BR_TABLE_I32_S:
    378   case WebAssembly::BR_TABLE_I64:
    379   case WebAssembly::BR_TABLE_I64_S:
    380     return true;
    381   default:
    382     return false;
    383   }
    384 }
    385 
    386 inline bool isMarker(unsigned Opc) {
    387   switch (Opc) {
    388   case WebAssembly::BLOCK:
    389   case WebAssembly::BLOCK_S:
    390   case WebAssembly::END_BLOCK:
    391   case WebAssembly::END_BLOCK_S:
    392   case WebAssembly::LOOP:
    393   case WebAssembly::LOOP_S:
    394   case WebAssembly::END_LOOP:
    395   case WebAssembly::END_LOOP_S:
    396   case WebAssembly::TRY:
    397   case WebAssembly::TRY_S:
    398   case WebAssembly::END_TRY:
    399   case WebAssembly::END_TRY_S:
    400     return true;
    401   default:
    402     return false;
    403   }
    404 }
    405 
    406 inline bool isCatch(unsigned Opc) {
    407   switch (Opc) {
    408   case WebAssembly::CATCH:
    409   case WebAssembly::CATCH_S:
    410   case WebAssembly::CATCH_ALL:
    411   case WebAssembly::CATCH_ALL_S:
    412     return true;
    413   default:
    414     return false;
    415   }
    416 }
    417 
    418 } // end namespace WebAssembly
    419 } // end namespace llvm
    420 
    421 #endif
    422