1 // Copyright 2014 the V8 project authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file.
4
5 #include "src/codegen/external-reference.h"
6 #include "src/objects/objects-inl.h"
7 #include "test/cctest/cctest.h"
8 #include "test/cctest/compiler/codegen-tester.h"
9 #include "test/cctest/compiler/value-helper.h"
10
11 #if V8_ENABLE_WEBASSEMBLY
12 #include "src/wasm/wasm-external-refs.h"
13 #endif // V8_ENABLE_WEBASSEMBLY
14
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18
19 template <typename InType, typename OutType, typename Iterable>
TestExternalReference_ConvertOp(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,void (* wrapper)(Address),Iterable inputs)20 void TestExternalReference_ConvertOp(
21 BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
22 void (*wrapper)(Address), Iterable inputs) {
23 constexpr size_t kBufferSize = std::max(sizeof(InType), sizeof(OutType));
24 uint8_t buffer[kBufferSize] = {0};
25 Address buffer_addr = reinterpret_cast<Address>(buffer);
26
27 Node* function = m->ExternalConstant(ref);
28 m->CallCFunction(
29 function, MachineType::Pointer(),
30 std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer)));
31 m->Return(m->Int32Constant(4356));
32
33 for (InType input : inputs) {
34 WriteUnalignedValue<InType>(buffer_addr, input);
35
36 CHECK_EQ(4356, m->Call());
37 OutType output = ReadUnalignedValue<OutType>(buffer_addr);
38
39 WriteUnalignedValue<InType>(buffer_addr, input);
40 wrapper(buffer_addr);
41 OutType expected_output = ReadUnalignedValue<OutType>(buffer_addr);
42
43 CHECK_EQ(expected_output, output);
44 }
45 }
46
47 template <typename InType, typename OutType, typename Iterable>
TestExternalReference_ConvertOpWithOutputAndReturn(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,int32_t (* wrapper)(Address),Iterable inputs)48 void TestExternalReference_ConvertOpWithOutputAndReturn(
49 BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
50 int32_t (*wrapper)(Address), Iterable inputs) {
51 constexpr size_t kBufferSize = std::max(sizeof(InType), sizeof(OutType));
52 uint8_t buffer[kBufferSize] = {0};
53 Address buffer_addr = reinterpret_cast<Address>(buffer);
54
55 Node* function = m->ExternalConstant(ref);
56 m->Return(m->CallCFunction(
57 function, MachineType::Int32(),
58 std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer))));
59
60 for (InType input : inputs) {
61 WriteUnalignedValue<InType>(buffer_addr, input);
62
63 int32_t ret = m->Call();
64 OutType output = ReadUnalignedValue<OutType>(buffer_addr);
65
66 WriteUnalignedValue<InType>(buffer_addr, input);
67 int32_t expected_ret = wrapper(buffer_addr);
68 OutType expected_output = ReadUnalignedValue<OutType>(buffer_addr);
69
70 CHECK_EQ(expected_ret, ret);
71 CHECK_EQ(expected_output, output);
72 }
73 }
74
75 template <typename InType, typename OutType, typename Iterable>
TestExternalReference_ConvertOpWithReturn(BufferedRawMachineAssemblerTester<OutType> * m,ExternalReference ref,OutType (* wrapper)(Address),Iterable inputs)76 void TestExternalReference_ConvertOpWithReturn(
77 BufferedRawMachineAssemblerTester<OutType>* m, ExternalReference ref,
78 OutType (*wrapper)(Address), Iterable inputs) {
79 constexpr size_t kBufferSize = sizeof(InType);
80 uint8_t buffer[kBufferSize] = {0};
81 Address buffer_addr = reinterpret_cast<Address>(buffer);
82
83 Node* function = m->ExternalConstant(ref);
84 m->Return(m->CallCFunction(
85 function, MachineType::Int32(),
86 std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer))));
87
88 for (InType input : inputs) {
89 WriteUnalignedValue<InType>(buffer_addr, input);
90
91 OutType ret = m->Call();
92
93 WriteUnalignedValue<InType>(buffer_addr, input);
94 OutType expected_ret = wrapper(buffer_addr);
95
96 CHECK_EQ(expected_ret, ret);
97 }
98 }
99
100 template <typename Type>
isnan(Type value)101 bool isnan(Type value) {
102 return false;
103 }
104 template <>
isnan(float value)105 bool isnan<float>(float value) {
106 return std::isnan(value);
107 }
108 template <>
isnan(double value)109 bool isnan<double>(double value) {
110 return std::isnan(value);
111 }
112
113 template <typename Type, typename Iterable>
TestExternalReference_UnOp(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,void (* wrapper)(Address),Iterable inputs)114 void TestExternalReference_UnOp(BufferedRawMachineAssemblerTester<int32_t>* m,
115 ExternalReference ref, void (*wrapper)(Address),
116 Iterable inputs) {
117 constexpr size_t kBufferSize = sizeof(Type);
118 uint8_t buffer[kBufferSize] = {0};
119 Address buffer_addr = reinterpret_cast<Address>(buffer);
120
121 Node* function = m->ExternalConstant(ref);
122 m->CallCFunction(
123 function, MachineType::Int32(),
124 std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer)));
125 m->Return(m->Int32Constant(4356));
126
127 for (Type input : inputs) {
128 WriteUnalignedValue<Type>(buffer_addr, input);
129 CHECK_EQ(4356, m->Call());
130 Type output = ReadUnalignedValue<Type>(buffer_addr);
131
132 WriteUnalignedValue<Type>(buffer_addr, input);
133 wrapper(buffer_addr);
134 Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
135
136 if (isnan(expected_output) && isnan(output)) continue;
137 CHECK_EQ(expected_output, output);
138 }
139 }
140
141 template <typename Type, typename Iterable>
TestExternalReference_BinOp(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,void (* wrapper)(Address),Iterable inputs)142 void TestExternalReference_BinOp(BufferedRawMachineAssemblerTester<int32_t>* m,
143 ExternalReference ref,
144 void (*wrapper)(Address), Iterable inputs) {
145 constexpr size_t kBufferSize = 2 * sizeof(Type);
146 uint8_t buffer[kBufferSize] = {0};
147 Address buffer_addr = reinterpret_cast<Address>(buffer);
148
149 Node* function = m->ExternalConstant(ref);
150 m->CallCFunction(
151 function, MachineType::Int32(),
152 std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer)));
153 m->Return(m->Int32Constant(4356));
154
155 for (Type input1 : inputs) {
156 for (Type input2 : inputs) {
157 WriteUnalignedValue<Type>(buffer_addr, input1);
158 WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
159 CHECK_EQ(4356, m->Call());
160 Type output = ReadUnalignedValue<Type>(buffer_addr);
161
162 WriteUnalignedValue<Type>(buffer_addr, input1);
163 WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
164 wrapper(buffer_addr);
165 Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
166
167 if (isnan(expected_output) && isnan(output)) continue;
168 CHECK_EQ(expected_output, output);
169 }
170 }
171 }
172
173 template <typename Type, typename Iterable>
TestExternalReference_BinOpWithReturn(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,int32_t (* wrapper)(Address),Iterable inputs)174 void TestExternalReference_BinOpWithReturn(
175 BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
176 int32_t (*wrapper)(Address), Iterable inputs) {
177 constexpr size_t kBufferSize = 2 * sizeof(Type);
178 uint8_t buffer[kBufferSize] = {0};
179 Address buffer_addr = reinterpret_cast<Address>(buffer);
180
181 Node* function = m->ExternalConstant(ref);
182 m->Return(m->CallCFunction(
183 function, MachineType::Int32(),
184 std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer))));
185
186 for (Type input1 : inputs) {
187 for (Type input2 : inputs) {
188 WriteUnalignedValue<Type>(buffer_addr, input1);
189 WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
190 int32_t ret = m->Call();
191 Type output = ReadUnalignedValue<Type>(buffer_addr);
192
193 WriteUnalignedValue<Type>(buffer_addr, input1);
194 WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
195 int32_t expected_ret = wrapper(buffer_addr);
196 Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
197
198 CHECK_EQ(expected_ret, ret);
199 if (isnan(expected_output) && isnan(output)) continue;
200 CHECK_EQ(expected_output, output);
201 }
202 }
203 }
204
205 #if V8_ENABLE_WEBASSEMBLY
TEST(RunCallF32Trunc)206 TEST(RunCallF32Trunc) {
207 BufferedRawMachineAssemblerTester<int32_t> m;
208 ExternalReference ref = ExternalReference::wasm_f32_trunc();
209 TestExternalReference_UnOp<float>(&m, ref, wasm::f32_trunc_wrapper,
210 ValueHelper::float32_vector());
211 }
212
TEST(RunCallF32Floor)213 TEST(RunCallF32Floor) {
214 BufferedRawMachineAssemblerTester<int32_t> m;
215 ExternalReference ref = ExternalReference::wasm_f32_floor();
216 TestExternalReference_UnOp<float>(&m, ref, wasm::f32_floor_wrapper,
217 ValueHelper::float32_vector());
218 }
219
TEST(RunCallF32Ceil)220 TEST(RunCallF32Ceil) {
221 BufferedRawMachineAssemblerTester<int32_t> m;
222 ExternalReference ref = ExternalReference::wasm_f32_ceil();
223 TestExternalReference_UnOp<float>(&m, ref, wasm::f32_ceil_wrapper,
224 ValueHelper::float32_vector());
225 }
226
TEST(RunCallF32RoundTiesEven)227 TEST(RunCallF32RoundTiesEven) {
228 BufferedRawMachineAssemblerTester<int32_t> m;
229 ExternalReference ref = ExternalReference::wasm_f32_nearest_int();
230 TestExternalReference_UnOp<float>(&m, ref, wasm::f32_nearest_int_wrapper,
231 ValueHelper::float32_vector());
232 }
233
TEST(RunCallF64Trunc)234 TEST(RunCallF64Trunc) {
235 BufferedRawMachineAssemblerTester<int32_t> m;
236 ExternalReference ref = ExternalReference::wasm_f64_trunc();
237 TestExternalReference_UnOp<double>(&m, ref, wasm::f64_trunc_wrapper,
238 ValueHelper::float64_vector());
239 }
240
TEST(RunCallF64Floor)241 TEST(RunCallF64Floor) {
242 BufferedRawMachineAssemblerTester<int32_t> m;
243 ExternalReference ref = ExternalReference::wasm_f64_floor();
244 TestExternalReference_UnOp<double>(&m, ref, wasm::f64_floor_wrapper,
245 ValueHelper::float64_vector());
246 }
247
TEST(RunCallF64Ceil)248 TEST(RunCallF64Ceil) {
249 BufferedRawMachineAssemblerTester<int32_t> m;
250 ExternalReference ref = ExternalReference::wasm_f64_ceil();
251 TestExternalReference_UnOp<double>(&m, ref, wasm::f64_ceil_wrapper,
252 ValueHelper::float64_vector());
253 }
254
TEST(RunCallF64RoundTiesEven)255 TEST(RunCallF64RoundTiesEven) {
256 BufferedRawMachineAssemblerTester<int32_t> m;
257 ExternalReference ref = ExternalReference::wasm_f64_nearest_int();
258 TestExternalReference_UnOp<double>(&m, ref, wasm::f64_nearest_int_wrapper,
259 ValueHelper::float64_vector());
260 }
261
TEST(RunCallInt64ToFloat32)262 TEST(RunCallInt64ToFloat32) {
263 BufferedRawMachineAssemblerTester<int32_t> m;
264 ExternalReference ref = ExternalReference::wasm_int64_to_float32();
265 TestExternalReference_ConvertOp<int64_t, float>(
266 &m, ref, wasm::int64_to_float32_wrapper, ValueHelper::int64_vector());
267 }
268
TEST(RunCallUint64ToFloat32)269 TEST(RunCallUint64ToFloat32) {
270 BufferedRawMachineAssemblerTester<int32_t> m;
271 ExternalReference ref = ExternalReference::wasm_uint64_to_float32();
272 TestExternalReference_ConvertOp<uint64_t, float>(
273 &m, ref, wasm::uint64_to_float32_wrapper, ValueHelper::uint64_vector());
274 }
275
TEST(RunCallInt64ToFloat64)276 TEST(RunCallInt64ToFloat64) {
277 BufferedRawMachineAssemblerTester<int32_t> m;
278 ExternalReference ref = ExternalReference::wasm_int64_to_float64();
279 TestExternalReference_ConvertOp<int64_t, double>(
280 &m, ref, wasm::int64_to_float64_wrapper, ValueHelper::int64_vector());
281 }
282
TEST(RunCallUint64ToFloat64)283 TEST(RunCallUint64ToFloat64) {
284 BufferedRawMachineAssemblerTester<int32_t> m;
285 ExternalReference ref = ExternalReference::wasm_uint64_to_float64();
286 TestExternalReference_ConvertOp<uint64_t, double>(
287 &m, ref, wasm::uint64_to_float64_wrapper, ValueHelper::uint64_vector());
288 }
289
TEST(RunCallFloat32ToInt64)290 TEST(RunCallFloat32ToInt64) {
291 BufferedRawMachineAssemblerTester<int32_t> m;
292 ExternalReference ref = ExternalReference::wasm_float32_to_int64();
293 TestExternalReference_ConvertOpWithOutputAndReturn<float, int64_t>(
294 &m, ref, wasm::float32_to_int64_wrapper, ValueHelper::float32_vector());
295 }
296
TEST(RunCallFloat32ToUint64)297 TEST(RunCallFloat32ToUint64) {
298 BufferedRawMachineAssemblerTester<int32_t> m;
299 ExternalReference ref = ExternalReference::wasm_float32_to_uint64();
300 TestExternalReference_ConvertOpWithOutputAndReturn<float, uint64_t>(
301 &m, ref, wasm::float32_to_uint64_wrapper, ValueHelper::float32_vector());
302 }
303
TEST(RunCallFloat64ToInt64)304 TEST(RunCallFloat64ToInt64) {
305 BufferedRawMachineAssemblerTester<int32_t> m;
306 ExternalReference ref = ExternalReference::wasm_float64_to_int64();
307 TestExternalReference_ConvertOpWithOutputAndReturn<double, int64_t>(
308 &m, ref, wasm::float64_to_int64_wrapper, ValueHelper::float64_vector());
309 }
310
TEST(RunCallFloat64ToUint64)311 TEST(RunCallFloat64ToUint64) {
312 BufferedRawMachineAssemblerTester<int32_t> m;
313 ExternalReference ref = ExternalReference::wasm_float64_to_uint64();
314 TestExternalReference_ConvertOpWithOutputAndReturn<double, uint64_t>(
315 &m, ref, wasm::float64_to_uint64_wrapper, ValueHelper::float64_vector());
316 }
317
TEST(RunCallInt64Div)318 TEST(RunCallInt64Div) {
319 BufferedRawMachineAssemblerTester<int32_t> m;
320 ExternalReference ref = ExternalReference::wasm_int64_div();
321 TestExternalReference_BinOpWithReturn<int64_t>(
322 &m, ref, wasm::int64_div_wrapper, ValueHelper::int64_vector());
323 }
324
TEST(RunCallInt64Mod)325 TEST(RunCallInt64Mod) {
326 BufferedRawMachineAssemblerTester<int32_t> m;
327 ExternalReference ref = ExternalReference::wasm_int64_mod();
328 TestExternalReference_BinOpWithReturn<int64_t>(
329 &m, ref, wasm::int64_mod_wrapper, ValueHelper::int64_vector());
330 }
331
TEST(RunCallUint64Div)332 TEST(RunCallUint64Div) {
333 BufferedRawMachineAssemblerTester<int32_t> m;
334 ExternalReference ref = ExternalReference::wasm_uint64_div();
335 TestExternalReference_BinOpWithReturn<uint64_t>(
336 &m, ref, wasm::uint64_div_wrapper, ValueHelper::uint64_vector());
337 }
338
TEST(RunCallUint64Mod)339 TEST(RunCallUint64Mod) {
340 BufferedRawMachineAssemblerTester<int32_t> m;
341 ExternalReference ref = ExternalReference::wasm_uint64_mod();
342 TestExternalReference_BinOpWithReturn<uint64_t>(
343 &m, ref, wasm::uint64_mod_wrapper, ValueHelper::uint64_vector());
344 }
345
TEST(RunCallWord32Ctz)346 TEST(RunCallWord32Ctz) {
347 BufferedRawMachineAssemblerTester<uint32_t> m;
348 ExternalReference ref = ExternalReference::wasm_word32_ctz();
349 TestExternalReference_ConvertOpWithReturn<int32_t, uint32_t>(
350 &m, ref, wasm::word32_ctz_wrapper, ValueHelper::int32_vector());
351 }
352
TEST(RunCallWord64Ctz)353 TEST(RunCallWord64Ctz) {
354 BufferedRawMachineAssemblerTester<uint32_t> m;
355 ExternalReference ref = ExternalReference::wasm_word64_ctz();
356 TestExternalReference_ConvertOpWithReturn<int64_t, uint32_t>(
357 &m, ref, wasm::word64_ctz_wrapper, ValueHelper::int64_vector());
358 }
359
TEST(RunCallWord32Popcnt)360 TEST(RunCallWord32Popcnt) {
361 BufferedRawMachineAssemblerTester<uint32_t> m;
362 ExternalReference ref = ExternalReference::wasm_word32_popcnt();
363 TestExternalReference_ConvertOpWithReturn<uint32_t, uint32_t>(
364 &m, ref, wasm::word32_popcnt_wrapper, ValueHelper::int32_vector());
365 }
366
TEST(RunCallWord64Popcnt)367 TEST(RunCallWord64Popcnt) {
368 BufferedRawMachineAssemblerTester<uint32_t> m;
369 ExternalReference ref = ExternalReference::wasm_word64_popcnt();
370 TestExternalReference_ConvertOpWithReturn<int64_t, uint32_t>(
371 &m, ref, wasm::word64_popcnt_wrapper, ValueHelper::int64_vector());
372 }
373
TEST(RunCallFloat64Pow)374 TEST(RunCallFloat64Pow) {
375 BufferedRawMachineAssemblerTester<int32_t> m;
376 ExternalReference ref = ExternalReference::wasm_float64_pow();
377 TestExternalReference_BinOp<double>(&m, ref, wasm::float64_pow_wrapper,
378 ValueHelper::float64_vector());
379 }
380 #endif // V8_ENABLE_WEBASSEMBLY
381
382 #ifdef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
383
384 template <typename T>
MachineTypeForCType()385 MachineType MachineTypeForCType() {
386 UNREACHABLE();
387 }
388
389 template <>
MachineTypeForCType()390 MachineType MachineTypeForCType<int32_t>() {
391 return MachineType::Int32();
392 }
393
394 template <>
MachineTypeForCType()395 MachineType MachineTypeForCType<double>() {
396 return MachineType::Float64();
397 }
398
399 template <>
MachineTypeForCType()400 MachineType MachineTypeForCType<float>() {
401 return MachineType::Float32();
402 }
403
404 #define SIGNATURE_TYPES_END(TYPE, IDX, VALUE) MachineTypeForCType<TYPE>()
405 #define SIGNATURE_TYPES(TYPE, IDX, VALUE) SIGNATURE_TYPES_END(TYPE, IDX, VALUE),
406
407 #define PARAM_PAIRS_END(TYPE, IDX, VALUE) \
408 std::make_pair(MachineTypeForCType<TYPE>(), m.Parameter(IDX))
409
410 #define PARAM_PAIRS(TYPE, IDX, VALUE) PARAM_PAIRS_END(TYPE, IDX, VALUE),
411
412 #define CALL_ARGS_END(TYPE, IDX, VALUE) static_cast<TYPE>(VALUE)
413 #define CALL_ARGS(TYPE, IDX, VALUE) CALL_ARGS_END(TYPE, IDX, VALUE),
414
415 #define COMPARE_ARG_I_END(TYPE, IDX, VALUE) (arg##IDX == VALUE)
416 #define COMPARE_ARG_I(TYPE, IDX, VALUE) COMPARE_ARG_I_END(TYPE, IDX, VALUE)&&
417
418 #define SIGNATURE_TEST(NAME, SIGNATURE, FUNC) \
419 TEST(NAME) { \
420 RawMachineAssemblerTester<int64_t> m(SIGNATURE(SIGNATURE_TYPES)); \
421 \
422 Address func_address = FUNCTION_ADDR(&FUNC); \
423 ExternalReference::Type dummy_type = ExternalReference::BUILTIN_CALL; \
424 ApiFunction func(func_address); \
425 ExternalReference ref = ExternalReference::Create(&func, dummy_type); \
426 \
427 Node* function = m.ExternalConstant(ref); \
428 m.Return(m.CallCFunction(function, MachineType::Int64(), \
429 SIGNATURE(PARAM_PAIRS))); \
430 \
431 int64_t c = m.Call(SIGNATURE(CALL_ARGS)); \
432 CHECK_EQ(c, 42); \
433 }
434
435 #define MIXED_SIGNATURE_SIMPLE(V) \
436 V(int32_t, 0, 0) \
437 V(double, 1, 1.5) \
438 V##_END(int32_t, 2, 2)
439
test_api_func_simple(int32_t arg0,double arg1,int32_t arg2)440 int64_t test_api_func_simple(int32_t arg0, double arg1, int32_t arg2) {
441 CHECK(MIXED_SIGNATURE_SIMPLE(COMPARE_ARG_I));
442 return 42;
443 }
444
SIGNATURE_TEST(RunCallWithMixedSignatureSimple,MIXED_SIGNATURE_SIMPLE,test_api_func_simple)445 SIGNATURE_TEST(RunCallWithMixedSignatureSimple, MIXED_SIGNATURE_SIMPLE,
446 test_api_func_simple)
447
448 #define MIXED_SIGNATURE(V) \
449 V(int32_t, 0, 0) \
450 V(double, 1, 1.5) \
451 V(int32_t, 2, 2) \
452 V(double, 3, 3.5) \
453 V(int32_t, 4, 4) \
454 V(double, 5, 5.5) \
455 V(int32_t, 6, 6) \
456 V(double, 7, 7.5) \
457 V(int32_t, 8, 8) \
458 V(double, 9, 9.5) \
459 V##_END(int32_t, 10, 10)
460
461 int64_t test_api_func(int32_t arg0, double arg1, int32_t arg2, double arg3,
462 int32_t arg4, double arg5, int32_t arg6, double arg7,
463 int32_t arg8, double arg9, int32_t arg10) {
464 CHECK(MIXED_SIGNATURE(COMPARE_ARG_I));
465 return 42;
466 }
467
SIGNATURE_TEST(RunCallWithMixedSignature,MIXED_SIGNATURE,test_api_func)468 SIGNATURE_TEST(RunCallWithMixedSignature, MIXED_SIGNATURE, test_api_func)
469
470 #define MIXED_SIGNATURE_DOUBLE_INT(V) \
471 V(double, 0, 0.5) \
472 V(double, 1, 1.5) \
473 V(double, 2, 2.5) \
474 V(double, 3, 3.5) \
475 V(double, 4, 4.5) \
476 V(double, 5, 5.5) \
477 V(double, 6, 6.5) \
478 V(double, 7, 7.5) \
479 V(double, 8, 8.5) \
480 V(double, 9, 9.5) \
481 V(int32_t, 10, 10) \
482 V(int32_t, 11, 11) \
483 V(int32_t, 12, 12) \
484 V(int32_t, 13, 13) \
485 V(int32_t, 14, 14) \
486 V(int32_t, 15, 15) \
487 V(int32_t, 16, 16) \
488 V(int32_t, 17, 17) \
489 V(int32_t, 18, 18) \
490 V##_END(int32_t, 19, 19)
491
492 int64_t func_mixed_double_int(double arg0, double arg1, double arg2,
493 double arg3, double arg4, double arg5,
494 double arg6, double arg7, double arg8,
495 double arg9, int32_t arg10, int32_t arg11,
496 int32_t arg12, int32_t arg13, int32_t arg14,
497 int32_t arg15, int32_t arg16, int32_t arg17,
498 int32_t arg18, int32_t arg19) {
499 CHECK(MIXED_SIGNATURE_DOUBLE_INT(COMPARE_ARG_I));
500 return 42;
501 }
502
SIGNATURE_TEST(RunCallWithMixedSignatureDoubleInt,MIXED_SIGNATURE_DOUBLE_INT,func_mixed_double_int)503 SIGNATURE_TEST(RunCallWithMixedSignatureDoubleInt, MIXED_SIGNATURE_DOUBLE_INT,
504 func_mixed_double_int)
505
506 #define MIXED_SIGNATURE_INT_DOUBLE(V) \
507 V(int32_t, 0, 0) \
508 V(int32_t, 1, 1) \
509 V(int32_t, 2, 2) \
510 V(int32_t, 3, 3) \
511 V(int32_t, 4, 4) \
512 V(int32_t, 5, 5) \
513 V(int32_t, 6, 6) \
514 V(int32_t, 7, 7) \
515 V(int32_t, 8, 8) \
516 V(int32_t, 9, 9) \
517 V(double, 10, 10.5) \
518 V(double, 11, 11.5) \
519 V(double, 12, 12.5) \
520 V(double, 13, 13.5) \
521 V(double, 14, 14.5) \
522 V(double, 15, 15.5) \
523 V(double, 16, 16.5) \
524 V(double, 17, 17.5) \
525 V(double, 18, 18.5) \
526 V##_END(double, 19, 19.5)
527
528 int64_t func_mixed_int_double(int32_t arg0, int32_t arg1, int32_t arg2,
529 int32_t arg3, int32_t arg4, int32_t arg5,
530 int32_t arg6, int32_t arg7, int32_t arg8,
531 int32_t arg9, double arg10, double arg11,
532 double arg12, double arg13, double arg14,
533 double arg15, double arg16, double arg17,
534 double arg18, double arg19) {
535 CHECK(MIXED_SIGNATURE_INT_DOUBLE(COMPARE_ARG_I));
536 return 42;
537 }
538
SIGNATURE_TEST(RunCallWithMixedSignatureIntDouble,MIXED_SIGNATURE_INT_DOUBLE,func_mixed_int_double)539 SIGNATURE_TEST(RunCallWithMixedSignatureIntDouble, MIXED_SIGNATURE_INT_DOUBLE,
540 func_mixed_int_double)
541
542 #define MIXED_SIGNATURE_INT_DOUBLE_ALT(V) \
543 V(int32_t, 0, 0) \
544 V(double, 1, 1.5) \
545 V(int32_t, 2, 2) \
546 V(double, 3, 3.5) \
547 V(int32_t, 4, 4) \
548 V(double, 5, 5.5) \
549 V(int32_t, 6, 6) \
550 V(double, 7, 7.5) \
551 V(int32_t, 8, 8) \
552 V(double, 9, 9.5) \
553 V(int32_t, 10, 10) \
554 V(double, 11, 11.5) \
555 V(int32_t, 12, 12) \
556 V(double, 13, 13.5) \
557 V(int32_t, 14, 14) \
558 V(double, 15, 15.5) \
559 V(int32_t, 16, 16) \
560 V(double, 17, 17.5) \
561 V(int32_t, 18, 18) \
562 V##_END(double, 19, 19.5)
563
564 int64_t func_mixed_int_double_alt(int32_t arg0, double arg1, int32_t arg2,
565 double arg3, int32_t arg4, double arg5,
566 int32_t arg6, double arg7, int32_t arg8,
567 double arg9, int32_t arg10, double arg11,
568 int32_t arg12, double arg13, int32_t arg14,
569 double arg15, int32_t arg16, double arg17,
570 int32_t arg18, double arg19) {
571 CHECK(MIXED_SIGNATURE_INT_DOUBLE_ALT(COMPARE_ARG_I));
572 return 42;
573 }
574
SIGNATURE_TEST(RunCallWithMixedSignatureIntDoubleAlt,MIXED_SIGNATURE_INT_DOUBLE_ALT,func_mixed_int_double_alt)575 SIGNATURE_TEST(RunCallWithMixedSignatureIntDoubleAlt,
576 MIXED_SIGNATURE_INT_DOUBLE_ALT, func_mixed_int_double_alt)
577
578 #define SIGNATURE_ONLY_DOUBLE(V) \
579 V(double, 0, 0.5) \
580 V(double, 1, 1.5) \
581 V(double, 2, 2.5) \
582 V(double, 3, 3.5) \
583 V(double, 4, 4.5) \
584 V(double, 5, 5.5) \
585 V(double, 6, 6.5) \
586 V(double, 7, 7.5) \
587 V(double, 8, 8.5) \
588 V##_END(double, 9, 9.5)
589
590 int64_t func_only_double(double arg0, double arg1, double arg2, double arg3,
591 double arg4, double arg5, double arg6, double arg7,
592 double arg8, double arg9) {
593 CHECK(SIGNATURE_ONLY_DOUBLE(COMPARE_ARG_I));
594 return 42;
595 }
596
SIGNATURE_TEST(RunCallWithSignatureOnlyDouble,SIGNATURE_ONLY_DOUBLE,func_only_double)597 SIGNATURE_TEST(RunCallWithSignatureOnlyDouble, SIGNATURE_ONLY_DOUBLE,
598 func_only_double)
599
600 #define SIGNATURE_ONLY_DOUBLE_20(V) \
601 V(double, 0, 0.5) \
602 V(double, 1, 1.5) \
603 V(double, 2, 2.5) \
604 V(double, 3, 3.5) \
605 V(double, 4, 4.5) \
606 V(double, 5, 5.5) \
607 V(double, 6, 6.5) \
608 V(double, 7, 7.5) \
609 V(double, 8, 8.5) \
610 V(double, 9, 9.5) \
611 V(double, 10, 10.5) \
612 V(double, 11, 11.5) \
613 V(double, 12, 12.5) \
614 V(double, 13, 13.5) \
615 V(double, 14, 14.5) \
616 V(double, 15, 15.5) \
617 V(double, 16, 16.5) \
618 V(double, 17, 17.5) \
619 V(double, 18, 18.5) \
620 V##_END(double, 19, 19.5)
621
622 int64_t func_only_double_20(double arg0, double arg1, double arg2, double arg3,
623 double arg4, double arg5, double arg6, double arg7,
624 double arg8, double arg9, double arg10,
625 double arg11, double arg12, double arg13,
626 double arg14, double arg15, double arg16,
627 double arg17, double arg18, double arg19) {
628 CHECK(SIGNATURE_ONLY_DOUBLE_20(COMPARE_ARG_I));
629 return 42;
630 }
631
SIGNATURE_TEST(RunCallWithSignatureOnlyDouble20,SIGNATURE_ONLY_DOUBLE_20,func_only_double_20)632 SIGNATURE_TEST(RunCallWithSignatureOnlyDouble20, SIGNATURE_ONLY_DOUBLE_20,
633 func_only_double_20)
634
635 #define SIGNATURE_ONLY_INT(V) \
636 V(int32_t, 0, 0) \
637 V(int32_t, 1, 1) \
638 V(int32_t, 2, 2) \
639 V(int32_t, 3, 3) \
640 V(int32_t, 4, 4) \
641 V(int32_t, 5, 5) \
642 V(int32_t, 6, 6) \
643 V(int32_t, 7, 7) \
644 V(int32_t, 8, 8) \
645 V##_END(int32_t, 9, 9)
646
647 int64_t func_only_int(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3,
648 int32_t arg4, int32_t arg5, int32_t arg6, int32_t arg7,
649 int32_t arg8, int32_t arg9) {
650 CHECK(SIGNATURE_ONLY_INT(COMPARE_ARG_I));
651 return 42;
652 }
653
SIGNATURE_TEST(RunCallWithSignatureOnlyInt,SIGNATURE_ONLY_INT,func_only_int)654 SIGNATURE_TEST(RunCallWithSignatureOnlyInt, SIGNATURE_ONLY_INT, func_only_int)
655
656 #define SIGNATURE_ONLY_INT_20(V) \
657 V(int32_t, 0, 0) \
658 V(int32_t, 1, 1) \
659 V(int32_t, 2, 2) \
660 V(int32_t, 3, 3) \
661 V(int32_t, 4, 4) \
662 V(int32_t, 5, 5) \
663 V(int32_t, 6, 6) \
664 V(int32_t, 7, 7) \
665 V(int32_t, 8, 8) \
666 V(int32_t, 9, 9) \
667 V(int32_t, 10, 10) \
668 V(int32_t, 11, 11) \
669 V(int32_t, 12, 12) \
670 V(int32_t, 13, 13) \
671 V(int32_t, 14, 14) \
672 V(int32_t, 15, 15) \
673 V(int32_t, 16, 16) \
674 V(int32_t, 17, 17) \
675 V(int32_t, 18, 18) \
676 V##_END(int32_t, 19, 19)
677
678 int64_t func_only_int_20(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3,
679 int32_t arg4, int32_t arg5, int32_t arg6, int32_t arg7,
680 int32_t arg8, int32_t arg9, int32_t arg10,
681 int32_t arg11, int32_t arg12, int32_t arg13,
682 int32_t arg14, int32_t arg15, int32_t arg16,
683 int32_t arg17, int32_t arg18, int32_t arg19) {
684 CHECK(SIGNATURE_ONLY_INT_20(COMPARE_ARG_I));
685 return 42;
686 }
687
SIGNATURE_TEST(RunCallWithSignatureOnlyInt20,SIGNATURE_ONLY_INT_20,func_only_int_20)688 SIGNATURE_TEST(RunCallWithSignatureOnlyInt20, SIGNATURE_ONLY_INT_20,
689 func_only_int_20)
690
691 #define MIXED_SIGNATURE_SIMPLE_FLOAT(V) \
692 V(int32_t, 0, 0) \
693 V(float, 1, 1.5) \
694 V##_END(int32_t, 2, 2)
695
696 int64_t test_api_func_simple_float(int32_t arg0, float arg1, int32_t arg2) {
697 CHECK(MIXED_SIGNATURE_SIMPLE_FLOAT(COMPARE_ARG_I));
698 return 42;
699 }
700
SIGNATURE_TEST(RunCallWithMixedSignatureSimpleFloat,MIXED_SIGNATURE_SIMPLE_FLOAT,test_api_func_simple_float)701 SIGNATURE_TEST(RunCallWithMixedSignatureSimpleFloat,
702 MIXED_SIGNATURE_SIMPLE_FLOAT, test_api_func_simple_float)
703
704 #define MIXED_SIGNATURE_FLOAT(V) \
705 V(int32_t, 0, 0) \
706 V(float, 1, 1.5) \
707 V(int32_t, 2, 2) \
708 V(float, 3, 3.5) \
709 V(int32_t, 4, 4) \
710 V(float, 5, 5.5) \
711 V(int32_t, 6, 6) \
712 V(float, 7, 7.5) \
713 V(int32_t, 8, 8) \
714 V(float, 9, 9.5) \
715 V##_END(int32_t, 10, 10)
716
717 int64_t test_api_func_float(int32_t arg0, float arg1, int32_t arg2, float arg3,
718 int32_t arg4, float arg5, int32_t arg6, float arg7,
719 int32_t arg8, float arg9, int32_t arg10) {
720 CHECK(MIXED_SIGNATURE_FLOAT(COMPARE_ARG_I));
721 return 42;
722 }
723
SIGNATURE_TEST(RunCallWithMixedSignatureFloat,MIXED_SIGNATURE_FLOAT,test_api_func_float)724 SIGNATURE_TEST(RunCallWithMixedSignatureFloat, MIXED_SIGNATURE_FLOAT,
725 test_api_func_float)
726
727 #define MIXED_SIGNATURE_INT_FLOAT_ALT(V) \
728 V(int32_t, 0, 0) \
729 V(float, 1, 1.5) \
730 V(int32_t, 2, 2) \
731 V(float, 3, 3.5) \
732 V(int32_t, 4, 4) \
733 V(float, 5, 5.5) \
734 V(int32_t, 6, 6) \
735 V(float, 7, 7.5) \
736 V(int32_t, 8, 8) \
737 V(float, 9, 9.5) \
738 V(int32_t, 10, 10) \
739 V(float, 11, 11.5) \
740 V(int32_t, 12, 12) \
741 V(float, 13, 13.5) \
742 V(int32_t, 14, 14) \
743 V(float, 15, 15.5) \
744 V(int32_t, 16, 16) \
745 V(float, 17, 17.5) \
746 V(int32_t, 18, 18) \
747 V##_END(float, 19, 19.5)
748
749 int64_t func_mixed_int_float_alt(int32_t arg0, float arg1, int32_t arg2,
750 float arg3, int32_t arg4, float arg5,
751 int32_t arg6, float arg7, int32_t arg8,
752 float arg9, int32_t arg10, float arg11,
753 int32_t arg12, float arg13, int32_t arg14,
754 float arg15, int32_t arg16, float arg17,
755 int32_t arg18, float arg19) {
756 CHECK(MIXED_SIGNATURE_INT_FLOAT_ALT(COMPARE_ARG_I));
757 return 42;
758 }
759
SIGNATURE_TEST(RunCallWithMixedSignatureIntFloatAlt,MIXED_SIGNATURE_INT_FLOAT_ALT,func_mixed_int_float_alt)760 SIGNATURE_TEST(RunCallWithMixedSignatureIntFloatAlt,
761 MIXED_SIGNATURE_INT_FLOAT_ALT, func_mixed_int_float_alt)
762
763 #define SIGNATURE_ONLY_FLOAT_20(V) \
764 V(float, 0, 0.5) \
765 V(float, 1, 1.5) \
766 V(float, 2, 2.5) \
767 V(float, 3, 3.5) \
768 V(float, 4, 4.5) \
769 V(float, 5, 5.5) \
770 V(float, 6, 6.5) \
771 V(float, 7, 7.5) \
772 V(float, 8, 8.5) \
773 V(float, 9, 9.5) \
774 V(float, 10, 10.5) \
775 V(float, 11, 11.5) \
776 V(float, 12, 12.5) \
777 V(float, 13, 13.5) \
778 V(float, 14, 14.5) \
779 V(float, 15, 15.5) \
780 V(float, 16, 16.5) \
781 V(float, 17, 17.5) \
782 V(float, 18, 18.5) \
783 V##_END(float, 19, 19.5)
784
785 int64_t func_only_float_20(float arg0, float arg1, float arg2, float arg3,
786 float arg4, float arg5, float arg6, float arg7,
787 float arg8, float arg9, float arg10, float arg11,
788 float arg12, float arg13, float arg14, float arg15,
789 float arg16, float arg17, float arg18, float arg19) {
790 CHECK(SIGNATURE_ONLY_FLOAT_20(COMPARE_ARG_I));
791 return 42;
792 }
793
SIGNATURE_TEST(RunCallWithSignatureOnlyFloat20,SIGNATURE_ONLY_FLOAT_20,func_only_float_20)794 SIGNATURE_TEST(RunCallWithSignatureOnlyFloat20, SIGNATURE_ONLY_FLOAT_20,
795 func_only_float_20)
796
797 #define MIXED_SIGNATURE_FLOAT_INT(V) \
798 V(float, 0, 0.5) \
799 V(float, 1, 1.5) \
800 V(float, 2, 2.5) \
801 V(float, 3, 3.5) \
802 V(float, 4, 4.5) \
803 V(float, 5, 5.5) \
804 V(float, 6, 6.5) \
805 V(float, 7, 7.5) \
806 V(float, 8, 8.5) \
807 V(float, 9, 9.5) \
808 V(int32_t, 10, 10) \
809 V(int32_t, 11, 11) \
810 V(int32_t, 12, 12) \
811 V(int32_t, 13, 13) \
812 V(int32_t, 14, 14) \
813 V(int32_t, 15, 15) \
814 V(int32_t, 16, 16) \
815 V(int32_t, 17, 17) \
816 V(int32_t, 18, 18) \
817 V##_END(int32_t, 19, 19)
818
819 int64_t func_mixed_float_int(float arg0, float arg1, float arg2, float arg3,
820 float arg4, float arg5, float arg6, float arg7,
821 float arg8, float arg9, int32_t arg10,
822 int32_t arg11, int32_t arg12, int32_t arg13,
823 int32_t arg14, int32_t arg15, int32_t arg16,
824 int32_t arg17, int32_t arg18, int32_t arg19) {
825 CHECK(MIXED_SIGNATURE_FLOAT_INT(COMPARE_ARG_I));
826 return 42;
827 }
828
SIGNATURE_TEST(RunCallWithMixedSignatureFloatInt,MIXED_SIGNATURE_FLOAT_INT,func_mixed_float_int)829 SIGNATURE_TEST(RunCallWithMixedSignatureFloatInt, MIXED_SIGNATURE_FLOAT_INT,
830 func_mixed_float_int)
831
832 #define MIXED_SIGNATURE_INT_FLOAT(V) \
833 V(int32_t, 0, 0) \
834 V(int32_t, 1, 1) \
835 V(int32_t, 2, 2) \
836 V(int32_t, 3, 3) \
837 V(int32_t, 4, 4) \
838 V(int32_t, 5, 5) \
839 V(int32_t, 6, 6) \
840 V(int32_t, 7, 7) \
841 V(int32_t, 8, 8) \
842 V(int32_t, 9, 9) \
843 V(float, 10, 10.5) \
844 V(float, 11, 11.5) \
845 V(float, 12, 12.5) \
846 V(float, 13, 13.5) \
847 V(float, 14, 14.5) \
848 V(float, 15, 15.5) \
849 V(float, 16, 16.5) \
850 V(float, 17, 17.5) \
851 V(float, 18, 18.5) \
852 V##_END(float, 19, 19.5)
853
854 int64_t func_mixed_int_float(int32_t arg0, int32_t arg1, int32_t arg2,
855 int32_t arg3, int32_t arg4, int32_t arg5,
856 int32_t arg6, int32_t arg7, int32_t arg8,
857 int32_t arg9, float arg10, float arg11,
858 float arg12, float arg13, float arg14, float arg15,
859 float arg16, float arg17, float arg18,
860 float arg19) {
861 CHECK(MIXED_SIGNATURE_INT_FLOAT(COMPARE_ARG_I));
862 return 42;
863 }
864
SIGNATURE_TEST(RunCallWithMixedSignatureIntFloat,MIXED_SIGNATURE_INT_FLOAT,func_mixed_int_float)865 SIGNATURE_TEST(RunCallWithMixedSignatureIntFloat, MIXED_SIGNATURE_INT_FLOAT,
866 func_mixed_int_float)
867
868 #define MIXED_SIGNATURE_FLOAT_DOUBLE(V) \
869 V(float, 0, 0.5) \
870 V(float, 1, 1.5) \
871 V(float, 2, 2.5) \
872 V(float, 3, 3.5) \
873 V(float, 4, 4.5) \
874 V(float, 5, 5.5) \
875 V(float, 6, 6.5) \
876 V(float, 7, 7.5) \
877 V(float, 8, 8.5) \
878 V(float, 9, 9.5) \
879 V(double, 10, 10.7) \
880 V(double, 11, 11.7) \
881 V(double, 12, 12.7) \
882 V(double, 13, 13.7) \
883 V(double, 14, 14.7) \
884 V(double, 15, 15.7) \
885 V(double, 16, 16.7) \
886 V(double, 17, 17.7) \
887 V(double, 18, 18.7) \
888 V##_END(double, 19, 19.7)
889
890 int64_t func_mixed_float_double(float arg0, float arg1, float arg2, float arg3,
891 float arg4, float arg5, float arg6, float arg7,
892 float arg8, float arg9, double arg10,
893 double arg11, double arg12, double arg13,
894 double arg14, double arg15, double arg16,
895 double arg17, double arg18, double arg19) {
896 CHECK(MIXED_SIGNATURE_FLOAT_DOUBLE(COMPARE_ARG_I));
897 return 42;
898 }
899
SIGNATURE_TEST(RunCallWithMixedSignatureFloatDouble,MIXED_SIGNATURE_FLOAT_DOUBLE,func_mixed_float_double)900 SIGNATURE_TEST(RunCallWithMixedSignatureFloatDouble,
901 MIXED_SIGNATURE_FLOAT_DOUBLE, func_mixed_float_double)
902
903 #define MIXED_SIGNATURE_DOUBLE_FLOAT(V) \
904 V(double, 0, 0.7) \
905 V(double, 1, 1.7) \
906 V(double, 2, 2.7) \
907 V(double, 3, 3.7) \
908 V(double, 4, 4.7) \
909 V(double, 5, 5.7) \
910 V(double, 6, 6.7) \
911 V(double, 7, 7.7) \
912 V(double, 8, 8.7) \
913 V(double, 9, 9.7) \
914 V(float, 10, 10.5) \
915 V(float, 11, 11.5) \
916 V(float, 12, 12.5) \
917 V(float, 13, 13.5) \
918 V(float, 14, 14.5) \
919 V(float, 15, 15.5) \
920 V(float, 16, 16.5) \
921 V(float, 17, 17.5) \
922 V(float, 18, 18.5) \
923 V##_END(float, 19, 19.5)
924
925 int64_t func_mixed_double_float(double arg0, double arg1, double arg2,
926 double arg3, double arg4, double arg5,
927 double arg6, double arg7, double arg8,
928 double arg9, float arg10, float arg11,
929 float arg12, float arg13, float arg14,
930 float arg15, float arg16, float arg17,
931 float arg18, float arg19) {
932 CHECK(MIXED_SIGNATURE_DOUBLE_FLOAT(COMPARE_ARG_I));
933 return 42;
934 }
935
936 SIGNATURE_TEST(RunCallWithMixedSignatureDoubleFloat,
937 MIXED_SIGNATURE_DOUBLE_FLOAT, func_mixed_double_float)
938
939 #endif // V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
940
941 } // namespace compiler
942 } // namespace internal
943 } // namespace v8
944