OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_WASM_OPCODES_H_ | 5 #ifndef V8_WASM_OPCODES_H_ |
6 #define V8_WASM_OPCODES_H_ | 6 #define V8_WASM_OPCODES_H_ |
7 | 7 |
8 #include "src/machine-type.h" | 8 #include "src/machine-type.h" |
9 #include "src/signature.h" | 9 #include "src/signature.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 namespace wasm { | 13 namespace wasm { |
14 | 14 |
15 // Binary encoding of local types. | 15 // Binary encoding of local types. |
16 enum LocalTypeCode { | 16 enum LocalTypeCode { |
17 kLocalVoid = 0, | 17 kLocalVoid = 0, |
18 kLocalI32 = 1, | 18 kLocalI32 = 1, |
19 kLocalI64 = 2, | 19 kLocalI64 = 2, |
20 kLocalF32 = 3, | 20 kLocalF32 = 3, |
21 kLocalF64 = 4 | 21 kLocalF64 = 4, |
| 22 kLocalS128 = 5 |
22 }; | 23 }; |
23 | 24 |
24 // Binary encoding of memory types. | 25 // Binary encoding of memory types. |
25 enum MemTypeCode { | 26 enum MemTypeCode { |
26 kMemI8 = 0, | 27 kMemI8 = 0, |
27 kMemU8 = 1, | 28 kMemU8 = 1, |
28 kMemI16 = 2, | 29 kMemI16 = 2, |
29 kMemU16 = 3, | 30 kMemU16 = 3, |
30 kMemI32 = 4, | 31 kMemI32 = 4, |
31 kMemU32 = 5, | 32 kMemU32 = 5, |
32 kMemI64 = 6, | 33 kMemI64 = 6, |
33 kMemU64 = 7, | 34 kMemU64 = 7, |
34 kMemF32 = 8, | 35 kMemF32 = 8, |
35 kMemF64 = 9 | 36 kMemF64 = 9, |
| 37 kMemS128 = 10 |
36 }; | 38 }; |
37 | 39 |
38 // We reuse the internal machine type to represent WebAssembly AST types. | 40 // We reuse the internal machine type to represent WebAssembly AST types. |
39 // A typedef improves readability without adding a whole new type system. | 41 // A typedef improves readability without adding a whole new type system. |
40 typedef MachineRepresentation LocalType; | 42 typedef MachineRepresentation LocalType; |
41 const LocalType kAstStmt = MachineRepresentation::kNone; | 43 const LocalType kAstStmt = MachineRepresentation::kNone; |
42 const LocalType kAstI32 = MachineRepresentation::kWord32; | 44 const LocalType kAstI32 = MachineRepresentation::kWord32; |
43 const LocalType kAstI64 = MachineRepresentation::kWord64; | 45 const LocalType kAstI64 = MachineRepresentation::kWord64; |
44 const LocalType kAstF32 = MachineRepresentation::kFloat32; | 46 const LocalType kAstF32 = MachineRepresentation::kFloat32; |
45 const LocalType kAstF64 = MachineRepresentation::kFloat64; | 47 const LocalType kAstF64 = MachineRepresentation::kFloat64; |
| 48 const LocalType kAstS128 = MachineRepresentation::kSimd128; |
46 // We use kTagged here because kNone is already used by kAstStmt. | 49 // We use kTagged here because kNone is already used by kAstStmt. |
47 const LocalType kAstEnd = MachineRepresentation::kTagged; | 50 const LocalType kAstEnd = MachineRepresentation::kTagged; |
48 | 51 |
49 typedef Signature<LocalType> FunctionSig; | 52 typedef Signature<LocalType> FunctionSig; |
50 std::ostream& operator<<(std::ostream& os, const FunctionSig& function); | 53 std::ostream& operator<<(std::ostream& os, const FunctionSig& function); |
51 | 54 |
52 typedef Vector<const char> WasmName; | 55 typedef Vector<const char> WasmName; |
53 | 56 |
54 typedef int WasmCodePosition; | 57 typedef int WasmCodePosition; |
55 const WasmCodePosition kNoCodePosition = -1; | 58 const WasmCodePosition kNoCodePosition = -1; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 V(F32StoreMem, 0x35, f_if) \ | 116 V(F32StoreMem, 0x35, f_if) \ |
114 V(F64StoreMem, 0x36, d_id) | 117 V(F64StoreMem, 0x36, d_id) |
115 | 118 |
116 // Load memory expressions. | 119 // Load memory expressions. |
117 #define FOREACH_MISC_MEM_OPCODE(V) \ | 120 #define FOREACH_MISC_MEM_OPCODE(V) \ |
118 V(MemorySize, 0x3b, i_v) \ | 121 V(MemorySize, 0x3b, i_v) \ |
119 V(GrowMemory, 0x39, i_i) | 122 V(GrowMemory, 0x39, i_i) |
120 | 123 |
121 // Expressions with signatures. | 124 // Expressions with signatures. |
122 #define FOREACH_SIMPLE_OPCODE(V) \ | 125 #define FOREACH_SIMPLE_OPCODE(V) \ |
| 126 FOREACH_SIMD_OPCODE(V) \ |
123 V(I32Add, 0x40, i_ii) \ | 127 V(I32Add, 0x40, i_ii) \ |
124 V(I32Sub, 0x41, i_ii) \ | 128 V(I32Sub, 0x41, i_ii) \ |
125 V(I32Mul, 0x42, i_ii) \ | 129 V(I32Mul, 0x42, i_ii) \ |
126 V(I32DivS, 0x43, i_ii) \ | 130 V(I32DivS, 0x43, i_ii) \ |
127 V(I32DivU, 0x44, i_ii) \ | 131 V(I32DivU, 0x44, i_ii) \ |
128 V(I32RemS, 0x45, i_ii) \ | 132 V(I32RemS, 0x45, i_ii) \ |
129 V(I32RemU, 0x46, i_ii) \ | 133 V(I32RemU, 0x46, i_ii) \ |
130 V(I32And, 0x47, i_ii) \ | 134 V(I32And, 0x47, i_ii) \ |
131 V(I32Ior, 0x48, i_ii) \ | 135 V(I32Ior, 0x48, i_ii) \ |
132 V(I32Xor, 0x49, i_ii) \ | 136 V(I32Xor, 0x49, i_ii) \ |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 V(I32AsmjsStoreMem8, 0xdb, i_ii) \ | 275 V(I32AsmjsStoreMem8, 0xdb, i_ii) \ |
272 V(I32AsmjsStoreMem16, 0xdc, i_ii) \ | 276 V(I32AsmjsStoreMem16, 0xdc, i_ii) \ |
273 V(I32AsmjsStoreMem, 0xdd, i_ii) \ | 277 V(I32AsmjsStoreMem, 0xdd, i_ii) \ |
274 V(F32AsmjsStoreMem, 0xde, f_if) \ | 278 V(F32AsmjsStoreMem, 0xde, f_if) \ |
275 V(F64AsmjsStoreMem, 0xdf, d_id) \ | 279 V(F64AsmjsStoreMem, 0xdf, d_id) \ |
276 V(I32AsmjsSConvertF32, 0xe0, i_f) \ | 280 V(I32AsmjsSConvertF32, 0xe0, i_f) \ |
277 V(I32AsmjsUConvertF32, 0xe1, i_f) \ | 281 V(I32AsmjsUConvertF32, 0xe1, i_f) \ |
278 V(I32AsmjsSConvertF64, 0xe2, i_d) \ | 282 V(I32AsmjsSConvertF64, 0xe2, i_d) \ |
279 V(I32AsmjsUConvertF64, 0xe3, i_d) | 283 V(I32AsmjsUConvertF64, 0xe3, i_d) |
280 | 284 |
| 285 // Simd opcodes |
| 286 #define FOREACH_SIMD_OPCODE(V) \ |
| 287 V(Int32x4Splat, 0xe4, s_i) \ |
| 288 V(Int32x4ExtractLane, 0xe5, i_si) |
| 289 |
281 // All opcodes. | 290 // All opcodes. |
282 #define FOREACH_OPCODE(V) \ | 291 #define FOREACH_OPCODE(V) \ |
283 FOREACH_CONTROL_OPCODE(V) \ | 292 FOREACH_CONTROL_OPCODE(V) \ |
284 FOREACH_MISC_OPCODE(V) \ | 293 FOREACH_MISC_OPCODE(V) \ |
285 FOREACH_SIMPLE_OPCODE(V) \ | 294 FOREACH_SIMPLE_OPCODE(V) \ |
286 FOREACH_STORE_MEM_OPCODE(V) \ | 295 FOREACH_STORE_MEM_OPCODE(V) \ |
287 FOREACH_LOAD_MEM_OPCODE(V) \ | 296 FOREACH_LOAD_MEM_OPCODE(V) \ |
288 FOREACH_MISC_MEM_OPCODE(V) \ | 297 FOREACH_MISC_MEM_OPCODE(V) \ |
289 FOREACH_ASMJS_COMPAT_OPCODE(V) | 298 FOREACH_ASMJS_COMPAT_OPCODE(V) |
290 | 299 |
(...skipping 18 matching lines...) Expand all Loading... |
309 V(f_d, kAstF32, kAstF64) \ | 318 V(f_d, kAstF32, kAstF64) \ |
310 V(f_i, kAstF32, kAstI32) \ | 319 V(f_i, kAstF32, kAstI32) \ |
311 V(f_l, kAstF32, kAstI64) \ | 320 V(f_l, kAstF32, kAstI64) \ |
312 V(d_dd, kAstF64, kAstF64, kAstF64) \ | 321 V(d_dd, kAstF64, kAstF64, kAstF64) \ |
313 V(d_d, kAstF64, kAstF64) \ | 322 V(d_d, kAstF64, kAstF64) \ |
314 V(d_f, kAstF64, kAstF32) \ | 323 V(d_f, kAstF64, kAstF32) \ |
315 V(d_i, kAstF64, kAstI32) \ | 324 V(d_i, kAstF64, kAstI32) \ |
316 V(d_l, kAstF64, kAstI64) \ | 325 V(d_l, kAstF64, kAstI64) \ |
317 V(d_id, kAstF64, kAstI32, kAstF64) \ | 326 V(d_id, kAstF64, kAstI32, kAstF64) \ |
318 V(f_if, kAstF32, kAstI32, kAstF32) \ | 327 V(f_if, kAstF32, kAstI32, kAstF32) \ |
319 V(l_il, kAstI64, kAstI32, kAstI64) | 328 V(l_il, kAstI64, kAstI32, kAstI64) \ |
| 329 V(s_i, kAstS128, kAstI32) \ |
| 330 V(i_si, kAstI32, kAstS128, kAstI32) |
320 | 331 |
321 enum WasmOpcode { | 332 enum WasmOpcode { |
322 // Declare expression opcodes. | 333 // Declare expression opcodes. |
323 #define DECLARE_NAMED_ENUM(name, opcode, sig) kExpr##name = opcode, | 334 #define DECLARE_NAMED_ENUM(name, opcode, sig) kExpr##name = opcode, |
324 FOREACH_OPCODE(DECLARE_NAMED_ENUM) | 335 FOREACH_OPCODE(DECLARE_NAMED_ENUM) |
325 #undef DECLARE_NAMED_ENUM | 336 #undef DECLARE_NAMED_ENUM |
326 }; | 337 }; |
327 | 338 |
328 // The reason for a trap. | 339 // The reason for a trap. |
329 #define FOREACH_WASM_TRAPREASON(V) \ | 340 #define FOREACH_WASM_TRAPREASON(V) \ |
(...skipping 12 matching lines...) Expand all Loading... |
342 kTrapCount | 353 kTrapCount |
343 #undef DECLARE_ENUM | 354 #undef DECLARE_ENUM |
344 }; | 355 }; |
345 | 356 |
346 // A collection of opcode-related static methods. | 357 // A collection of opcode-related static methods. |
347 class WasmOpcodes { | 358 class WasmOpcodes { |
348 public: | 359 public: |
349 static const char* OpcodeName(WasmOpcode opcode); | 360 static const char* OpcodeName(WasmOpcode opcode); |
350 static const char* ShortOpcodeName(WasmOpcode opcode); | 361 static const char* ShortOpcodeName(WasmOpcode opcode); |
351 static FunctionSig* Signature(WasmOpcode opcode); | 362 static FunctionSig* Signature(WasmOpcode opcode); |
| 363 static bool IsSimd(WasmOpcode opcode); |
352 | 364 |
353 static int TrapReasonToMessageId(TrapReason reason); | 365 static int TrapReasonToMessageId(TrapReason reason); |
354 static const char* TrapReasonMessage(TrapReason reason); | 366 static const char* TrapReasonMessage(TrapReason reason); |
355 | 367 |
356 static byte MemSize(MachineType type) { | 368 static byte MemSize(MachineType type) { |
357 return 1 << ElementSizeLog2Of(type.representation()); | 369 return 1 << ElementSizeLog2Of(type.representation()); |
358 } | 370 } |
359 | 371 |
360 static LocalTypeCode LocalTypeCodeFor(LocalType type) { | 372 static LocalTypeCode LocalTypeCodeFor(LocalType type) { |
361 switch (type) { | 373 switch (type) { |
362 case kAstI32: | 374 case kAstI32: |
363 return kLocalI32; | 375 return kLocalI32; |
364 case kAstI64: | 376 case kAstI64: |
365 return kLocalI64; | 377 return kLocalI64; |
366 case kAstF32: | 378 case kAstF32: |
367 return kLocalF32; | 379 return kLocalF32; |
368 case kAstF64: | 380 case kAstF64: |
369 return kLocalF64; | 381 return kLocalF64; |
370 case kAstStmt: | 382 case kAstStmt: |
371 return kLocalVoid; | 383 return kLocalVoid; |
| 384 case kAstS128: |
| 385 return kLocalS128; |
372 default: | 386 default: |
373 UNREACHABLE(); | 387 UNREACHABLE(); |
374 return kLocalVoid; | 388 return kLocalVoid; |
375 } | 389 } |
376 } | 390 } |
377 | 391 |
378 static MemTypeCode MemTypeCodeFor(MachineType type) { | 392 static MemTypeCode MemTypeCodeFor(MachineType type) { |
379 if (type == MachineType::Int8()) { | 393 if (type == MachineType::Int8()) { |
380 return kMemI8; | 394 return kMemI8; |
381 } else if (type == MachineType::Uint8()) { | 395 } else if (type == MachineType::Uint8()) { |
382 return kMemU8; | 396 return kMemU8; |
383 } else if (type == MachineType::Int16()) { | 397 } else if (type == MachineType::Int16()) { |
384 return kMemI16; | 398 return kMemI16; |
385 } else if (type == MachineType::Uint16()) { | 399 } else if (type == MachineType::Uint16()) { |
386 return kMemU16; | 400 return kMemU16; |
387 } else if (type == MachineType::Int32()) { | 401 } else if (type == MachineType::Int32()) { |
388 return kMemI32; | 402 return kMemI32; |
389 } else if (type == MachineType::Uint32()) { | 403 } else if (type == MachineType::Uint32()) { |
390 return kMemU32; | 404 return kMemU32; |
391 } else if (type == MachineType::Int64()) { | 405 } else if (type == MachineType::Int64()) { |
392 return kMemI64; | 406 return kMemI64; |
393 } else if (type == MachineType::Uint64()) { | 407 } else if (type == MachineType::Uint64()) { |
394 return kMemU64; | 408 return kMemU64; |
395 } else if (type == MachineType::Float32()) { | 409 } else if (type == MachineType::Float32()) { |
396 return kMemF32; | 410 return kMemF32; |
397 } else if (type == MachineType::Float64()) { | 411 } else if (type == MachineType::Float64()) { |
398 return kMemF64; | 412 return kMemF64; |
| 413 } else if (type == MachineType::Simd128()) { |
| 414 return kMemS128; |
399 } else { | 415 } else { |
400 UNREACHABLE(); | 416 UNREACHABLE(); |
401 return kMemI32; | 417 return kMemI32; |
402 } | 418 } |
403 } | 419 } |
404 | 420 |
405 static MachineType MachineTypeFor(LocalType type) { | 421 static MachineType MachineTypeFor(LocalType type) { |
406 switch (type) { | 422 switch (type) { |
407 case kAstI32: | 423 case kAstI32: |
408 return MachineType::Int32(); | 424 return MachineType::Int32(); |
409 case kAstI64: | 425 case kAstI64: |
410 return MachineType::Int64(); | 426 return MachineType::Int64(); |
411 case kAstF32: | 427 case kAstF32: |
412 return MachineType::Float32(); | 428 return MachineType::Float32(); |
413 case kAstF64: | 429 case kAstF64: |
414 return MachineType::Float64(); | 430 return MachineType::Float64(); |
| 431 case kAstS128: |
| 432 return MachineType::Simd128(); |
415 case kAstStmt: | 433 case kAstStmt: |
416 return MachineType::None(); | 434 return MachineType::None(); |
417 default: | 435 default: |
418 UNREACHABLE(); | 436 UNREACHABLE(); |
419 return MachineType::None(); | 437 return MachineType::None(); |
420 } | 438 } |
421 } | 439 } |
422 | 440 |
423 static LocalType LocalTypeFor(MachineType type) { | 441 static LocalType LocalTypeFor(MachineType type) { |
424 if (type == MachineType::Int8()) { | 442 if (type == MachineType::Int8()) { |
425 return kAstI32; | 443 return kAstI32; |
426 } else if (type == MachineType::Uint8()) { | 444 } else if (type == MachineType::Uint8()) { |
427 return kAstI32; | 445 return kAstI32; |
428 } else if (type == MachineType::Int16()) { | 446 } else if (type == MachineType::Int16()) { |
429 return kAstI32; | 447 return kAstI32; |
430 } else if (type == MachineType::Uint16()) { | 448 } else if (type == MachineType::Uint16()) { |
431 return kAstI32; | 449 return kAstI32; |
432 } else if (type == MachineType::Int32()) { | 450 } else if (type == MachineType::Int32()) { |
433 return kAstI32; | 451 return kAstI32; |
434 } else if (type == MachineType::Uint32()) { | 452 } else if (type == MachineType::Uint32()) { |
435 return kAstI32; | 453 return kAstI32; |
436 } else if (type == MachineType::Int64()) { | 454 } else if (type == MachineType::Int64()) { |
437 return kAstI64; | 455 return kAstI64; |
438 } else if (type == MachineType::Uint64()) { | 456 } else if (type == MachineType::Uint64()) { |
439 return kAstI64; | 457 return kAstI64; |
440 } else if (type == MachineType::Float32()) { | 458 } else if (type == MachineType::Float32()) { |
441 return kAstF32; | 459 return kAstF32; |
442 } else if (type == MachineType::Float64()) { | 460 } else if (type == MachineType::Float64()) { |
443 return kAstF64; | 461 return kAstF64; |
| 462 } else if (type == MachineType::Simd128()) { |
| 463 return kAstS128; |
444 } else { | 464 } else { |
445 UNREACHABLE(); | 465 UNREACHABLE(); |
446 return kAstI32; | 466 return kAstI32; |
447 } | 467 } |
448 } | 468 } |
449 | 469 |
450 static WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) { | 470 static WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) { |
451 if (type == MachineType::Int8()) { | 471 if (type == MachineType::Int8()) { |
452 return store ? kExprI32StoreMem8 : kExprI32LoadMem8S; | 472 return store ? kExprI32StoreMem8 : kExprI32LoadMem8S; |
453 } else if (type == MachineType::Uint8()) { | 473 } else if (type == MachineType::Uint8()) { |
(...skipping 23 matching lines...) Expand all Loading... |
477 static char ShortNameOf(LocalType type) { | 497 static char ShortNameOf(LocalType type) { |
478 switch (type) { | 498 switch (type) { |
479 case kAstI32: | 499 case kAstI32: |
480 return 'i'; | 500 return 'i'; |
481 case kAstI64: | 501 case kAstI64: |
482 return 'l'; | 502 return 'l'; |
483 case kAstF32: | 503 case kAstF32: |
484 return 'f'; | 504 return 'f'; |
485 case kAstF64: | 505 case kAstF64: |
486 return 'd'; | 506 return 'd'; |
| 507 case kAstS128: |
| 508 return 's'; |
487 case kAstStmt: | 509 case kAstStmt: |
488 return 'v'; | 510 return 'v'; |
489 case kAstEnd: | 511 case kAstEnd: |
490 return 'x'; | 512 return 'x'; |
491 default: | 513 default: |
492 UNREACHABLE(); | 514 UNREACHABLE(); |
493 return '?'; | 515 return '?'; |
494 } | 516 } |
495 } | 517 } |
496 | 518 |
497 static const char* TypeName(LocalType type) { | 519 static const char* TypeName(LocalType type) { |
498 switch (type) { | 520 switch (type) { |
499 case kAstI32: | 521 case kAstI32: |
500 return "i32"; | 522 return "i32"; |
501 case kAstI64: | 523 case kAstI64: |
502 return "i64"; | 524 return "i64"; |
503 case kAstF32: | 525 case kAstF32: |
504 return "f32"; | 526 return "f32"; |
505 case kAstF64: | 527 case kAstF64: |
506 return "f64"; | 528 return "f64"; |
| 529 case kAstS128: |
| 530 return "s128"; |
507 case kAstStmt: | 531 case kAstStmt: |
508 return "<stmt>"; | 532 return "<stmt>"; |
509 case kAstEnd: | 533 case kAstEnd: |
510 return "<end>"; | 534 return "<end>"; |
511 default: | 535 default: |
512 return "<unknown>"; | 536 return "<unknown>"; |
513 } | 537 } |
514 } | 538 } |
515 }; | 539 }; |
516 } // namespace wasm | 540 } // namespace wasm |
517 } // namespace internal | 541 } // namespace internal |
518 } // namespace v8 | 542 } // namespace v8 |
519 | 543 |
520 #endif // V8_WASM_OPCODES_H_ | 544 #endif // V8_WASM_OPCODES_H_ |
OLD | NEW |