kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

insn.c (14658B)


      1 #include "wasm/wasm.h"
      2 #include "wasm/wasm_insn_table.h"
      3 
      4 int wasm_is_num_type(WasmValType vt) {
      5   return vt == WASM_VAL_I32 || vt == WASM_VAL_I64 || vt == WASM_VAL_F32 ||
      6          vt == WASM_VAL_F64;
      7 }
      8 
      9 int wasm_is_ref_type(WasmValType vt) {
     10   return vt == WASM_VAL_FUNCREF || vt == WASM_VAL_EXTERNREF;
     11 }
     12 
     13 int wasm_is_frontend_value_type(WasmValType vt) {
     14   return wasm_is_num_type(vt) || vt == WASM_VAL_FUNCREF;
     15 }
     16 
     17 void wasm_block_sig(const WasmModule* m, const WasmInsn* in,
     18                     WasmValType* result_scratch, WasmBlockSig* out) {
     19   out->params = NULL;
     20   out->nparams = 0;
     21   out->results = NULL;
     22   out->nresults = 0;
     23   if (wasm_insn_blocktype_is_typeidx(in)) {
     24     uint32_t idx = wasm_insn_blocktype_typeidx(in);
     25     if (idx < m->ntypes) {
     26       const WasmFuncType* t = &m->types[idx];
     27       out->params = t->params;
     28       out->nparams = t->nparams;
     29       out->results = t->results;
     30       out->nresults = t->nresults;
     31     }
     32   } else if (in->type) {
     33     result_scratch[0] = (WasmValType)in->type;
     34     out->results = result_scratch;
     35     out->nresults = 1;
     36   }
     37 }
     38 
     39 int wasm_feature_enabled(const WasmModule* m, WasmFeatureSet feature) {
     40   return (m->features & (uint32_t)feature) != 0;
     41 }
     42 
     43 void wasm_require_feature_at(KitCompiler* c, const WasmModule* m,
     44                              WasmFeatureSet feature, const char* feature_name,
     45                              const char* what, KitSrcLoc loc) {
     46   if (!wasm_feature_enabled(m, feature))
     47     wasm_error(c, loc, "wasm: %s requires %s", what, feature_name);
     48 }
     49 
     50 void wasm_require_feature(KitCompiler* c, const WasmModule* m,
     51                           WasmFeatureSet feature, const char* feature_name,
     52                           const char* what) {
     53   wasm_require_feature_at(c, m, feature, feature_name, what, wasm_loc(0, 0));
     54 }
     55 
     56 int wasm_insn_is_load(WasmInsnKind kind) {
     57   return kind == WASM_INSN_I32_LOAD || kind == WASM_INSN_I64_LOAD ||
     58          kind == WASM_INSN_F32_LOAD || kind == WASM_INSN_F64_LOAD ||
     59          kind == WASM_INSN_I32_LOAD8_S || kind == WASM_INSN_I32_LOAD8_U ||
     60          kind == WASM_INSN_I32_LOAD16_S || kind == WASM_INSN_I32_LOAD16_U ||
     61          kind == WASM_INSN_I64_LOAD8_S || kind == WASM_INSN_I64_LOAD8_U ||
     62          kind == WASM_INSN_I64_LOAD16_S || kind == WASM_INSN_I64_LOAD16_U ||
     63          kind == WASM_INSN_I64_LOAD32_S || kind == WASM_INSN_I64_LOAD32_U;
     64 }
     65 
     66 int wasm_insn_is_store(WasmInsnKind kind) {
     67   return kind == WASM_INSN_I32_STORE || kind == WASM_INSN_I64_STORE ||
     68          kind == WASM_INSN_F32_STORE || kind == WASM_INSN_F64_STORE ||
     69          kind == WASM_INSN_I32_STORE8 || kind == WASM_INSN_I32_STORE16 ||
     70          kind == WASM_INSN_I64_STORE8 || kind == WASM_INSN_I64_STORE16 ||
     71          kind == WASM_INSN_I64_STORE32;
     72 }
     73 
     74 int wasm_insn_is_atomic_load(WasmInsnKind kind) {
     75   return kind == WASM_INSN_I32_ATOMIC_LOAD ||
     76          kind == WASM_INSN_I64_ATOMIC_LOAD ||
     77          kind == WASM_INSN_I32_ATOMIC_LOAD8_U ||
     78          kind == WASM_INSN_I32_ATOMIC_LOAD16_U ||
     79          kind == WASM_INSN_I64_ATOMIC_LOAD8_U ||
     80          kind == WASM_INSN_I64_ATOMIC_LOAD16_U ||
     81          kind == WASM_INSN_I64_ATOMIC_LOAD32_U;
     82 }
     83 
     84 int wasm_insn_is_atomic_store(WasmInsnKind kind) {
     85   return kind == WASM_INSN_I32_ATOMIC_STORE ||
     86          kind == WASM_INSN_I64_ATOMIC_STORE ||
     87          kind == WASM_INSN_I32_ATOMIC_STORE8 ||
     88          kind == WASM_INSN_I32_ATOMIC_STORE16 ||
     89          kind == WASM_INSN_I64_ATOMIC_STORE8 ||
     90          kind == WASM_INSN_I64_ATOMIC_STORE16 ||
     91          kind == WASM_INSN_I64_ATOMIC_STORE32;
     92 }
     93 
     94 int wasm_insn_is_atomic_rmw(WasmInsnKind kind) {
     95   return kind == WASM_INSN_I32_ATOMIC_RMW_ADD ||
     96          kind == WASM_INSN_I64_ATOMIC_RMW_ADD ||
     97          kind == WASM_INSN_I32_ATOMIC_RMW_SUB ||
     98          kind == WASM_INSN_I64_ATOMIC_RMW_SUB ||
     99          kind == WASM_INSN_I32_ATOMIC_RMW_AND ||
    100          kind == WASM_INSN_I64_ATOMIC_RMW_AND ||
    101          kind == WASM_INSN_I32_ATOMIC_RMW_OR ||
    102          kind == WASM_INSN_I64_ATOMIC_RMW_OR ||
    103          kind == WASM_INSN_I32_ATOMIC_RMW_XOR ||
    104          kind == WASM_INSN_I64_ATOMIC_RMW_XOR ||
    105          kind == WASM_INSN_I32_ATOMIC_RMW_XCHG ||
    106          kind == WASM_INSN_I64_ATOMIC_RMW_XCHG;
    107 }
    108 
    109 int wasm_insn_is_atomic_cmpxchg(WasmInsnKind kind) {
    110   return kind == WASM_INSN_I32_ATOMIC_RMW_CMPXCHG ||
    111          kind == WASM_INSN_I64_ATOMIC_RMW_CMPXCHG;
    112 }
    113 
    114 int wasm_insn_is_atomic_wait_notify(WasmInsnKind kind) {
    115   return kind == WASM_INSN_I32_ATOMIC_WAIT ||
    116          kind == WASM_INSN_I64_ATOMIC_WAIT ||
    117          kind == WASM_INSN_MEMORY_ATOMIC_NOTIFY;
    118 }
    119 
    120 int wasm_insn_is_atomic_mem(WasmInsnKind kind) {
    121   return wasm_insn_is_atomic_load(kind) || wasm_insn_is_atomic_store(kind) ||
    122          wasm_insn_is_atomic_rmw(kind) || wasm_insn_is_atomic_cmpxchg(kind) ||
    123          wasm_insn_is_atomic_wait_notify(kind);
    124 }
    125 
    126 int wasm_insn_is_mem(WasmInsnKind kind) {
    127   return wasm_insn_is_load(kind) || wasm_insn_is_store(kind) ||
    128          wasm_insn_is_atomic_mem(kind);
    129 }
    130 
    131 WasmValType wasm_func_local_type(const WasmFunc* f, uint32_t index) {
    132   if (index < f->nparams) return f->params[index];
    133   return f->locals[index - f->nparams];
    134 }
    135 
    136 uint32_t wasm_mem_width(uint8_t kind) {
    137   switch (kind) {
    138     case WASM_INSN_I32_LOAD8_S:
    139     case WASM_INSN_I32_LOAD8_U:
    140     case WASM_INSN_I64_LOAD8_S:
    141     case WASM_INSN_I64_LOAD8_U:
    142     case WASM_INSN_I32_STORE8:
    143     case WASM_INSN_I64_STORE8:
    144     case WASM_INSN_I32_ATOMIC_LOAD8_U:
    145     case WASM_INSN_I64_ATOMIC_LOAD8_U:
    146     case WASM_INSN_I32_ATOMIC_STORE8:
    147     case WASM_INSN_I64_ATOMIC_STORE8:
    148       return 1;
    149     case WASM_INSN_I32_LOAD16_S:
    150     case WASM_INSN_I32_LOAD16_U:
    151     case WASM_INSN_I64_LOAD16_S:
    152     case WASM_INSN_I64_LOAD16_U:
    153     case WASM_INSN_I32_STORE16:
    154     case WASM_INSN_I64_STORE16:
    155     case WASM_INSN_I32_ATOMIC_LOAD16_U:
    156     case WASM_INSN_I64_ATOMIC_LOAD16_U:
    157     case WASM_INSN_I32_ATOMIC_STORE16:
    158     case WASM_INSN_I64_ATOMIC_STORE16:
    159       return 2;
    160     case WASM_INSN_I32_LOAD:
    161     case WASM_INSN_F32_LOAD:
    162     case WASM_INSN_I64_LOAD32_S:
    163     case WASM_INSN_I64_LOAD32_U:
    164     case WASM_INSN_I32_STORE:
    165     case WASM_INSN_F32_STORE:
    166     case WASM_INSN_I64_STORE32:
    167     case WASM_INSN_I32_ATOMIC_LOAD:
    168     case WASM_INSN_I64_ATOMIC_LOAD32_U:
    169     case WASM_INSN_I32_ATOMIC_STORE:
    170     case WASM_INSN_I64_ATOMIC_STORE32:
    171     case WASM_INSN_I32_ATOMIC_RMW_ADD:
    172     case WASM_INSN_I32_ATOMIC_RMW_SUB:
    173     case WASM_INSN_I32_ATOMIC_RMW_AND:
    174     case WASM_INSN_I32_ATOMIC_RMW_OR:
    175     case WASM_INSN_I32_ATOMIC_RMW_XOR:
    176     case WASM_INSN_I32_ATOMIC_RMW_XCHG:
    177     case WASM_INSN_I32_ATOMIC_RMW_CMPXCHG:
    178     case WASM_INSN_I32_ATOMIC_WAIT:
    179     case WASM_INSN_MEMORY_ATOMIC_NOTIFY:
    180       return 4;
    181     default:
    182       return 8;
    183   }
    184 }
    185 
    186 int wasm_int_cmp_op(uint8_t kind, KitCgIntCmpOp* out) {
    187   switch (kind) {
    188     case WASM_INSN_I32_EQ:
    189     case WASM_INSN_I64_EQ:
    190       *out = KIT_CG_INT_EQ;
    191       return 1;
    192     case WASM_INSN_I32_NE:
    193     case WASM_INSN_I64_NE:
    194       *out = KIT_CG_INT_NE;
    195       return 1;
    196     case WASM_INSN_I32_LT_S:
    197     case WASM_INSN_I64_LT_S:
    198       *out = KIT_CG_INT_LT_S;
    199       return 1;
    200     case WASM_INSN_I32_LT_U:
    201     case WASM_INSN_I64_LT_U:
    202       *out = KIT_CG_INT_LT_U;
    203       return 1;
    204     case WASM_INSN_I32_GT_S:
    205     case WASM_INSN_I64_GT_S:
    206       *out = KIT_CG_INT_GT_S;
    207       return 1;
    208     case WASM_INSN_I32_GT_U:
    209     case WASM_INSN_I64_GT_U:
    210       *out = KIT_CG_INT_GT_U;
    211       return 1;
    212     case WASM_INSN_I32_LE_S:
    213     case WASM_INSN_I64_LE_S:
    214       *out = KIT_CG_INT_LE_S;
    215       return 1;
    216     case WASM_INSN_I32_LE_U:
    217     case WASM_INSN_I64_LE_U:
    218       *out = KIT_CG_INT_LE_U;
    219       return 1;
    220     case WASM_INSN_I32_GE_S:
    221     case WASM_INSN_I64_GE_S:
    222       *out = KIT_CG_INT_GE_S;
    223       return 1;
    224     case WASM_INSN_I32_GE_U:
    225     case WASM_INSN_I64_GE_U:
    226       *out = KIT_CG_INT_GE_U;
    227       return 1;
    228     default:
    229       return 0;
    230   }
    231 }
    232 
    233 WasmValType wasm_load_result_type(uint8_t kind) {
    234   switch (kind) {
    235     case WASM_INSN_F32_LOAD:
    236       return WASM_VAL_F32;
    237     case WASM_INSN_F64_LOAD:
    238       return WASM_VAL_F64;
    239     case WASM_INSN_I64_LOAD:
    240     case WASM_INSN_I64_LOAD8_S:
    241     case WASM_INSN_I64_LOAD8_U:
    242     case WASM_INSN_I64_LOAD16_S:
    243     case WASM_INSN_I64_LOAD16_U:
    244     case WASM_INSN_I64_LOAD32_S:
    245     case WASM_INSN_I64_LOAD32_U:
    246     case WASM_INSN_I64_ATOMIC_LOAD:
    247     case WASM_INSN_I64_ATOMIC_LOAD8_U:
    248     case WASM_INSN_I64_ATOMIC_LOAD16_U:
    249     case WASM_INSN_I64_ATOMIC_LOAD32_U:
    250       return WASM_VAL_I64;
    251     default:
    252       return WASM_VAL_I32;
    253   }
    254 }
    255 
    256 WasmValType wasm_store_value_type(uint8_t kind) {
    257   switch (kind) {
    258     case WASM_INSN_F32_STORE:
    259       return WASM_VAL_F32;
    260     case WASM_INSN_F64_STORE:
    261       return WASM_VAL_F64;
    262     case WASM_INSN_I64_STORE:
    263     case WASM_INSN_I64_STORE8:
    264     case WASM_INSN_I64_STORE16:
    265     case WASM_INSN_I64_STORE32:
    266     case WASM_INSN_I64_ATOMIC_STORE:
    267     case WASM_INSN_I64_ATOMIC_STORE8:
    268     case WASM_INSN_I64_ATOMIC_STORE16:
    269     case WASM_INSN_I64_ATOMIC_STORE32:
    270       return WASM_VAL_I64;
    271     default:
    272       return WASM_VAL_I32;
    273   }
    274 }
    275 
    276 WasmValType wasm_atomic_value_type(uint8_t kind) {
    277   switch (kind) {
    278     case WASM_INSN_I64_ATOMIC_LOAD:
    279     case WASM_INSN_I64_ATOMIC_LOAD8_U:
    280     case WASM_INSN_I64_ATOMIC_LOAD16_U:
    281     case WASM_INSN_I64_ATOMIC_LOAD32_U:
    282     case WASM_INSN_I64_ATOMIC_STORE:
    283     case WASM_INSN_I64_ATOMIC_STORE8:
    284     case WASM_INSN_I64_ATOMIC_STORE16:
    285     case WASM_INSN_I64_ATOMIC_STORE32:
    286     case WASM_INSN_I64_ATOMIC_RMW_ADD:
    287     case WASM_INSN_I64_ATOMIC_RMW_SUB:
    288     case WASM_INSN_I64_ATOMIC_RMW_AND:
    289     case WASM_INSN_I64_ATOMIC_RMW_OR:
    290     case WASM_INSN_I64_ATOMIC_RMW_XOR:
    291     case WASM_INSN_I64_ATOMIC_RMW_XCHG:
    292     case WASM_INSN_I64_ATOMIC_RMW_CMPXCHG:
    293     case WASM_INSN_I64_ATOMIC_WAIT:
    294       return WASM_VAL_I64;
    295     default:
    296       return WASM_VAL_I32;
    297   }
    298 }
    299 
    300 KitCgAtomicOp wasm_atomic_rmw_op(uint8_t kind) {
    301   switch (kind) {
    302     case WASM_INSN_I32_ATOMIC_RMW_ADD:
    303     case WASM_INSN_I64_ATOMIC_RMW_ADD:
    304       return KIT_CG_ATOMIC_ADD;
    305     case WASM_INSN_I32_ATOMIC_RMW_SUB:
    306     case WASM_INSN_I64_ATOMIC_RMW_SUB:
    307       return KIT_CG_ATOMIC_SUB;
    308     case WASM_INSN_I32_ATOMIC_RMW_AND:
    309     case WASM_INSN_I64_ATOMIC_RMW_AND:
    310       return KIT_CG_ATOMIC_AND;
    311     case WASM_INSN_I32_ATOMIC_RMW_OR:
    312     case WASM_INSN_I64_ATOMIC_RMW_OR:
    313       return KIT_CG_ATOMIC_OR;
    314     case WASM_INSN_I32_ATOMIC_RMW_XOR:
    315     case WASM_INSN_I64_ATOMIC_RMW_XOR:
    316       return KIT_CG_ATOMIC_XOR;
    317     default:
    318       return KIT_CG_ATOMIC_XCHG;
    319   }
    320 }
    321 
    322 int wasm_int_unop_kind(uint8_t kind, WasmValType* vt) {
    323   if (kind == WASM_INSN_I32_CLZ || kind == WASM_INSN_I32_CTZ ||
    324       kind == WASM_INSN_I32_POPCNT || kind == WASM_INSN_I32_EXTEND8_S ||
    325       kind == WASM_INSN_I32_EXTEND16_S) {
    326     *vt = WASM_VAL_I32;
    327     return 1;
    328   }
    329   if (kind == WASM_INSN_I64_CLZ || kind == WASM_INSN_I64_CTZ ||
    330       kind == WASM_INSN_I64_POPCNT || kind == WASM_INSN_I64_EXTEND8_S ||
    331       kind == WASM_INSN_I64_EXTEND16_S || kind == WASM_INSN_I64_EXTEND32_S) {
    332     *vt = WASM_VAL_I64;
    333     return 1;
    334   }
    335   return 0;
    336 }
    337 
    338 int wasm_fp_unop_kind(uint8_t kind, WasmValType* vt) {
    339   if (kind == WASM_INSN_F32_NEG) {
    340     *vt = WASM_VAL_F32;
    341     return 1;
    342   }
    343   if (kind == WASM_INSN_F64_NEG) {
    344     *vt = WASM_VAL_F64;
    345     return 1;
    346   }
    347   return 0;
    348 }
    349 
    350 int wasm_fp_binop_kind(uint8_t kind, WasmValType* vt) {
    351   if (kind == WASM_INSN_F32_ADD || kind == WASM_INSN_F32_SUB ||
    352       kind == WASM_INSN_F32_MUL || kind == WASM_INSN_F32_DIV) {
    353     *vt = WASM_VAL_F32;
    354     return 1;
    355   }
    356   if (kind == WASM_INSN_F64_ADD || kind == WASM_INSN_F64_SUB ||
    357       kind == WASM_INSN_F64_MUL || kind == WASM_INSN_F64_DIV) {
    358     *vt = WASM_VAL_F64;
    359     return 1;
    360   }
    361   return 0;
    362 }
    363 
    364 int wasm_fp_cmp_kind(uint8_t kind, WasmValType* vt) {
    365   if (kind == WASM_INSN_F32_EQ || kind == WASM_INSN_F32_NE ||
    366       kind == WASM_INSN_F32_LT || kind == WASM_INSN_F32_GT ||
    367       kind == WASM_INSN_F32_LE || kind == WASM_INSN_F32_GE) {
    368     *vt = WASM_VAL_F32;
    369     return 1;
    370   }
    371   if (kind == WASM_INSN_F64_EQ || kind == WASM_INSN_F64_NE ||
    372       kind == WASM_INSN_F64_LT || kind == WASM_INSN_F64_GT ||
    373       kind == WASM_INSN_F64_LE || kind == WASM_INSN_F64_GE) {
    374     *vt = WASM_VAL_F64;
    375     return 1;
    376   }
    377   return 0;
    378 }
    379 
    380 int wasm_conversion_kind(uint8_t kind, WasmValType* src, WasmValType* dst) {
    381   switch (kind) {
    382     case WASM_INSN_I32_WRAP_I64:
    383       *src = WASM_VAL_I64;
    384       *dst = WASM_VAL_I32;
    385       return 1;
    386     case WASM_INSN_I64_EXTEND_I32_S:
    387     case WASM_INSN_I64_EXTEND_I32_U:
    388       *src = WASM_VAL_I32;
    389       *dst = WASM_VAL_I64;
    390       return 1;
    391     case WASM_INSN_I32_TRUNC_F32_S:
    392     case WASM_INSN_I32_TRUNC_F32_U:
    393       *src = WASM_VAL_F32;
    394       *dst = WASM_VAL_I32;
    395       return 1;
    396     case WASM_INSN_I32_TRUNC_F64_S:
    397     case WASM_INSN_I32_TRUNC_F64_U:
    398       *src = WASM_VAL_F64;
    399       *dst = WASM_VAL_I32;
    400       return 1;
    401     case WASM_INSN_I64_TRUNC_F32_S:
    402     case WASM_INSN_I64_TRUNC_F32_U:
    403       *src = WASM_VAL_F32;
    404       *dst = WASM_VAL_I64;
    405       return 1;
    406     case WASM_INSN_I64_TRUNC_F64_S:
    407     case WASM_INSN_I64_TRUNC_F64_U:
    408       *src = WASM_VAL_F64;
    409       *dst = WASM_VAL_I64;
    410       return 1;
    411     case WASM_INSN_F32_CONVERT_I32_S:
    412     case WASM_INSN_F32_CONVERT_I32_U:
    413       *src = WASM_VAL_I32;
    414       *dst = WASM_VAL_F32;
    415       return 1;
    416     case WASM_INSN_F32_CONVERT_I64_S:
    417     case WASM_INSN_F32_CONVERT_I64_U:
    418       *src = WASM_VAL_I64;
    419       *dst = WASM_VAL_F32;
    420       return 1;
    421     case WASM_INSN_F64_CONVERT_I32_S:
    422     case WASM_INSN_F64_CONVERT_I32_U:
    423       *src = WASM_VAL_I32;
    424       *dst = WASM_VAL_F64;
    425       return 1;
    426     case WASM_INSN_F64_CONVERT_I64_S:
    427     case WASM_INSN_F64_CONVERT_I64_U:
    428       *src = WASM_VAL_I64;
    429       *dst = WASM_VAL_F64;
    430       return 1;
    431     case WASM_INSN_F32_DEMOTE_F64:
    432       *src = WASM_VAL_F64;
    433       *dst = WASM_VAL_F32;
    434       return 1;
    435     case WASM_INSN_F64_PROMOTE_F32:
    436       *src = WASM_VAL_F32;
    437       *dst = WASM_VAL_F64;
    438       return 1;
    439     case WASM_INSN_I32_REINTERPRET_F32:
    440       *src = WASM_VAL_F32;
    441       *dst = WASM_VAL_I32;
    442       return 1;
    443     case WASM_INSN_I64_REINTERPRET_F64:
    444       *src = WASM_VAL_F64;
    445       *dst = WASM_VAL_I64;
    446       return 1;
    447     case WASM_INSN_F32_REINTERPRET_I32:
    448       *src = WASM_VAL_I32;
    449       *dst = WASM_VAL_F32;
    450       return 1;
    451     case WASM_INSN_F64_REINTERPRET_I64:
    452       *src = WASM_VAL_I64;
    453       *dst = WASM_VAL_F64;
    454       return 1;
    455     default:
    456       return 0;
    457   }
    458 }
    459 
    460 /* WAT mnemonic for an instruction kind. Spellings live in WASM_INSN_TABLE so
    461  * the encoder, disassembler, and WAT parser all agree. Returns ".unknown" for
    462  * any out-of-range kind rather than NULL so callers can print unconditionally.
    463  */
    464 const char* wasm_insn_mnemonic(WasmInsnKind kind) {
    465   const WasmInsnInfo* info = wasm_insn_info(kind);
    466   return info ? info->mnemonic : ".unknown";
    467 }