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