1// Copyright 2020 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#if !V8_ENABLE_WEBASSEMBLY 6#error This header should only be included if WebAssembly is enabled. 7#endif // !V8_ENABLE_WEBASSEMBLY 8 9#ifndef V8_WASM_WASM_OPCODES_INL_H_ 10#define V8_WASM_WASM_OPCODES_INL_H_ 11 12#include <array> 13 14#include "src/base/template-utils.h" 15#include "src/codegen/signature.h" 16#include "src/execution/messages.h" 17#include "src/runtime/runtime.h" 18#include "src/wasm/wasm-opcodes.h" 19 20namespace v8 { 21namespace internal { 22namespace wasm { 23 24#define CASE_OP(name, str) \ 25 case kExpr##name: \ 26 return str; 27#define CASE_I32_OP(name, str) CASE_OP(I32##name, "i32." str) 28#define CASE_I64_OP(name, str) CASE_OP(I64##name, "i64." str) 29#define CASE_F32_OP(name, str) CASE_OP(F32##name, "f32." str) 30#define CASE_F64_OP(name, str) CASE_OP(F64##name, "f64." str) 31#define CASE_REF_OP(name, str) CASE_OP(Ref##name, "ref." str) 32#define CASE_F64x2_OP(name, str) CASE_OP(F64x2##name, "f64x2." str) 33#define CASE_F32x4_OP(name, str) CASE_OP(F32x4##name, "f32x4." str) 34#define CASE_I64x2_OP(name, str) CASE_OP(I64x2##name, "i64x2." str) 35#define CASE_I32x4_OP(name, str) CASE_OP(I32x4##name, "i32x4." str) 36#define CASE_I16x8_OP(name, str) CASE_OP(I16x8##name, "i16x8." str) 37#define CASE_I8x16_OP(name, str) CASE_OP(I8x16##name, "i8x16." str) 38#define CASE_S128_OP(name, str) CASE_OP(S128##name, "s128." str) 39#define CASE_V128_OP(name, str) CASE_OP(V128##name, "v128." str) 40#define CASE_S64x2_OP(name, str) CASE_OP(S64x2##name, "s64x2." str) 41#define CASE_S32x4_OP(name, str) CASE_OP(S32x4##name, "s32x4." str) 42#define CASE_S16x8_OP(name, str) CASE_OP(S16x8##name, "s16x8." str) 43#define CASE_V64x2_OP(name, str) CASE_OP(V64x2##name, "v64x2." str) 44#define CASE_V32x4_OP(name, str) CASE_OP(V32x4##name, "v32x4." str) 45#define CASE_V16x8_OP(name, str) CASE_OP(V16x8##name, "v16x8." str) 46#define CASE_V8x16_OP(name, str) CASE_OP(V8x16##name, "v8x16." str) 47#define CASE_INT_OP(name, str) CASE_I32_OP(name, str) CASE_I64_OP(name, str) 48#define CASE_FLOAT_OP(name, str) CASE_F32_OP(name, str) CASE_F64_OP(name, str) 49#define CASE_ALL_OP(name, str) CASE_FLOAT_OP(name, str) CASE_INT_OP(name, str) 50#define CASE_SIMD_OP(name, str) \ 51 CASE_F64x2_OP(name, str) CASE_I64x2_OP(name, str) CASE_F32x4_OP(name, str) \ 52 CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) \ 53 CASE_I8x16_OP(name, str) 54#define CASE_SIMDF_OP(name, str) \ 55 CASE_F32x4_OP(name, str) CASE_F64x2_OP(name, str) 56#define CASE_SIMDI_OP(name, str) \ 57 CASE_I64x2_OP(name, str) CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) \ 58 CASE_I8x16_OP(name, str) 59#define CASE_SIMDI_NO64X2_OP(name, str) \ 60 CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) CASE_I8x16_OP(name, str) 61#define CASE_SIGN_OP(TYPE, name, str) \ 62 CASE_##TYPE##_OP(name##S, str "_s") CASE_##TYPE##_OP(name##U, str "_u") 63#define CASE_UNSIGNED_OP(TYPE, name, str) CASE_##TYPE##_OP(name##U, str "_u") 64#define CASE_ALL_SIGN_OP(name, str) \ 65 CASE_FLOAT_OP(name, str) CASE_SIGN_OP(INT, name, str) 66#define CASE_CONVERT_OP(name, RES, SRC, src_suffix, str) \ 67 CASE_##RES##_OP(U##name##SRC, str "_" src_suffix "_u") \ 68 CASE_##RES##_OP(S##name##SRC, str "_" src_suffix "_s") 69#define CASE_CONVERT_SAT_OP(name, RES, SRC, src_suffix, str) \ 70 CASE_##RES##_OP(U##name##Sat##SRC, str "_sat_" src_suffix "_u") \ 71 CASE_##RES##_OP(S##name##Sat##SRC, str "_sat_" src_suffix "_s") 72#define CASE_L32_OP(name, str) \ 73 CASE_SIGN_OP(I32, name##8, str "8") \ 74 CASE_SIGN_OP(I32, name##16, str "16") \ 75 CASE_I32_OP(name, str "32") 76#define CASE_U32_OP(name, str) \ 77 CASE_I32_OP(name, str "32") \ 78 CASE_UNSIGNED_OP(I32, name##8, str "8") \ 79 CASE_UNSIGNED_OP(I32, name##16, str "16") 80#define CASE_UNSIGNED_ALL_OP(name, str) \ 81 CASE_U32_OP(name, str) \ 82 CASE_I64_OP(name, str "64") \ 83 CASE_UNSIGNED_OP(I64, name##8, str "8") \ 84 CASE_UNSIGNED_OP(I64, name##16, str "16") \ 85 CASE_UNSIGNED_OP(I64, name##32, str "32") 86 87// static 88constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) { 89 switch (opcode) { 90 // clang-format off 91 92 // Standard opcodes 93 CASE_INT_OP(Eqz, "eqz") 94 CASE_ALL_OP(Eq, "eq") 95 CASE_ALL_OP(Ne, "ne") 96 CASE_ALL_OP(Add, "add") 97 CASE_ALL_OP(Sub, "sub") 98 CASE_ALL_OP(Mul, "mul") 99 CASE_ALL_SIGN_OP(Lt, "lt") 100 CASE_ALL_SIGN_OP(Gt, "gt") 101 CASE_ALL_SIGN_OP(Le, "le") 102 CASE_ALL_SIGN_OP(Ge, "ge") 103 CASE_INT_OP(Clz, "clz") 104 CASE_INT_OP(Ctz, "ctz") 105 CASE_INT_OP(Popcnt, "popcnt") 106 CASE_ALL_SIGN_OP(Div, "div") 107 CASE_SIGN_OP(INT, Rem, "rem") 108 CASE_INT_OP(And, "and") 109 CASE_INT_OP(Ior, "or") 110 CASE_INT_OP(Xor, "xor") 111 CASE_INT_OP(Shl, "shl") 112 CASE_SIGN_OP(INT, Shr, "shr") 113 CASE_INT_OP(Rol, "rol") 114 CASE_INT_OP(Ror, "ror") 115 CASE_FLOAT_OP(Abs, "abs") 116 CASE_FLOAT_OP(Neg, "neg") 117 CASE_FLOAT_OP(Ceil, "ceil") 118 CASE_FLOAT_OP(Floor, "floor") 119 CASE_FLOAT_OP(Trunc, "trunc") 120 CASE_FLOAT_OP(NearestInt, "nearest") 121 CASE_FLOAT_OP(Sqrt, "sqrt") 122 CASE_FLOAT_OP(Min, "min") 123 CASE_FLOAT_OP(Max, "max") 124 CASE_FLOAT_OP(CopySign, "copysign") 125 CASE_REF_OP(Null, "null") 126 CASE_REF_OP(IsNull, "is_null") 127 CASE_REF_OP(Func, "func") 128 CASE_REF_OP(AsNonNull, "as_non_null") 129 CASE_I32_OP(ConvertI64, "wrap_i64") 130 CASE_CONVERT_OP(Convert, INT, F32, "f32", "trunc") 131 CASE_CONVERT_OP(Convert, INT, F64, "f64", "trunc") 132 CASE_CONVERT_OP(Convert, I64, I32, "i32", "extend") 133 CASE_CONVERT_OP(Convert, F32, I32, "i32", "convert") 134 CASE_CONVERT_OP(Convert, F32, I64, "i64", "convert") 135 CASE_F32_OP(ConvertF64, "demote_f64") 136 CASE_CONVERT_OP(Convert, F64, I32, "i32", "convert") 137 CASE_CONVERT_OP(Convert, F64, I64, "i64", "convert") 138 CASE_F64_OP(ConvertF32, "promote_f32") 139 CASE_I32_OP(ReinterpretF32, "reinterpret_f32") 140 CASE_I64_OP(ReinterpretF64, "reinterpret_f64") 141 CASE_F32_OP(ReinterpretI32, "reinterpret_i32") 142 CASE_F64_OP(ReinterpretI64, "reinterpret_i64") 143 CASE_INT_OP(SExtendI8, "extend8_s") 144 CASE_INT_OP(SExtendI16, "extend16_s") 145 CASE_I64_OP(SExtendI32, "extend32_s") 146 CASE_OP(Unreachable, "unreachable") 147 CASE_OP(Nop, "nop") 148 CASE_OP(NopForTestingUnsupportedInLiftoff, "nop_for_testing") 149 CASE_OP(Block, "block") 150 CASE_OP(Loop, "loop") 151 CASE_OP(If, "if") 152 CASE_OP(Else, "else") 153 CASE_OP(End, "end") 154 CASE_OP(Br, "br") 155 CASE_OP(BrIf, "br_if") 156 CASE_OP(BrTable, "br_table") 157 CASE_OP(Return, "return") 158 CASE_OP(CallFunction, "call") 159 CASE_OP(CallIndirect, "call_indirect") 160 CASE_OP(ReturnCall, "return_call") 161 CASE_OP(ReturnCallIndirect, "return_call_indirect") 162 CASE_OP(CallRef, "call_ref") 163 CASE_OP(ReturnCallRef, "return_call_ref") 164 CASE_OP(BrOnNull, "br_on_null") 165 CASE_OP(BrOnNonNull, "br_on_non_null") 166 CASE_OP(Drop, "drop") 167 CASE_OP(Select, "select") 168 CASE_OP(SelectWithType, "select") 169 CASE_OP(LocalGet, "local.get") 170 CASE_OP(LocalSet, "local.set") 171 CASE_OP(LocalTee, "local.tee") 172 CASE_OP(GlobalGet, "global.get") 173 CASE_OP(GlobalSet, "global.set") 174 CASE_OP(TableGet, "table.get") 175 CASE_OP(TableSet, "table.set") 176 CASE_ALL_OP(Const, "const") 177 CASE_OP(MemorySize, "memory.size") 178 CASE_OP(MemoryGrow, "memory.grow") 179 CASE_ALL_OP(LoadMem, "load") 180 CASE_SIGN_OP(INT, LoadMem8, "load8") 181 CASE_SIGN_OP(INT, LoadMem16, "load16") 182 CASE_SIGN_OP(I64, LoadMem32, "load32") 183 CASE_S128_OP(LoadMem, "load128") 184 CASE_S128_OP(Const, "const") 185 CASE_ALL_OP(StoreMem, "store") 186 CASE_INT_OP(StoreMem8, "store8") 187 CASE_INT_OP(StoreMem16, "store16") 188 CASE_I64_OP(StoreMem32, "store32") 189 CASE_S128_OP(StoreMem, "store128") 190 CASE_OP(RefEq, "ref.eq") 191 CASE_OP(Let, "let") 192 193 // Exception handling opcodes. 194 CASE_OP(Try, "try") 195 CASE_OP(Catch, "catch") 196 CASE_OP(Delegate, "delegate") 197 CASE_OP(Throw, "throw") 198 CASE_OP(Rethrow, "rethrow") 199 CASE_OP(CatchAll, "catch-all") 200 201 // asm.js-only opcodes. 202 CASE_F64_OP(Acos, "acos") 203 CASE_F64_OP(Asin, "asin") 204 CASE_F64_OP(Atan, "atan") 205 CASE_F64_OP(Cos, "cos") 206 CASE_F64_OP(Sin, "sin") 207 CASE_F64_OP(Tan, "tan") 208 CASE_F64_OP(Exp, "exp") 209 CASE_F64_OP(Log, "log") 210 CASE_F64_OP(Atan2, "atan2") 211 CASE_F64_OP(Pow, "pow") 212 CASE_F64_OP(Mod, "mod") 213 CASE_F32_OP(AsmjsLoadMem, "asmjs_load") 214 CASE_F64_OP(AsmjsLoadMem, "asmjs_load") 215 CASE_L32_OP(AsmjsLoadMem, "asmjs_load") 216 CASE_I32_OP(AsmjsStoreMem, "asmjs_store") 217 CASE_F32_OP(AsmjsStoreMem, "asmjs_store") 218 CASE_F64_OP(AsmjsStoreMem, "asmjs_store") 219 CASE_I32_OP(AsmjsStoreMem8, "asmjs_store8") 220 CASE_I32_OP(AsmjsStoreMem16, "asmjs_store16") 221 CASE_SIGN_OP(I32, AsmjsDiv, "asmjs_div") 222 CASE_SIGN_OP(I32, AsmjsRem, "asmjs_rem") 223 CASE_I32_OP(AsmjsSConvertF32, "asmjs_convert_f32_s") 224 CASE_I32_OP(AsmjsUConvertF32, "asmjs_convert_f32_u") 225 CASE_I32_OP(AsmjsSConvertF64, "asmjs_convert_f64_s") 226 CASE_I32_OP(AsmjsUConvertF64, "asmjs_convert_f64_u") 227 228 // Numeric Opcodes. 229 CASE_CONVERT_SAT_OP(Convert, I32, F32, "f32", "trunc") 230 CASE_CONVERT_SAT_OP(Convert, I32, F64, "f64", "trunc") 231 CASE_CONVERT_SAT_OP(Convert, I64, F32, "f32", "trunc") 232 CASE_CONVERT_SAT_OP(Convert, I64, F64, "f64", "trunc") 233 CASE_OP(MemoryInit, "memory.init") 234 CASE_OP(DataDrop, "data.drop") 235 CASE_OP(MemoryCopy, "memory.copy") 236 CASE_OP(MemoryFill, "memory.fill") 237 CASE_OP(TableInit, "table.init") 238 CASE_OP(ElemDrop, "elem.drop") 239 CASE_OP(TableCopy, "table.copy") 240 CASE_OP(TableGrow, "table.grow") 241 CASE_OP(TableSize, "table.size") 242 CASE_OP(TableFill, "table.fill") 243 244 // SIMD opcodes. 245 CASE_SIMD_OP(Splat, "splat") 246 CASE_SIMD_OP(Neg, "neg") 247 CASE_SIMDF_OP(Sqrt, "sqrt") 248 CASE_SIMD_OP(Eq, "eq") 249 CASE_SIMD_OP(Ne, "ne") 250 CASE_SIMD_OP(Add, "add") 251 CASE_SIMD_OP(Sub, "sub") 252 CASE_I16x8_OP(Mul, "mul") 253 CASE_I32x4_OP(Mul, "mul") 254 CASE_I64x2_OP(Mul, "mul") 255 CASE_SIMDF_OP(Mul, "mul") 256 CASE_SIMDF_OP(Div, "div") 257 CASE_SIMDF_OP(Lt, "lt") 258 CASE_SIMDF_OP(Le, "le") 259 CASE_SIMDF_OP(Gt, "gt") 260 CASE_SIMDF_OP(Ge, "ge") 261 CASE_SIMDF_OP(Abs, "abs") 262 CASE_SIMDF_OP(Min, "min") 263 CASE_SIMDF_OP(Max, "max") 264 CASE_CONVERT_OP(Convert, F32x4, I32x4, "i32x4", "convert") 265 CASE_CONVERT_OP(Convert, I32x4, F32x4, "f32x4", "convert") 266 CASE_CONVERT_OP(Convert, I32x4, I16x8Low, "i16x8_low", "convert") 267 CASE_CONVERT_OP(Convert, I32x4, I16x8High, "i16x8_high", "convert") 268 CASE_CONVERT_OP(Convert, I16x8, I32x4, "i32x4", "convert") 269 CASE_CONVERT_OP(Convert, I16x8, I8x16Low, "i8x16_low", "convert") 270 CASE_CONVERT_OP(Convert, I16x8, I8x16High, "i8x16_high", "convert") 271 CASE_CONVERT_OP(Convert, I8x16, I16x8, "i16x8", "convert") 272 CASE_SIMDF_OP(ExtractLane, "extract_lane") 273 CASE_SIMDF_OP(ReplaceLane, "replace_lane") 274 CASE_I64x2_OP(ExtractLane, "extract_lane") 275 CASE_I32x4_OP(ExtractLane, "extract_lane") 276 CASE_SIGN_OP(I16x8, ExtractLane, "extract_lane") 277 CASE_SIGN_OP(I8x16, ExtractLane, "extract_lane") 278 CASE_SIMDI_OP(ReplaceLane, "replace_lane") 279 CASE_SIGN_OP(SIMDI_NO64X2, Min, "min") 280 CASE_SIGN_OP(SIMDI_NO64X2, Max, "max") 281 CASE_SIGN_OP(SIMDI_NO64X2, Lt, "lt") 282 CASE_I64x2_OP(LtS, "lt_s") 283 CASE_I64x2_OP(GtS, "gt_s") 284 CASE_I64x2_OP(LeS, "le_s") 285 CASE_I64x2_OP(GeS, "ge_s") 286 CASE_SIGN_OP(SIMDI_NO64X2, Le, "le") 287 CASE_SIGN_OP(SIMDI_NO64X2, Gt, "gt") 288 CASE_SIGN_OP(SIMDI_NO64X2, Ge, "ge") 289 CASE_CONVERT_OP(Convert, I64x2, I32x4Low, "i32x4_low", "convert") 290 CASE_CONVERT_OP(Convert, I64x2, I32x4High, "i32x4_high", "convert") 291 CASE_SIGN_OP(SIMDI, Shr, "shr") 292 CASE_SIMDI_OP(Shl, "shl") 293 CASE_SIGN_OP(I16x8, AddSat, "add_sat") 294 CASE_SIGN_OP(I8x16, AddSat, "add_sat") 295 CASE_SIGN_OP(I16x8, SubSat, "sub_sat") 296 CASE_SIGN_OP(I8x16, SubSat, "sub_sat") 297 CASE_S128_OP(And, "and") 298 CASE_S128_OP(Or, "or") 299 CASE_S128_OP(Xor, "xor") 300 CASE_S128_OP(Not, "not") 301 CASE_S128_OP(Select, "select") 302 CASE_S128_OP(AndNot, "andnot") 303 CASE_I8x16_OP(Swizzle, "swizzle") 304 CASE_I8x16_OP(Shuffle, "shuffle") 305 CASE_V128_OP(AnyTrue, "any_true") 306 CASE_SIMDI_OP(AllTrue, "all_true") 307 308 CASE_S128_OP(Load32Zero, "load32_zero") 309 CASE_S128_OP(Load64Zero, "load64_zero") 310 CASE_S128_OP(Load8Splat, "load8_splat") 311 CASE_S128_OP(Load16Splat, "load16_splat") 312 CASE_S128_OP(Load32Splat, "load32_splat") 313 CASE_S128_OP(Load64Splat, "load64_splat") 314 CASE_S128_OP(Load8x8S, "load8x8_s") 315 CASE_S128_OP(Load8x8U, "load8x8_u") 316 CASE_S128_OP(Load16x4S, "load16x4_s") 317 CASE_S128_OP(Load16x4U, "load16x4_u") 318 CASE_S128_OP(Load32x2S, "load32x2_s") 319 CASE_S128_OP(Load32x2U, "load32x2_u") 320 CASE_S128_OP(Load8Lane, "load8_lane") 321 CASE_S128_OP(Load16Lane, "load16_lane") 322 CASE_S128_OP(Load32Lane, "load32_lane") 323 CASE_S128_OP(Load64Lane, "load64_lane") 324 CASE_S128_OP(Store8Lane, "store8_lane") 325 CASE_S128_OP(Store16Lane, "store16_lane") 326 CASE_S128_OP(Store32Lane, "store32_lane") 327 CASE_S128_OP(Store64Lane, "store64_lane") 328 329 CASE_I8x16_OP(RoundingAverageU, "avgr_u") 330 CASE_I16x8_OP(RoundingAverageU, "avgr_u") 331 CASE_I16x8_OP(Q15MulRSatS, "q15mulr_sat_s") 332 333 CASE_SIMDI_OP(Abs, "abs") 334 CASE_SIMDI_OP(BitMask, "bitmask") 335 CASE_I8x16_OP(Popcnt, "popcnt") 336 337 338 CASE_SIMDF_OP(Pmin, "pmin") 339 CASE_SIMDF_OP(Pmax, "pmax") 340 341 CASE_SIMDF_OP(Ceil, "ceil") 342 CASE_SIMDF_OP(Floor, "floor") 343 CASE_SIMDF_OP(Trunc, "trunc") 344 CASE_SIMDF_OP(NearestInt, "nearest") 345 346 CASE_I32x4_OP(DotI16x8S, "dot_i16x8_s") 347 348 CASE_SIGN_OP(I16x8, ExtMulLowI8x16, "extmul_low_i8x16") 349 CASE_SIGN_OP(I16x8, ExtMulHighI8x16, "extmul_high_i8x16") 350 CASE_SIGN_OP(I32x4, ExtMulLowI16x8, "extmul_low_i16x8") 351 CASE_SIGN_OP(I32x4, ExtMulHighI16x8, "extmul_high_i16x8") 352 CASE_SIGN_OP(I64x2, ExtMulLowI32x4, "extmul_low_i32x4") 353 CASE_SIGN_OP(I64x2, ExtMulHighI32x4, "extmul_high_i32x4") 354 355 CASE_SIGN_OP(I32x4, ExtAddPairwiseI16x8, "extadd_pairwise_i16x8") 356 CASE_SIGN_OP(I16x8, ExtAddPairwiseI8x16, "extadd_pairwise_i8x6") 357 358 CASE_F64x2_OP(ConvertLowI32x4S, "convert_low_i32x4_s") 359 CASE_F64x2_OP(ConvertLowI32x4U, "convert_low_i32x4_u") 360 CASE_I32x4_OP(TruncSatF64x2SZero, "trunc_sat_f64x2_s_zero") 361 CASE_I32x4_OP(TruncSatF64x2UZero, "trunc_sat_f64x2_u_zero") 362 CASE_F32x4_OP(DemoteF64x2Zero, "demote_f64x2_zero") 363 CASE_F64x2_OP(PromoteLowF32x4, "promote_low_f32x4") 364 365 // Relaxed SIMD opcodes. 366 CASE_F32x4_OP(RecipApprox, "recip_approx") 367 CASE_F32x4_OP(RecipSqrtApprox, "recip_sqrt_approx") 368 CASE_SIMDF_OP(Qfma, "qfma") 369 CASE_SIMDF_OP(Qfms, "qfms") 370 CASE_I8x16_OP(RelaxedSwizzle, "relaxed_swizzle"); 371 CASE_I8x16_OP(RelaxedLaneSelect, "relaxed_laneselect"); 372 CASE_I16x8_OP(RelaxedLaneSelect, "relaxed_laneselect"); 373 CASE_I32x4_OP(RelaxedLaneSelect, "relaxed_laneselect"); 374 CASE_I64x2_OP(RelaxedLaneSelect, "relaxed_laneselect"); 375 CASE_SIMDF_OP(RelaxedMin, "relaxed_min"); 376 CASE_SIMDF_OP(RelaxedMax, "relaxed_max"); 377 CASE_I32x4_OP(RelaxedTruncF32x4S, "relaxed_trunc_f32x4_s"); 378 CASE_I32x4_OP(RelaxedTruncF32x4U, "relaxed_trunc_f32x4_u"); 379 CASE_I32x4_OP(RelaxedTruncF64x2SZero, "relaxed_trunc_f64x2_s_zero"); 380 CASE_I32x4_OP(RelaxedTruncF64x2UZero, "relaxed_trunc_f64x2_u_zero"); 381 382 // Atomic operations. 383 CASE_OP(AtomicNotify, "atomic.notify") 384 CASE_INT_OP(AtomicWait, "atomic.wait") 385 CASE_OP(AtomicFence, "atomic.fence") 386 CASE_UNSIGNED_ALL_OP(AtomicLoad, "atomic.load") 387 CASE_UNSIGNED_ALL_OP(AtomicStore, "atomic.store") 388 CASE_UNSIGNED_ALL_OP(AtomicAdd, "atomic.add") 389 CASE_UNSIGNED_ALL_OP(AtomicSub, "atomic.sub") 390 CASE_UNSIGNED_ALL_OP(AtomicAnd, "atomic.and") 391 CASE_UNSIGNED_ALL_OP(AtomicOr, "atomic.or") 392 CASE_UNSIGNED_ALL_OP(AtomicXor, "atomic.xor") 393 CASE_UNSIGNED_ALL_OP(AtomicExchange, "atomic.xchng") 394 CASE_UNSIGNED_ALL_OP(AtomicCompareExchange, "atomic.cmpxchng") 395 396 // GC operations. 397 CASE_OP(StructNewWithRtt, "struct.new_with_rtt") 398 CASE_OP(StructNewDefaultWithRtt, "struct.new_default_with_rtt") 399 CASE_OP(StructNew, "struct.new") 400 CASE_OP(StructNewDefault, "struct.new_default") 401 CASE_OP(StructGet, "struct.get") 402 CASE_OP(StructGetS, "struct.get_s") 403 CASE_OP(StructGetU, "struct.get_u") 404 CASE_OP(StructSet, "struct.set") 405 CASE_OP(ArrayNewWithRtt, "array.new_with_rtt") 406 CASE_OP(ArrayNewDefaultWithRtt, "array.new_default_with_rtt") 407 CASE_OP(ArrayNew, "array.new") 408 CASE_OP(ArrayNewDefault, "array.new_default") 409 CASE_OP(ArrayGet, "array.get") 410 CASE_OP(ArrayGetS, "array.get_s") 411 CASE_OP(ArrayGetU, "array.get_u") 412 CASE_OP(ArraySet, "array.set") 413 CASE_OP(ArrayLen, "array.len") 414 CASE_OP(ArrayCopy, "array.copy") 415 CASE_OP(ArrayInit, "array.init") 416 CASE_OP(ArrayInitStatic, "array.init_static") 417 CASE_OP(ArrayInitFromData, "array.init_from_data") 418 CASE_OP(ArrayInitFromDataStatic, "array.init_from_data_static") 419 CASE_OP(I31New, "i31.new") 420 CASE_OP(I31GetS, "i31.get_s") 421 CASE_OP(I31GetU, "i31.get_u") 422 CASE_OP(RttCanon, "rtt.canon") 423 CASE_OP(RefTest, "ref.test") 424 CASE_OP(RefTestStatic, "ref.test_static") 425 CASE_OP(RefCast, "ref.cast") 426 CASE_OP(RefCastStatic, "ref.cast_static") 427 CASE_OP(BrOnCast, "br_on_cast") 428 CASE_OP(BrOnCastStatic, "br_on_cast_static") 429 CASE_OP(BrOnCastFail, "br_on_cast_fail") 430 CASE_OP(BrOnCastStaticFail, "br_on_cast_static_fail") 431 CASE_OP(RefIsFunc, "ref.is_func") 432 CASE_OP(RefIsData, "ref.is_data") 433 CASE_OP(RefIsI31, "ref.is_i31") 434 CASE_OP(RefIsArray, "ref.is_array") 435 CASE_OP(RefAsFunc, "ref.as_func") 436 CASE_OP(RefAsData, "ref.as_data") 437 CASE_OP(RefAsI31, "ref.as_i31") 438 CASE_OP(RefAsArray, "ref.as_array") 439 CASE_OP(BrOnFunc, "br_on_func") 440 CASE_OP(BrOnData, "br_on_data") 441 CASE_OP(BrOnI31, "br_on_i31") 442 CASE_OP(BrOnArray, "br_on_array") 443 CASE_OP(BrOnNonFunc, "br_on_non_func") 444 CASE_OP(BrOnNonData, "br_on_non_data") 445 CASE_OP(BrOnNonI31, "br_on_non_i31") 446 CASE_OP(BrOnNonArray, "br_on_non_array") 447 448 case kNumericPrefix: 449 case kSimdPrefix: 450 case kAtomicPrefix: 451 case kGCPrefix: 452 return "unknown"; 453 // clang-format on 454 } 455 // Even though the switch above handles all well-defined enum values, 456 // random modules (e.g. fuzzer generated) can call this function with 457 // random (invalid) opcodes. Handle those here: 458 return "invalid opcode"; 459} 460 461#undef CASE_OP 462#undef CASE_I32_OP 463#undef CASE_I64_OP 464#undef CASE_F32_OP 465#undef CASE_F64_OP 466#undef CASE_REF_OP 467#undef CASE_F64x2_OP 468#undef CASE_F32x4_OP 469#undef CASE_I64x2_OP 470#undef CASE_I32x4_OP 471#undef CASE_I16x8_OP 472#undef CASE_I8x16_OP 473#undef CASE_S128_OP 474#undef CASE_S64x2_OP 475#undef CASE_S32x4_OP 476#undef CASE_S16x8_OP 477#undef CASE_INT_OP 478#undef CASE_FLOAT_OP 479#undef CASE_ALL_OP 480#undef CASE_SIMD_OP 481#undef CASE_SIMDI_OP 482#undef CASE_SIMDI_NO64X2_OP 483#undef CASE_SIGN_OP 484#undef CASE_UNSIGNED_OP 485#undef CASE_UNSIGNED_ALL_OP 486#undef CASE_ALL_SIGN_OP 487#undef CASE_CONVERT_OP 488#undef CASE_CONVERT_SAT_OP 489#undef CASE_L32_OP 490#undef CASE_U32_OP 491 492// static 493constexpr bool WasmOpcodes::IsPrefixOpcode(WasmOpcode opcode) { 494 switch (opcode) { 495#define CHECK_PREFIX(name, opcode) case k##name##Prefix: 496 FOREACH_PREFIX(CHECK_PREFIX) 497#undef CHECK_PREFIX 498 return true; 499 default: 500 return false; 501 } 502} 503 504// static 505constexpr bool WasmOpcodes::IsControlOpcode(WasmOpcode opcode) { 506 switch (opcode) { 507#define CHECK_OPCODE(name, opcode, _) case kExpr##name: 508 FOREACH_CONTROL_OPCODE(CHECK_OPCODE) 509#undef CHECK_OPCODE 510 return true; 511 default: 512 return false; 513 } 514} 515 516// static 517constexpr bool WasmOpcodes::IsUnconditionalJump(WasmOpcode opcode) { 518 switch (opcode) { 519 case kExprUnreachable: 520 case kExprBr: 521 case kExprBrTable: 522 case kExprReturn: 523 case kExprReturnCall: 524 case kExprReturnCallIndirect: 525 case kExprThrow: 526 case kExprRethrow: 527 return true; 528 default: 529 return false; 530 } 531} 532 533// static 534constexpr bool WasmOpcodes::IsBreakable(WasmOpcode opcode) { 535 switch (opcode) { 536 case kExprBlock: 537 case kExprTry: 538 case kExprCatch: 539 case kExprLoop: 540 case kExprElse: 541 return false; 542 default: 543 return true; 544 } 545} 546 547// static 548constexpr bool WasmOpcodes::IsExternRefOpcode(WasmOpcode opcode) { 549 switch (opcode) { 550 case kExprRefNull: 551 case kExprRefIsNull: 552 case kExprRefFunc: 553 case kExprRefAsNonNull: 554 return true; 555 default: 556 return false; 557 } 558} 559 560// static 561constexpr bool WasmOpcodes::IsThrowingOpcode(WasmOpcode opcode) { 562 // TODO(8729): Trapping opcodes are not yet considered to be throwing. 563 switch (opcode) { 564 case kExprThrow: 565 case kExprRethrow: 566 case kExprCallFunction: 567 case kExprCallIndirect: 568 return true; 569 default: 570 return false; 571 } 572} 573 574// static 575constexpr bool WasmOpcodes::IsRelaxedSimdOpcode(WasmOpcode opcode) { 576 switch (opcode) { 577#define CHECK_OPCODE(name, opcode, _) case kExpr##name: 578 FOREACH_RELAXED_SIMD_OPCODE(CHECK_OPCODE) 579#undef CHECK_OPCODE 580 return true; 581 default: 582 return false; 583 } 584} 585 586namespace impl { 587 588#define DECLARE_SIG_ENUM(name, ...) kSigEnum_##name, 589enum WasmOpcodeSig : byte { 590 kSigEnum_None, 591 FOREACH_SIGNATURE(DECLARE_SIG_ENUM) 592}; 593#undef DECLARE_SIG_ENUM 594#define DECLARE_SIG(name, ...) \ 595 constexpr ValueType kTypes_##name[] = {__VA_ARGS__}; \ 596 constexpr int kReturnsCount_##name = kTypes_##name[0] == kWasmVoid ? 0 : 1; \ 597 constexpr FunctionSig kSig_##name( \ 598 kReturnsCount_##name, static_cast<int>(arraysize(kTypes_##name)) - 1, \ 599 kTypes_##name + (1 - kReturnsCount_##name)); 600FOREACH_SIGNATURE(DECLARE_SIG) 601#undef DECLARE_SIG 602 603#define DECLARE_SIG_ENTRY(name, ...) &kSig_##name, 604constexpr const FunctionSig* kCachedSigs[] = { 605 nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)}; 606#undef DECLARE_SIG_ENTRY 607 608constexpr WasmOpcodeSig GetShortOpcodeSigIndex(byte opcode) { 609#define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig: 610 return FOREACH_SIMPLE_OPCODE(CASE) FOREACH_SIMPLE_PROTOTYPE_OPCODE(CASE) 611 kSigEnum_None; 612#undef CASE 613} 614 615constexpr WasmOpcodeSig GetAsmJsOpcodeSigIndex(byte opcode) { 616#define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig: 617 return FOREACH_ASMJS_COMPAT_OPCODE(CASE) kSigEnum_None; 618#undef CASE 619} 620 621constexpr WasmOpcodeSig GetSimdOpcodeSigIndex(byte opcode) { 622#define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig: 623 return FOREACH_SIMD_0_OPERAND_OPCODE(CASE) FOREACH_SIMD_MEM_OPCODE(CASE) 624 FOREACH_SIMD_MEM_1_OPERAND_OPCODE(CASE) kSigEnum_None; 625#undef CASE 626} 627 628constexpr WasmOpcodeSig GetAtomicOpcodeSigIndex(byte opcode) { 629#define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig: 630 return FOREACH_ATOMIC_OPCODE(CASE) FOREACH_ATOMIC_0_OPERAND_OPCODE(CASE) 631 kSigEnum_None; 632#undef CASE 633} 634 635constexpr WasmOpcodeSig GetNumericOpcodeSigIndex(byte opcode) { 636#define CASE_SIG(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig: 637#define CASE_VARIADIC(name, opc) 638 return FOREACH_NUMERIC_OPCODE(CASE_SIG, CASE_VARIADIC) kSigEnum_None; 639#undef CASE_SIG 640#undef CASE_VARIADIC 641} 642 643constexpr std::array<WasmOpcodeSig, 256> kShortSigTable = 644 base::make_array<256>(GetShortOpcodeSigIndex); 645constexpr std::array<WasmOpcodeSig, 256> kSimpleAsmjsExprSigTable = 646 base::make_array<256>(GetAsmJsOpcodeSigIndex); 647constexpr std::array<WasmOpcodeSig, 256> kSimdExprSigTable = 648 base::make_array<256>(GetSimdOpcodeSigIndex); 649constexpr std::array<WasmOpcodeSig, 256> kAtomicExprSigTable = 650 base::make_array<256>(GetAtomicOpcodeSigIndex); 651constexpr std::array<WasmOpcodeSig, 256> kNumericExprSigTable = 652 base::make_array<256>(GetNumericOpcodeSigIndex); 653 654} // namespace impl 655 656constexpr const FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) { 657 switch (opcode >> 8) { 658 case 0: 659 return impl::kCachedSigs[impl::kShortSigTable[opcode]]; 660 case kSimdPrefix: 661 return impl::kCachedSigs[impl::kSimdExprSigTable[opcode & 0xFF]]; 662 case kAtomicPrefix: 663 return impl::kCachedSigs[impl::kAtomicExprSigTable[opcode & 0xFF]]; 664 case kNumericPrefix: 665 return impl::kCachedSigs[impl::kNumericExprSigTable[opcode & 0xFF]]; 666 default: 667 UNREACHABLE(); // invalid prefix. 668 } 669} 670 671constexpr const FunctionSig* WasmOpcodes::AsmjsSignature(WasmOpcode opcode) { 672 DCHECK_GT(impl::kSimpleAsmjsExprSigTable.size(), opcode); 673 return impl::kCachedSigs[impl::kSimpleAsmjsExprSigTable[opcode]]; 674} 675 676constexpr MessageTemplate WasmOpcodes::TrapReasonToMessageId( 677 TrapReason reason) { 678 switch (reason) { 679#define TRAPREASON_TO_MESSAGE(name) \ 680 case k##name: \ 681 return MessageTemplate::kWasm##name; 682 FOREACH_WASM_TRAPREASON(TRAPREASON_TO_MESSAGE) 683#undef TRAPREASON_TO_MESSAGE 684 default: 685 return MessageTemplate::kNone; 686 } 687} 688 689const char* WasmOpcodes::TrapReasonMessage(TrapReason reason) { 690 return MessageFormatter::TemplateString(TrapReasonToMessageId(reason)); 691} 692 693} // namespace wasm 694} // namespace internal 695} // namespace v8 696 697#endif // V8_WASM_WASM_OPCODES_INL_H_ 698