blob: a609e032611ce8633ee5c148882dfb0df9503e50 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
3// found in the LICENSE file.
4
5#include "src/wasm/wasm-opcodes.h"
6#include "src/signature.h"
7
8namespace v8 {
9namespace internal {
10namespace wasm {
11
12typedef Signature<LocalType> FunctionSig;
13
14const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
15 switch (opcode) {
16#define DECLARE_NAME_CASE(name, opcode, sig) \
17 case kExpr##name: \
18 return "Expr" #name;
19 FOREACH_OPCODE(DECLARE_NAME_CASE)
20#undef DECLARE_NAME_CASE
21 default:
22 break;
23 }
24 return "Unknown";
25}
26
27
Ben Murdoch097c5b22016-05-18 11:27:45 +010028std::ostream& operator<<(std::ostream& os, const FunctionSig& sig) {
29 if (sig.return_count() == 0) os << "v";
30 for (size_t i = 0; i < sig.return_count(); i++) {
31 os << WasmOpcodes::ShortNameOf(sig.GetReturn(i));
32 }
33 os << "_";
34 if (sig.parameter_count() == 0) os << "v";
35 for (size_t i = 0; i < sig.parameter_count(); i++) {
36 os << WasmOpcodes::ShortNameOf(sig.GetParam(i));
37 }
38 return os;
39}
40
41
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042#define DECLARE_SIG_ENUM(name, ...) kSigEnum_##name,
43
44
45enum WasmOpcodeSig { FOREACH_SIGNATURE(DECLARE_SIG_ENUM) };
46
47
48// TODO(titzer): not static-initializer safe. Wrap in LazyInstance.
49#define DECLARE_SIG(name, ...) \
50 static LocalType kTypes_##name[] = {__VA_ARGS__}; \
51 static const FunctionSig kSig_##name( \
52 1, static_cast<int>(arraysize(kTypes_##name)) - 1, kTypes_##name);
53
54FOREACH_SIGNATURE(DECLARE_SIG)
55
56#define DECLARE_SIG_ENTRY(name, ...) &kSig_##name,
57
58static const FunctionSig* kSimpleExprSigs[] = {
59 nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)};
60
61static byte kSimpleExprSigTable[256];
62
63
64// Initialize the signature table.
65static void InitSigTable() {
66#define SET_SIG_TABLE(name, opcode, sig) \
67 kSimpleExprSigTable[opcode] = static_cast<int>(kSigEnum_##sig) + 1;
68 FOREACH_SIMPLE_OPCODE(SET_SIG_TABLE);
69#undef SET_SIG_TABLE
70}
71
72
73FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
74 // TODO(titzer): use LazyInstance to make this thread safe.
75 if (kSimpleExprSigTable[kExprI32Add] == 0) InitSigTable();
76 return const_cast<FunctionSig*>(
77 kSimpleExprSigs[kSimpleExprSigTable[static_cast<byte>(opcode)]]);
78}
79
80
81// TODO(titzer): pull WASM_64 up to a common header.
82#if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64
83#define WASM_64 1
84#else
85#define WASM_64 0
86#endif
87
88
89bool WasmOpcodes::IsSupported(WasmOpcode opcode) {
90#if !WASM_64
91 switch (opcode) {
92 // Opcodes not supported on 32-bit platforms.
93 case kExprI64Add:
94 case kExprI64Sub:
95 case kExprI64Mul:
96 case kExprI64DivS:
97 case kExprI64DivU:
98 case kExprI64RemS:
99 case kExprI64RemU:
100 case kExprI64And:
101 case kExprI64Ior:
102 case kExprI64Xor:
103 case kExprI64Shl:
104 case kExprI64ShrU:
105 case kExprI64ShrS:
106 case kExprI64Eq:
107 case kExprI64Ne:
108 case kExprI64LtS:
109 case kExprI64LeS:
110 case kExprI64LtU:
111 case kExprI64LeU:
112 case kExprI64GtS:
113 case kExprI64GeS:
114 case kExprI64GtU:
115 case kExprI64GeU:
116
117 case kExprI32ConvertI64:
118 case kExprI64SConvertI32:
119 case kExprI64UConvertI32:
120
121 case kExprF64ReinterpretI64:
122 case kExprI64ReinterpretF64:
123
124 case kExprI64Clz:
125 case kExprI64Ctz:
126 case kExprI64Popcnt:
127
128 case kExprF32SConvertI64:
129 case kExprF32UConvertI64:
130 case kExprF64SConvertI64:
131 case kExprF64UConvertI64:
132 case kExprI64SConvertF32:
133 case kExprI64SConvertF64:
134 case kExprI64UConvertF32:
135 case kExprI64UConvertF64:
136
137 return false;
138 default:
139 return true;
140 }
141#else
142 return true;
143#endif
144}
145} // namespace wasm
146} // namespace internal
147} // namespace v8