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 #include <stdint.h> | 5 #include <stdint.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "src/wasm/wasm-macro-gen.h" | 9 #include "src/wasm/wasm-macro-gen.h" |
10 | 10 |
11 #include "test/cctest/cctest.h" | 11 #include "test/cctest/cctest.h" |
12 #include "test/cctest/compiler/value-helper.h" | 12 #include "test/cctest/compiler/value-helper.h" |
| 13 #include "test/cctest/wasm/test-signatures.h" |
13 #include "test/cctest/wasm/wasm-run-utils.h" | 14 #include "test/cctest/wasm/wasm-run-utils.h" |
14 | 15 |
15 // using namespace v8::base; | 16 #define B2(a, b) kExprBlock, 2, a, b |
16 // using namespace v8::internal; | 17 #define B1(a) kExprBlock, 1, a |
17 // using namespace v8::internal::compiler; | 18 |
18 // using namespace v8::internal::wasm; | 19 // Can't bridge macro land with nested macros. |
| 20 #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_X87 |
| 21 #define MIPS_OR_X87 true |
| 22 #else |
| 23 #define MIPS_OR_X87 false |
| 24 #endif |
| 25 |
| 26 #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_X87 || V8_TARGET_ARCH_ARM |
| 27 #define MIPS_OR_ARM_OR_X87 true |
| 28 #else |
| 29 #define MIPS_OR_ARM_OR_X87 false |
| 30 #endif |
| 31 |
| 32 #define FOREACH_I64_OPERATOR(V) \ |
| 33 V(DepthFirst, false) \ |
| 34 V(I64Const, true) \ |
| 35 V(I64Return, true) \ |
| 36 V(I64Param, true) \ |
| 37 V(I64LoadStore, true) \ |
| 38 V(I64Add, false) \ |
| 39 V(I64Sub, false) \ |
| 40 V(I64Mul, false) \ |
| 41 V(I64DivS, false) \ |
| 42 V(I64DivU, false) \ |
| 43 V(I64RemS, false) \ |
| 44 V(I64RemU, false) \ |
| 45 V(I64And, true) \ |
| 46 V(I64Ior, true) \ |
| 47 V(I64Xor, true) \ |
| 48 V(I64Shl, !MIPS_OR_X87) \ |
| 49 V(I64ShrU, !MIPS_OR_ARM_OR_X87) \ |
| 50 V(I64ShrS, !MIPS_OR_ARM_OR_X87) \ |
| 51 V(I64Eq, true) \ |
| 52 V(I64Ne, true) \ |
| 53 V(I64LtS, true) \ |
| 54 V(I64LeS, true) \ |
| 55 V(I64LtU, true) \ |
| 56 V(I64LeU, true) \ |
| 57 V(I64GtS, true) \ |
| 58 V(I64GeS, true) \ |
| 59 V(I64GtU, true) \ |
| 60 V(I64GeU, true) \ |
| 61 V(I64Clz, false) \ |
| 62 V(I64Ctz, false) \ |
| 63 V(I64Popcnt, false) \ |
| 64 V(I32ConvertI64, true) \ |
| 65 V(I64SConvertF32, false) \ |
| 66 V(I64SConvertF64, false) \ |
| 67 V(I64UConvertF32, false) \ |
| 68 V(I64UConvertF64, false) \ |
| 69 V(I64SConvertI32, true) \ |
| 70 V(I64UConvertI32, true) \ |
| 71 V(F32SConvertI64, true) \ |
| 72 V(F32UConvertI64, true) \ |
| 73 V(F64SConvertI64, true) \ |
| 74 V(F64UConvertI64, true) \ |
| 75 V(F64ReinterpretI64, false) \ |
| 76 V(I64ReinterpretF64, false) \ |
| 77 V(I64Ror, false) \ |
| 78 V(I64Rol, false) |
| 79 |
| 80 #define DECLARE_CONST(name, cond) static const bool kSupported_##name = cond; |
| 81 FOREACH_I64_OPERATOR(DECLARE_CONST) |
| 82 #undef DECLARE_CONST |
| 83 |
| 84 #define REQUIRE(name) \ |
| 85 if (!WASM_64 && !kSupported_##name) return |
| 86 |
| 87 TEST(Run_Wasm_I64Const) { |
| 88 REQUIRE(I64Const); |
| 89 WasmRunner<int64_t> r; |
| 90 const int64_t kExpectedValue = 0x1122334455667788LL; |
| 91 // return(kExpectedValue) |
| 92 BUILD(r, WASM_I64V_9(kExpectedValue)); |
| 93 CHECK_EQ(kExpectedValue, r.Call()); |
| 94 } |
| 95 |
| 96 TEST(Run_Wasm_I64Const_many) { |
| 97 REQUIRE(I64Const); |
| 98 int cntr = 0; |
| 99 FOR_INT32_INPUTS(i) { |
| 100 WasmRunner<int64_t> r; |
| 101 const int64_t kExpectedValue = (static_cast<int64_t>(*i) << 32) | cntr; |
| 102 // return(kExpectedValue) |
| 103 BUILD(r, WASM_I64V(kExpectedValue)); |
| 104 CHECK_EQ(kExpectedValue, r.Call()); |
| 105 cntr++; |
| 106 } |
| 107 } |
| 108 |
| 109 TEST(Run_Wasm_Return_I64) { |
| 110 REQUIRE(I64Return); |
| 111 WasmRunner<int64_t> r(MachineType::Int64()); |
| 112 |
| 113 BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0))); |
| 114 |
| 115 FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); } |
| 116 } |
19 | 117 |
20 // todo(ahaas): I added a list of missing instructions here to make merging | 118 // todo(ahaas): I added a list of missing instructions here to make merging |
21 // easier when I do them one by one. | 119 // easier when I do them one by one. |
22 // kExprI64Add: | 120 // kExprI64Add: |
23 // kExprI64Sub: | 121 // kExprI64Sub: |
24 // kExprI64Mul: | 122 // kExprI64Mul: |
25 // kExprI64DivS: | 123 // kExprI64DivS: |
26 // kExprI64DivU: | 124 // kExprI64DivU: |
27 // kExprI64RemS: | 125 // kExprI64RemS: |
28 // kExprI64RemU: | 126 // kExprI64RemU: |
29 // kExprI64And: | 127 // kExprI64And: |
30 TEST(Run_WasmI64And) { | 128 TEST(Run_Wasm_I64And) { |
| 129 REQUIRE(I64And); |
31 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); | 130 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
32 BUILD(r, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 131 BUILD(r, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
33 FOR_INT64_INPUTS(i) { | 132 FOR_INT64_INPUTS(i) { |
34 FOR_INT64_INPUTS(j) { CHECK_EQ((*i) & (*j), r.Call(*i, *j)); } | 133 FOR_INT64_INPUTS(j) { CHECK_EQ((*i) & (*j), r.Call(*i, *j)); } |
35 } | 134 } |
36 } | 135 } |
37 // kExprI64Ior: | 136 // kExprI64Ior: |
38 TEST(Run_WasmI64Ior) { | 137 TEST(Run_Wasm_I64Ior) { |
| 138 REQUIRE(I64Ior); |
39 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); | 139 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
40 BUILD(r, WASM_I64_IOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 140 BUILD(r, WASM_I64_IOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
41 FOR_INT64_INPUTS(i) { | 141 FOR_INT64_INPUTS(i) { |
42 FOR_INT64_INPUTS(j) { CHECK_EQ((*i) | (*j), r.Call(*i, *j)); } | 142 FOR_INT64_INPUTS(j) { CHECK_EQ((*i) | (*j), r.Call(*i, *j)); } |
43 } | 143 } |
44 } | 144 } |
45 // kExprI64Xor: | 145 // kExprI64Xor: |
46 TEST(Run_WasmI64Xor) { | 146 TEST(Run_Wasm_I64Xor) { |
| 147 REQUIRE(I64Xor); |
47 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); | 148 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
48 BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 149 BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
49 FOR_INT64_INPUTS(i) { | 150 FOR_INT64_INPUTS(i) { |
50 FOR_INT64_INPUTS(j) { CHECK_EQ((*i) ^ (*j), r.Call(*i, *j)); } | 151 FOR_INT64_INPUTS(j) { CHECK_EQ((*i) ^ (*j), r.Call(*i, *j)); } |
51 } | 152 } |
52 } | 153 } |
53 // kExprI64Shl: | 154 // kExprI64Shl: |
54 #if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_X87 | 155 TEST(Run_Wasm_I64Shl) { |
55 TEST(Run_WasmI64Shl) { | 156 REQUIRE(I64Shl); |
56 { | 157 { |
57 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); | 158 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
58 BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 159 BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
59 FOR_UINT64_INPUTS(i) { | 160 FOR_UINT64_INPUTS(i) { |
60 for (int64_t j = 1; j < 64; j++) { | 161 for (int64_t j = 1; j < 64; j++) { |
61 CHECK_EQ(*i << j, r.Call(*i, j)); | 162 CHECK_EQ(*i << j, r.Call(*i, j)); |
62 } | 163 } |
63 } | 164 } |
64 } | 165 } |
65 { | 166 { |
(...skipping 10 matching lines...) Expand all Loading... |
76 WasmRunner<int64_t> r(MachineType::Int64()); | 177 WasmRunner<int64_t> r(MachineType::Int64()); |
77 BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(20))); | 178 BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(20))); |
78 FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 20, r.Call(*i)); } | 179 FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 20, r.Call(*i)); } |
79 } | 180 } |
80 { | 181 { |
81 WasmRunner<int64_t> r(MachineType::Int64()); | 182 WasmRunner<int64_t> r(MachineType::Int64()); |
82 BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(40))); | 183 BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(40))); |
83 FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 40, r.Call(*i)); } | 184 FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 40, r.Call(*i)); } |
84 } | 185 } |
85 } | 186 } |
86 #endif | |
87 // kExprI64ShrU: | 187 // kExprI64ShrU: |
88 #if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_X87 && !V8_TARGET_ARCH_ARM | 188 TEST(Run_Wasm_I64ShrU) { |
89 TEST(Run_WasmI64ShrU) { | 189 REQUIRE(I64ShrU); |
90 { | 190 { |
91 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); | 191 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
92 BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 192 BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
93 FOR_UINT64_INPUTS(i) { | 193 FOR_UINT64_INPUTS(i) { |
94 for (int64_t j = 1; j < 64; j++) { | 194 for (int64_t j = 1; j < 64; j++) { |
95 CHECK_EQ(*i >> j, r.Call(*i, j)); | 195 CHECK_EQ(*i >> j, r.Call(*i, j)); |
96 } | 196 } |
97 } | 197 } |
98 } | 198 } |
99 { | 199 { |
(...skipping 10 matching lines...) Expand all Loading... |
110 WasmRunner<int64_t> r(MachineType::Int64()); | 210 WasmRunner<int64_t> r(MachineType::Int64()); |
111 BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(20))); | 211 BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(20))); |
112 FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 20, r.Call(*i)); } | 212 FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 20, r.Call(*i)); } |
113 } | 213 } |
114 { | 214 { |
115 WasmRunner<int64_t> r(MachineType::Int64()); | 215 WasmRunner<int64_t> r(MachineType::Int64()); |
116 BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(40))); | 216 BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(40))); |
117 FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 40, r.Call(*i)); } | 217 FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 40, r.Call(*i)); } |
118 } | 218 } |
119 } | 219 } |
120 #endif | |
121 // kExprI64ShrS: | 220 // kExprI64ShrS: |
122 #if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_X87 && !V8_TARGET_ARCH_ARM | 221 TEST(Run_Wasm_I64ShrS) { |
123 TEST(Run_WasmI64ShrS) { | 222 REQUIRE(I64ShrS); |
124 { | 223 { |
125 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); | 224 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
126 BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 225 BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
127 FOR_INT64_INPUTS(i) { | 226 FOR_INT64_INPUTS(i) { |
128 for (int64_t j = 1; j < 64; j++) { | 227 for (int64_t j = 1; j < 64; j++) { |
129 CHECK_EQ(*i >> j, r.Call(*i, j)); | 228 CHECK_EQ(*i >> j, r.Call(*i, j)); |
130 } | 229 } |
131 } | 230 } |
132 } | 231 } |
133 { | 232 { |
(...skipping 10 matching lines...) Expand all Loading... |
144 WasmRunner<int64_t> r(MachineType::Int64()); | 243 WasmRunner<int64_t> r(MachineType::Int64()); |
145 BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(20))); | 244 BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(20))); |
146 FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 20, r.Call(*i)); } | 245 FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 20, r.Call(*i)); } |
147 } | 246 } |
148 { | 247 { |
149 WasmRunner<int64_t> r(MachineType::Int64()); | 248 WasmRunner<int64_t> r(MachineType::Int64()); |
150 BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(40))); | 249 BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(40))); |
151 FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 40, r.Call(*i)); } | 250 FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 40, r.Call(*i)); } |
152 } | 251 } |
153 } | 252 } |
154 #endif | |
155 // kExprI64Eq: | 253 // kExprI64Eq: |
156 TEST(Run_WasmI64Eq) { | 254 TEST(Run_Wasm_I64Eq) { |
| 255 REQUIRE(I64Eq); |
157 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 256 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
158 BUILD(r, WASM_I64_EQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 257 BUILD(r, WASM_I64_EQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
159 FOR_INT64_INPUTS(i) { | 258 FOR_INT64_INPUTS(i) { |
160 FOR_INT64_INPUTS(j) { CHECK_EQ(*i == *j ? 1 : 0, r.Call(*i, *j)); } | 259 FOR_INT64_INPUTS(j) { CHECK_EQ(*i == *j ? 1 : 0, r.Call(*i, *j)); } |
161 } | 260 } |
162 } | 261 } |
163 // kExprI64Ne: | 262 // kExprI64Ne: |
164 TEST(Run_WasmI64Ne) { | 263 TEST(Run_Wasm_I64Ne) { |
| 264 REQUIRE(I64Ne); |
165 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 265 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
166 BUILD(r, WASM_I64_NE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 266 BUILD(r, WASM_I64_NE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
167 FOR_INT64_INPUTS(i) { | 267 FOR_INT64_INPUTS(i) { |
168 FOR_INT64_INPUTS(j) { CHECK_EQ(*i != *j ? 1 : 0, r.Call(*i, *j)); } | 268 FOR_INT64_INPUTS(j) { CHECK_EQ(*i != *j ? 1 : 0, r.Call(*i, *j)); } |
169 } | 269 } |
170 } | 270 } |
171 // kExprI64LtS: | 271 // kExprI64LtS: |
172 TEST(Run_WasmI64LtS) { | 272 TEST(Run_Wasm_I64LtS) { |
| 273 REQUIRE(I64LtS); |
173 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 274 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
174 BUILD(r, WASM_I64_LTS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 275 BUILD(r, WASM_I64_LTS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
175 FOR_INT64_INPUTS(i) { | 276 FOR_INT64_INPUTS(i) { |
176 FOR_INT64_INPUTS(j) { CHECK_EQ(*i < *j ? 1 : 0, r.Call(*i, *j)); } | 277 FOR_INT64_INPUTS(j) { CHECK_EQ(*i < *j ? 1 : 0, r.Call(*i, *j)); } |
177 } | 278 } |
178 } | 279 } |
179 TEST(Run_WasmI64LeS) { | 280 TEST(Run_Wasm_I64LeS) { |
| 281 REQUIRE(I64LeS); |
180 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 282 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
181 BUILD(r, WASM_I64_LES(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 283 BUILD(r, WASM_I64_LES(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
182 FOR_INT64_INPUTS(i) { | 284 FOR_INT64_INPUTS(i) { |
183 FOR_INT64_INPUTS(j) { CHECK_EQ(*i <= *j ? 1 : 0, r.Call(*i, *j)); } | 285 FOR_INT64_INPUTS(j) { CHECK_EQ(*i <= *j ? 1 : 0, r.Call(*i, *j)); } |
184 } | 286 } |
185 } | 287 } |
186 TEST(Run_WasmI64LtU) { | 288 TEST(Run_Wasm_I64LtU) { |
| 289 REQUIRE(I64LtU); |
187 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 290 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
188 BUILD(r, WASM_I64_LTU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 291 BUILD(r, WASM_I64_LTU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
189 FOR_UINT64_INPUTS(i) { | 292 FOR_UINT64_INPUTS(i) { |
190 FOR_UINT64_INPUTS(j) { CHECK_EQ(*i < *j ? 1 : 0, r.Call(*i, *j)); } | 293 FOR_UINT64_INPUTS(j) { CHECK_EQ(*i < *j ? 1 : 0, r.Call(*i, *j)); } |
191 } | 294 } |
192 } | 295 } |
193 TEST(Run_WasmI64LeU) { | 296 TEST(Run_Wasm_I64LeU) { |
| 297 REQUIRE(I64LeU); |
194 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 298 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
195 BUILD(r, WASM_I64_LEU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 299 BUILD(r, WASM_I64_LEU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
196 FOR_UINT64_INPUTS(i) { | 300 FOR_UINT64_INPUTS(i) { |
197 FOR_UINT64_INPUTS(j) { CHECK_EQ(*i <= *j ? 1 : 0, r.Call(*i, *j)); } | 301 FOR_UINT64_INPUTS(j) { CHECK_EQ(*i <= *j ? 1 : 0, r.Call(*i, *j)); } |
198 } | 302 } |
199 } | 303 } |
200 TEST(Run_WasmI64GtS) { | 304 TEST(Run_Wasm_I64GtS) { |
| 305 REQUIRE(I64GtS); |
201 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 306 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
202 BUILD(r, WASM_I64_GTS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 307 BUILD(r, WASM_I64_GTS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
203 FOR_INT64_INPUTS(i) { | 308 FOR_INT64_INPUTS(i) { |
204 FOR_INT64_INPUTS(j) { CHECK_EQ(*i > *j ? 1 : 0, r.Call(*i, *j)); } | 309 FOR_INT64_INPUTS(j) { CHECK_EQ(*i > *j ? 1 : 0, r.Call(*i, *j)); } |
205 } | 310 } |
206 } | 311 } |
207 TEST(Run_WasmI64GeS) { | 312 TEST(Run_Wasm_I64GeS) { |
| 313 REQUIRE(I64GeS); |
208 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 314 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
209 BUILD(r, WASM_I64_GES(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 315 BUILD(r, WASM_I64_GES(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
210 FOR_INT64_INPUTS(i) { | 316 FOR_INT64_INPUTS(i) { |
211 FOR_INT64_INPUTS(j) { CHECK_EQ(*i >= *j ? 1 : 0, r.Call(*i, *j)); } | 317 FOR_INT64_INPUTS(j) { CHECK_EQ(*i >= *j ? 1 : 0, r.Call(*i, *j)); } |
212 } | 318 } |
213 } | 319 } |
214 | 320 |
215 TEST(Run_WasmI64GtU) { | 321 TEST(Run_Wasm_I64GtU) { |
| 322 REQUIRE(I64GtU); |
216 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 323 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
217 BUILD(r, WASM_I64_GTU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 324 BUILD(r, WASM_I64_GTU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
218 FOR_UINT64_INPUTS(i) { | 325 FOR_UINT64_INPUTS(i) { |
219 FOR_UINT64_INPUTS(j) { CHECK_EQ(*i > *j ? 1 : 0, r.Call(*i, *j)); } | 326 FOR_UINT64_INPUTS(j) { CHECK_EQ(*i > *j ? 1 : 0, r.Call(*i, *j)); } |
220 } | 327 } |
221 } | 328 } |
222 | 329 |
223 TEST(Run_WasmI64GeU) { | 330 TEST(Run_Wasm_I64GeU) { |
| 331 REQUIRE(I64GeU); |
224 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); | 332 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
225 BUILD(r, WASM_I64_GEU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 333 BUILD(r, WASM_I64_GEU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
226 FOR_UINT64_INPUTS(i) { | 334 FOR_UINT64_INPUTS(i) { |
227 FOR_UINT64_INPUTS(j) { CHECK_EQ(*i >= *j ? 1 : 0, r.Call(*i, *j)); } | 335 FOR_UINT64_INPUTS(j) { CHECK_EQ(*i >= *j ? 1 : 0, r.Call(*i, *j)); } |
228 } | 336 } |
229 } | 337 } |
230 // kExprI32ConvertI64: | 338 // kExprI32ConvertI64: |
231 TEST(Run_WasmI32ConvertI64) { | 339 TEST(Run_Wasm_I32ConvertI64) { |
| 340 REQUIRE(I32ConvertI64); |
232 FOR_INT64_INPUTS(i) { | 341 FOR_INT64_INPUTS(i) { |
233 WasmRunner<int32_t> r; | 342 WasmRunner<int32_t> r; |
234 BUILD(r, WASM_I32_CONVERT_I64(WASM_I64V(*i))); | 343 BUILD(r, WASM_I32_CONVERT_I64(WASM_I64V(*i))); |
235 CHECK_EQ(static_cast<int32_t>(*i), r.Call()); | 344 CHECK_EQ(static_cast<int32_t>(*i), r.Call()); |
236 } | 345 } |
237 } | 346 } |
238 // kExprI64SConvertI32: | 347 // kExprI64SConvertI32: |
239 TEST(Run_WasmI64SConvertI32) { | 348 TEST(Run_Wasm_I64SConvertI32) { |
| 349 REQUIRE(I64SConvertI32); |
240 WasmRunner<int64_t> r(MachineType::Int32()); | 350 WasmRunner<int64_t> r(MachineType::Int32()); |
241 BUILD(r, WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0))); | 351 BUILD(r, WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0))); |
242 FOR_INT32_INPUTS(i) { CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); } | 352 FOR_INT32_INPUTS(i) { CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); } |
243 } | 353 } |
244 | 354 |
245 // kExprI64UConvertI32: | 355 // kExprI64UConvertI32: |
246 TEST(Run_WasmI64UConvertI32) { | 356 TEST(Run_Wasm_I64UConvertI32) { |
| 357 REQUIRE(I64UConvertI32); |
247 WasmRunner<int64_t> r(MachineType::Uint32()); | 358 WasmRunner<int64_t> r(MachineType::Uint32()); |
248 BUILD(r, WASM_I64_UCONVERT_I32(WASM_GET_LOCAL(0))); | 359 BUILD(r, WASM_I64_UCONVERT_I32(WASM_GET_LOCAL(0))); |
249 FOR_UINT32_INPUTS(i) { CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); } | 360 FOR_UINT32_INPUTS(i) { CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); } |
250 } | 361 } |
251 | 362 |
252 // kExprF64ReinterpretI64: | 363 // kExprF64ReinterpretI64: |
253 // kExprI64ReinterpretF64: | 364 // kExprI64ReinterpretF64: |
254 | 365 |
255 // kExprI64Clz: | 366 // kExprI64Clz: |
256 // kExprI64Ctz: | 367 // kExprI64Ctz: |
257 // kExprI64Popcnt: | 368 // kExprI64Popcnt: |
258 | 369 |
259 // kExprF32SConvertI64: | 370 // kExprF32SConvertI64: |
260 TEST(Run_WasmF32SConvertI64) { | 371 TEST(Run_WasmF32SConvertI64) { |
| 372 REQUIRE(F32SConvertI64); |
261 WasmRunner<float> r(MachineType::Int64()); | 373 WasmRunner<float> r(MachineType::Int64()); |
262 BUILD(r, WASM_F32_SCONVERT_I64(WASM_GET_LOCAL(0))); | 374 BUILD(r, WASM_F32_SCONVERT_I64(WASM_GET_LOCAL(0))); |
263 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), r.Call(*i)); } | 375 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), r.Call(*i)); } |
264 } | 376 } |
265 // kExprF32UConvertI64: | 377 // kExprF32UConvertI64: |
266 TEST(Run_WasmF32UConvertI64) { | 378 TEST(Run_WasmF32UConvertI64) { |
| 379 REQUIRE(F32UConvertI64); |
267 struct { | 380 struct { |
268 uint64_t input; | 381 uint64_t input; |
269 uint32_t expected; | 382 uint32_t expected; |
270 } values[] = {{0x0, 0x0}, | 383 } values[] = {{0x0, 0x0}, |
271 {0x1, 0x3f800000}, | 384 {0x1, 0x3f800000}, |
272 {0xffffffff, 0x4f800000}, | 385 {0xffffffff, 0x4f800000}, |
273 {0x1b09788b, 0x4dd84bc4}, | 386 {0x1b09788b, 0x4dd84bc4}, |
274 {0x4c5fce8, 0x4c98bf9d}, | 387 {0x4c5fce8, 0x4c98bf9d}, |
275 {0xcc0de5bf, 0x4f4c0de6}, | 388 {0xcc0de5bf, 0x4f4c0de6}, |
276 {0x2, 0x40000000}, | 389 {0x2, 0x40000000}, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 {0x8000000000000400, 0x5f000000}, | 457 {0x8000000000000400, 0x5f000000}, |
345 {0x8000000000000401, 0x5f000000}}; | 458 {0x8000000000000401, 0x5f000000}}; |
346 WasmRunner<float> r(MachineType::Uint64()); | 459 WasmRunner<float> r(MachineType::Uint64()); |
347 BUILD(r, WASM_F32_UCONVERT_I64(WASM_GET_LOCAL(0))); | 460 BUILD(r, WASM_F32_UCONVERT_I64(WASM_GET_LOCAL(0))); |
348 for (size_t i = 0; i < arraysize(values); i++) { | 461 for (size_t i = 0; i < arraysize(values); i++) { |
349 CHECK_EQ(bit_cast<float>(values[i].expected), r.Call(values[i].input)); | 462 CHECK_EQ(bit_cast<float>(values[i].expected), r.Call(values[i].input)); |
350 } | 463 } |
351 } | 464 } |
352 // kExprF64SConvertI64: | 465 // kExprF64SConvertI64: |
353 TEST(Run_WasmF64SConvertI64) { | 466 TEST(Run_WasmF64SConvertI64) { |
| 467 REQUIRE(F64SConvertI64); |
354 WasmRunner<double> r(MachineType::Int64()); | 468 WasmRunner<double> r(MachineType::Int64()); |
355 BUILD(r, WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0))); | 469 BUILD(r, WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0))); |
356 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), r.Call(*i)); } | 470 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), r.Call(*i)); } |
357 } | 471 } |
358 // kExprF64UConvertI64: | 472 // kExprF64UConvertI64: |
359 TEST(Run_Wasm_F64UConvertI64) { | 473 TEST(Run_Wasm_F64UConvertI64) { |
| 474 REQUIRE(F64UConvertI64); |
360 struct { | 475 struct { |
361 uint64_t input; | 476 uint64_t input; |
362 uint64_t expected; | 477 uint64_t expected; |
363 } values[] = {{0x0, 0x0}, | 478 } values[] = {{0x0, 0x0}, |
364 {0x1, 0x3ff0000000000000}, | 479 {0x1, 0x3ff0000000000000}, |
365 {0xffffffff, 0x41efffffffe00000}, | 480 {0xffffffff, 0x41efffffffe00000}, |
366 {0x1b09788b, 0x41bb09788b000000}, | 481 {0x1b09788b, 0x41bb09788b000000}, |
367 {0x4c5fce8, 0x419317f3a0000000}, | 482 {0x4c5fce8, 0x419317f3a0000000}, |
368 {0xcc0de5bf, 0x41e981bcb7e00000}, | 483 {0xcc0de5bf, 0x41e981bcb7e00000}, |
369 {0x2, 0x4000000000000000}, | 484 {0x2, 0x4000000000000000}, |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 {0x8000000000000400, 0x43e0000000000000}, | 551 {0x8000000000000400, 0x43e0000000000000}, |
437 {0x8000000000000401, 0x43e0000000000001}}; | 552 {0x8000000000000401, 0x43e0000000000001}}; |
438 WasmRunner<double> r(MachineType::Uint64()); | 553 WasmRunner<double> r(MachineType::Uint64()); |
439 BUILD(r, WASM_F64_UCONVERT_I64(WASM_GET_LOCAL(0))); | 554 BUILD(r, WASM_F64_UCONVERT_I64(WASM_GET_LOCAL(0))); |
440 for (size_t i = 0; i < arraysize(values); i++) { | 555 for (size_t i = 0; i < arraysize(values); i++) { |
441 CHECK_EQ(bit_cast<double>(values[i].expected), r.Call(values[i].input)); | 556 CHECK_EQ(bit_cast<double>(values[i].expected), r.Call(values[i].input)); |
442 } | 557 } |
443 } | 558 } |
444 // kExprI64SConvertF32: | 559 // kExprI64SConvertF32: |
445 | 560 |
446 TEST(Run_Wasm_I64SConvertF32) { | 561 TEST(Run_Wasm_I64SConvertF32a) { |
447 WasmRunner<int64_t> r(MachineType::Float32()); | 562 WasmRunner<int64_t> r(MachineType::Float32()); |
448 BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0))); | 563 BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0))); |
449 | 564 |
450 FOR_FLOAT32_INPUTS(i) { | 565 FOR_FLOAT32_INPUTS(i) { |
451 if (*i < static_cast<float>(std::numeric_limits<int64_t>::max()) && | 566 if (*i < static_cast<float>(std::numeric_limits<int64_t>::max()) && |
452 *i >= static_cast<float>(std::numeric_limits<int64_t>::min())) { | 567 *i >= static_cast<float>(std::numeric_limits<int64_t>::min())) { |
453 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); | 568 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); |
454 } else { | 569 } else { |
455 CHECK_TRAP64(r.Call(*i)); | 570 CHECK_TRAP64(r.Call(*i)); |
456 } | 571 } |
457 } | 572 } |
458 } | 573 } |
459 // kExprI64SConvertF64: | 574 // kExprI64SConvertF64: |
460 TEST(Run_Wasm_I64SConvertF64) { | 575 TEST(Run_Wasm_I64SConvertF64a) { |
461 WasmRunner<int64_t> r(MachineType::Float64()); | 576 WasmRunner<int64_t> r(MachineType::Float64()); |
462 BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0))); | 577 BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0))); |
463 | 578 |
464 FOR_FLOAT64_INPUTS(i) { | 579 FOR_FLOAT64_INPUTS(i) { |
465 if (*i < static_cast<double>(std::numeric_limits<int64_t>::max()) && | 580 if (*i < static_cast<double>(std::numeric_limits<int64_t>::max()) && |
466 *i >= static_cast<double>(std::numeric_limits<int64_t>::min())) { | 581 *i >= static_cast<double>(std::numeric_limits<int64_t>::min())) { |
467 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); | 582 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); |
468 } else { | 583 } else { |
469 CHECK_TRAP64(r.Call(*i)); | 584 CHECK_TRAP64(r.Call(*i)); |
470 } | 585 } |
471 } | 586 } |
472 } | 587 } |
473 | 588 |
474 // kExprI64UConvertF32: | 589 // kExprI64UConvertF32: |
475 TEST(Run_Wasm_I64UConvertF32) { | 590 TEST(Run_Wasm_I64UConvertF32a) { |
476 WasmRunner<uint64_t> r(MachineType::Float32()); | 591 WasmRunner<uint64_t> r(MachineType::Float32()); |
477 BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0))); | 592 BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0))); |
478 | 593 |
479 FOR_FLOAT32_INPUTS(i) { | 594 FOR_FLOAT32_INPUTS(i) { |
480 if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) && | 595 if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) && |
481 *i > -1) { | 596 *i > -1) { |
482 CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); | 597 CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); |
483 } else { | 598 } else { |
484 CHECK_TRAP64(r.Call(*i)); | 599 CHECK_TRAP64(r.Call(*i)); |
485 } | 600 } |
486 } | 601 } |
487 } | 602 } |
488 | 603 |
489 // kExprI64UConvertF64: | 604 // kExprI64UConvertF64: |
490 TEST(Run_Wasm_I64UConvertF64) { | 605 TEST(Run_Wasm_I64UConvertF64a) { |
491 WasmRunner<uint64_t> r(MachineType::Float64()); | 606 WasmRunner<uint64_t> r(MachineType::Float64()); |
492 BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0))); | 607 BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0))); |
493 | 608 |
494 FOR_FLOAT64_INPUTS(i) { | 609 FOR_FLOAT64_INPUTS(i) { |
495 if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) && | 610 if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) && |
496 *i > -1) { | 611 *i > -1) { |
497 CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); | 612 CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); |
498 } else { | 613 } else { |
499 CHECK_TRAP64(r.Call(*i)); | 614 CHECK_TRAP64(r.Call(*i)); |
500 } | 615 } |
(...skipping 30 matching lines...) Expand all Loading... |
531 WASM_I64V_10(0xbcd1234000000013), WASM_I64V_10(0xbcd1234000000014), | 646 WASM_I64V_10(0xbcd1234000000013), WASM_I64V_10(0xbcd1234000000014), |
532 WASM_I64V_10(0xbcd1234000000015), WASM_I64V_10(0xbcd1234000000016), | 647 WASM_I64V_10(0xbcd1234000000015), WASM_I64V_10(0xbcd1234000000016), |
533 WASM_I64V_10(0xbcd1234000000017), WASM_I64V_10(0xbcd1234000000018), | 648 WASM_I64V_10(0xbcd1234000000017), WASM_I64V_10(0xbcd1234000000018), |
534 WASM_I64V_10(0xbcd1234000000019), WASM_I64V_10(0xbcd123400000001a), | 649 WASM_I64V_10(0xbcd1234000000019), WASM_I64V_10(0xbcd123400000001a), |
535 WASM_I64V_10(0xbcd123400000001b), WASM_I64V_10(0xbcd123400000001c), | 650 WASM_I64V_10(0xbcd123400000001b), WASM_I64V_10(0xbcd123400000001c), |
536 WASM_I64V_10(0xbcd123400000001d)))); | 651 WASM_I64V_10(0xbcd123400000001d)))); |
537 | 652 |
538 CHECK_EQ(i + 0xb, r.Call()); | 653 CHECK_EQ(i + 0xb, r.Call()); |
539 } | 654 } |
540 } | 655 } |
| 656 |
| 657 void TestI64Binop(WasmOpcode opcode, int64_t expected, int64_t a, int64_t b) { |
| 658 { |
| 659 WasmRunner<int64_t> r; |
| 660 // return K op K |
| 661 BUILD(r, WASM_BINOP(opcode, WASM_I64V(a), WASM_I64V(b))); |
| 662 CHECK_EQ(expected, r.Call()); |
| 663 } |
| 664 { |
| 665 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
| 666 // return a op b |
| 667 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 668 CHECK_EQ(expected, r.Call(a, b)); |
| 669 } |
| 670 } |
| 671 |
| 672 void TestI64Cmp(WasmOpcode opcode, int64_t expected, int64_t a, int64_t b) { |
| 673 { |
| 674 WasmRunner<int32_t> r; |
| 675 // return K op K |
| 676 BUILD(r, WASM_BINOP(opcode, WASM_I64V(a), WASM_I64V(b))); |
| 677 CHECK_EQ(expected, r.Call()); |
| 678 } |
| 679 { |
| 680 WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); |
| 681 // return a op b |
| 682 BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 683 CHECK_EQ(expected, r.Call(a, b)); |
| 684 } |
| 685 } |
| 686 |
| 687 #define TEST_I64_BINOP(name, expected, a, b) \ |
| 688 do { \ |
| 689 if (WASM_64 || kSupported_##name) \ |
| 690 TestI64Binop(kExpr##name, expected, a, b); \ |
| 691 } while (false) |
| 692 |
| 693 TEST(Run_Wasm_I64Binops) { |
| 694 // TODO(titzer): real 64-bit numbers |
| 695 TEST_I64_BINOP(I64Add, 8888888888888LL, 3333333333333LL, 5555555555555LL); |
| 696 TEST_I64_BINOP(I64Sub, -111111111111LL, 777777777777LL, 888888888888LL); |
| 697 TEST_I64_BINOP(I64Mul, 65130756, 88734, 734); |
| 698 TEST_I64_BINOP(I64DivS, -66, -4777344, 72384); |
| 699 TEST_I64_BINOP(I64DivU, 805306368, 0xF0000000, 5); |
| 700 TEST_I64_BINOP(I64RemS, -3, -3003, 1000); |
| 701 TEST_I64_BINOP(I64RemU, 4, 4004, 1000); |
| 702 TEST_I64_BINOP(I64And, 0xEE, 0xFFEE, 0xFF0000FF); |
| 703 TEST_I64_BINOP(I64Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011); |
| 704 TEST_I64_BINOP(I64Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE); |
| 705 TEST_I64_BINOP(I64Shl, 0xA0000000, 0xA, 28); |
| 706 TEST_I64_BINOP(I64ShrU, 0x0700001000123456LL, 0x7000010001234567LL, 4); |
| 707 TEST_I64_BINOP(I64ShrS, 0xFF00000000000000LL, 0x8000000000000000LL, 7); |
| 708 TEST_I64_BINOP(I64Ror, 0x0100000000000000LL, 0x8000000000000000LL, 7); |
| 709 TEST_I64_BINOP(I64Ror, 0x0100000000000000LL, 0x8000000000000000LL, 71); |
| 710 TEST_I64_BINOP(I64Rol, 0x0000000000000040LL, 0x8000000000000000LL, 7); |
| 711 TEST_I64_BINOP(I64Rol, 0x0000000000000040LL, 0x8000000000000000LL, 71); |
| 712 } |
| 713 |
| 714 #define TEST_I64_CMP(name, expected, a, b) \ |
| 715 do { \ |
| 716 if (WASM_64 || kSupported_##name) TestI64Cmp(kExpr##name, expected, a, b); \ |
| 717 } while (false) |
| 718 |
| 719 TEST(Run_Wasm_I64Compare) { |
| 720 // TODO(titzer): real 64-bit numbers |
| 721 TEST_I64_CMP(I64Eq, 1, -9999, -9999); |
| 722 TEST_I64_CMP(I64Ne, 1, -9199, -9999); |
| 723 TEST_I64_CMP(I64LtS, 1, -4, 4); |
| 724 TEST_I64_CMP(I64LeS, 0, -2, -3); |
| 725 TEST_I64_CMP(I64LtU, 1, 0, -6); |
| 726 TEST_I64_CMP(I64LeU, 1, 98978, 0xF0000000); |
| 727 TEST_I64_CMP(I64GtS, 1, 4, -4); |
| 728 TEST_I64_CMP(I64GeS, 0, -3, -2); |
| 729 TEST_I64_CMP(I64GtU, 1, -6, 0); |
| 730 TEST_I64_CMP(I64GeU, 1, 0xF0000000, 98978); |
| 731 } |
| 732 |
| 733 TEST(Run_Wasm_I64Clz) { |
| 734 REQUIRE(I64Clz); |
| 735 struct { |
| 736 int64_t expected; |
| 737 uint64_t input; |
| 738 } values[] = {{0, 0x8000100000000000}, {1, 0x4000050000000000}, |
| 739 {2, 0x2000030000000000}, {3, 0x1000000300000000}, |
| 740 {4, 0x0805000000000000}, {5, 0x0400600000000000}, |
| 741 {6, 0x0200000000000000}, {7, 0x010000a000000000}, |
| 742 {8, 0x00800c0000000000}, {9, 0x0040000000000000}, |
| 743 {10, 0x0020000d00000000}, {11, 0x00100f0000000000}, |
| 744 {12, 0x0008000000000000}, {13, 0x0004100000000000}, |
| 745 {14, 0x0002002000000000}, {15, 0x0001030000000000}, |
| 746 {16, 0x0000804000000000}, {17, 0x0000400500000000}, |
| 747 {18, 0x0000205000000000}, {19, 0x0000170000000000}, |
| 748 {20, 0x0000087000000000}, {21, 0x0000040500000000}, |
| 749 {22, 0x0000020300000000}, {23, 0x0000010100000000}, |
| 750 {24, 0x0000008900000000}, {25, 0x0000004100000000}, |
| 751 {26, 0x0000002200000000}, {27, 0x0000001300000000}, |
| 752 {28, 0x0000000800000000}, {29, 0x0000000400000000}, |
| 753 {30, 0x0000000200000000}, {31, 0x0000000100000000}, |
| 754 {32, 0x0000000080001000}, {33, 0x0000000040000500}, |
| 755 {34, 0x0000000020000300}, {35, 0x0000000010000003}, |
| 756 {36, 0x0000000008050000}, {37, 0x0000000004006000}, |
| 757 {38, 0x0000000002000000}, {39, 0x00000000010000a0}, |
| 758 {40, 0x0000000000800c00}, {41, 0x0000000000400000}, |
| 759 {42, 0x000000000020000d}, {43, 0x0000000000100f00}, |
| 760 {44, 0x0000000000080000}, {45, 0x0000000000041000}, |
| 761 {46, 0x0000000000020020}, {47, 0x0000000000010300}, |
| 762 {48, 0x0000000000008040}, {49, 0x0000000000004005}, |
| 763 {50, 0x0000000000002050}, {51, 0x0000000000001700}, |
| 764 {52, 0x0000000000000870}, {53, 0x0000000000000405}, |
| 765 {54, 0x0000000000000203}, {55, 0x0000000000000101}, |
| 766 {56, 0x0000000000000089}, {57, 0x0000000000000041}, |
| 767 {58, 0x0000000000000022}, {59, 0x0000000000000013}, |
| 768 {60, 0x0000000000000008}, {61, 0x0000000000000004}, |
| 769 {62, 0x0000000000000002}, {63, 0x0000000000000001}, |
| 770 {64, 0x0000000000000000}}; |
| 771 |
| 772 WasmRunner<int64_t> r(MachineType::Uint64()); |
| 773 BUILD(r, WASM_I64_CLZ(WASM_GET_LOCAL(0))); |
| 774 for (size_t i = 0; i < arraysize(values); i++) { |
| 775 CHECK_EQ(values[i].expected, r.Call(values[i].input)); |
| 776 } |
| 777 } |
| 778 |
| 779 TEST(Run_Wasm_I64Ctz) { |
| 780 REQUIRE(I64Ctz); |
| 781 struct { |
| 782 int64_t expected; |
| 783 uint64_t input; |
| 784 } values[] = {{64, 0x0000000000000000}, {63, 0x8000000000000000}, |
| 785 {62, 0x4000000000000000}, {61, 0x2000000000000000}, |
| 786 {60, 0x1000000000000000}, {59, 0xa800000000000000}, |
| 787 {58, 0xf400000000000000}, {57, 0x6200000000000000}, |
| 788 {56, 0x9100000000000000}, {55, 0xcd80000000000000}, |
| 789 {54, 0x0940000000000000}, {53, 0xaf20000000000000}, |
| 790 {52, 0xac10000000000000}, {51, 0xe0b8000000000000}, |
| 791 {50, 0x9ce4000000000000}, {49, 0xc792000000000000}, |
| 792 {48, 0xb8f1000000000000}, {47, 0x3b9f800000000000}, |
| 793 {46, 0xdb4c400000000000}, {45, 0xe9a3200000000000}, |
| 794 {44, 0xfca6100000000000}, {43, 0x6c8a780000000000}, |
| 795 {42, 0x8ce5a40000000000}, {41, 0xcb7d020000000000}, |
| 796 {40, 0xcb4dc10000000000}, {39, 0xdfbec58000000000}, |
| 797 {38, 0x27a9db4000000000}, {37, 0xde3bcb2000000000}, |
| 798 {36, 0xd7e8a61000000000}, {35, 0x9afdbc8800000000}, |
| 799 {34, 0x9afdbc8400000000}, {33, 0x9afdbc8200000000}, |
| 800 {32, 0x9afdbc8100000000}, {31, 0x0000000080000000}, |
| 801 {30, 0x0000000040000000}, {29, 0x0000000020000000}, |
| 802 {28, 0x0000000010000000}, {27, 0x00000000a8000000}, |
| 803 {26, 0x00000000f4000000}, {25, 0x0000000062000000}, |
| 804 {24, 0x0000000091000000}, {23, 0x00000000cd800000}, |
| 805 {22, 0x0000000009400000}, {21, 0x00000000af200000}, |
| 806 {20, 0x00000000ac100000}, {19, 0x00000000e0b80000}, |
| 807 {18, 0x000000009ce40000}, {17, 0x00000000c7920000}, |
| 808 {16, 0x00000000b8f10000}, {15, 0x000000003b9f8000}, |
| 809 {14, 0x00000000db4c4000}, {13, 0x00000000e9a32000}, |
| 810 {12, 0x00000000fca61000}, {11, 0x000000006c8a7800}, |
| 811 {10, 0x000000008ce5a400}, {9, 0x00000000cb7d0200}, |
| 812 {8, 0x00000000cb4dc100}, {7, 0x00000000dfbec580}, |
| 813 {6, 0x0000000027a9db40}, {5, 0x00000000de3bcb20}, |
| 814 {4, 0x00000000d7e8a610}, {3, 0x000000009afdbc88}, |
| 815 {2, 0x000000009afdbc84}, {1, 0x000000009afdbc82}, |
| 816 {0, 0x000000009afdbc81}}; |
| 817 |
| 818 WasmRunner<int64_t> r(MachineType::Uint64()); |
| 819 BUILD(r, WASM_I64_CTZ(WASM_GET_LOCAL(0))); |
| 820 for (size_t i = 0; i < arraysize(values); i++) { |
| 821 CHECK_EQ(values[i].expected, r.Call(values[i].input)); |
| 822 } |
| 823 } |
| 824 |
| 825 TEST(Run_Wasm_I64Popcnt) { |
| 826 REQUIRE(I64Popcnt); |
| 827 struct { |
| 828 int64_t expected; |
| 829 uint64_t input; |
| 830 } values[] = {{64, 0xffffffffffffffff}, |
| 831 {0, 0x0000000000000000}, |
| 832 {2, 0x0000080000008000}, |
| 833 {26, 0x1123456782345678}, |
| 834 {38, 0xffedcba09edcba09}}; |
| 835 |
| 836 WasmRunner<int64_t> r(MachineType::Uint64()); |
| 837 BUILD(r, WASM_I64_POPCNT(WASM_GET_LOCAL(0))); |
| 838 for (size_t i = 0; i < arraysize(values); i++) { |
| 839 CHECK_EQ(values[i].expected, r.Call(values[i].input)); |
| 840 } |
| 841 } |
| 842 |
| 843 // Test the WasmRunner with an Int64 return value and different numbers of |
| 844 // Int64 parameters. |
| 845 TEST(Run_TestI64WasmRunner) { |
| 846 REQUIRE(I64Param); |
| 847 REQUIRE(I64Xor); |
| 848 {FOR_INT64_INPUTS(i){WasmRunner<int64_t> r; |
| 849 BUILD(r, WASM_I64V(*i)); |
| 850 CHECK_EQ(*i, r.Call()); |
| 851 } |
| 852 } |
| 853 { |
| 854 WasmRunner<int64_t> r(MachineType::Int64()); |
| 855 BUILD(r, WASM_GET_LOCAL(0)); |
| 856 FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); } |
| 857 } |
| 858 { |
| 859 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
| 860 BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 861 FOR_INT64_INPUTS(i) { |
| 862 FOR_INT64_INPUTS(j) { CHECK_EQ(*i ^ *j, r.Call(*i, *j)); } |
| 863 } |
| 864 } |
| 865 { |
| 866 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64(), |
| 867 MachineType::Int64()); |
| 868 BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), |
| 869 WASM_I64_XOR(WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)))); |
| 870 FOR_INT64_INPUTS(i) { |
| 871 FOR_INT64_INPUTS(j) { |
| 872 CHECK_EQ(*i ^ *j ^ *j, r.Call(*i, *j, *j)); |
| 873 CHECK_EQ(*j ^ *i ^ *j, r.Call(*j, *i, *j)); |
| 874 CHECK_EQ(*j ^ *j ^ *i, r.Call(*j, *j, *i)); |
| 875 } |
| 876 } |
| 877 } |
| 878 { |
| 879 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64(), |
| 880 MachineType::Int64(), MachineType::Int64()); |
| 881 BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), |
| 882 WASM_I64_XOR(WASM_GET_LOCAL(1), |
| 883 WASM_I64_XOR(WASM_GET_LOCAL(2), |
| 884 WASM_GET_LOCAL(3))))); |
| 885 FOR_INT64_INPUTS(i) { |
| 886 FOR_INT64_INPUTS(j) { |
| 887 CHECK_EQ(*i ^ *j ^ *j ^ *j, r.Call(*i, *j, *j, *j)); |
| 888 CHECK_EQ(*j ^ *i ^ *j ^ *j, r.Call(*j, *i, *j, *j)); |
| 889 CHECK_EQ(*j ^ *j ^ *i ^ *j, r.Call(*j, *j, *i, *j)); |
| 890 CHECK_EQ(*j ^ *j ^ *j ^ *i, r.Call(*j, *j, *j, *i)); |
| 891 } |
| 892 } |
| 893 } |
| 894 } |
| 895 |
| 896 TEST(Run_WasmCall_Int64Sub) { |
| 897 REQUIRE(I64Sub); |
| 898 // Build the target function. |
| 899 TestSignatures sigs; |
| 900 TestingModule module; |
| 901 WasmFunctionCompiler t(sigs.l_ll(), &module); |
| 902 BUILD(t, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 903 uint32_t index = t.CompileAndAdd(); |
| 904 |
| 905 // Build the caller function. |
| 906 WasmRunner<int64_t> r(&module, MachineType::Int64(), MachineType::Int64()); |
| 907 BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 908 |
| 909 FOR_INT32_INPUTS(i) { |
| 910 FOR_INT32_INPUTS(j) { |
| 911 int64_t a = static_cast<int64_t>(*i) << 32 | |
| 912 (static_cast<int64_t>(*j) | 0xFFFFFFFF); |
| 913 int64_t b = static_cast<int64_t>(*j) << 32 | |
| 914 (static_cast<int64_t>(*i) | 0xFFFFFFFF); |
| 915 |
| 916 int64_t expected = static_cast<int64_t>(static_cast<uint64_t>(a) - |
| 917 static_cast<uint64_t>(b)); |
| 918 CHECK_EQ(expected, r.Call(a, b)); |
| 919 } |
| 920 } |
| 921 } |
| 922 |
| 923 TEST(Run_Wasm_LoadStoreI64_sx) { |
| 924 REQUIRE(I64LoadStore); |
| 925 REQUIRE(DepthFirst); // TODO(titzer): temporary hack |
| 926 byte loads[] = {kExprI64LoadMem8S, kExprI64LoadMem16S, kExprI64LoadMem32S, |
| 927 kExprI64LoadMem}; |
| 928 |
| 929 for (size_t m = 0; m < arraysize(loads); m++) { |
| 930 TestingModule module; |
| 931 byte* memory = module.AddMemoryElems<byte>(16); |
| 932 WasmRunner<int64_t> r(&module); |
| 933 |
| 934 byte code[] = {kExprI64StoreMem, ZERO_ALIGNMENT, |
| 935 ZERO_OFFSET, // -- |
| 936 kExprI8Const, 8, // -- |
| 937 loads[m], ZERO_ALIGNMENT, |
| 938 ZERO_OFFSET, // -- |
| 939 kExprI8Const, 0}; // -- |
| 940 |
| 941 r.Build(code, code + arraysize(code)); |
| 942 |
| 943 // Try a bunch of different negative values. |
| 944 for (int i = -1; i >= -128; i -= 11) { |
| 945 int size = 1 << m; |
| 946 module.BlankMemory(); |
| 947 memory[size - 1] = static_cast<byte>(i); // set the high order byte. |
| 948 |
| 949 int64_t expected = static_cast<int64_t>(i) << ((size - 1) * 8); |
| 950 |
| 951 CHECK_EQ(expected, r.Call()); |
| 952 CHECK_EQ(static_cast<byte>(i), memory[8 + size - 1]); |
| 953 for (int j = size; j < 8; j++) { |
| 954 CHECK_EQ(255, memory[8 + j]); |
| 955 } |
| 956 } |
| 957 } |
| 958 } |
| 959 |
| 960 TEST(Run_Wasm_I64SConvertF32b) { |
| 961 REQUIRE(I64SConvertF32); |
| 962 WasmRunner<int64_t> r(MachineType::Float32()); |
| 963 BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0))); |
| 964 |
| 965 FOR_FLOAT32_INPUTS(i) { |
| 966 if (*i < static_cast<float>(INT64_MAX) && |
| 967 *i >= static_cast<float>(INT64_MIN)) { |
| 968 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); |
| 969 } else { |
| 970 CHECK_TRAP64(r.Call(*i)); |
| 971 } |
| 972 } |
| 973 } |
| 974 |
| 975 TEST(Run_Wasm_I64SConvertF64b) { |
| 976 REQUIRE(I64SConvertF64); |
| 977 WasmRunner<int64_t> r(MachineType::Float64()); |
| 978 BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0))); |
| 979 |
| 980 FOR_FLOAT64_INPUTS(i) { |
| 981 if (*i < static_cast<double>(INT64_MAX) && |
| 982 *i >= static_cast<double>(INT64_MIN)) { |
| 983 CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); |
| 984 } else { |
| 985 CHECK_TRAP64(r.Call(*i)); |
| 986 } |
| 987 } |
| 988 } |
| 989 |
| 990 TEST(Run_Wasm_I64UConvertF32b) { |
| 991 REQUIRE(I64UConvertF32); |
| 992 WasmRunner<uint64_t> r(MachineType::Float32()); |
| 993 BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0))); |
| 994 |
| 995 FOR_FLOAT32_INPUTS(i) { |
| 996 if (*i < static_cast<float>(UINT64_MAX) && *i > -1) { |
| 997 CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); |
| 998 } else { |
| 999 CHECK_TRAP64(r.Call(*i)); |
| 1000 } |
| 1001 } |
| 1002 } |
| 1003 |
| 1004 TEST(Run_Wasm_I64UConvertF64b) { |
| 1005 REQUIRE(I64UConvertF64); |
| 1006 WasmRunner<uint64_t> r(MachineType::Float64()); |
| 1007 BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0))); |
| 1008 |
| 1009 FOR_FLOAT64_INPUTS(i) { |
| 1010 if (*i < static_cast<float>(UINT64_MAX) && *i > -1) { |
| 1011 CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); |
| 1012 } else { |
| 1013 CHECK_TRAP64(r.Call(*i)); |
| 1014 } |
| 1015 } |
| 1016 } |
| 1017 |
| 1018 #define as64(x) static_cast<int64_t>(x) |
| 1019 TEST(Run_WASM_I64DivS_trap) { |
| 1020 REQUIRE(I64DivS); |
| 1021 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
| 1022 BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 1023 CHECK_EQ(0, r.Call(as64(0), as64(100))); |
| 1024 CHECK_TRAP64(r.Call(as64(100), as64(0))); |
| 1025 CHECK_TRAP64(r.Call(as64(-1001), as64(0))); |
| 1026 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(-1))); |
| 1027 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0))); |
| 1028 } |
| 1029 |
| 1030 TEST(Run_WASM_I64RemS_trap) { |
| 1031 REQUIRE(I64RemS); |
| 1032 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
| 1033 BUILD(r, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 1034 CHECK_EQ(33, r.Call(as64(133), as64(100))); |
| 1035 CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), as64(-1))); |
| 1036 CHECK_TRAP64(r.Call(as64(100), as64(0))); |
| 1037 CHECK_TRAP64(r.Call(as64(-1001), as64(0))); |
| 1038 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0))); |
| 1039 } |
| 1040 |
| 1041 TEST(Run_WASM_I64DivU_trap) { |
| 1042 REQUIRE(I64DivU); |
| 1043 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
| 1044 BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 1045 CHECK_EQ(0, r.Call(as64(0), as64(100))); |
| 1046 CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), as64(-1))); |
| 1047 CHECK_TRAP64(r.Call(as64(100), as64(0))); |
| 1048 CHECK_TRAP64(r.Call(as64(-1001), as64(0))); |
| 1049 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0))); |
| 1050 } |
| 1051 |
| 1052 TEST(Run_WASM_I64RemU_trap) { |
| 1053 REQUIRE(I64RemU); |
| 1054 WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); |
| 1055 BUILD(r, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 1056 CHECK_EQ(17, r.Call(as64(217), as64(100))); |
| 1057 CHECK_TRAP64(r.Call(as64(100), as64(0))); |
| 1058 CHECK_TRAP64(r.Call(as64(-1001), as64(0))); |
| 1059 CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0))); |
| 1060 CHECK_EQ(std::numeric_limits<int64_t>::min(), |
| 1061 r.Call(std::numeric_limits<int64_t>::min(), as64(-1))); |
| 1062 } |
| 1063 |
| 1064 TEST(Run_WASM_I64DivS_byzero_const) { |
| 1065 REQUIRE(I64DivS); |
| 1066 for (int8_t denom = -2; denom < 8; denom++) { |
| 1067 WasmRunner<int64_t> r(MachineType::Int64()); |
| 1068 BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64V_1(denom))); |
| 1069 for (int64_t val = -7; val < 8; val++) { |
| 1070 if (denom == 0) { |
| 1071 CHECK_TRAP64(r.Call(val)); |
| 1072 } else { |
| 1073 CHECK_EQ(val / denom, r.Call(val)); |
| 1074 } |
| 1075 } |
| 1076 } |
| 1077 } |
| 1078 |
| 1079 TEST(Run_WASM_I64DivU_byzero_const) { |
| 1080 REQUIRE(I64DivU); |
| 1081 for (uint64_t denom = 0xfffffffffffffffe; denom < 8; denom++) { |
| 1082 WasmRunner<uint64_t> r(MachineType::Uint64()); |
| 1083 BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64V_1(denom))); |
| 1084 |
| 1085 for (uint64_t val = 0xfffffffffffffff0; val < 8; val++) { |
| 1086 if (denom == 0) { |
| 1087 CHECK_TRAP64(r.Call(val)); |
| 1088 } else { |
| 1089 CHECK_EQ(val / denom, r.Call(val)); |
| 1090 } |
| 1091 } |
| 1092 } |
| 1093 } |
| 1094 |
| 1095 TEST(Run_Wasm_F64ReinterpretI64) { |
| 1096 REQUIRE(F64ReinterpretI64); |
| 1097 TestingModule module; |
| 1098 int64_t* memory = module.AddMemoryElems<int64_t>(8); |
| 1099 WasmRunner<int64_t> r(&module); |
| 1100 |
| 1101 BUILD(r, WASM_I64_REINTERPRET_F64( |
| 1102 WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO))); |
| 1103 |
| 1104 FOR_INT32_INPUTS(i) { |
| 1105 int64_t expected = static_cast<int64_t>(*i) * 0x300010001; |
| 1106 memory[0] = expected; |
| 1107 CHECK_EQ(expected, r.Call()); |
| 1108 } |
| 1109 } |
| 1110 |
| 1111 TEST(Run_Wasm_I64ReinterpretF64) { |
| 1112 REQUIRE(I64ReinterpretF64); |
| 1113 TestingModule module; |
| 1114 int64_t* memory = module.AddMemoryElems<int64_t>(8); |
| 1115 WasmRunner<int64_t> r(&module, MachineType::Int64()); |
| 1116 |
| 1117 BUILD(r, WASM_BLOCK( |
| 1118 2, WASM_STORE_MEM(MachineType::Float64(), WASM_ZERO, |
| 1119 WASM_F64_REINTERPRET_I64(WASM_GET_LOCAL(0))), |
| 1120 WASM_GET_LOCAL(0))); |
| 1121 |
| 1122 FOR_INT32_INPUTS(i) { |
| 1123 int64_t expected = static_cast<int64_t>(*i) * 0x300010001; |
| 1124 CHECK_EQ(expected, r.Call(expected)); |
| 1125 CHECK_EQ(expected, memory[0]); |
| 1126 } |
| 1127 } |
| 1128 |
| 1129 TEST(Run_Wasm_LoadMemI64) { |
| 1130 REQUIRE(I64LoadStore); |
| 1131 TestingModule module; |
| 1132 int64_t* memory = module.AddMemoryElems<int64_t>(8); |
| 1133 module.RandomizeMemory(1111); |
| 1134 WasmRunner<int64_t> r(&module); |
| 1135 |
| 1136 BUILD(r, WASM_LOAD_MEM(MachineType::Int64(), WASM_I8(0))); |
| 1137 |
| 1138 memory[0] = 0xaabbccdd00112233LL; |
| 1139 CHECK_EQ(0xaabbccdd00112233LL, r.Call()); |
| 1140 |
| 1141 memory[0] = 0x33aabbccdd001122LL; |
| 1142 CHECK_EQ(0x33aabbccdd001122LL, r.Call()); |
| 1143 |
| 1144 memory[0] = 77777777; |
| 1145 CHECK_EQ(77777777, r.Call()); |
| 1146 } |
| 1147 |
| 1148 TEST(Run_Wasm_MemI64_Sum) { |
| 1149 REQUIRE(I64LoadStore); |
| 1150 REQUIRE(I64Add); |
| 1151 REQUIRE(I64Sub); |
| 1152 const int kNumElems = 20; |
| 1153 TestingModule module; |
| 1154 uint64_t* memory = module.AddMemoryElems<uint64_t>(kNumElems); |
| 1155 WasmRunner<uint64_t> r(&module, MachineType::Int32()); |
| 1156 const byte kSum = r.AllocateLocal(kAstI64); |
| 1157 |
| 1158 BUILD(r, WASM_BLOCK( |
| 1159 2, WASM_WHILE( |
| 1160 WASM_GET_LOCAL(0), |
| 1161 WASM_BLOCK( |
| 1162 2, WASM_SET_LOCAL( |
| 1163 kSum, WASM_I64_ADD( |
| 1164 WASM_GET_LOCAL(kSum), |
| 1165 WASM_LOAD_MEM(MachineType::Int64(), |
| 1166 WASM_GET_LOCAL(0)))), |
| 1167 WASM_SET_LOCAL( |
| 1168 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(8))))), |
| 1169 WASM_GET_LOCAL(1))); |
| 1170 |
| 1171 // Run 4 trials. |
| 1172 for (int i = 0; i < 3; i++) { |
| 1173 module.RandomizeMemory(i * 33); |
| 1174 uint64_t expected = 0; |
| 1175 for (size_t j = kNumElems - 1; j > 0; j--) { |
| 1176 expected += memory[j]; |
| 1177 } |
| 1178 uint64_t result = r.Call(8 * (kNumElems - 1)); |
| 1179 CHECK_EQ(expected, result); |
| 1180 } |
| 1181 } |
| 1182 |
| 1183 TEST(Run_Wasm_I64Global) { |
| 1184 REQUIRE(I64LoadStore); |
| 1185 REQUIRE(I64SConvertI32); |
| 1186 REQUIRE(I64And); |
| 1187 REQUIRE(DepthFirst); // TODO(titzer): temporary hack |
| 1188 TestingModule module; |
| 1189 int64_t* global = module.AddGlobal<int64_t>(MachineType::Int64()); |
| 1190 WasmRunner<int32_t> r(&module, MachineType::Int32()); |
| 1191 // global = global + p0 |
| 1192 BUILD(r, B2(WASM_STORE_GLOBAL( |
| 1193 0, WASM_I64_AND(WASM_LOAD_GLOBAL(0), |
| 1194 WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0)))), |
| 1195 WASM_ZERO)); |
| 1196 |
| 1197 *global = 0xFFFFFFFFFFFFFFFFLL; |
| 1198 for (int i = 9; i < 444444; i += 111111) { |
| 1199 int64_t expected = *global & i; |
| 1200 r.Call(i); |
| 1201 CHECK_EQ(expected, *global); |
| 1202 } |
| 1203 } |
OLD | NEW |