blob: cbb631f24e0dbdbbab505bb03b34abc2f0f9ba5f [file] [log] [blame]
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// This file has been automatically generated. Please do not edit it manually.
#include <stddef.h>
#include <stdlib.h>
#include <sys/types.h>
#include <cmath>
#include <iostream>
#include <limits>
#if defined(_WIN32)
#define DART_EXPORT extern "C" __declspec(dllexport)
#else
#define DART_EXPORT \
extern "C" __attribute__((visibility("default"))) __attribute((used))
#endif
namespace dart {
#define CHECK(X) \
if (!(X)) { \
fprintf(stderr, "%s\n", "Check failed: " #X); \
return 1; \
}
#define CHECK_EQ(X, Y) CHECK((X) == (Y))
// Works for positive, negative and zero.
#define CHECK_APPROX(EXPECTED, ACTUAL) \
CHECK(((EXPECTED * 0.99) <= (ACTUAL) && (EXPECTED * 1.01) >= (ACTUAL)) || \
((EXPECTED * 0.99) >= (ACTUAL) && (EXPECTED * 1.01) <= (ACTUAL)))
struct Struct0Bytes {};
struct Struct1ByteInt {
int8_t a0;
};
struct Struct3BytesHomogeneousUint8 {
uint8_t a0;
uint8_t a1;
uint8_t a2;
};
struct Struct3BytesInt2ByteAligned {
int16_t a0;
int8_t a1;
};
struct Struct4BytesHomogeneousInt16 {
int16_t a0;
int16_t a1;
};
struct Struct7BytesHomogeneousUint8 {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
};
struct Struct7BytesInt4ByteAligned {
int32_t a0;
int16_t a1;
int8_t a2;
};
struct Struct8BytesInt {
int16_t a0;
int16_t a1;
int32_t a2;
};
struct Struct8BytesHomogeneousFloat {
float a0;
float a1;
};
struct Struct8BytesMixed {
float a0;
int16_t a1;
int16_t a2;
};
struct Struct9BytesHomogeneousUint8 {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
uint8_t a7;
uint8_t a8;
};
struct Struct9BytesInt4Or8ByteAligned {
int64_t a0;
int8_t a1;
};
struct Struct12BytesHomogeneousFloat {
float a0;
float a1;
float a2;
};
struct Struct16BytesHomogeneousFloat {
float a0;
float a1;
float a2;
float a3;
};
struct Struct16BytesMixed {
double a0;
int64_t a1;
};
struct Struct16BytesMixed2 {
float a0;
float a1;
float a2;
int32_t a3;
};
struct Struct17BytesInt {
int64_t a0;
int64_t a1;
int8_t a2;
};
struct Struct19BytesHomogeneousUint8 {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
uint8_t a7;
uint8_t a8;
uint8_t a9;
uint8_t a10;
uint8_t a11;
uint8_t a12;
uint8_t a13;
uint8_t a14;
uint8_t a15;
uint8_t a16;
uint8_t a17;
uint8_t a18;
};
struct Struct20BytesHomogeneousInt32 {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
};
struct Struct20BytesHomogeneousFloat {
float a0;
float a1;
float a2;
float a3;
float a4;
};
struct Struct32BytesHomogeneousDouble {
double a0;
double a1;
double a2;
double a3;
};
struct Struct40BytesHomogeneousDouble {
double a0;
double a1;
double a2;
double a3;
double a4;
};
struct Struct1024BytesHomogeneousUint64 {
uint64_t a0;
uint64_t a1;
uint64_t a2;
uint64_t a3;
uint64_t a4;
uint64_t a5;
uint64_t a6;
uint64_t a7;
uint64_t a8;
uint64_t a9;
uint64_t a10;
uint64_t a11;
uint64_t a12;
uint64_t a13;
uint64_t a14;
uint64_t a15;
uint64_t a16;
uint64_t a17;
uint64_t a18;
uint64_t a19;
uint64_t a20;
uint64_t a21;
uint64_t a22;
uint64_t a23;
uint64_t a24;
uint64_t a25;
uint64_t a26;
uint64_t a27;
uint64_t a28;
uint64_t a29;
uint64_t a30;
uint64_t a31;
uint64_t a32;
uint64_t a33;
uint64_t a34;
uint64_t a35;
uint64_t a36;
uint64_t a37;
uint64_t a38;
uint64_t a39;
uint64_t a40;
uint64_t a41;
uint64_t a42;
uint64_t a43;
uint64_t a44;
uint64_t a45;
uint64_t a46;
uint64_t a47;
uint64_t a48;
uint64_t a49;
uint64_t a50;
uint64_t a51;
uint64_t a52;
uint64_t a53;
uint64_t a54;
uint64_t a55;
uint64_t a56;
uint64_t a57;
uint64_t a58;
uint64_t a59;
uint64_t a60;
uint64_t a61;
uint64_t a62;
uint64_t a63;
uint64_t a64;
uint64_t a65;
uint64_t a66;
uint64_t a67;
uint64_t a68;
uint64_t a69;
uint64_t a70;
uint64_t a71;
uint64_t a72;
uint64_t a73;
uint64_t a74;
uint64_t a75;
uint64_t a76;
uint64_t a77;
uint64_t a78;
uint64_t a79;
uint64_t a80;
uint64_t a81;
uint64_t a82;
uint64_t a83;
uint64_t a84;
uint64_t a85;
uint64_t a86;
uint64_t a87;
uint64_t a88;
uint64_t a89;
uint64_t a90;
uint64_t a91;
uint64_t a92;
uint64_t a93;
uint64_t a94;
uint64_t a95;
uint64_t a96;
uint64_t a97;
uint64_t a98;
uint64_t a99;
uint64_t a100;
uint64_t a101;
uint64_t a102;
uint64_t a103;
uint64_t a104;
uint64_t a105;
uint64_t a106;
uint64_t a107;
uint64_t a108;
uint64_t a109;
uint64_t a110;
uint64_t a111;
uint64_t a112;
uint64_t a113;
uint64_t a114;
uint64_t a115;
uint64_t a116;
uint64_t a117;
uint64_t a118;
uint64_t a119;
uint64_t a120;
uint64_t a121;
uint64_t a122;
uint64_t a123;
uint64_t a124;
uint64_t a125;
uint64_t a126;
uint64_t a127;
};
struct StructAlignmentInt16 {
int8_t a0;
int16_t a1;
int8_t a2;
};
struct StructAlignmentInt32 {
int8_t a0;
int32_t a1;
int8_t a2;
};
struct StructAlignmentInt64 {
int8_t a0;
int64_t a1;
int8_t a2;
};
// Used for testing structs by value.
// Smallest struct with data.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t PassStruct1ByteIntx10(Struct1ByteInt a0,
Struct1ByteInt a1,
Struct1ByteInt a2,
Struct1ByteInt a3,
Struct1ByteInt a4,
Struct1ByteInt a5,
Struct1ByteInt a6,
Struct1ByteInt a7,
Struct1ByteInt a8,
Struct1ByteInt a9) {
std::cout << "PassStruct1ByteIntx10"
<< "((" << static_cast<int>(a0.a0) << "), ("
<< static_cast<int>(a1.a0) << "), (" << static_cast<int>(a2.a0)
<< "), (" << static_cast<int>(a3.a0) << "), ("
<< static_cast<int>(a4.a0) << "), (" << static_cast<int>(a5.a0)
<< "), (" << static_cast<int>(a6.a0) << "), ("
<< static_cast<int>(a7.a0) << "), (" << static_cast<int>(a8.a0)
<< "), (" << static_cast<int>(a9.a0) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a1.a0;
result += a2.a0;
result += a3.a0;
result += a4.a0;
result += a5.a0;
result += a6.a0;
result += a7.a0;
result += a8.a0;
result += a9.a0;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Not a multiple of word size, not a power of two.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct3BytesHomogeneousUint8x10(Struct3BytesHomogeneousUint8 a0,
Struct3BytesHomogeneousUint8 a1,
Struct3BytesHomogeneousUint8 a2,
Struct3BytesHomogeneousUint8 a3,
Struct3BytesHomogeneousUint8 a4,
Struct3BytesHomogeneousUint8 a5,
Struct3BytesHomogeneousUint8 a6,
Struct3BytesHomogeneousUint8 a7,
Struct3BytesHomogeneousUint8 a8,
Struct3BytesHomogeneousUint8 a9) {
std::cout << "PassStruct3BytesHomogeneousUint8x10"
<< "((" << static_cast<int>(a0.a0) << ", "
<< static_cast<int>(a0.a1) << ", " << static_cast<int>(a0.a2)
<< "), (" << static_cast<int>(a1.a0) << ", "
<< static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< "), (" << static_cast<int>(a2.a0) << ", "
<< static_cast<int>(a2.a1) << ", " << static_cast<int>(a2.a2)
<< "), (" << static_cast<int>(a3.a0) << ", "
<< static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< "), (" << static_cast<int>(a4.a0) << ", "
<< static_cast<int>(a4.a1) << ", " << static_cast<int>(a4.a2)
<< "), (" << static_cast<int>(a5.a0) << ", "
<< static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< "), (" << static_cast<int>(a6.a0) << ", "
<< static_cast<int>(a6.a1) << ", " << static_cast<int>(a6.a2)
<< "), (" << static_cast<int>(a7.a0) << ", "
<< static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< "), (" << static_cast<int>(a8.a0) << ", "
<< static_cast<int>(a8.a1) << ", " << static_cast<int>(a8.a2)
<< "), (" << static_cast<int>(a9.a0) << ", "
<< static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Not a multiple of word size, not a power of two.
// With alignment rules taken into account size is 4 bytes.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct3BytesInt2ByteAlignedx10(Struct3BytesInt2ByteAligned a0,
Struct3BytesInt2ByteAligned a1,
Struct3BytesInt2ByteAligned a2,
Struct3BytesInt2ByteAligned a3,
Struct3BytesInt2ByteAligned a4,
Struct3BytesInt2ByteAligned a5,
Struct3BytesInt2ByteAligned a6,
Struct3BytesInt2ByteAligned a7,
Struct3BytesInt2ByteAligned a8,
Struct3BytesInt2ByteAligned a9) {
std::cout << "PassStruct3BytesInt2ByteAlignedx10"
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
<< a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
<< ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
<< static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
<< static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
<< static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
<< static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
<< static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
<< static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
<< static_cast<int>(a9.a1) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Exactly word size on 32-bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct4BytesHomogeneousInt16x10(Struct4BytesHomogeneousInt16 a0,
Struct4BytesHomogeneousInt16 a1,
Struct4BytesHomogeneousInt16 a2,
Struct4BytesHomogeneousInt16 a3,
Struct4BytesHomogeneousInt16 a4,
Struct4BytesHomogeneousInt16 a5,
Struct4BytesHomogeneousInt16 a6,
Struct4BytesHomogeneousInt16 a7,
Struct4BytesHomogeneousInt16 a8,
Struct4BytesHomogeneousInt16 a9) {
std::cout << "PassStruct4BytesHomogeneousInt16x10"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Sub word size on 64 bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct7BytesHomogeneousUint8x10(Struct7BytesHomogeneousUint8 a0,
Struct7BytesHomogeneousUint8 a1,
Struct7BytesHomogeneousUint8 a2,
Struct7BytesHomogeneousUint8 a3,
Struct7BytesHomogeneousUint8 a4,
Struct7BytesHomogeneousUint8 a5,
Struct7BytesHomogeneousUint8 a6,
Struct7BytesHomogeneousUint8 a7,
Struct7BytesHomogeneousUint8 a8,
Struct7BytesHomogeneousUint8 a9) {
std::cout
<< "PassStruct7BytesHomogeneousUint8x10"
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a0.a5;
result += a0.a6;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a1.a5;
result += a1.a6;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a2.a5;
result += a2.a6;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a3.a5;
result += a3.a6;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a4.a5;
result += a4.a6;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a5.a5;
result += a5.a6;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a6.a5;
result += a6.a6;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a7.a5;
result += a7.a6;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a8.a5;
result += a8.a6;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
result += a9.a5;
result += a9.a6;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Sub word size on 64 bit architectures.
// With alignment rules taken into account size is 8 bytes.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t
PassStruct7BytesInt4ByteAlignedx10(Struct7BytesInt4ByteAligned a0,
Struct7BytesInt4ByteAligned a1,
Struct7BytesInt4ByteAligned a2,
Struct7BytesInt4ByteAligned a3,
Struct7BytesInt4ByteAligned a4,
Struct7BytesInt4ByteAligned a5,
Struct7BytesInt4ByteAligned a6,
Struct7BytesInt4ByteAligned a7,
Struct7BytesInt4ByteAligned a8,
Struct7BytesInt4ByteAligned a9) {
std::cout << "PassStruct7BytesInt4ByteAlignedx10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
<< "), (" << a1.a0 << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
<< ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
<< ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
<< "), (" << a6.a0 << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
<< ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
<< a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
<< ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Exactly word size struct on 64bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT int64_t PassStruct8BytesIntx10(Struct8BytesInt a0,
Struct8BytesInt a1,
Struct8BytesInt a2,
Struct8BytesInt a3,
Struct8BytesInt a4,
Struct8BytesInt a5,
Struct8BytesInt a6,
Struct8BytesInt a7,
Struct8BytesInt a8,
Struct8BytesInt a9) {
std::cout << "PassStruct8BytesIntx10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
<< a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
<< ", " << a9.a1 << ", " << a9.a2 << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Arguments passed in FP registers as long as they fit.
// 10 struct arguments will exhaust available registers.
DART_EXPORT float PassStruct8BytesHomogeneousFloatx10(
Struct8BytesHomogeneousFloat a0,
Struct8BytesHomogeneousFloat a1,
Struct8BytesHomogeneousFloat a2,
Struct8BytesHomogeneousFloat a3,
Struct8BytesHomogeneousFloat a4,
Struct8BytesHomogeneousFloat a5,
Struct8BytesHomogeneousFloat a6,
Struct8BytesHomogeneousFloat a7,
Struct8BytesHomogeneousFloat a8,
Struct8BytesHomogeneousFloat a9) {
std::cout << "PassStruct8BytesHomogeneousFloatx10"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// On x64, arguments go in int registers because it is not only float.
// 10 struct arguments will exhaust available registers.
DART_EXPORT float PassStruct8BytesMixedx10(Struct8BytesMixed a0,
Struct8BytesMixed a1,
Struct8BytesMixed a2,
Struct8BytesMixed a3,
Struct8BytesMixed a4,
Struct8BytesMixed a5,
Struct8BytesMixed a6,
Struct8BytesMixed a7,
Struct8BytesMixed a8,
Struct8BytesMixed a9) {
std::cout << "PassStruct8BytesMixedx10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
<< a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
<< ", " << a9.a1 << ", " << a9.a2 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Argument is a single byte over a multiple of word size.
// 10 struct arguments will exhaust available registers.
// Struct only has 1-byte aligned fields to test struct alignment itself.
// Tests upper bytes in the integer registers that are partly filled.
// Tests stack alignment of non word size stack arguments.
DART_EXPORT int64_t
PassStruct9BytesHomogeneousUint8x10(Struct9BytesHomogeneousUint8 a0,
Struct9BytesHomogeneousUint8 a1,
Struct9BytesHomogeneousUint8 a2,
Struct9BytesHomogeneousUint8 a3,
Struct9BytesHomogeneousUint8 a4,
Struct9BytesHomogeneousUint8 a5,
Struct9BytesHomogeneousUint8 a6,
Struct9BytesHomogeneousUint8 a7,
Struct9BytesHomogeneousUint8 a8,
Struct9BytesHomogeneousUint8 a9) {
std::cout
<< "PassStruct9BytesHomogeneousUint8x10"
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
<< ", " << static_cast<int>(a0.a8) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
<< ", " << static_cast<int>(a2.a8) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
<< ", " << static_cast<int>(a4.a8) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
<< ", " << static_cast<int>(a6.a8) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
<< ", " << static_cast<int>(a8.a8) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
<< "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a0.a5;
result += a0.a6;
result += a0.a7;
result += a0.a8;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a1.a5;
result += a1.a6;
result += a1.a7;
result += a1.a8;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a2.a5;
result += a2.a6;
result += a2.a7;
result += a2.a8;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a3.a5;
result += a3.a6;
result += a3.a7;
result += a3.a8;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a4.a5;
result += a4.a6;
result += a4.a7;
result += a4.a8;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a5.a5;
result += a5.a6;
result += a5.a7;
result += a5.a8;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a6.a5;
result += a6.a6;
result += a6.a7;
result += a6.a8;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a7.a5;
result += a7.a6;
result += a7.a7;
result += a7.a8;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a8.a5;
result += a8.a6;
result += a8.a7;
result += a8.a8;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
result += a9.a5;
result += a9.a6;
result += a9.a7;
result += a9.a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Argument is a single byte over a multiple of word size.
// With alignment rules taken into account size is 12 or 16 bytes.
// 10 struct arguments will exhaust available registers.
//
DART_EXPORT int64_t
PassStruct9BytesInt4Or8ByteAlignedx10(Struct9BytesInt4Or8ByteAligned a0,
Struct9BytesInt4Or8ByteAligned a1,
Struct9BytesInt4Or8ByteAligned a2,
Struct9BytesInt4Or8ByteAligned a3,
Struct9BytesInt4Or8ByteAligned a4,
Struct9BytesInt4Or8ByteAligned a5,
Struct9BytesInt4Or8ByteAligned a6,
Struct9BytesInt4Or8ByteAligned a7,
Struct9BytesInt4Or8ByteAligned a8,
Struct9BytesInt4Or8ByteAligned a9) {
std::cout << "PassStruct9BytesInt4Or8ByteAlignedx10"
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
<< a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
<< ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
<< static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
<< static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
<< static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
<< static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
<< static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
<< static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
<< static_cast<int>(a9.a1) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Arguments in FPU registers on arm hardfp and arm64.
// Struct arguments will exhaust available registers, and leave some empty.
// The last argument is to test whether arguments are backfilled.
DART_EXPORT float PassStruct12BytesHomogeneousFloatx6(
Struct12BytesHomogeneousFloat a0,
Struct12BytesHomogeneousFloat a1,
Struct12BytesHomogeneousFloat a2,
Struct12BytesHomogeneousFloat a3,
Struct12BytesHomogeneousFloat a4,
Struct12BytesHomogeneousFloat a5) {
std::cout << "PassStruct12BytesHomogeneousFloatx6"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// On Linux x64 argument is transferred on stack because it is over 16 bytes.
// Arguments in FPU registers on arm hardfp and arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT float PassStruct16BytesHomogeneousFloatx5(
Struct16BytesHomogeneousFloat a0,
Struct16BytesHomogeneousFloat a1,
Struct16BytesHomogeneousFloat a2,
Struct16BytesHomogeneousFloat a3,
Struct16BytesHomogeneousFloat a4) {
std::cout << "PassStruct16BytesHomogeneousFloatx5"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// On x64, arguments are split over FP and int registers.
// On x64, it will exhaust the integer registers with the 6th argument.
// The rest goes on the stack.
// On arm, arguments are 8 byte aligned.
DART_EXPORT double PassStruct16BytesMixedx10(Struct16BytesMixed a0,
Struct16BytesMixed a1,
Struct16BytesMixed a2,
Struct16BytesMixed a3,
Struct16BytesMixed a4,
Struct16BytesMixed a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
Struct16BytesMixed a8,
Struct16BytesMixed a9) {
std::cout << "PassStruct16BytesMixedx10"
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
result += a3.a0;
result += a3.a1;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// On x64, arguments are split over FP and int registers.
// On x64, it will exhaust the integer registers with the 6th argument.
// The rest goes on the stack.
// On arm, arguments are 4 byte aligned.
DART_EXPORT float PassStruct16BytesMixed2x10(Struct16BytesMixed2 a0,
Struct16BytesMixed2 a1,
Struct16BytesMixed2 a2,
Struct16BytesMixed2 a3,
Struct16BytesMixed2 a4,
Struct16BytesMixed2 a5,
Struct16BytesMixed2 a6,
Struct16BytesMixed2 a7,
Struct16BytesMixed2 a8,
Struct16BytesMixed2 a9) {
std::cout << "PassStruct16BytesMixed2x10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "), (" << a5.a0 << ", "
<< a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), (" << a6.a0
<< ", " << a6.a1 << ", " << a6.a2 << ", " << a6.a3 << "), ("
<< a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
<< a8.a3 << "), (" << a9.a0 << ", " << a9.a1 << ", " << a9.a2
<< ", " << a9.a3 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Arguments are passed as pointer to copy on arm64.
// Tests that the memory allocated for copies are rounded up to word size.
DART_EXPORT int64_t PassStruct17BytesIntx10(Struct17BytesInt a0,
Struct17BytesInt a1,
Struct17BytesInt a2,
Struct17BytesInt a3,
Struct17BytesInt a4,
Struct17BytesInt a5,
Struct17BytesInt a6,
Struct17BytesInt a7,
Struct17BytesInt a8,
Struct17BytesInt a9) {
std::cout << "PassStruct17BytesIntx10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
<< "), (" << a1.a0 << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
<< ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
<< ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
<< "), (" << a6.a0 << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
<< ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
<< a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
<< ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a9.a0;
result += a9.a1;
result += a9.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// The minimum alignment of this struct is only 1 byte based on its fields.
// Test that the memory backing these structs is extended to the right size.
//
DART_EXPORT int64_t
PassStruct19BytesHomogeneousUint8x10(Struct19BytesHomogeneousUint8 a0,
Struct19BytesHomogeneousUint8 a1,
Struct19BytesHomogeneousUint8 a2,
Struct19BytesHomogeneousUint8 a3,
Struct19BytesHomogeneousUint8 a4,
Struct19BytesHomogeneousUint8 a5,
Struct19BytesHomogeneousUint8 a6,
Struct19BytesHomogeneousUint8 a7,
Struct19BytesHomogeneousUint8 a8,
Struct19BytesHomogeneousUint8 a9) {
std::cout
<< "PassStruct19BytesHomogeneousUint8x10"
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
<< ", " << static_cast<int>(a0.a8) << ", " << static_cast<int>(a0.a9)
<< ", " << static_cast<int>(a0.a10) << ", " << static_cast<int>(a0.a11)
<< ", " << static_cast<int>(a0.a12) << ", " << static_cast<int>(a0.a13)
<< ", " << static_cast<int>(a0.a14) << ", " << static_cast<int>(a0.a15)
<< ", " << static_cast<int>(a0.a16) << ", " << static_cast<int>(a0.a17)
<< ", " << static_cast<int>(a0.a18) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
<< ", " << static_cast<int>(a1.a9) << ", " << static_cast<int>(a1.a10)
<< ", " << static_cast<int>(a1.a11) << ", " << static_cast<int>(a1.a12)
<< ", " << static_cast<int>(a1.a13) << ", " << static_cast<int>(a1.a14)
<< ", " << static_cast<int>(a1.a15) << ", " << static_cast<int>(a1.a16)
<< ", " << static_cast<int>(a1.a17) << ", " << static_cast<int>(a1.a18)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
<< ", " << static_cast<int>(a2.a8) << ", " << static_cast<int>(a2.a9)
<< ", " << static_cast<int>(a2.a10) << ", " << static_cast<int>(a2.a11)
<< ", " << static_cast<int>(a2.a12) << ", " << static_cast<int>(a2.a13)
<< ", " << static_cast<int>(a2.a14) << ", " << static_cast<int>(a2.a15)
<< ", " << static_cast<int>(a2.a16) << ", " << static_cast<int>(a2.a17)
<< ", " << static_cast<int>(a2.a18) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
<< ", " << static_cast<int>(a3.a9) << ", " << static_cast<int>(a3.a10)
<< ", " << static_cast<int>(a3.a11) << ", " << static_cast<int>(a3.a12)
<< ", " << static_cast<int>(a3.a13) << ", " << static_cast<int>(a3.a14)
<< ", " << static_cast<int>(a3.a15) << ", " << static_cast<int>(a3.a16)
<< ", " << static_cast<int>(a3.a17) << ", " << static_cast<int>(a3.a18)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
<< ", " << static_cast<int>(a4.a8) << ", " << static_cast<int>(a4.a9)
<< ", " << static_cast<int>(a4.a10) << ", " << static_cast<int>(a4.a11)
<< ", " << static_cast<int>(a4.a12) << ", " << static_cast<int>(a4.a13)
<< ", " << static_cast<int>(a4.a14) << ", " << static_cast<int>(a4.a15)
<< ", " << static_cast<int>(a4.a16) << ", " << static_cast<int>(a4.a17)
<< ", " << static_cast<int>(a4.a18) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
<< ", " << static_cast<int>(a5.a9) << ", " << static_cast<int>(a5.a10)
<< ", " << static_cast<int>(a5.a11) << ", " << static_cast<int>(a5.a12)
<< ", " << static_cast<int>(a5.a13) << ", " << static_cast<int>(a5.a14)
<< ", " << static_cast<int>(a5.a15) << ", " << static_cast<int>(a5.a16)
<< ", " << static_cast<int>(a5.a17) << ", " << static_cast<int>(a5.a18)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
<< ", " << static_cast<int>(a6.a8) << ", " << static_cast<int>(a6.a9)
<< ", " << static_cast<int>(a6.a10) << ", " << static_cast<int>(a6.a11)
<< ", " << static_cast<int>(a6.a12) << ", " << static_cast<int>(a6.a13)
<< ", " << static_cast<int>(a6.a14) << ", " << static_cast<int>(a6.a15)
<< ", " << static_cast<int>(a6.a16) << ", " << static_cast<int>(a6.a17)
<< ", " << static_cast<int>(a6.a18) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
<< ", " << static_cast<int>(a7.a9) << ", " << static_cast<int>(a7.a10)
<< ", " << static_cast<int>(a7.a11) << ", " << static_cast<int>(a7.a12)
<< ", " << static_cast<int>(a7.a13) << ", " << static_cast<int>(a7.a14)
<< ", " << static_cast<int>(a7.a15) << ", " << static_cast<int>(a7.a16)
<< ", " << static_cast<int>(a7.a17) << ", " << static_cast<int>(a7.a18)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
<< ", " << static_cast<int>(a8.a8) << ", " << static_cast<int>(a8.a9)
<< ", " << static_cast<int>(a8.a10) << ", " << static_cast<int>(a8.a11)
<< ", " << static_cast<int>(a8.a12) << ", " << static_cast<int>(a8.a13)
<< ", " << static_cast<int>(a8.a14) << ", " << static_cast<int>(a8.a15)
<< ", " << static_cast<int>(a8.a16) << ", " << static_cast<int>(a8.a17)
<< ", " << static_cast<int>(a8.a18) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
<< ", " << static_cast<int>(a9.a9) << ", " << static_cast<int>(a9.a10)
<< ", " << static_cast<int>(a9.a11) << ", " << static_cast<int>(a9.a12)
<< ", " << static_cast<int>(a9.a13) << ", " << static_cast<int>(a9.a14)
<< ", " << static_cast<int>(a9.a15) << ", " << static_cast<int>(a9.a16)
<< ", " << static_cast<int>(a9.a17) << ", " << static_cast<int>(a9.a18)
<< "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a0.a5;
result += a0.a6;
result += a0.a7;
result += a0.a8;
result += a0.a9;
result += a0.a10;
result += a0.a11;
result += a0.a12;
result += a0.a13;
result += a0.a14;
result += a0.a15;
result += a0.a16;
result += a0.a17;
result += a0.a18;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a1.a5;
result += a1.a6;
result += a1.a7;
result += a1.a8;
result += a1.a9;
result += a1.a10;
result += a1.a11;
result += a1.a12;
result += a1.a13;
result += a1.a14;
result += a1.a15;
result += a1.a16;
result += a1.a17;
result += a1.a18;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a2.a5;
result += a2.a6;
result += a2.a7;
result += a2.a8;
result += a2.a9;
result += a2.a10;
result += a2.a11;
result += a2.a12;
result += a2.a13;
result += a2.a14;
result += a2.a15;
result += a2.a16;
result += a2.a17;
result += a2.a18;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a3.a5;
result += a3.a6;
result += a3.a7;
result += a3.a8;
result += a3.a9;
result += a3.a10;
result += a3.a11;
result += a3.a12;
result += a3.a13;
result += a3.a14;
result += a3.a15;
result += a3.a16;
result += a3.a17;
result += a3.a18;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a4.a5;
result += a4.a6;
result += a4.a7;
result += a4.a8;
result += a4.a9;
result += a4.a10;
result += a4.a11;
result += a4.a12;
result += a4.a13;
result += a4.a14;
result += a4.a15;
result += a4.a16;
result += a4.a17;
result += a4.a18;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a5.a5;
result += a5.a6;
result += a5.a7;
result += a5.a8;
result += a5.a9;
result += a5.a10;
result += a5.a11;
result += a5.a12;
result += a5.a13;
result += a5.a14;
result += a5.a15;
result += a5.a16;
result += a5.a17;
result += a5.a18;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a6.a5;
result += a6.a6;
result += a6.a7;
result += a6.a8;
result += a6.a9;
result += a6.a10;
result += a6.a11;
result += a6.a12;
result += a6.a13;
result += a6.a14;
result += a6.a15;
result += a6.a16;
result += a6.a17;
result += a6.a18;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a7.a5;
result += a7.a6;
result += a7.a7;
result += a7.a8;
result += a7.a9;
result += a7.a10;
result += a7.a11;
result += a7.a12;
result += a7.a13;
result += a7.a14;
result += a7.a15;
result += a7.a16;
result += a7.a17;
result += a7.a18;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a8.a5;
result += a8.a6;
result += a8.a7;
result += a8.a8;
result += a8.a9;
result += a8.a10;
result += a8.a11;
result += a8.a12;
result += a8.a13;
result += a8.a14;
result += a8.a15;
result += a8.a16;
result += a8.a17;
result += a8.a18;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
result += a9.a5;
result += a9.a6;
result += a9.a7;
result += a9.a8;
result += a9.a9;
result += a9.a10;
result += a9.a11;
result += a9.a12;
result += a9.a13;
result += a9.a14;
result += a9.a15;
result += a9.a16;
result += a9.a17;
result += a9.a18;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Argument too big to go into integer registers on arm64.
// The arguments are passed as pointers to copies.
// The amount of arguments exhausts the number of integer registers, such that
// pointers to copies are also passed on the stack.
DART_EXPORT int32_t
PassStruct20BytesHomogeneousInt32x10(Struct20BytesHomogeneousInt32 a0,
Struct20BytesHomogeneousInt32 a1,
Struct20BytesHomogeneousInt32 a2,
Struct20BytesHomogeneousInt32 a3,
Struct20BytesHomogeneousInt32 a4,
Struct20BytesHomogeneousInt32 a5,
Struct20BytesHomogeneousInt32 a6,
Struct20BytesHomogeneousInt32 a7,
Struct20BytesHomogeneousInt32 a8,
Struct20BytesHomogeneousInt32 a9) {
std::cout << "PassStruct20BytesHomogeneousInt32x10"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << ", "
<< a1.a2 << ", " << a1.a3 << ", " << a1.a4 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << ", " << a2.a3 << ", " << a2.a4
<< "), (" << a3.a0 << ", " << a3.a1 << ", " << a3.a2 << ", "
<< a3.a3 << ", " << a3.a4 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << ", " << a4.a4 << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << ", "
<< a5.a4 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< ", " << a6.a3 << ", " << a6.a4 << "), (" << a7.a0 << ", "
<< a7.a1 << ", " << a7.a2 << ", " << a7.a3 << ", " << a7.a4
<< "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
<< a8.a3 << ", " << a8.a4 << "), (" << a9.a0 << ", " << a9.a1
<< ", " << a9.a2 << ", " << a9.a3 << ", " << a9.a4 << "))"
<< "\n";
int32_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a1.a4;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a2.a4;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a3.a4;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
result += a4.a4;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a5.a4;
result += a6.a0;
result += a6.a1;
result += a6.a2;
result += a6.a3;
result += a6.a4;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a7.a4;
result += a8.a0;
result += a8.a1;
result += a8.a2;
result += a8.a3;
result += a8.a4;
result += a9.a0;
result += a9.a1;
result += a9.a2;
result += a9.a3;
result += a9.a4;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Argument too big to go into FPU registers in hardfp and arm64.
DART_EXPORT float PassStruct20BytesHomogeneousFloat(
Struct20BytesHomogeneousFloat a0) {
std::cout << "PassStruct20BytesHomogeneousFloat"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< "\n";
float result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Arguments in FPU registers on arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT double PassStruct32BytesHomogeneousDoublex5(
Struct32BytesHomogeneousDouble a0,
Struct32BytesHomogeneousDouble a1,
Struct32BytesHomogeneousDouble a2,
Struct32BytesHomogeneousDouble a3,
Struct32BytesHomogeneousDouble a4) {
std::cout << "PassStruct32BytesHomogeneousDoublex5"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2.a0;
result += a2.a1;
result += a2.a2;
result += a2.a3;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4.a0;
result += a4.a1;
result += a4.a2;
result += a4.a3;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Argument too big to go into FPU registers in arm64.
DART_EXPORT double PassStruct40BytesHomogeneousDouble(
Struct40BytesHomogeneousDouble a0) {
std::cout << "PassStruct40BytesHomogeneousDouble"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Test 1kb struct.
DART_EXPORT uint64_t
PassStruct1024BytesHomogeneousUint64(Struct1024BytesHomogeneousUint64 a0) {
std::cout << "PassStruct1024BytesHomogeneousUint64"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << ", " << a0.a5 << ", " << a0.a6 << ", " << a0.a7
<< ", " << a0.a8 << ", " << a0.a9 << ", " << a0.a10 << ", "
<< a0.a11 << ", " << a0.a12 << ", " << a0.a13 << ", " << a0.a14
<< ", " << a0.a15 << ", " << a0.a16 << ", " << a0.a17 << ", "
<< a0.a18 << ", " << a0.a19 << ", " << a0.a20 << ", " << a0.a21
<< ", " << a0.a22 << ", " << a0.a23 << ", " << a0.a24 << ", "
<< a0.a25 << ", " << a0.a26 << ", " << a0.a27 << ", " << a0.a28
<< ", " << a0.a29 << ", " << a0.a30 << ", " << a0.a31 << ", "
<< a0.a32 << ", " << a0.a33 << ", " << a0.a34 << ", " << a0.a35
<< ", " << a0.a36 << ", " << a0.a37 << ", " << a0.a38 << ", "
<< a0.a39 << ", " << a0.a40 << ", " << a0.a41 << ", " << a0.a42
<< ", " << a0.a43 << ", " << a0.a44 << ", " << a0.a45 << ", "
<< a0.a46 << ", " << a0.a47 << ", " << a0.a48 << ", " << a0.a49
<< ", " << a0.a50 << ", " << a0.a51 << ", " << a0.a52 << ", "
<< a0.a53 << ", " << a0.a54 << ", " << a0.a55 << ", " << a0.a56
<< ", " << a0.a57 << ", " << a0.a58 << ", " << a0.a59 << ", "
<< a0.a60 << ", " << a0.a61 << ", " << a0.a62 << ", " << a0.a63
<< ", " << a0.a64 << ", " << a0.a65 << ", " << a0.a66 << ", "
<< a0.a67 << ", " << a0.a68 << ", " << a0.a69 << ", " << a0.a70
<< ", " << a0.a71 << ", " << a0.a72 << ", " << a0.a73 << ", "
<< a0.a74 << ", " << a0.a75 << ", " << a0.a76 << ", " << a0.a77
<< ", " << a0.a78 << ", " << a0.a79 << ", " << a0.a80 << ", "
<< a0.a81 << ", " << a0.a82 << ", " << a0.a83 << ", " << a0.a84
<< ", " << a0.a85 << ", " << a0.a86 << ", " << a0.a87 << ", "
<< a0.a88 << ", " << a0.a89 << ", " << a0.a90 << ", " << a0.a91
<< ", " << a0.a92 << ", " << a0.a93 << ", " << a0.a94 << ", "
<< a0.a95 << ", " << a0.a96 << ", " << a0.a97 << ", " << a0.a98
<< ", " << a0.a99 << ", " << a0.a100 << ", " << a0.a101 << ", "
<< a0.a102 << ", " << a0.a103 << ", " << a0.a104 << ", " << a0.a105
<< ", " << a0.a106 << ", " << a0.a107 << ", " << a0.a108 << ", "
<< a0.a109 << ", " << a0.a110 << ", " << a0.a111 << ", " << a0.a112
<< ", " << a0.a113 << ", " << a0.a114 << ", " << a0.a115 << ", "
<< a0.a116 << ", " << a0.a117 << ", " << a0.a118 << ", " << a0.a119
<< ", " << a0.a120 << ", " << a0.a121 << ", " << a0.a122 << ", "
<< a0.a123 << ", " << a0.a124 << ", " << a0.a125 << ", " << a0.a126
<< ", " << a0.a127 << "))"
<< "\n";
uint64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a0.a5;
result += a0.a6;
result += a0.a7;
result += a0.a8;
result += a0.a9;
result += a0.a10;
result += a0.a11;
result += a0.a12;
result += a0.a13;
result += a0.a14;
result += a0.a15;
result += a0.a16;
result += a0.a17;
result += a0.a18;
result += a0.a19;
result += a0.a20;
result += a0.a21;
result += a0.a22;
result += a0.a23;
result += a0.a24;
result += a0.a25;
result += a0.a26;
result += a0.a27;
result += a0.a28;
result += a0.a29;
result += a0.a30;
result += a0.a31;
result += a0.a32;
result += a0.a33;
result += a0.a34;
result += a0.a35;
result += a0.a36;
result += a0.a37;
result += a0.a38;
result += a0.a39;
result += a0.a40;
result += a0.a41;
result += a0.a42;
result += a0.a43;
result += a0.a44;
result += a0.a45;
result += a0.a46;
result += a0.a47;
result += a0.a48;
result += a0.a49;
result += a0.a50;
result += a0.a51;
result += a0.a52;
result += a0.a53;
result += a0.a54;
result += a0.a55;
result += a0.a56;
result += a0.a57;
result += a0.a58;
result += a0.a59;
result += a0.a60;
result += a0.a61;
result += a0.a62;
result += a0.a63;
result += a0.a64;
result += a0.a65;
result += a0.a66;
result += a0.a67;
result += a0.a68;
result += a0.a69;
result += a0.a70;
result += a0.a71;
result += a0.a72;
result += a0.a73;
result += a0.a74;
result += a0.a75;
result += a0.a76;
result += a0.a77;
result += a0.a78;
result += a0.a79;
result += a0.a80;
result += a0.a81;
result += a0.a82;
result += a0.a83;
result += a0.a84;
result += a0.a85;
result += a0.a86;
result += a0.a87;
result += a0.a88;
result += a0.a89;
result += a0.a90;
result += a0.a91;
result += a0.a92;
result += a0.a93;
result += a0.a94;
result += a0.a95;
result += a0.a96;
result += a0.a97;
result += a0.a98;
result += a0.a99;
result += a0.a100;
result += a0.a101;
result += a0.a102;
result += a0.a103;
result += a0.a104;
result += a0.a105;
result += a0.a106;
result += a0.a107;
result += a0.a108;
result += a0.a109;
result += a0.a110;
result += a0.a111;
result += a0.a112;
result += a0.a113;
result += a0.a114;
result += a0.a115;
result += a0.a116;
result += a0.a117;
result += a0.a118;
result += a0.a119;
result += a0.a120;
result += a0.a121;
result += a0.a122;
result += a0.a123;
result += a0.a124;
result += a0.a125;
result += a0.a126;
result += a0.a127;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Tests the alignment of structs in FPU registers and backfilling.
DART_EXPORT float PassFloatStruct16BytesHomogeneousFloatFloatStruct1(
float a0,
Struct16BytesHomogeneousFloat a1,
float a2,
Struct16BytesHomogeneousFloat a3,
float a4,
Struct16BytesHomogeneousFloat a5,
float a6,
Struct16BytesHomogeneousFloat a7,
float a8) {
std::cout << "PassFloatStruct16BytesHomogeneousFloatFloatStruct1"
<< "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
<< ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
<< ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
<< ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
<< ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), " << a8 << ")"
<< "\n";
float result = 0;
result += a0;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a6;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Tests the alignment of structs in FPU registers and backfilling.
DART_EXPORT double PassFloatStruct32BytesHomogeneousDoubleFloatStruct(
float a0,
Struct32BytesHomogeneousDouble a1,
float a2,
Struct32BytesHomogeneousDouble a3,
float a4,
Struct32BytesHomogeneousDouble a5,
float a6,
Struct32BytesHomogeneousDouble a7,
float a8) {
std::cout << "PassFloatStruct32BytesHomogeneousDoubleFloatStruct"
<< "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
<< ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
<< ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
<< ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
<< ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), " << a8 << ")"
<< "\n";
double result = 0;
result += a0;
result += a1.a0;
result += a1.a1;
result += a1.a2;
result += a1.a3;
result += a2;
result += a3.a0;
result += a3.a1;
result += a3.a2;
result += a3.a3;
result += a4;
result += a5.a0;
result += a5.a1;
result += a5.a2;
result += a5.a3;
result += a6;
result += a7.a0;
result += a7.a1;
result += a7.a2;
result += a7.a3;
result += a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Tests the alignment of structs in integers registers and on the stack.
// Arm32 aligns this struct at 8.
// Also, arm32 allocates the second struct partially in registers, partially
// on stack.
// Test backfilling of integer registers.
DART_EXPORT double PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
int8_t a0,
Struct16BytesMixed a1,
int8_t a2,
Struct16BytesMixed a3,
int8_t a4,
Struct16BytesMixed a5,
int8_t a6,
Struct16BytesMixed a7,
int8_t a8) {
std::cout << "PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn"
<< "(" << static_cast<int>(a0) << ", (" << a1.a0 << ", " << a1.a1
<< "), " << static_cast<int>(a2) << ", (" << a3.a0 << ", " << a3.a1
<< "), " << static_cast<int>(a4) << ", (" << a5.a0 << ", " << a5.a1
<< "), " << static_cast<int>(a6) << ", (" << a7.a0 << ", " << a7.a1
<< "), " << static_cast<int>(a8) << ")"
<< "\n";
double result = 0;
result += a0;
result += a1.a0;
result += a1.a1;
result += a2;
result += a3.a0;
result += a3.a1;
result += a4;
result += a5.a0;
result += a5.a1;
result += a6;
result += a7.a0;
result += a7.a1;
result += a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
// structs. The rest of the structs will go on the stack.
// The int will be backfilled into the int register.
DART_EXPORT double PassDoublex6Struct16BytesMixedx4Int32(double a0,
double a1,
double a2,
double a3,
double a4,
double a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
Struct16BytesMixed a8,
Struct16BytesMixed a9,
int32_t a10) {
std::cout << "PassDoublex6Struct16BytesMixedx4Int32"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0
<< ", " << a7.a1 << "), (" << a8.a0 << ", " << a8.a1 << "), ("
<< a9.a0 << ", " << a9.a1 << "), " << a10 << ")"
<< "\n";
double result = 0;
result += a0;
result += a1;
result += a2;
result += a3;
result += a4;
result += a5;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8.a0;
result += a8.a1;
result += a9.a0;
result += a9.a1;
result += a10;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// On Linux x64, it will exhaust int registers first.
// The rest of the structs will go on the stack.
// The double will be backfilled into the xmm register.
DART_EXPORT double PassInt32x4Struct16BytesMixedx4Double(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
Struct16BytesMixed a4,
Struct16BytesMixed a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
double a8) {
std::cout << "PassInt32x4Struct16BytesMixedx4Double"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", ("
<< a4.a0 << ", " << a4.a1 << "), (" << a5.a0 << ", " << a5.a1
<< "), (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0 << ", "
<< a7.a1 << "), " << a8 << ")"
<< "\n";
double result = 0;
result += a0;
result += a1;
result += a2;
result += a3;
result += a4.a0;
result += a4.a1;
result += a5.a0;
result += a5.a1;
result += a6.a0;
result += a6.a1;
result += a7.a0;
result += a7.a1;
result += a8;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// On various architectures, first struct is allocated on stack.
// Check that the other two arguments are allocated on registers.
DART_EXPORT double PassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
Struct40BytesHomogeneousDouble a0,
Struct4BytesHomogeneousInt16 a1,
Struct8BytesHomogeneousFloat a2) {
std::cout << "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << "), ("
<< a2.a0 << ", " << a2.a1 << "))"
<< "\n";
double result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
result += a0.a3;
result += a0.a4;
result += a1.a0;
result += a1.a1;
result += a2.a0;
result += a2.a1;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT int64_t PassStructAlignmentInt16(StructAlignmentInt16 a0) {
std::cout << "PassStructAlignmentInt16"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Test alignment and padding of 32 byte int within struct.
DART_EXPORT int64_t PassStructAlignmentInt32(StructAlignmentInt32 a0) {
std::cout << "PassStructAlignmentInt32"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Test alignment and padding of 64 byte int within struct.
DART_EXPORT int64_t PassStructAlignmentInt64(StructAlignmentInt64 a0) {
std::cout << "PassStructAlignmentInt64"
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< "\n";
int64_t result = 0;
result += a0.a0;
result += a0.a1;
result += a0.a2;
std::cout << "result = " << result << "\n";
return result;
}
// Used for testing structs by value.
// Smallest struct with data.
DART_EXPORT Struct1ByteInt ReturnStruct1ByteInt(int8_t a0) {
std::cout << "ReturnStruct1ByteInt"
<< "(" << static_cast<int>(a0) << ")"
<< "\n";
Struct1ByteInt result;
result.a0 = a0;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Smaller than word size return value on all architectures.
DART_EXPORT Struct3BytesHomogeneousUint8
ReturnStruct3BytesHomogeneousUint8(uint8_t a0, uint8_t a1, uint8_t a2) {
std::cout << "ReturnStruct3BytesHomogeneousUint8"
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ")"
<< "\n";
Struct3BytesHomogeneousUint8 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Smaller than word size return value on all architectures.
// With alignment rules taken into account size is 4 bytes.
DART_EXPORT Struct3BytesInt2ByteAligned
ReturnStruct3BytesInt2ByteAligned(int16_t a0, int8_t a1) {
std::cout << "ReturnStruct3BytesInt2ByteAligned"
<< "(" << a0 << ", " << static_cast<int>(a1) << ")"
<< "\n";
Struct3BytesInt2ByteAligned result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Word size return value on 32 bit architectures..
DART_EXPORT Struct4BytesHomogeneousInt16
ReturnStruct4BytesHomogeneousInt16(int16_t a0, int16_t a1) {
std::cout << "ReturnStruct4BytesHomogeneousInt16"
<< "(" << a0 << ", " << a1 << ")"
<< "\n";
Struct4BytesHomogeneousInt16 result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Non-wordsize return value.
DART_EXPORT Struct7BytesHomogeneousUint8
ReturnStruct7BytesHomogeneousUint8(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6) {
std::cout << "ReturnStruct7BytesHomogeneousUint8"
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ")"
<< "\n";
Struct7BytesHomogeneousUint8 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
result.a5 = a5;
result.a6 = a6;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Non-wordsize return value.
// With alignment rules taken into account size is 8 bytes.
DART_EXPORT Struct7BytesInt4ByteAligned
ReturnStruct7BytesInt4ByteAligned(int32_t a0, int16_t a1, int8_t a2) {
std::cout << "ReturnStruct7BytesInt4ByteAligned"
<< "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
<< "\n";
Struct7BytesInt4ByteAligned result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value in integer registers on many architectures.
DART_EXPORT Struct8BytesInt ReturnStruct8BytesInt(int16_t a0,
int16_t a1,
int32_t a2) {
std::cout << "ReturnStruct8BytesInt"
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< "\n";
Struct8BytesInt result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value in FP registers on many architectures.
DART_EXPORT Struct8BytesHomogeneousFloat
ReturnStruct8BytesHomogeneousFloat(float a0, float a1) {
std::cout << "ReturnStruct8BytesHomogeneousFloat"
<< "(" << a0 << ", " << a1 << ")"
<< "\n";
Struct8BytesHomogeneousFloat result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value split over FP and integer register in x64.
DART_EXPORT Struct8BytesMixed ReturnStruct8BytesMixed(float a0,
int16_t a1,
int16_t a2) {
std::cout << "ReturnStruct8BytesMixed"
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< "\n";
Struct8BytesMixed result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// The minimum alignment of this struct is only 1 byte based on its fields.
// Test that the memory backing these structs is the right size and that
// dart:ffi trampolines do not write outside this size.
DART_EXPORT Struct9BytesHomogeneousUint8
ReturnStruct9BytesHomogeneousUint8(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6,
uint8_t a7,
uint8_t a8) {
std::cout << "ReturnStruct9BytesHomogeneousUint8"
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
<< ", " << static_cast<int>(a8) << ")"
<< "\n";
Struct9BytesHomogeneousUint8 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
result.a5 = a5;
result.a6 = a6;
result.a7 = a7;
result.a8 = a8;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ", "
<< static_cast<int>(result.a7) << ", "
<< static_cast<int>(result.a8) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value in two integer registers on x64.
// With alignment rules taken into account size is 12 or 16 bytes.
DART_EXPORT Struct9BytesInt4Or8ByteAligned
ReturnStruct9BytesInt4Or8ByteAligned(int64_t a0, int8_t a1) {
std::cout << "ReturnStruct9BytesInt4Or8ByteAligned"
<< "(" << a0 << ", " << static_cast<int>(a1) << ")"
<< "\n";
Struct9BytesInt4Or8ByteAligned result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value in FPU registers, but does not use all registers on arm hardfp
// and arm64.
DART_EXPORT Struct12BytesHomogeneousFloat
ReturnStruct12BytesHomogeneousFloat(float a0, float a1, float a2) {
std::cout << "ReturnStruct12BytesHomogeneousFloat"
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< "\n";
Struct12BytesHomogeneousFloat result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value in FPU registers on arm hardfp and arm64.
DART_EXPORT Struct16BytesHomogeneousFloat
ReturnStruct16BytesHomogeneousFloat(float a0, float a1, float a2, float a3) {
std::cout << "ReturnStruct16BytesHomogeneousFloat"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< "\n";
Struct16BytesHomogeneousFloat result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value split over FP and integer register in x64.
DART_EXPORT Struct16BytesMixed ReturnStruct16BytesMixed(double a0, int64_t a1) {
std::cout << "ReturnStruct16BytesMixed"
<< "(" << a0 << ", " << a1 << ")"
<< "\n";
Struct16BytesMixed result;
result.a0 = a0;
result.a1 = a1;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value split over FP and integer register in x64.
// The integer register contains half float half int.
DART_EXPORT Struct16BytesMixed2 ReturnStruct16BytesMixed2(float a0,
float a1,
float a2,
int32_t a3) {
std::cout << "ReturnStruct16BytesMixed2"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< "\n";
Struct16BytesMixed2 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Rerturn value returned in preallocated space passed by pointer on most ABIs.
// Is non word size on purpose, to test that structs are rounded up to word size
// on all ABIs.
DART_EXPORT Struct17BytesInt ReturnStruct17BytesInt(int64_t a0,
int64_t a1,
int8_t a2) {
std::cout << "ReturnStruct17BytesInt"
<< "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
<< "\n";
Struct17BytesInt result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// The minimum alignment of this struct is only 1 byte based on its fields.
// Test that the memory backing these structs is the right size and that
// dart:ffi trampolines do not write outside this size.
DART_EXPORT Struct19BytesHomogeneousUint8
ReturnStruct19BytesHomogeneousUint8(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6,
uint8_t a7,
uint8_t a8,
uint8_t a9,
uint8_t a10,
uint8_t a11,
uint8_t a12,
uint8_t a13,
uint8_t a14,
uint8_t a15,
uint8_t a16,
uint8_t a17,
uint8_t a18) {
std::cout << "ReturnStruct19BytesHomogeneousUint8"
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
<< ", " << static_cast<int>(a8) << ", " << static_cast<int>(a9)
<< ", " << static_cast<int>(a10) << ", " << static_cast<int>(a11)
<< ", " << static_cast<int>(a12) << ", " << static_cast<int>(a13)
<< ", " << static_cast<int>(a14) << ", " << static_cast<int>(a15)
<< ", " << static_cast<int>(a16) << ", " << static_cast<int>(a17)
<< ", " << static_cast<int>(a18) << ")"
<< "\n";
Struct19BytesHomogeneousUint8 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
result.a5 = a5;
result.a6 = a6;
result.a7 = a7;
result.a8 = a8;
result.a9 = a9;
result.a10 = a10;
result.a11 = a11;
result.a12 = a12;
result.a13 = a13;
result.a14 = a14;
result.a15 = a15;
result.a16 = a16;
result.a17 = a17;
result.a18 = a18;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ", "
<< static_cast<int>(result.a7) << ", "
<< static_cast<int>(result.a8) << ", "
<< static_cast<int>(result.a9) << ", "
<< static_cast<int>(result.a10) << ", "
<< static_cast<int>(result.a11) << ", "
<< static_cast<int>(result.a12) << ", "
<< static_cast<int>(result.a13) << ", "
<< static_cast<int>(result.a14) << ", "
<< static_cast<int>(result.a15) << ", "
<< static_cast<int>(result.a16) << ", "
<< static_cast<int>(result.a17) << ", "
<< static_cast<int>(result.a18) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value too big to go in cpu registers on arm64.
DART_EXPORT Struct20BytesHomogeneousInt32
ReturnStruct20BytesHomogeneousInt32(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4) {
std::cout << "ReturnStruct20BytesHomogeneousInt32"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< "\n";
Struct20BytesHomogeneousInt32 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
DART_EXPORT Struct20BytesHomogeneousFloat
ReturnStruct20BytesHomogeneousFloat(float a0,
float a1,
float a2,
float a3,
float a4) {
std::cout << "ReturnStruct20BytesHomogeneousFloat"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< "\n";
Struct20BytesHomogeneousFloat result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value in FPU registers on arm64.
DART_EXPORT Struct32BytesHomogeneousDouble
ReturnStruct32BytesHomogeneousDouble(double a0,
double a1,
double a2,
double a3) {
std::cout << "ReturnStruct32BytesHomogeneousDouble"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< "\n";
Struct32BytesHomogeneousDouble result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Return value too big to go in FPU registers on arm64.
DART_EXPORT Struct40BytesHomogeneousDouble
ReturnStruct40BytesHomogeneousDouble(double a0,
double a1,
double a2,
double a3,
double a4) {
std::cout << "ReturnStruct40BytesHomogeneousDouble"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< "\n";
Struct40BytesHomogeneousDouble result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Test 1kb struct.
DART_EXPORT Struct1024BytesHomogeneousUint64
ReturnStruct1024BytesHomogeneousUint64(uint64_t a0,
uint64_t a1,
uint64_t a2,
uint64_t a3,
uint64_t a4,
uint64_t a5,
uint64_t a6,
uint64_t a7,
uint64_t a8,
uint64_t a9,
uint64_t a10,
uint64_t a11,
uint64_t a12,
uint64_t a13,
uint64_t a14,
uint64_t a15,
uint64_t a16,
uint64_t a17,
uint64_t a18,
uint64_t a19,
uint64_t a20,
uint64_t a21,
uint64_t a22,
uint64_t a23,
uint64_t a24,
uint64_t a25,
uint64_t a26,
uint64_t a27,
uint64_t a28,
uint64_t a29,
uint64_t a30,
uint64_t a31,
uint64_t a32,
uint64_t a33,
uint64_t a34,
uint64_t a35,
uint64_t a36,
uint64_t a37,
uint64_t a38,
uint64_t a39,
uint64_t a40,
uint64_t a41,
uint64_t a42,
uint64_t a43,
uint64_t a44,
uint64_t a45,
uint64_t a46,
uint64_t a47,
uint64_t a48,
uint64_t a49,
uint64_t a50,
uint64_t a51,
uint64_t a52,
uint64_t a53,
uint64_t a54,
uint64_t a55,
uint64_t a56,
uint64_t a57,
uint64_t a58,
uint64_t a59,
uint64_t a60,
uint64_t a61,
uint64_t a62,
uint64_t a63,
uint64_t a64,
uint64_t a65,
uint64_t a66,
uint64_t a67,
uint64_t a68,
uint64_t a69,
uint64_t a70,
uint64_t a71,
uint64_t a72,
uint64_t a73,
uint64_t a74,
uint64_t a75,
uint64_t a76,
uint64_t a77,
uint64_t a78,
uint64_t a79,
uint64_t a80,
uint64_t a81,
uint64_t a82,
uint64_t a83,
uint64_t a84,
uint64_t a85,
uint64_t a86,
uint64_t a87,
uint64_t a88,
uint64_t a89,
uint64_t a90,
uint64_t a91,
uint64_t a92,
uint64_t a93,
uint64_t a94,
uint64_t a95,
uint64_t a96,
uint64_t a97,
uint64_t a98,
uint64_t a99,
uint64_t a100,
uint64_t a101,
uint64_t a102,
uint64_t a103,
uint64_t a104,
uint64_t a105,
uint64_t a106,
uint64_t a107,
uint64_t a108,
uint64_t a109,
uint64_t a110,
uint64_t a111,
uint64_t a112,
uint64_t a113,
uint64_t a114,
uint64_t a115,
uint64_t a116,
uint64_t a117,
uint64_t a118,
uint64_t a119,
uint64_t a120,
uint64_t a121,
uint64_t a122,
uint64_t a123,
uint64_t a124,
uint64_t a125,
uint64_t a126,
uint64_t a127) {
std::cout << "ReturnStruct1024BytesHomogeneousUint64"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
<< a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
<< ", " << a14 << ", " << a15 << ", " << a16 << ", " << a17 << ", "
<< a18 << ", " << a19 << ", " << a20 << ", " << a21 << ", " << a22
<< ", " << a23 << ", " << a24 << ", " << a25 << ", " << a26 << ", "
<< a27 << ", " << a28 << ", " << a29 << ", " << a30 << ", " << a31
<< ", " << a32 << ", " << a33 << ", " << a34 << ", " << a35 << ", "
<< a36 << ", " << a37 << ", " << a38 << ", " << a39 << ", " << a40
<< ", " << a41 << ", " << a42 << ", " << a43 << ", " << a44 << ", "
<< a45 << ", " << a46 << ", " << a47 << ", " << a48 << ", " << a49
<< ", " << a50 << ", " << a51 << ", " << a52 << ", " << a53 << ", "
<< a54 << ", " << a55 << ", " << a56 << ", " << a57 << ", " << a58
<< ", " << a59 << ", " << a60 << ", " << a61 << ", " << a62 << ", "
<< a63 << ", " << a64 << ", " << a65 << ", " << a66 << ", " << a67
<< ", " << a68 << ", " << a69 << ", " << a70 << ", " << a71 << ", "
<< a72 << ", " << a73 << ", " << a74 << ", " << a75 << ", " << a76
<< ", " << a77 << ", " << a78 << ", " << a79 << ", " << a80 << ", "
<< a81 << ", " << a82 << ", " << a83 << ", " << a84 << ", " << a85
<< ", " << a86 << ", " << a87 << ", " << a88 << ", " << a89 << ", "
<< a90 << ", " << a91 << ", " << a92 << ", " << a93 << ", " << a94
<< ", " << a95 << ", " << a96 << ", " << a97 << ", " << a98 << ", "
<< a99 << ", " << a100 << ", " << a101 << ", " << a102 << ", "
<< a103 << ", " << a104 << ", " << a105 << ", " << a106 << ", "
<< a107 << ", " << a108 << ", " << a109 << ", " << a110 << ", "
<< a111 << ", " << a112 << ", " << a113 << ", " << a114 << ", "
<< a115 << ", " << a116 << ", " << a117 << ", " << a118 << ", "
<< a119 << ", " << a120 << ", " << a121 << ", " << a122 << ", "
<< a123 << ", " << a124 << ", " << a125 << ", " << a126 << ", "
<< a127 << ")"
<< "\n";
Struct1024BytesHomogeneousUint64 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
result.a3 = a3;
result.a4 = a4;
result.a5 = a5;
result.a6 = a6;
result.a7 = a7;
result.a8 = a8;
result.a9 = a9;
result.a10 = a10;
result.a11 = a11;
result.a12 = a12;
result.a13 = a13;
result.a14 = a14;
result.a15 = a15;
result.a16 = a16;
result.a17 = a17;
result.a18 = a18;
result.a19 = a19;
result.a20 = a20;
result.a21 = a21;
result.a22 = a22;
result.a23 = a23;
result.a24 = a24;
result.a25 = a25;
result.a26 = a26;
result.a27 = a27;
result.a28 = a28;
result.a29 = a29;
result.a30 = a30;
result.a31 = a31;
result.a32 = a32;
result.a33 = a33;
result.a34 = a34;
result.a35 = a35;
result.a36 = a36;
result.a37 = a37;
result.a38 = a38;
result.a39 = a39;
result.a40 = a40;
result.a41 = a41;
result.a42 = a42;
result.a43 = a43;
result.a44 = a44;
result.a45 = a45;
result.a46 = a46;
result.a47 = a47;
result.a48 = a48;
result.a49 = a49;
result.a50 = a50;
result.a51 = a51;
result.a52 = a52;
result.a53 = a53;
result.a54 = a54;
result.a55 = a55;
result.a56 = a56;
result.a57 = a57;
result.a58 = a58;
result.a59 = a59;
result.a60 = a60;
result.a61 = a61;
result.a62 = a62;
result.a63 = a63;
result.a64 = a64;
result.a65 = a65;
result.a66 = a66;
result.a67 = a67;
result.a68 = a68;
result.a69 = a69;
result.a70 = a70;
result.a71 = a71;
result.a72 = a72;
result.a73 = a73;
result.a74 = a74;
result.a75 = a75;
result.a76 = a76;
result.a77 = a77;
result.a78 = a78;
result.a79 = a79;
result.a80 = a80;
result.a81 = a81;
result.a82 = a82;
result.a83 = a83;
result.a84 = a84;
result.a85 = a85;
result.a86 = a86;
result.a87 = a87;
result.a88 = a88;
result.a89 = a89;
result.a90 = a90;
result.a91 = a91;
result.a92 = a92;
result.a93 = a93;
result.a94 = a94;
result.a95 = a95;
result.a96 = a96;
result.a97 = a97;
result.a98 = a98;
result.a99 = a99;
result.a100 = a100;
result.a101 = a101;
result.a102 = a102;
result.a103 = a103;
result.a104 = a104;
result.a105 = a105;
result.a106 = a106;
result.a107 = a107;
result.a108 = a108;
result.a109 = a109;
result.a110 = a110;
result.a111 = a111;
result.a112 = a112;
result.a113 = a113;
result.a114 = a114;
result.a115 = a115;
result.a116 = a116;
result.a117 = a117;
result.a118 = a118;
result.a119 = a119;
result.a120 = a120;
result.a121 = a121;
result.a122 = a122;
result.a123 = a123;
result.a124 = a124;
result.a125 = a125;
result.a126 = a126;
result.a127 = a127;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ", " << result.a5
<< ", " << result.a6 << ", " << result.a7 << ", " << result.a8
<< ", " << result.a9 << ", " << result.a10 << ", " << result.a11
<< ", " << result.a12 << ", " << result.a13 << ", " << result.a14
<< ", " << result.a15 << ", " << result.a16 << ", " << result.a17
<< ", " << result.a18 << ", " << result.a19 << ", " << result.a20
<< ", " << result.a21 << ", " << result.a22 << ", " << result.a23
<< ", " << result.a24 << ", " << result.a25 << ", " << result.a26
<< ", " << result.a27 << ", " << result.a28 << ", " << result.a29
<< ", " << result.a30 << ", " << result.a31 << ", " << result.a32
<< ", " << result.a33 << ", " << result.a34 << ", " << result.a35
<< ", " << result.a36 << ", " << result.a37 << ", " << result.a38
<< ", " << result.a39 << ", " << result.a40 << ", " << result.a41
<< ", " << result.a42 << ", " << result.a43 << ", " << result.a44
<< ", " << result.a45 << ", " << result.a46 << ", " << result.a47
<< ", " << result.a48 << ", " << result.a49 << ", " << result.a50
<< ", " << result.a51 << ", " << result.a52 << ", " << result.a53
<< ", " << result.a54 << ", " << result.a55 << ", " << result.a56
<< ", " << result.a57 << ", " << result.a58 << ", " << result.a59
<< ", " << result.a60 << ", " << result.a61 << ", " << result.a62
<< ", " << result.a63 << ", " << result.a64 << ", " << result.a65
<< ", " << result.a66 << ", " << result.a67 << ", " << result.a68
<< ", " << result.a69 << ", " << result.a70 << ", " << result.a71
<< ", " << result.a72 << ", " << result.a73 << ", " << result.a74
<< ", " << result.a75 << ", " << result.a76 << ", " << result.a77
<< ", " << result.a78 << ", " << result.a79 << ", " << result.a80
<< ", " << result.a81 << ", " << result.a82 << ", " << result.a83
<< ", " << result.a84 << ", " << result.a85 << ", " << result.a86
<< ", " << result.a87 << ", " << result.a88 << ", " << result.a89
<< ", " << result.a90 << ", " << result.a91 << ", " << result.a92
<< ", " << result.a93 << ", " << result.a94 << ", " << result.a95
<< ", " << result.a96 << ", " << result.a97 << ", " << result.a98
<< ", " << result.a99 << ", " << result.a100 << ", " << result.a101
<< ", " << result.a102 << ", " << result.a103 << ", " << result.a104
<< ", " << result.a105 << ", " << result.a106 << ", " << result.a107
<< ", " << result.a108 << ", " << result.a109 << ", " << result.a110
<< ", " << result.a111 << ", " << result.a112 << ", " << result.a113
<< ", " << result.a114 << ", " << result.a115 << ", " << result.a116
<< ", " << result.a117 << ", " << result.a118 << ", " << result.a119
<< ", " << result.a120 << ", " << result.a121 << ", " << result.a122
<< ", " << result.a123 << ", " << result.a124 << ", " << result.a125
<< ", " << result.a126 << ", " << result.a127 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed in int registers in most ABIs.
DART_EXPORT Struct1ByteInt
ReturnStructArgumentStruct1ByteInt(Struct1ByteInt a0) {
std::cout << "ReturnStructArgumentStruct1ByteInt"
<< "((" << static_cast<int>(a0.a0) << "))"
<< "\n";
Struct1ByteInt result = a0;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed on stack on all ABIs.
DART_EXPORT Struct1ByteInt
ReturnStructArgumentInt32x8Struct1ByteInt(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
Struct1ByteInt a8) {
std::cout << "ReturnStructArgumentInt32x8Struct1ByteInt"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", ("
<< static_cast<int>(a8.a0) << "))"
<< "\n";
Struct1ByteInt result = a8;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed in float registers in most ABIs.
DART_EXPORT Struct8BytesHomogeneousFloat
ReturnStructArgumentStruct8BytesHomogeneousFloat(
Struct8BytesHomogeneousFloat a0) {
std::cout << "ReturnStructArgumentStruct8BytesHomogeneousFloat"
<< "((" << a0.a0 << ", " << a0.a1 << "))"
<< "\n";
Struct8BytesHomogeneousFloat result = a0;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// On arm64, both argument and return value are passed in by pointer.
DART_EXPORT Struct20BytesHomogeneousInt32
ReturnStructArgumentStruct20BytesHomogeneousInt32(
Struct20BytesHomogeneousInt32 a0) {
std::cout << "ReturnStructArgumentStruct20BytesHomogeneousInt32"
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< "\n";
Struct20BytesHomogeneousInt32 result = a0;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// On arm64, both argument and return value are passed in by pointer.
// Ints exhaust registers, so that pointer is passed on stack.
DART_EXPORT Struct20BytesHomogeneousInt32
ReturnStructArgumentInt32x8Struct20BytesHomogeneou(
int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
Struct20BytesHomogeneousInt32 a8) {
std::cout << "ReturnStructArgumentInt32x8Struct20BytesHomogeneou"
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", (" << a8.a0 << ", "
<< a8.a1 << ", " << a8.a2 << ", " << a8.a3 << ", " << a8.a4 << "))"
<< "\n";
Struct20BytesHomogeneousInt32 result = a8;
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT StructAlignmentInt16 ReturnStructAlignmentInt16(int8_t a0,
int16_t a1,
int8_t a2) {
std::cout << "ReturnStructAlignmentInt16"
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< "\n";
StructAlignmentInt16 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Test alignment and padding of 32 byte int within struct.
DART_EXPORT StructAlignmentInt32 ReturnStructAlignmentInt32(int8_t a0,
int32_t a1,
int8_t a2) {
std::cout << "ReturnStructAlignmentInt32"
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< "\n";
StructAlignmentInt32 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Test alignment and padding of 64 byte int within struct.
DART_EXPORT StructAlignmentInt64 ReturnStructAlignmentInt64(int8_t a0,
int64_t a1,
int8_t a2) {
std::cout << "ReturnStructAlignmentInt64"
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< "\n";
StructAlignmentInt64 result;
result.a0 = a0;
result.a1 = a1;
result.a2 = a2;
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
return result;
}
// Used for testing structs by value.
// Smallest struct with data.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct1ByteIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct1ByteInt a0,
Struct1ByteInt a1,
Struct1ByteInt a2,
Struct1ByteInt a3,
Struct1ByteInt a4,
Struct1ByteInt a5,
Struct1ByteInt a6,
Struct1ByteInt a7,
Struct1ByteInt a8,
Struct1ByteInt a9)) {
Struct1ByteInt a0;
Struct1ByteInt a1;
Struct1ByteInt a2;
Struct1ByteInt a3;
Struct1ByteInt a4;
Struct1ByteInt a5;
Struct1ByteInt a6;
Struct1ByteInt a7;
Struct1ByteInt a8;
Struct1ByteInt a9;
a0.a0 = -1;
a1.a0 = 2;
a2.a0 = -3;
a3.a0 = 4;
a4.a0 = -5;
a5.a0 = 6;
a6.a0 = -7;
a7.a0 = 8;
a8.a0 = -9;
a9.a0 = 10;
std::cout << "Calling TestPassStruct1ByteIntx10("
<< "((" << static_cast<int>(a0.a0) << "), ("
<< static_cast<int>(a1.a0) << "), (" << static_cast<int>(a2.a0)
<< "), (" << static_cast<int>(a3.a0) << "), ("
<< static_cast<int>(a4.a0) << "), (" << static_cast<int>(a5.a0)
<< "), (" << static_cast<int>(a6.a0) << "), ("
<< static_cast<int>(a7.a0) << "), (" << static_cast<int>(a8.a0)
<< "), (" << static_cast<int>(a9.a0) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(5, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Not a multiple of word size, not a power of two.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct3BytesHomogeneousUint8x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct3BytesHomogeneousUint8 a0,
Struct3BytesHomogeneousUint8 a1,
Struct3BytesHomogeneousUint8 a2,
Struct3BytesHomogeneousUint8 a3,
Struct3BytesHomogeneousUint8 a4,
Struct3BytesHomogeneousUint8 a5,
Struct3BytesHomogeneousUint8 a6,
Struct3BytesHomogeneousUint8 a7,
Struct3BytesHomogeneousUint8 a8,
Struct3BytesHomogeneousUint8 a9)) {
Struct3BytesHomogeneousUint8 a0;
Struct3BytesHomogeneousUint8 a1;
Struct3BytesHomogeneousUint8 a2;
Struct3BytesHomogeneousUint8 a3;
Struct3BytesHomogeneousUint8 a4;
Struct3BytesHomogeneousUint8 a5;
Struct3BytesHomogeneousUint8 a6;
Struct3BytesHomogeneousUint8 a7;
Struct3BytesHomogeneousUint8 a8;
Struct3BytesHomogeneousUint8 a9;
a0.a0 = 1;
a0.a1 = 2;
a0.a2 = 3;
a1.a0 = 4;
a1.a1 = 5;
a1.a2 = 6;
a2.a0 = 7;
a2.a1 = 8;
a2.a2 = 9;
a3.a0 = 10;
a3.a1 = 11;
a3.a2 = 12;
a4.a0 = 13;
a4.a1 = 14;
a4.a2 = 15;
a5.a0 = 16;
a5.a1 = 17;
a5.a2 = 18;
a6.a0 = 19;
a6.a1 = 20;
a6.a2 = 21;
a7.a0 = 22;
a7.a1 = 23;
a7.a2 = 24;
a8.a0 = 25;
a8.a1 = 26;
a8.a2 = 27;
a9.a0 = 28;
a9.a1 = 29;
a9.a2 = 30;
std::cout << "Calling TestPassStruct3BytesHomogeneousUint8x10("
<< "((" << static_cast<int>(a0.a0) << ", "
<< static_cast<int>(a0.a1) << ", " << static_cast<int>(a0.a2)
<< "), (" << static_cast<int>(a1.a0) << ", "
<< static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< "), (" << static_cast<int>(a2.a0) << ", "
<< static_cast<int>(a2.a1) << ", " << static_cast<int>(a2.a2)
<< "), (" << static_cast<int>(a3.a0) << ", "
<< static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< "), (" << static_cast<int>(a4.a0) << ", "
<< static_cast<int>(a4.a1) << ", " << static_cast<int>(a4.a2)
<< "), (" << static_cast<int>(a5.a0) << ", "
<< static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< "), (" << static_cast<int>(a6.a0) << ", "
<< static_cast<int>(a6.a1) << ", " << static_cast<int>(a6.a2)
<< "), (" << static_cast<int>(a7.a0) << ", "
<< static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< "), (" << static_cast<int>(a8.a0) << ", "
<< static_cast<int>(a8.a1) << ", " << static_cast<int>(a8.a2)
<< "), (" << static_cast<int>(a9.a0) << ", "
<< static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(465, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Not a multiple of word size, not a power of two.
// With alignment rules taken into account size is 4 bytes.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct3BytesInt2ByteAlignedx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct3BytesInt2ByteAligned a0,
Struct3BytesInt2ByteAligned a1,
Struct3BytesInt2ByteAligned a2,
Struct3BytesInt2ByteAligned a3,
Struct3BytesInt2ByteAligned a4,
Struct3BytesInt2ByteAligned a5,
Struct3BytesInt2ByteAligned a6,
Struct3BytesInt2ByteAligned a7,
Struct3BytesInt2ByteAligned a8,
Struct3BytesInt2ByteAligned a9)) {
Struct3BytesInt2ByteAligned a0;
Struct3BytesInt2ByteAligned a1;
Struct3BytesInt2ByteAligned a2;
Struct3BytesInt2ByteAligned a3;
Struct3BytesInt2ByteAligned a4;
Struct3BytesInt2ByteAligned a5;
Struct3BytesInt2ByteAligned a6;
Struct3BytesInt2ByteAligned a7;
Struct3BytesInt2ByteAligned a8;
Struct3BytesInt2ByteAligned a9;
a0.a0 = -1;
a0.a1 = 2;
a1.a0 = -3;
a1.a1 = 4;
a2.a0 = -5;
a2.a1 = 6;
a3.a0 = -7;
a3.a1 = 8;
a4.a0 = -9;
a4.a1 = 10;
a5.a0 = -11;
a5.a1 = 12;
a6.a0 = -13;
a6.a1 = 14;
a7.a0 = -15;
a7.a1 = 16;
a8.a0 = -17;
a8.a1 = 18;
a9.a0 = -19;
a9.a1 = 20;
std::cout << "Calling TestPassStruct3BytesInt2ByteAlignedx10("
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
<< a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
<< ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
<< static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
<< static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
<< static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
<< static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
<< static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
<< static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
<< static_cast<int>(a9.a1) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(10, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Exactly word size on 32-bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct4BytesHomogeneousInt16x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct4BytesHomogeneousInt16 a0,
Struct4BytesHomogeneousInt16 a1,
Struct4BytesHomogeneousInt16 a2,
Struct4BytesHomogeneousInt16 a3,
Struct4BytesHomogeneousInt16 a4,
Struct4BytesHomogeneousInt16 a5,
Struct4BytesHomogeneousInt16 a6,
Struct4BytesHomogeneousInt16 a7,
Struct4BytesHomogeneousInt16 a8,
Struct4BytesHomogeneousInt16 a9)) {
Struct4BytesHomogeneousInt16 a0;
Struct4BytesHomogeneousInt16 a1;
Struct4BytesHomogeneousInt16 a2;
Struct4BytesHomogeneousInt16 a3;
Struct4BytesHomogeneousInt16 a4;
Struct4BytesHomogeneousInt16 a5;
Struct4BytesHomogeneousInt16 a6;
Struct4BytesHomogeneousInt16 a7;
Struct4BytesHomogeneousInt16 a8;
Struct4BytesHomogeneousInt16 a9;
a0.a0 = -1;
a0.a1 = 2;
a1.a0 = -3;
a1.a1 = 4;
a2.a0 = -5;
a2.a1 = 6;
a3.a0 = -7;
a3.a1 = 8;
a4.a0 = -9;
a4.a1 = 10;
a5.a0 = -11;
a5.a1 = 12;
a6.a0 = -13;
a6.a1 = 14;
a7.a0 = -15;
a7.a1 = 16;
a8.a0 = -17;
a8.a1 = 18;
a9.a0 = -19;
a9.a1 = 20;
std::cout << "Calling TestPassStruct4BytesHomogeneousInt16x10("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(10, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Sub word size on 64 bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct7BytesHomogeneousUint8x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct7BytesHomogeneousUint8 a0,
Struct7BytesHomogeneousUint8 a1,
Struct7BytesHomogeneousUint8 a2,
Struct7BytesHomogeneousUint8 a3,
Struct7BytesHomogeneousUint8 a4,
Struct7BytesHomogeneousUint8 a5,
Struct7BytesHomogeneousUint8 a6,
Struct7BytesHomogeneousUint8 a7,
Struct7BytesHomogeneousUint8 a8,
Struct7BytesHomogeneousUint8 a9)) {
Struct7BytesHomogeneousUint8 a0;
Struct7BytesHomogeneousUint8 a1;
Struct7BytesHomogeneousUint8 a2;
Struct7BytesHomogeneousUint8 a3;
Struct7BytesHomogeneousUint8 a4;
Struct7BytesHomogeneousUint8 a5;
Struct7BytesHomogeneousUint8 a6;
Struct7BytesHomogeneousUint8 a7;
Struct7BytesHomogeneousUint8 a8;
Struct7BytesHomogeneousUint8 a9;
a0.a0 = 1;
a0.a1 = 2;
a0.a2 = 3;
a0.a3 = 4;
a0.a4 = 5;
a0.a5 = 6;
a0.a6 = 7;
a1.a0 = 8;
a1.a1 = 9;
a1.a2 = 10;
a1.a3 = 11;
a1.a4 = 12;
a1.a5 = 13;
a1.a6 = 14;
a2.a0 = 15;
a2.a1 = 16;
a2.a2 = 17;
a2.a3 = 18;
a2.a4 = 19;
a2.a5 = 20;
a2.a6 = 21;
a3.a0 = 22;
a3.a1 = 23;
a3.a2 = 24;
a3.a3 = 25;
a3.a4 = 26;
a3.a5 = 27;
a3.a6 = 28;
a4.a0 = 29;
a4.a1 = 30;
a4.a2 = 31;
a4.a3 = 32;
a4.a4 = 33;
a4.a5 = 34;
a4.a6 = 35;
a5.a0 = 36;
a5.a1 = 37;
a5.a2 = 38;
a5.a3 = 39;
a5.a4 = 40;
a5.a5 = 41;
a5.a6 = 42;
a6.a0 = 43;
a6.a1 = 44;
a6.a2 = 45;
a6.a3 = 46;
a6.a4 = 47;
a6.a5 = 48;
a6.a6 = 49;
a7.a0 = 50;
a7.a1 = 51;
a7.a2 = 52;
a7.a3 = 53;
a7.a4 = 54;
a7.a5 = 55;
a7.a6 = 56;
a8.a0 = 57;
a8.a1 = 58;
a8.a2 = 59;
a8.a3 = 60;
a8.a4 = 61;
a8.a5 = 62;
a8.a6 = 63;
a9.a0 = 64;
a9.a1 = 65;
a9.a2 = 66;
a9.a3 = 67;
a9.a4 = 68;
a9.a5 = 69;
a9.a6 = 70;
std::cout
<< "Calling TestPassStruct7BytesHomogeneousUint8x10("
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(2485, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Sub word size on 64 bit architectures.
// With alignment rules taken into account size is 8 bytes.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct7BytesInt4ByteAlignedx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct7BytesInt4ByteAligned a0,
Struct7BytesInt4ByteAligned a1,
Struct7BytesInt4ByteAligned a2,
Struct7BytesInt4ByteAligned a3,
Struct7BytesInt4ByteAligned a4,
Struct7BytesInt4ByteAligned a5,
Struct7BytesInt4ByteAligned a6,
Struct7BytesInt4ByteAligned a7,
Struct7BytesInt4ByteAligned a8,
Struct7BytesInt4ByteAligned a9)) {
Struct7BytesInt4ByteAligned a0;
Struct7BytesInt4ByteAligned a1;
Struct7BytesInt4ByteAligned a2;
Struct7BytesInt4ByteAligned a3;
Struct7BytesInt4ByteAligned a4;
Struct7BytesInt4ByteAligned a5;
Struct7BytesInt4ByteAligned a6;
Struct7BytesInt4ByteAligned a7;
Struct7BytesInt4ByteAligned a8;
Struct7BytesInt4ByteAligned a9;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a1.a0 = 4;
a1.a1 = -5;
a1.a2 = 6;
a2.a0 = -7;
a2.a1 = 8;
a2.a2 = -9;
a3.a0 = 10;
a3.a1 = -11;
a3.a2 = 12;
a4.a0 = -13;
a4.a1 = 14;
a4.a2 = -15;
a5.a0 = 16;
a5.a1 = -17;
a5.a2 = 18;
a6.a0 = -19;
a6.a1 = 20;
a6.a2 = -21;
a7.a0 = 22;
a7.a1 = -23;
a7.a2 = 24;
a8.a0 = -25;
a8.a1 = 26;
a8.a2 = -27;
a9.a0 = 28;
a9.a1 = -29;
a9.a2 = 30;
std::cout << "Calling TestPassStruct7BytesInt4ByteAlignedx10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
<< "), (" << a1.a0 << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
<< ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
<< ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
<< "), (" << a6.a0 << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
<< ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
<< a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
<< ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(15, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Exactly word size struct on 64bit architectures.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct8BytesIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct8BytesInt a0,
Struct8BytesInt a1,
Struct8BytesInt a2,
Struct8BytesInt a3,
Struct8BytesInt a4,
Struct8BytesInt a5,
Struct8BytesInt a6,
Struct8BytesInt a7,
Struct8BytesInt a8,
Struct8BytesInt a9)) {
Struct8BytesInt a0;
Struct8BytesInt a1;
Struct8BytesInt a2;
Struct8BytesInt a3;
Struct8BytesInt a4;
Struct8BytesInt a5;
Struct8BytesInt a6;
Struct8BytesInt a7;
Struct8BytesInt a8;
Struct8BytesInt a9;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a1.a0 = 4;
a1.a1 = -5;
a1.a2 = 6;
a2.a0 = -7;
a2.a1 = 8;
a2.a2 = -9;
a3.a0 = 10;
a3.a1 = -11;
a3.a2 = 12;
a4.a0 = -13;
a4.a1 = 14;
a4.a2 = -15;
a5.a0 = 16;
a5.a1 = -17;
a5.a2 = 18;
a6.a0 = -19;
a6.a1 = 20;
a6.a2 = -21;
a7.a0 = 22;
a7.a1 = -23;
a7.a2 = 24;
a8.a0 = -25;
a8.a1 = 26;
a8.a2 = -27;
a9.a0 = 28;
a9.a1 = -29;
a9.a2 = 30;
std::cout << "Calling TestPassStruct8BytesIntx10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
<< a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
<< ", " << a9.a1 << ", " << a9.a2 << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(15, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Arguments passed in FP registers as long as they fit.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct8BytesHomogeneousFloatx10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct8BytesHomogeneousFloat a0,
Struct8BytesHomogeneousFloat a1,
Struct8BytesHomogeneousFloat a2,
Struct8BytesHomogeneousFloat a3,
Struct8BytesHomogeneousFloat a4,
Struct8BytesHomogeneousFloat a5,
Struct8BytesHomogeneousFloat a6,
Struct8BytesHomogeneousFloat a7,
Struct8BytesHomogeneousFloat a8,
Struct8BytesHomogeneousFloat a9)) {
Struct8BytesHomogeneousFloat a0;
Struct8BytesHomogeneousFloat a1;
Struct8BytesHomogeneousFloat a2;
Struct8BytesHomogeneousFloat a3;
Struct8BytesHomogeneousFloat a4;
Struct8BytesHomogeneousFloat a5;
Struct8BytesHomogeneousFloat a6;
Struct8BytesHomogeneousFloat a7;
Struct8BytesHomogeneousFloat a8;
Struct8BytesHomogeneousFloat a9;
a0.a0 = -1.0;
a0.a1 = 2.0;
a1.a0 = -3.0;
a1.a1 = 4.0;
a2.a0 = -5.0;
a2.a1 = 6.0;
a3.a0 = -7.0;
a3.a1 = 8.0;
a4.a0 = -9.0;
a4.a1 = 10.0;
a5.a0 = -11.0;
a5.a1 = 12.0;
a6.a0 = -13.0;
a6.a1 = 14.0;
a7.a0 = -15.0;
a7.a1 = 16.0;
a8.a0 = -17.0;
a8.a1 = 18.0;
a9.a0 = -19.0;
a9.a1 = 20.0;
std::cout << "Calling TestPassStruct8BytesHomogeneousFloatx10("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// On x64, arguments go in int registers because it is not only float.
// 10 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct8BytesMixedx10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct8BytesMixed a0,
Struct8BytesMixed a1,
Struct8BytesMixed a2,
Struct8BytesMixed a3,
Struct8BytesMixed a4,
Struct8BytesMixed a5,
Struct8BytesMixed a6,
Struct8BytesMixed a7,
Struct8BytesMixed a8,
Struct8BytesMixed a9)) {
Struct8BytesMixed a0;
Struct8BytesMixed a1;
Struct8BytesMixed a2;
Struct8BytesMixed a3;
Struct8BytesMixed a4;
Struct8BytesMixed a5;
Struct8BytesMixed a6;
Struct8BytesMixed a7;
Struct8BytesMixed a8;
Struct8BytesMixed a9;
a0.a0 = -1.0;
a0.a1 = 2;
a0.a2 = -3;
a1.a0 = 4.0;
a1.a1 = -5;
a1.a2 = 6;
a2.a0 = -7.0;
a2.a1 = 8;
a2.a2 = -9;
a3.a0 = 10.0;
a3.a1 = -11;
a3.a2 = 12;
a4.a0 = -13.0;
a4.a1 = 14;
a4.a2 = -15;
a5.a0 = 16.0;
a5.a1 = -17;
a5.a2 = 18;
a6.a0 = -19.0;
a6.a1 = 20;
a6.a2 = -21;
a7.a0 = 22.0;
a7.a1 = -23;
a7.a2 = 24;
a8.a0 = -25.0;
a8.a1 = 26;
a8.a2 = -27;
a9.a0 = 28.0;
a9.a1 = -29;
a9.a2 = 30;
std::cout << "Calling TestPassStruct8BytesMixedx10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
<< a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
<< ", " << a9.a1 << ", " << a9.a2 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(15.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Argument is a single byte over a multiple of word size.
// 10 struct arguments will exhaust available registers.
// Struct only has 1-byte aligned fields to test struct alignment itself.
// Tests upper bytes in the integer registers that are partly filled.
// Tests stack alignment of non word size stack arguments.
DART_EXPORT intptr_t TestPassStruct9BytesHomogeneousUint8x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct9BytesHomogeneousUint8 a0,
Struct9BytesHomogeneousUint8 a1,
Struct9BytesHomogeneousUint8 a2,
Struct9BytesHomogeneousUint8 a3,
Struct9BytesHomogeneousUint8 a4,
Struct9BytesHomogeneousUint8 a5,
Struct9BytesHomogeneousUint8 a6,
Struct9BytesHomogeneousUint8 a7,
Struct9BytesHomogeneousUint8 a8,
Struct9BytesHomogeneousUint8 a9)) {
Struct9BytesHomogeneousUint8 a0;
Struct9BytesHomogeneousUint8 a1;
Struct9BytesHomogeneousUint8 a2;
Struct9BytesHomogeneousUint8 a3;
Struct9BytesHomogeneousUint8 a4;
Struct9BytesHomogeneousUint8 a5;
Struct9BytesHomogeneousUint8 a6;
Struct9BytesHomogeneousUint8 a7;
Struct9BytesHomogeneousUint8 a8;
Struct9BytesHomogeneousUint8 a9;
a0.a0 = 1;
a0.a1 = 2;
a0.a2 = 3;
a0.a3 = 4;
a0.a4 = 5;
a0.a5 = 6;
a0.a6 = 7;
a0.a7 = 8;
a0.a8 = 9;
a1.a0 = 10;
a1.a1 = 11;
a1.a2 = 12;
a1.a3 = 13;
a1.a4 = 14;
a1.a5 = 15;
a1.a6 = 16;
a1.a7 = 17;
a1.a8 = 18;
a2.a0 = 19;
a2.a1 = 20;
a2.a2 = 21;
a2.a3 = 22;
a2.a4 = 23;
a2.a5 = 24;
a2.a6 = 25;
a2.a7 = 26;
a2.a8 = 27;
a3.a0 = 28;
a3.a1 = 29;
a3.a2 = 30;
a3.a3 = 31;
a3.a4 = 32;
a3.a5 = 33;
a3.a6 = 34;
a3.a7 = 35;
a3.a8 = 36;
a4.a0 = 37;
a4.a1 = 38;
a4.a2 = 39;
a4.a3 = 40;
a4.a4 = 41;
a4.a5 = 42;
a4.a6 = 43;
a4.a7 = 44;
a4.a8 = 45;
a5.a0 = 46;
a5.a1 = 47;
a5.a2 = 48;
a5.a3 = 49;
a5.a4 = 50;
a5.a5 = 51;
a5.a6 = 52;
a5.a7 = 53;
a5.a8 = 54;
a6.a0 = 55;
a6.a1 = 56;
a6.a2 = 57;
a6.a3 = 58;
a6.a4 = 59;
a6.a5 = 60;
a6.a6 = 61;
a6.a7 = 62;
a6.a8 = 63;
a7.a0 = 64;
a7.a1 = 65;
a7.a2 = 66;
a7.a3 = 67;
a7.a4 = 68;
a7.a5 = 69;
a7.a6 = 70;
a7.a7 = 71;
a7.a8 = 72;
a8.a0 = 73;
a8.a1 = 74;
a8.a2 = 75;
a8.a3 = 76;
a8.a4 = 77;
a8.a5 = 78;
a8.a6 = 79;
a8.a7 = 80;
a8.a8 = 81;
a9.a0 = 82;
a9.a1 = 83;
a9.a2 = 84;
a9.a3 = 85;
a9.a4 = 86;
a9.a5 = 87;
a9.a6 = 88;
a9.a7 = 89;
a9.a8 = 90;
std::cout
<< "Calling TestPassStruct9BytesHomogeneousUint8x10("
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
<< ", " << static_cast<int>(a0.a8) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
<< ", " << static_cast<int>(a2.a8) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
<< ", " << static_cast<int>(a4.a8) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
<< ", " << static_cast<int>(a6.a8) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
<< ", " << static_cast<int>(a8.a8) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
<< "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(4095, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Argument is a single byte over a multiple of word size.
// With alignment rules taken into account size is 12 or 16 bytes.
// 10 struct arguments will exhaust available registers.
//
DART_EXPORT intptr_t TestPassStruct9BytesInt4Or8ByteAlignedx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct9BytesInt4Or8ByteAligned a0,
Struct9BytesInt4Or8ByteAligned a1,
Struct9BytesInt4Or8ByteAligned a2,
Struct9BytesInt4Or8ByteAligned a3,
Struct9BytesInt4Or8ByteAligned a4,
Struct9BytesInt4Or8ByteAligned a5,
Struct9BytesInt4Or8ByteAligned a6,
Struct9BytesInt4Or8ByteAligned a7,
Struct9BytesInt4Or8ByteAligned a8,
Struct9BytesInt4Or8ByteAligned a9)) {
Struct9BytesInt4Or8ByteAligned a0;
Struct9BytesInt4Or8ByteAligned a1;
Struct9BytesInt4Or8ByteAligned a2;
Struct9BytesInt4Or8ByteAligned a3;
Struct9BytesInt4Or8ByteAligned a4;
Struct9BytesInt4Or8ByteAligned a5;
Struct9BytesInt4Or8ByteAligned a6;
Struct9BytesInt4Or8ByteAligned a7;
Struct9BytesInt4Or8ByteAligned a8;
Struct9BytesInt4Or8ByteAligned a9;
a0.a0 = -1;
a0.a1 = 2;
a1.a0 = -3;
a1.a1 = 4;
a2.a0 = -5;
a2.a1 = 6;
a3.a0 = -7;
a3.a1 = 8;
a4.a0 = -9;
a4.a1 = 10;
a5.a0 = -11;
a5.a1 = 12;
a6.a0 = -13;
a6.a1 = 14;
a7.a0 = -15;
a7.a1 = 16;
a8.a0 = -17;
a8.a1 = 18;
a9.a0 = -19;
a9.a1 = 20;
std::cout << "Calling TestPassStruct9BytesInt4Or8ByteAlignedx10("
<< "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
<< a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
<< ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
<< static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
<< static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
<< static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
<< static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
<< static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
<< static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
<< static_cast<int>(a9.a1) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(10, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Arguments in FPU registers on arm hardfp and arm64.
// Struct arguments will exhaust available registers, and leave some empty.
// The last argument is to test whether arguments are backfilled.
DART_EXPORT intptr_t TestPassStruct12BytesHomogeneousFloatx6(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct12BytesHomogeneousFloat a0,
Struct12BytesHomogeneousFloat a1,
Struct12BytesHomogeneousFloat a2,
Struct12BytesHomogeneousFloat a3,
Struct12BytesHomogeneousFloat a4,
Struct12BytesHomogeneousFloat a5)) {
Struct12BytesHomogeneousFloat a0;
Struct12BytesHomogeneousFloat a1;
Struct12BytesHomogeneousFloat a2;
Struct12BytesHomogeneousFloat a3;
Struct12BytesHomogeneousFloat a4;
Struct12BytesHomogeneousFloat a5;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a1.a0 = 4.0;
a1.a1 = -5.0;
a1.a2 = 6.0;
a2.a0 = -7.0;
a2.a1 = 8.0;
a2.a2 = -9.0;
a3.a0 = 10.0;
a3.a1 = -11.0;
a3.a2 = 12.0;
a4.a0 = -13.0;
a4.a1 = 14.0;
a4.a2 = -15.0;
a5.a0 = 16.0;
a5.a1 = -17.0;
a5.a2 = 18.0;
std::cout << "Calling TestPassStruct12BytesHomogeneousFloatx6("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
<< a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
<< a5.a2 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5);
std::cout << "result = " << result << "\n";
CHECK_APPROX(9.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// On Linux x64 argument is transferred on stack because it is over 16 bytes.
// Arguments in FPU registers on arm hardfp and arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct16BytesHomogeneousFloatx5(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct16BytesHomogeneousFloat a0,
Struct16BytesHomogeneousFloat a1,
Struct16BytesHomogeneousFloat a2,
Struct16BytesHomogeneousFloat a3,
Struct16BytesHomogeneousFloat a4)) {
Struct16BytesHomogeneousFloat a0;
Struct16BytesHomogeneousFloat a1;
Struct16BytesHomogeneousFloat a2;
Struct16BytesHomogeneousFloat a3;
Struct16BytesHomogeneousFloat a4;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a0.a3 = 4.0;
a1.a0 = -5.0;
a1.a1 = 6.0;
a1.a2 = -7.0;
a1.a3 = 8.0;
a2.a0 = -9.0;
a2.a1 = 10.0;
a2.a2 = -11.0;
a2.a3 = 12.0;
a3.a0 = -13.0;
a3.a1 = 14.0;
a3.a2 = -15.0;
a3.a3 = 16.0;
a4.a0 = -17.0;
a4.a1 = 18.0;
a4.a2 = -19.0;
a4.a3 = 20.0;
std::cout << "Calling TestPassStruct16BytesHomogeneousFloatx5("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// On x64, arguments are split over FP and int registers.
// On x64, it will exhaust the integer registers with the 6th argument.
// The rest goes on the stack.
// On arm, arguments are 8 byte aligned.
DART_EXPORT intptr_t TestPassStruct16BytesMixedx10(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct16BytesMixed a0,
Struct16BytesMixed a1,
Struct16BytesMixed a2,
Struct16BytesMixed a3,
Struct16BytesMixed a4,
Struct16BytesMixed a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
Struct16BytesMixed a8,
Struct16BytesMixed a9)) {
Struct16BytesMixed a0;
Struct16BytesMixed a1;
Struct16BytesMixed a2;
Struct16BytesMixed a3;
Struct16BytesMixed a4;
Struct16BytesMixed a5;
Struct16BytesMixed a6;
Struct16BytesMixed a7;
Struct16BytesMixed a8;
Struct16BytesMixed a9;
a0.a0 = -1.0;
a0.a1 = 2;
a1.a0 = -3.0;
a1.a1 = 4;
a2.a0 = -5.0;
a2.a1 = 6;
a3.a0 = -7.0;
a3.a1 = 8;
a4.a0 = -9.0;
a4.a1 = 10;
a5.a0 = -11.0;
a5.a1 = 12;
a6.a0 = -13.0;
a6.a1 = 14;
a7.a0 = -15.0;
a7.a1 = 16;
a8.a0 = -17.0;
a8.a1 = 18;
a9.a0 = -19.0;
a9.a1 = 20;
std::cout << "Calling TestPassStruct16BytesMixedx10("
<< "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
<< a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
<< ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
<< a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
<< "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
<< a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// On x64, arguments are split over FP and int registers.
// On x64, it will exhaust the integer registers with the 6th argument.
// The rest goes on the stack.
// On arm, arguments are 4 byte aligned.
DART_EXPORT intptr_t TestPassStruct16BytesMixed2x10(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct16BytesMixed2 a0,
Struct16BytesMixed2 a1,
Struct16BytesMixed2 a2,
Struct16BytesMixed2 a3,
Struct16BytesMixed2 a4,
Struct16BytesMixed2 a5,
Struct16BytesMixed2 a6,
Struct16BytesMixed2 a7,
Struct16BytesMixed2 a8,
Struct16BytesMixed2 a9)) {
Struct16BytesMixed2 a0;
Struct16BytesMixed2 a1;
Struct16BytesMixed2 a2;
Struct16BytesMixed2 a3;
Struct16BytesMixed2 a4;
Struct16BytesMixed2 a5;
Struct16BytesMixed2 a6;
Struct16BytesMixed2 a7;
Struct16BytesMixed2 a8;
Struct16BytesMixed2 a9;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a0.a3 = 4;
a1.a0 = -5.0;
a1.a1 = 6.0;
a1.a2 = -7.0;
a1.a3 = 8;
a2.a0 = -9.0;
a2.a1 = 10.0;
a2.a2 = -11.0;
a2.a3 = 12;
a3.a0 = -13.0;
a3.a1 = 14.0;
a3.a2 = -15.0;
a3.a3 = 16;
a4.a0 = -17.0;
a4.a1 = 18.0;
a4.a2 = -19.0;
a4.a3 = 20;
a5.a0 = -21.0;
a5.a1 = 22.0;
a5.a2 = -23.0;
a5.a3 = 24;
a6.a0 = -25.0;
a6.a1 = 26.0;
a6.a2 = -27.0;
a6.a3 = 28;
a7.a0 = -29.0;
a7.a1 = 30.0;
a7.a2 = -31.0;
a7.a3 = 32;
a8.a0 = -33.0;
a8.a1 = 34.0;
a8.a2 = -35.0;
a8.a3 = 36;
a9.a0 = -37.0;
a9.a1 = 38.0;
a9.a2 = -39.0;
a9.a3 = 40;
std::cout << "Calling TestPassStruct16BytesMixed2x10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "), (" << a5.a0 << ", "
<< a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), (" << a6.a0
<< ", " << a6.a1 << ", " << a6.a2 << ", " << a6.a3 << "), ("
<< a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
<< a8.a3 << "), (" << a9.a0 << ", " << a9.a1 << ", " << a9.a2
<< ", " << a9.a3 << "))"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_APPROX(20.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Arguments are passed as pointer to copy on arm64.
// Tests that the memory allocated for copies are rounded up to word size.
DART_EXPORT intptr_t TestPassStruct17BytesIntx10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct17BytesInt a0,
Struct17BytesInt a1,
Struct17BytesInt a2,
Struct17BytesInt a3,
Struct17BytesInt a4,
Struct17BytesInt a5,
Struct17BytesInt a6,
Struct17BytesInt a7,
Struct17BytesInt a8,
Struct17BytesInt a9)) {
Struct17BytesInt a0;
Struct17BytesInt a1;
Struct17BytesInt a2;
Struct17BytesInt a3;
Struct17BytesInt a4;
Struct17BytesInt a5;
Struct17BytesInt a6;
Struct17BytesInt a7;
Struct17BytesInt a8;
Struct17BytesInt a9;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a1.a0 = 4;
a1.a1 = -5;
a1.a2 = 6;
a2.a0 = -7;
a2.a1 = 8;
a2.a2 = -9;
a3.a0 = 10;
a3.a1 = -11;
a3.a2 = 12;
a4.a0 = -13;
a4.a1 = 14;
a4.a2 = -15;
a5.a0 = 16;
a5.a1 = -17;
a5.a2 = 18;
a6.a0 = -19;
a6.a1 = 20;
a6.a2 = -21;
a7.a0 = 22;
a7.a1 = -23;
a7.a2 = 24;
a8.a0 = -25;
a8.a1 = 26;
a8.a2 = -27;
a9.a0 = 28;
a9.a1 = -29;
a9.a2 = 30;
std::cout << "Calling TestPassStruct17BytesIntx10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
<< "), (" << a1.a0 << ", " << a1.a1 << ", "
<< static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
<< ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
<< a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
<< ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
<< "), (" << a6.a0 << ", " << a6.a1 << ", "
<< static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
<< ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
<< a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
<< ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(15, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// The minimum alignment of this struct is only 1 byte based on its fields.
// Test that the memory backing these structs is extended to the right size.
//
DART_EXPORT intptr_t TestPassStruct19BytesHomogeneousUint8x10(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(Struct19BytesHomogeneousUint8 a0,
Struct19BytesHomogeneousUint8 a1,
Struct19BytesHomogeneousUint8 a2,
Struct19BytesHomogeneousUint8 a3,
Struct19BytesHomogeneousUint8 a4,
Struct19BytesHomogeneousUint8 a5,
Struct19BytesHomogeneousUint8 a6,
Struct19BytesHomogeneousUint8 a7,
Struct19BytesHomogeneousUint8 a8,
Struct19BytesHomogeneousUint8 a9)) {
Struct19BytesHomogeneousUint8 a0;
Struct19BytesHomogeneousUint8 a1;
Struct19BytesHomogeneousUint8 a2;
Struct19BytesHomogeneousUint8 a3;
Struct19BytesHomogeneousUint8 a4;
Struct19BytesHomogeneousUint8 a5;
Struct19BytesHomogeneousUint8 a6;
Struct19BytesHomogeneousUint8 a7;
Struct19BytesHomogeneousUint8 a8;
Struct19BytesHomogeneousUint8 a9;
a0.a0 = 1;
a0.a1 = 2;
a0.a2 = 3;
a0.a3 = 4;
a0.a4 = 5;
a0.a5 = 6;
a0.a6 = 7;
a0.a7 = 8;
a0.a8 = 9;
a0.a9 = 10;
a0.a10 = 11;
a0.a11 = 12;
a0.a12 = 13;
a0.a13 = 14;
a0.a14 = 15;
a0.a15 = 16;
a0.a16 = 17;
a0.a17 = 18;
a0.a18 = 19;
a1.a0 = 20;
a1.a1 = 21;
a1.a2 = 22;
a1.a3 = 23;
a1.a4 = 24;
a1.a5 = 25;
a1.a6 = 26;
a1.a7 = 27;
a1.a8 = 28;
a1.a9 = 29;
a1.a10 = 30;
a1.a11 = 31;
a1.a12 = 32;
a1.a13 = 33;
a1.a14 = 34;
a1.a15 = 35;
a1.a16 = 36;
a1.a17 = 37;
a1.a18 = 38;
a2.a0 = 39;
a2.a1 = 40;
a2.a2 = 41;
a2.a3 = 42;
a2.a4 = 43;
a2.a5 = 44;
a2.a6 = 45;
a2.a7 = 46;
a2.a8 = 47;
a2.a9 = 48;
a2.a10 = 49;
a2.a11 = 50;
a2.a12 = 51;
a2.a13 = 52;
a2.a14 = 53;
a2.a15 = 54;
a2.a16 = 55;
a2.a17 = 56;
a2.a18 = 57;
a3.a0 = 58;
a3.a1 = 59;
a3.a2 = 60;
a3.a3 = 61;
a3.a4 = 62;
a3.a5 = 63;
a3.a6 = 64;
a3.a7 = 65;
a3.a8 = 66;
a3.a9 = 67;
a3.a10 = 68;
a3.a11 = 69;
a3.a12 = 70;
a3.a13 = 71;
a3.a14 = 72;
a3.a15 = 73;
a3.a16 = 74;
a3.a17 = 75;
a3.a18 = 76;
a4.a0 = 77;
a4.a1 = 78;
a4.a2 = 79;
a4.a3 = 80;
a4.a4 = 81;
a4.a5 = 82;
a4.a6 = 83;
a4.a7 = 84;
a4.a8 = 85;
a4.a9 = 86;
a4.a10 = 87;
a4.a11 = 88;
a4.a12 = 89;
a4.a13 = 90;
a4.a14 = 91;
a4.a15 = 92;
a4.a16 = 93;
a4.a17 = 94;
a4.a18 = 95;
a5.a0 = 96;
a5.a1 = 97;
a5.a2 = 98;
a5.a3 = 99;
a5.a4 = 100;
a5.a5 = 101;
a5.a6 = 102;
a5.a7 = 103;
a5.a8 = 104;
a5.a9 = 105;
a5.a10 = 106;
a5.a11 = 107;
a5.a12 = 108;
a5.a13 = 109;
a5.a14 = 110;
a5.a15 = 111;
a5.a16 = 112;
a5.a17 = 113;
a5.a18 = 114;
a6.a0 = 115;
a6.a1 = 116;
a6.a2 = 117;
a6.a3 = 118;
a6.a4 = 119;
a6.a5 = 120;
a6.a6 = 121;
a6.a7 = 122;
a6.a8 = 123;
a6.a9 = 124;
a6.a10 = 125;
a6.a11 = 126;
a6.a12 = 127;
a6.a13 = 128;
a6.a14 = 129;
a6.a15 = 130;
a6.a16 = 131;
a6.a17 = 132;
a6.a18 = 133;
a7.a0 = 134;
a7.a1 = 135;
a7.a2 = 136;
a7.a3 = 137;
a7.a4 = 138;
a7.a5 = 139;
a7.a6 = 140;
a7.a7 = 141;
a7.a8 = 142;
a7.a9 = 143;
a7.a10 = 144;
a7.a11 = 145;
a7.a12 = 146;
a7.a13 = 147;
a7.a14 = 148;
a7.a15 = 149;
a7.a16 = 150;
a7.a17 = 151;
a7.a18 = 152;
a8.a0 = 153;
a8.a1 = 154;
a8.a2 = 155;
a8.a3 = 156;
a8.a4 = 157;
a8.a5 = 158;
a8.a6 = 159;
a8.a7 = 160;
a8.a8 = 161;
a8.a9 = 162;
a8.a10 = 163;
a8.a11 = 164;
a8.a12 = 165;
a8.a13 = 166;
a8.a14 = 167;
a8.a15 = 168;
a8.a16 = 169;
a8.a17 = 170;
a8.a18 = 171;
a9.a0 = 172;
a9.a1 = 173;
a9.a2 = 174;
a9.a3 = 175;
a9.a4 = 176;
a9.a5 = 177;
a9.a6 = 178;
a9.a7 = 179;
a9.a8 = 180;
a9.a9 = 181;
a9.a10 = 182;
a9.a11 = 183;
a9.a12 = 184;
a9.a13 = 185;
a9.a14 = 186;
a9.a15 = 187;
a9.a16 = 188;
a9.a17 = 189;
a9.a18 = 190;
std::cout
<< "Calling TestPassStruct19BytesHomogeneousUint8x10("
<< "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
<< ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
<< ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
<< ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
<< ", " << static_cast<int>(a0.a8) << ", " << static_cast<int>(a0.a9)
<< ", " << static_cast<int>(a0.a10) << ", " << static_cast<int>(a0.a11)
<< ", " << static_cast<int>(a0.a12) << ", " << static_cast<int>(a0.a13)
<< ", " << static_cast<int>(a0.a14) << ", " << static_cast<int>(a0.a15)
<< ", " << static_cast<int>(a0.a16) << ", " << static_cast<int>(a0.a17)
<< ", " << static_cast<int>(a0.a18) << "), (" << static_cast<int>(a1.a0)
<< ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
<< ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
<< ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
<< ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
<< ", " << static_cast<int>(a1.a9) << ", " << static_cast<int>(a1.a10)
<< ", " << static_cast<int>(a1.a11) << ", " << static_cast<int>(a1.a12)
<< ", " << static_cast<int>(a1.a13) << ", " << static_cast<int>(a1.a14)
<< ", " << static_cast<int>(a1.a15) << ", " << static_cast<int>(a1.a16)
<< ", " << static_cast<int>(a1.a17) << ", " << static_cast<int>(a1.a18)
<< "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
<< ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
<< ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
<< ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
<< ", " << static_cast<int>(a2.a8) << ", " << static_cast<int>(a2.a9)
<< ", " << static_cast<int>(a2.a10) << ", " << static_cast<int>(a2.a11)
<< ", " << static_cast<int>(a2.a12) << ", " << static_cast<int>(a2.a13)
<< ", " << static_cast<int>(a2.a14) << ", " << static_cast<int>(a2.a15)
<< ", " << static_cast<int>(a2.a16) << ", " << static_cast<int>(a2.a17)
<< ", " << static_cast<int>(a2.a18) << "), (" << static_cast<int>(a3.a0)
<< ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
<< ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
<< ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
<< ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
<< ", " << static_cast<int>(a3.a9) << ", " << static_cast<int>(a3.a10)
<< ", " << static_cast<int>(a3.a11) << ", " << static_cast<int>(a3.a12)
<< ", " << static_cast<int>(a3.a13) << ", " << static_cast<int>(a3.a14)
<< ", " << static_cast<int>(a3.a15) << ", " << static_cast<int>(a3.a16)
<< ", " << static_cast<int>(a3.a17) << ", " << static_cast<int>(a3.a18)
<< "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
<< ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
<< ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
<< ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
<< ", " << static_cast<int>(a4.a8) << ", " << static_cast<int>(a4.a9)
<< ", " << static_cast<int>(a4.a10) << ", " << static_cast<int>(a4.a11)
<< ", " << static_cast<int>(a4.a12) << ", " << static_cast<int>(a4.a13)
<< ", " << static_cast<int>(a4.a14) << ", " << static_cast<int>(a4.a15)
<< ", " << static_cast<int>(a4.a16) << ", " << static_cast<int>(a4.a17)
<< ", " << static_cast<int>(a4.a18) << "), (" << static_cast<int>(a5.a0)
<< ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
<< ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
<< ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
<< ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
<< ", " << static_cast<int>(a5.a9) << ", " << static_cast<int>(a5.a10)
<< ", " << static_cast<int>(a5.a11) << ", " << static_cast<int>(a5.a12)
<< ", " << static_cast<int>(a5.a13) << ", " << static_cast<int>(a5.a14)
<< ", " << static_cast<int>(a5.a15) << ", " << static_cast<int>(a5.a16)
<< ", " << static_cast<int>(a5.a17) << ", " << static_cast<int>(a5.a18)
<< "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
<< ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
<< ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
<< ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
<< ", " << static_cast<int>(a6.a8) << ", " << static_cast<int>(a6.a9)
<< ", " << static_cast<int>(a6.a10) << ", " << static_cast<int>(a6.a11)
<< ", " << static_cast<int>(a6.a12) << ", " << static_cast<int>(a6.a13)
<< ", " << static_cast<int>(a6.a14) << ", " << static_cast<int>(a6.a15)
<< ", " << static_cast<int>(a6.a16) << ", " << static_cast<int>(a6.a17)
<< ", " << static_cast<int>(a6.a18) << "), (" << static_cast<int>(a7.a0)
<< ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
<< ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
<< ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
<< ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
<< ", " << static_cast<int>(a7.a9) << ", " << static_cast<int>(a7.a10)
<< ", " << static_cast<int>(a7.a11) << ", " << static_cast<int>(a7.a12)
<< ", " << static_cast<int>(a7.a13) << ", " << static_cast<int>(a7.a14)
<< ", " << static_cast<int>(a7.a15) << ", " << static_cast<int>(a7.a16)
<< ", " << static_cast<int>(a7.a17) << ", " << static_cast<int>(a7.a18)
<< "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
<< ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
<< ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
<< ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
<< ", " << static_cast<int>(a8.a8) << ", " << static_cast<int>(a8.a9)
<< ", " << static_cast<int>(a8.a10) << ", " << static_cast<int>(a8.a11)
<< ", " << static_cast<int>(a8.a12) << ", " << static_cast<int>(a8.a13)
<< ", " << static_cast<int>(a8.a14) << ", " << static_cast<int>(a8.a15)
<< ", " << static_cast<int>(a8.a16) << ", " << static_cast<int>(a8.a17)
<< ", " << static_cast<int>(a8.a18) << "), (" << static_cast<int>(a9.a0)
<< ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
<< ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
<< ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
<< ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
<< ", " << static_cast<int>(a9.a9) << ", " << static_cast<int>(a9.a10)
<< ", " << static_cast<int>(a9.a11) << ", " << static_cast<int>(a9.a12)
<< ", " << static_cast<int>(a9.a13) << ", " << static_cast<int>(a9.a14)
<< ", " << static_cast<int>(a9.a15) << ", " << static_cast<int>(a9.a16)
<< ", " << static_cast<int>(a9.a17) << ", " << static_cast<int>(a9.a18)
<< "))"
<< ")\n";
int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(18145, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Argument too big to go into integer registers on arm64.
// The arguments are passed as pointers to copies.
// The amount of arguments exhausts the number of integer registers, such that
// pointers to copies are also passed on the stack.
DART_EXPORT intptr_t TestPassStruct20BytesHomogeneousInt32x10(
// NOLINTNEXTLINE(whitespace/parens)
int32_t (*f)(Struct20BytesHomogeneousInt32 a0,
Struct20BytesHomogeneousInt32 a1,
Struct20BytesHomogeneousInt32 a2,
Struct20BytesHomogeneousInt32 a3,
Struct20BytesHomogeneousInt32 a4,
Struct20BytesHomogeneousInt32 a5,
Struct20BytesHomogeneousInt32 a6,
Struct20BytesHomogeneousInt32 a7,
Struct20BytesHomogeneousInt32 a8,
Struct20BytesHomogeneousInt32 a9)) {
Struct20BytesHomogeneousInt32 a0;
Struct20BytesHomogeneousInt32 a1;
Struct20BytesHomogeneousInt32 a2;
Struct20BytesHomogeneousInt32 a3;
Struct20BytesHomogeneousInt32 a4;
Struct20BytesHomogeneousInt32 a5;
Struct20BytesHomogeneousInt32 a6;
Struct20BytesHomogeneousInt32 a7;
Struct20BytesHomogeneousInt32 a8;
Struct20BytesHomogeneousInt32 a9;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a0.a3 = 4;
a0.a4 = -5;
a1.a0 = 6;
a1.a1 = -7;
a1.a2 = 8;
a1.a3 = -9;
a1.a4 = 10;
a2.a0 = -11;
a2.a1 = 12;
a2.a2 = -13;
a2.a3 = 14;
a2.a4 = -15;
a3.a0 = 16;
a3.a1 = -17;
a3.a2 = 18;
a3.a3 = -19;
a3.a4 = 20;
a4.a0 = -21;
a4.a1 = 22;
a4.a2 = -23;
a4.a3 = 24;
a4.a4 = -25;
a5.a0 = 26;
a5.a1 = -27;
a5.a2 = 28;
a5.a3 = -29;
a5.a4 = 30;
a6.a0 = -31;
a6.a1 = 32;
a6.a2 = -33;
a6.a3 = 34;
a6.a4 = -35;
a7.a0 = 36;
a7.a1 = -37;
a7.a2 = 38;
a7.a3 = -39;
a7.a4 = 40;
a8.a0 = -41;
a8.a1 = 42;
a8.a2 = -43;
a8.a3 = 44;
a8.a4 = -45;
a9.a0 = 46;
a9.a1 = -47;
a9.a2 = 48;
a9.a3 = -49;
a9.a4 = 50;
std::cout << "Calling TestPassStruct20BytesHomogeneousInt32x10("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << ", "
<< a1.a2 << ", " << a1.a3 << ", " << a1.a4 << "), (" << a2.a0
<< ", " << a2.a1 << ", " << a2.a2 << ", " << a2.a3 << ", " << a2.a4
<< "), (" << a3.a0 << ", " << a3.a1 << ", " << a3.a2 << ", "
<< a3.a3 << ", " << a3.a4 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << ", " << a4.a4 << "), ("
<< a5.a0 << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << ", "
<< a5.a4 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
<< ", " << a6.a3 << ", " << a6.a4 << "), (" << a7.a0 << ", "
<< a7.a1 << ", " << a7.a2 << ", " << a7.a3 << ", " << a7.a4
<< "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
<< a8.a3 << ", " << a8.a4 << "), (" << a9.a0 << ", " << a9.a1
<< ", " << a9.a2 << ", " << a9.a3 << ", " << a9.a4 << "))"
<< ")\n";
int32_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
std::cout << "result = " << result << "\n";
CHECK_EQ(25, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Argument too big to go into FPU registers in hardfp and arm64.
DART_EXPORT intptr_t TestPassStruct20BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(Struct20BytesHomogeneousFloat a0)) {
Struct20BytesHomogeneousFloat a0;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a0.a3 = 4.0;
a0.a4 = -5.0;
std::cout << "Calling TestPassStruct20BytesHomogeneousFloat("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< ")\n";
float result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-3.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Arguments in FPU registers on arm64.
// 5 struct arguments will exhaust available registers.
DART_EXPORT intptr_t TestPassStruct32BytesHomogeneousDoublex5(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct32BytesHomogeneousDouble a0,
Struct32BytesHomogeneousDouble a1,
Struct32BytesHomogeneousDouble a2,
Struct32BytesHomogeneousDouble a3,
Struct32BytesHomogeneousDouble a4)) {
Struct32BytesHomogeneousDouble a0;
Struct32BytesHomogeneousDouble a1;
Struct32BytesHomogeneousDouble a2;
Struct32BytesHomogeneousDouble a3;
Struct32BytesHomogeneousDouble a4;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a0.a3 = 4.0;
a1.a0 = -5.0;
a1.a1 = 6.0;
a1.a2 = -7.0;
a1.a3 = 8.0;
a2.a0 = -9.0;
a2.a1 = 10.0;
a2.a2 = -11.0;
a2.a3 = 12.0;
a3.a0 = -13.0;
a3.a1 = 14.0;
a3.a2 = -15.0;
a3.a3 = 16.0;
a4.a0 = -17.0;
a4.a1 = 18.0;
a4.a2 = -19.0;
a4.a3 = 20.0;
std::cout << "Calling TestPassStruct32BytesHomogeneousDoublex5("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
<< a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
<< ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
<< a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
<< ", " << a4.a2 << ", " << a4.a3 << "))"
<< ")\n";
double result = f(a0, a1, a2, a3, a4);
std::cout << "result = " << result << "\n";
CHECK_APPROX(10.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Argument too big to go into FPU registers in arm64.
DART_EXPORT intptr_t TestPassStruct40BytesHomogeneousDouble(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct40BytesHomogeneousDouble a0)) {
Struct40BytesHomogeneousDouble a0;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a0.a3 = 4.0;
a0.a4 = -5.0;
std::cout << "Calling TestPassStruct40BytesHomogeneousDouble("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< ")\n";
double result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-3.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Test 1kb struct.
DART_EXPORT intptr_t TestPassStruct1024BytesHomogeneousUint64(
// NOLINTNEXTLINE(whitespace/parens)
uint64_t (*f)(Struct1024BytesHomogeneousUint64 a0)) {
Struct1024BytesHomogeneousUint64 a0;
a0.a0 = 1;
a0.a1 = 2;
a0.a2 = 3;
a0.a3 = 4;
a0.a4 = 5;
a0.a5 = 6;
a0.a6 = 7;
a0.a7 = 8;
a0.a8 = 9;
a0.a9 = 10;
a0.a10 = 11;
a0.a11 = 12;
a0.a12 = 13;
a0.a13 = 14;
a0.a14 = 15;
a0.a15 = 16;
a0.a16 = 17;
a0.a17 = 18;
a0.a18 = 19;
a0.a19 = 20;
a0.a20 = 21;
a0.a21 = 22;
a0.a22 = 23;
a0.a23 = 24;
a0.a24 = 25;
a0.a25 = 26;
a0.a26 = 27;
a0.a27 = 28;
a0.a28 = 29;
a0.a29 = 30;
a0.a30 = 31;
a0.a31 = 32;
a0.a32 = 33;
a0.a33 = 34;
a0.a34 = 35;
a0.a35 = 36;
a0.a36 = 37;
a0.a37 = 38;
a0.a38 = 39;
a0.a39 = 40;
a0.a40 = 41;
a0.a41 = 42;
a0.a42 = 43;
a0.a43 = 44;
a0.a44 = 45;
a0.a45 = 46;
a0.a46 = 47;
a0.a47 = 48;
a0.a48 = 49;
a0.a49 = 50;
a0.a50 = 51;
a0.a51 = 52;
a0.a52 = 53;
a0.a53 = 54;
a0.a54 = 55;
a0.a55 = 56;
a0.a56 = 57;
a0.a57 = 58;
a0.a58 = 59;
a0.a59 = 60;
a0.a60 = 61;
a0.a61 = 62;
a0.a62 = 63;
a0.a63 = 64;
a0.a64 = 65;
a0.a65 = 66;
a0.a66 = 67;
a0.a67 = 68;
a0.a68 = 69;
a0.a69 = 70;
a0.a70 = 71;
a0.a71 = 72;
a0.a72 = 73;
a0.a73 = 74;
a0.a74 = 75;
a0.a75 = 76;
a0.a76 = 77;
a0.a77 = 78;
a0.a78 = 79;
a0.a79 = 80;
a0.a80 = 81;
a0.a81 = 82;
a0.a82 = 83;
a0.a83 = 84;
a0.a84 = 85;
a0.a85 = 86;
a0.a86 = 87;
a0.a87 = 88;
a0.a88 = 89;
a0.a89 = 90;
a0.a90 = 91;
a0.a91 = 92;
a0.a92 = 93;
a0.a93 = 94;
a0.a94 = 95;
a0.a95 = 96;
a0.a96 = 97;
a0.a97 = 98;
a0.a98 = 99;
a0.a99 = 100;
a0.a100 = 101;
a0.a101 = 102;
a0.a102 = 103;
a0.a103 = 104;
a0.a104 = 105;
a0.a105 = 106;
a0.a106 = 107;
a0.a107 = 108;
a0.a108 = 109;
a0.a109 = 110;
a0.a110 = 111;
a0.a111 = 112;
a0.a112 = 113;
a0.a113 = 114;
a0.a114 = 115;
a0.a115 = 116;
a0.a116 = 117;
a0.a117 = 118;
a0.a118 = 119;
a0.a119 = 120;
a0.a120 = 121;
a0.a121 = 122;
a0.a122 = 123;
a0.a123 = 124;
a0.a124 = 125;
a0.a125 = 126;
a0.a126 = 127;
a0.a127 = 128;
std::cout << "Calling TestPassStruct1024BytesHomogeneousUint64("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << ", " << a0.a5 << ", " << a0.a6 << ", " << a0.a7
<< ", " << a0.a8 << ", " << a0.a9 << ", " << a0.a10 << ", "
<< a0.a11 << ", " << a0.a12 << ", " << a0.a13 << ", " << a0.a14
<< ", " << a0.a15 << ", " << a0.a16 << ", " << a0.a17 << ", "
<< a0.a18 << ", " << a0.a19 << ", " << a0.a20 << ", " << a0.a21
<< ", " << a0.a22 << ", " << a0.a23 << ", " << a0.a24 << ", "
<< a0.a25 << ", " << a0.a26 << ", " << a0.a27 << ", " << a0.a28
<< ", " << a0.a29 << ", " << a0.a30 << ", " << a0.a31 << ", "
<< a0.a32 << ", " << a0.a33 << ", " << a0.a34 << ", " << a0.a35
<< ", " << a0.a36 << ", " << a0.a37 << ", " << a0.a38 << ", "
<< a0.a39 << ", " << a0.a40 << ", " << a0.a41 << ", " << a0.a42
<< ", " << a0.a43 << ", " << a0.a44 << ", " << a0.a45 << ", "
<< a0.a46 << ", " << a0.a47 << ", " << a0.a48 << ", " << a0.a49
<< ", " << a0.a50 << ", " << a0.a51 << ", " << a0.a52 << ", "
<< a0.a53 << ", " << a0.a54 << ", " << a0.a55 << ", " << a0.a56
<< ", " << a0.a57 << ", " << a0.a58 << ", " << a0.a59 << ", "
<< a0.a60 << ", " << a0.a61 << ", " << a0.a62 << ", " << a0.a63
<< ", " << a0.a64 << ", " << a0.a65 << ", " << a0.a66 << ", "
<< a0.a67 << ", " << a0.a68 << ", " << a0.a69 << ", " << a0.a70
<< ", " << a0.a71 << ", " << a0.a72 << ", " << a0.a73 << ", "
<< a0.a74 << ", " << a0.a75 << ", " << a0.a76 << ", " << a0.a77
<< ", " << a0.a78 << ", " << a0.a79 << ", " << a0.a80 << ", "
<< a0.a81 << ", " << a0.a82 << ", " << a0.a83 << ", " << a0.a84
<< ", " << a0.a85 << ", " << a0.a86 << ", " << a0.a87 << ", "
<< a0.a88 << ", " << a0.a89 << ", " << a0.a90 << ", " << a0.a91
<< ", " << a0.a92 << ", " << a0.a93 << ", " << a0.a94 << ", "
<< a0.a95 << ", " << a0.a96 << ", " << a0.a97 << ", " << a0.a98
<< ", " << a0.a99 << ", " << a0.a100 << ", " << a0.a101 << ", "
<< a0.a102 << ", " << a0.a103 << ", " << a0.a104 << ", " << a0.a105
<< ", " << a0.a106 << ", " << a0.a107 << ", " << a0.a108 << ", "
<< a0.a109 << ", " << a0.a110 << ", " << a0.a111 << ", " << a0.a112
<< ", " << a0.a113 << ", " << a0.a114 << ", " << a0.a115 << ", "
<< a0.a116 << ", " << a0.a117 << ", " << a0.a118 << ", " << a0.a119
<< ", " << a0.a120 << ", " << a0.a121 << ", " << a0.a122 << ", "
<< a0.a123 << ", " << a0.a124 << ", " << a0.a125 << ", " << a0.a126
<< ", " << a0.a127 << "))"
<< ")\n";
uint64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(8256, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Tests the alignment of structs in FPU registers and backfilling.
DART_EXPORT intptr_t TestPassFloatStruct16BytesHomogeneousFloatFloatStruct1(
// NOLINTNEXTLINE(whitespace/parens)
float (*f)(float a0,
Struct16BytesHomogeneousFloat a1,
float a2,
Struct16BytesHomogeneousFloat a3,
float a4,
Struct16BytesHomogeneousFloat a5,
float a6,
Struct16BytesHomogeneousFloat a7,
float a8)) {
float a0;
Struct16BytesHomogeneousFloat a1;
float a2;
Struct16BytesHomogeneousFloat a3;
float a4;
Struct16BytesHomogeneousFloat a5;
float a6;
Struct16BytesHomogeneousFloat a7;
float a8;
a0 = -1.0;
a1.a0 = 2.0;
a1.a1 = -3.0;
a1.a2 = 4.0;
a1.a3 = -5.0;
a2 = 6.0;
a3.a0 = -7.0;
a3.a1 = 8.0;
a3.a2 = -9.0;
a3.a3 = 10.0;
a4 = -11.0;
a5.a0 = 12.0;
a5.a1 = -13.0;
a5.a2 = 14.0;
a5.a3 = -15.0;
a6 = 16.0;
a7.a0 = -17.0;
a7.a1 = 18.0;
a7.a2 = -19.0;
a7.a3 = 20.0;
a8 = -21.0;
std::cout << "Calling TestPassFloatStruct16BytesHomogeneousFloatFloatStruct1("
<< "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
<< ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
<< ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
<< ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
<< ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), " << a8 << ")"
<< ")\n";
float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-11.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Tests the alignment of structs in FPU registers and backfilling.
DART_EXPORT intptr_t TestPassFloatStruct32BytesHomogeneousDoubleFloatStruct(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(float a0,
Struct32BytesHomogeneousDouble a1,
float a2,
Struct32BytesHomogeneousDouble a3,
float a4,
Struct32BytesHomogeneousDouble a5,
float a6,
Struct32BytesHomogeneousDouble a7,
float a8)) {
float a0;
Struct32BytesHomogeneousDouble a1;
float a2;
Struct32BytesHomogeneousDouble a3;
float a4;
Struct32BytesHomogeneousDouble a5;
float a6;
Struct32BytesHomogeneousDouble a7;
float a8;
a0 = -1.0;
a1.a0 = 2.0;
a1.a1 = -3.0;
a1.a2 = 4.0;
a1.a3 = -5.0;
a2 = 6.0;
a3.a0 = -7.0;
a3.a1 = 8.0;
a3.a2 = -9.0;
a3.a3 = 10.0;
a4 = -11.0;
a5.a0 = 12.0;
a5.a1 = -13.0;
a5.a2 = 14.0;
a5.a3 = -15.0;
a6 = 16.0;
a7.a0 = -17.0;
a7.a1 = 18.0;
a7.a2 = -19.0;
a7.a3 = 20.0;
a8 = -21.0;
std::cout << "Calling TestPassFloatStruct32BytesHomogeneousDoubleFloatStruct("
<< "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
<< ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
<< ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
<< ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
<< ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
<< "), " << a8 << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-11.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Tests the alignment of structs in integers registers and on the stack.
// Arm32 aligns this struct at 8.
// Also, arm32 allocates the second struct partially in registers, partially
// on stack.
// Test backfilling of integer registers.
DART_EXPORT intptr_t TestPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(int8_t a0,
Struct16BytesMixed a1,
int8_t a2,
Struct16BytesMixed a3,
int8_t a4,
Struct16BytesMixed a5,
int8_t a6,
Struct16BytesMixed a7,
int8_t a8)) {
int8_t a0;
Struct16BytesMixed a1;
int8_t a2;
Struct16BytesMixed a3;
int8_t a4;
Struct16BytesMixed a5;
int8_t a6;
Struct16BytesMixed a7;
int8_t a8;
a0 = -1;
a1.a0 = 2.0;
a1.a1 = -3;
a2 = 4;
a3.a0 = -5.0;
a3.a1 = 6;
a4 = -7;
a5.a0 = 8.0;
a5.a1 = -9;
a6 = 10;
a7.a0 = -11.0;
a7.a1 = 12;
a8 = -13;
std::cout << "Calling TestPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn("
<< "(" << static_cast<int>(a0) << ", (" << a1.a0 << ", " << a1.a1
<< "), " << static_cast<int>(a2) << ", (" << a3.a0 << ", " << a3.a1
<< "), " << static_cast<int>(a4) << ", (" << a5.a0 << ", " << a5.a1
<< "), " << static_cast<int>(a6) << ", (" << a7.a0 << ", " << a7.a1
<< "), " << static_cast<int>(a8) << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-7.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
// structs. The rest of the structs will go on the stack.
// The int will be backfilled into the int register.
DART_EXPORT intptr_t TestPassDoublex6Struct16BytesMixedx4Int32(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(double a0,
double a1,
double a2,
double a3,
double a4,
double a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
Struct16BytesMixed a8,
Struct16BytesMixed a9,
int32_t a10)) {
double a0;
double a1;
double a2;
double a3;
double a4;
double a5;
Struct16BytesMixed a6;
Struct16BytesMixed a7;
Struct16BytesMixed a8;
Struct16BytesMixed a9;
int32_t a10;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4.0;
a4 = -5.0;
a5 = 6.0;
a6.a0 = -7.0;
a6.a1 = 8;
a7.a0 = -9.0;
a7.a1 = 10;
a8.a0 = -11.0;
a8.a1 = 12;
a9.a0 = -13.0;
a9.a1 = 14;
a10 = -15;
std::cout << "Calling TestPassDoublex6Struct16BytesMixedx4Int32("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0
<< ", " << a7.a1 << "), (" << a8.a0 << ", " << a8.a1 << "), ("
<< a9.a0 << ", " << a9.a1 << "), " << a10 << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-8.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// On Linux x64, it will exhaust int registers first.
// The rest of the structs will go on the stack.
// The double will be backfilled into the xmm register.
DART_EXPORT intptr_t TestPassInt32x4Struct16BytesMixedx4Double(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
Struct16BytesMixed a4,
Struct16BytesMixed a5,
Struct16BytesMixed a6,
Struct16BytesMixed a7,
double a8)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
Struct16BytesMixed a4;
Struct16BytesMixed a5;
Struct16BytesMixed a6;
Struct16BytesMixed a7;
double a8;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4.a0 = -5.0;
a4.a1 = 6;
a5.a0 = -7.0;
a5.a1 = 8;
a6.a0 = -9.0;
a6.a1 = 10;
a7.a0 = -11.0;
a7.a1 = 12;
a8 = -13.0;
std::cout << "Calling TestPassInt32x4Struct16BytesMixedx4Double("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", ("
<< a4.a0 << ", " << a4.a1 << "), (" << a5.a0 << ", " << a5.a1
<< "), (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0 << ", "
<< a7.a1 << "), " << a8 << ")"
<< ")\n";
double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-7.0, result);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// On various architectures, first struct is allocated on stack.
// Check that the other two arguments are allocated on registers.
DART_EXPORT intptr_t TestPassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
// NOLINTNEXTLINE(whitespace/parens)
double (*f)(Struct40BytesHomogeneousDouble a0,
Struct4BytesHomogeneousInt16 a1,
Struct8BytesHomogeneousFloat a2)) {
Struct40BytesHomogeneousDouble a0;
Struct4BytesHomogeneousInt16 a1;
Struct8BytesHomogeneousFloat a2;
a0.a0 = -1.0;
a0.a1 = 2.0;
a0.a2 = -3.0;
a0.a3 = 4.0;
a0.a4 = -5.0;
a1.a0 = 6;
a1.a1 = -7;
a2.a0 = 8.0;
a2.a1 = -9.0;
std::cout << "Calling TestPassStruct40BytesHomogeneousDoubleStruct4BytesHomo("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << "), ("
<< a2.a0 << ", " << a2.a1 << "))"
<< ")\n";
double result = f(a0, a1, a2);
std::cout << "result = " << result << "\n";
CHECK_APPROX(-5.0, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result);
return 0;
}
// Used for testing structs by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT intptr_t TestPassStructAlignmentInt16(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructAlignmentInt16 a0)) {
StructAlignmentInt16 a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
std::cout << "Calling TestPassStructAlignmentInt16("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(-2, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Test alignment and padding of 32 byte int within struct.
DART_EXPORT intptr_t TestPassStructAlignmentInt32(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructAlignmentInt32 a0)) {
StructAlignmentInt32 a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
std::cout << "Calling TestPassStructAlignmentInt32("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(-2, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Test alignment and padding of 64 byte int within struct.
DART_EXPORT intptr_t TestPassStructAlignmentInt64(
// NOLINTNEXTLINE(whitespace/parens)
int64_t (*f)(StructAlignmentInt64 a0)) {
StructAlignmentInt64 a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
std::cout << "Calling TestPassStructAlignmentInt64("
<< "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
<< static_cast<int>(a0.a2) << "))"
<< ")\n";
int64_t result = f(a0);
std::cout << "result = " << result << "\n";
CHECK_EQ(-2, result);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result);
return 0;
}
// Used for testing structs by value.
// Smallest struct with data.
DART_EXPORT intptr_t TestReturnStruct1ByteInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct1ByteInt (*f)(int8_t a0)) {
int8_t a0;
a0 = -1;
std::cout << "Calling TestReturnStruct1ByteInt("
<< "(" << static_cast<int>(a0) << ")"
<< ")\n";
Struct1ByteInt result = f(a0);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0);
CHECK_EQ(0, result.a0);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0);
CHECK_EQ(0, result.a0);
return 0;
}
// Used for testing structs by value.
// Smaller than word size return value on all architectures.
DART_EXPORT intptr_t TestReturnStruct3BytesHomogeneousUint8(
// NOLINTNEXTLINE(whitespace/parens)
Struct3BytesHomogeneousUint8 (*f)(uint8_t a0, uint8_t a1, uint8_t a2)) {
uint8_t a0;
uint8_t a1;
uint8_t a2;
a0 = 1;
a1 = 2;
a2 = 3;
std::cout << "Calling TestReturnStruct3BytesHomogeneousUint8("
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ")"
<< ")\n";
Struct3BytesHomogeneousUint8 result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs by value.
// Smaller than word size return value on all architectures.
// With alignment rules taken into account size is 4 bytes.
DART_EXPORT intptr_t TestReturnStruct3BytesInt2ByteAligned(
// NOLINTNEXTLINE(whitespace/parens)
Struct3BytesInt2ByteAligned (*f)(int16_t a0, int8_t a1)) {
int16_t a0;
int8_t a1;
a0 = -1;
a1 = 2;
std::cout << "Calling TestReturnStruct3BytesInt2ByteAligned("
<< "(" << a0 << ", " << static_cast<int>(a1) << ")"
<< ")\n";
Struct3BytesInt2ByteAligned result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs by value.
// Word size return value on 32 bit architectures..
DART_EXPORT intptr_t TestReturnStruct4BytesHomogeneousInt16(
// NOLINTNEXTLINE(whitespace/parens)
Struct4BytesHomogeneousInt16 (*f)(int16_t a0, int16_t a1)) {
int16_t a0;
int16_t a1;
a0 = -1;
a1 = 2;
std::cout << "Calling TestReturnStruct4BytesHomogeneousInt16("
<< "(" << a0 << ", " << a1 << ")"
<< ")\n";
Struct4BytesHomogeneousInt16 result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs by value.
// Non-wordsize return value.
DART_EXPORT intptr_t TestReturnStruct7BytesHomogeneousUint8(
// NOLINTNEXTLINE(whitespace/parens)
Struct7BytesHomogeneousUint8 (*f)(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6)) {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
a0 = 1;
a1 = 2;
a2 = 3;
a3 = 4;
a4 = 5;
a5 = 6;
a6 = 7;
std::cout << "Calling TestReturnStruct7BytesHomogeneousUint8("
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ")"
<< ")\n";
Struct7BytesHomogeneousUint8 result = f(a0, a1, a2, a3, a4, a5, a6);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
CHECK_EQ(a5, result.a5);
CHECK_EQ(a6, result.a6);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
return 0;
}
// Used for testing structs by value.
// Non-wordsize return value.
// With alignment rules taken into account size is 8 bytes.
DART_EXPORT intptr_t TestReturnStruct7BytesInt4ByteAligned(
// NOLINTNEXTLINE(whitespace/parens)
Struct7BytesInt4ByteAligned (*f)(int32_t a0, int16_t a1, int8_t a2)) {
int32_t a0;
int16_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStruct7BytesInt4ByteAligned("
<< "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
<< ")\n";
Struct7BytesInt4ByteAligned result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs by value.
// Return value in integer registers on many architectures.
DART_EXPORT intptr_t TestReturnStruct8BytesInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesInt (*f)(int16_t a0, int16_t a1, int32_t a2)) {
int16_t a0;
int16_t a1;
int32_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStruct8BytesInt("
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< ")\n";
Struct8BytesInt result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs by value.
// Return value in FP registers on many architectures.
DART_EXPORT intptr_t TestReturnStruct8BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesHomogeneousFloat (*f)(float a0, float a1)) {
float a0;
float a1;
a0 = -1.0;
a1 = 2.0;
std::cout << "Calling TestReturnStruct8BytesHomogeneousFloat("
<< "(" << a0 << ", " << a1 << ")"
<< ")\n";
Struct8BytesHomogeneousFloat result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
return 0;
}
// Used for testing structs by value.
// Return value split over FP and integer register in x64.
DART_EXPORT intptr_t TestReturnStruct8BytesMixed(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesMixed (*f)(float a0, int16_t a1, int16_t a2)) {
float a0;
int16_t a1;
int16_t a2;
a0 = -1.0;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStruct8BytesMixed("
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< ")\n";
Struct8BytesMixed result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs by value.
// The minimum alignment of this struct is only 1 byte based on its fields.
// Test that the memory backing these structs is the right size and that
// dart:ffi trampolines do not write outside this size.
DART_EXPORT intptr_t TestReturnStruct9BytesHomogeneousUint8(
// NOLINTNEXTLINE(whitespace/parens)
Struct9BytesHomogeneousUint8 (*f)(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6,
uint8_t a7,
uint8_t a8)) {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
uint8_t a7;
uint8_t a8;
a0 = 1;
a1 = 2;
a2 = 3;
a3 = 4;
a4 = 5;
a5 = 6;
a6 = 7;
a7 = 8;
a8 = 9;
std::cout << "Calling TestReturnStruct9BytesHomogeneousUint8("
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
<< ", " << static_cast<int>(a8) << ")"
<< ")\n";
Struct9BytesHomogeneousUint8 result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ", "
<< static_cast<int>(result.a7) << ", "
<< static_cast<int>(result.a8) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
CHECK_EQ(a5, result.a5);
CHECK_EQ(a6, result.a6);
CHECK_EQ(a7, result.a7);
CHECK_EQ(a8, result.a8);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
return 0;
}
// Used for testing structs by value.
// Return value in two integer registers on x64.
// With alignment rules taken into account size is 12 or 16 bytes.
DART_EXPORT intptr_t TestReturnStruct9BytesInt4Or8ByteAligned(
// NOLINTNEXTLINE(whitespace/parens)
Struct9BytesInt4Or8ByteAligned (*f)(int64_t a0, int8_t a1)) {
int64_t a0;
int8_t a1;
a0 = -1;
a1 = 2;
std::cout << "Calling TestReturnStruct9BytesInt4Or8ByteAligned("
<< "(" << a0 << ", " << static_cast<int>(a1) << ")"
<< ")\n";
Struct9BytesInt4Or8ByteAligned result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs by value.
// Return value in FPU registers, but does not use all registers on arm hardfp
// and arm64.
DART_EXPORT intptr_t TestReturnStruct12BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct12BytesHomogeneousFloat (*f)(float a0, float a1, float a2)) {
float a0;
float a1;
float a2;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
std::cout << "Calling TestReturnStruct12BytesHomogeneousFloat("
<< "(" << a0 << ", " << a1 << ", " << a2 << ")"
<< ")\n";
Struct12BytesHomogeneousFloat result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
return 0;
}
// Used for testing structs by value.
// Return value in FPU registers on arm hardfp and arm64.
DART_EXPORT intptr_t TestReturnStruct16BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct16BytesHomogeneousFloat (
*f)(float a0, float a1, float a2, float a3)) {
float a0;
float a1;
float a2;
float a3;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4.0;
std::cout << "Calling TestReturnStruct16BytesHomogeneousFloat("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< ")\n";
Struct16BytesHomogeneousFloat result = f(a0, a1, a2, a3);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_APPROX(a3, result.a3);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
return 0;
}
// Used for testing structs by value.
// Return value split over FP and integer register in x64.
DART_EXPORT intptr_t TestReturnStruct16BytesMixed(
// NOLINTNEXTLINE(whitespace/parens)
Struct16BytesMixed (*f)(double a0, int64_t a1)) {
double a0;
int64_t a1;
a0 = -1.0;
a1 = 2;
std::cout << "Calling TestReturnStruct16BytesMixed("
<< "(" << a0 << ", " << a1 << ")"
<< ")\n";
Struct16BytesMixed result = f(a0, a1);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_EQ(a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0);
CHECK_EQ(0, result.a1);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1);
CHECK_APPROX(0.0, result.a0);
CHECK_EQ(0, result.a1);
return 0;
}
// Used for testing structs by value.
// Return value split over FP and integer register in x64.
// The integer register contains half float half int.
DART_EXPORT intptr_t TestReturnStruct16BytesMixed2(
// NOLINTNEXTLINE(whitespace/parens)
Struct16BytesMixed2 (*f)(float a0, float a1, float a2, int32_t a3)) {
float a0;
float a1;
float a2;
int32_t a3;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4;
std::cout << "Calling TestReturnStruct16BytesMixed2("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< ")\n";
Struct16BytesMixed2 result = f(a0, a1, a2, a3);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_EQ(a3, result.a3);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_EQ(0, result.a3);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_EQ(0, result.a3);
return 0;
}
// Used for testing structs by value.
// Rerturn value returned in preallocated space passed by pointer on most ABIs.
// Is non word size on purpose, to test that structs are rounded up to word size
// on all ABIs.
DART_EXPORT intptr_t TestReturnStruct17BytesInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct17BytesInt (*f)(int64_t a0, int64_t a1, int8_t a2)) {
int64_t a0;
int64_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStruct17BytesInt("
<< "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
<< ")\n";
Struct17BytesInt result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs by value.
// The minimum alignment of this struct is only 1 byte based on its fields.
// Test that the memory backing these structs is the right size and that
// dart:ffi trampolines do not write outside this size.
DART_EXPORT intptr_t TestReturnStruct19BytesHomogeneousUint8(
// NOLINTNEXTLINE(whitespace/parens)
Struct19BytesHomogeneousUint8 (*f)(uint8_t a0,
uint8_t a1,
uint8_t a2,
uint8_t a3,
uint8_t a4,
uint8_t a5,
uint8_t a6,
uint8_t a7,
uint8_t a8,
uint8_t a9,
uint8_t a10,
uint8_t a11,
uint8_t a12,
uint8_t a13,
uint8_t a14,
uint8_t a15,
uint8_t a16,
uint8_t a17,
uint8_t a18)) {
uint8_t a0;
uint8_t a1;
uint8_t a2;
uint8_t a3;
uint8_t a4;
uint8_t a5;
uint8_t a6;
uint8_t a7;
uint8_t a8;
uint8_t a9;
uint8_t a10;
uint8_t a11;
uint8_t a12;
uint8_t a13;
uint8_t a14;
uint8_t a15;
uint8_t a16;
uint8_t a17;
uint8_t a18;
a0 = 1;
a1 = 2;
a2 = 3;
a3 = 4;
a4 = 5;
a5 = 6;
a6 = 7;
a7 = 8;
a8 = 9;
a9 = 10;
a10 = 11;
a11 = 12;
a12 = 13;
a13 = 14;
a14 = 15;
a15 = 16;
a16 = 17;
a17 = 18;
a18 = 19;
std::cout << "Calling TestReturnStruct19BytesHomogeneousUint8("
<< "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
<< ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
<< ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
<< ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
<< ", " << static_cast<int>(a8) << ", " << static_cast<int>(a9)
<< ", " << static_cast<int>(a10) << ", " << static_cast<int>(a11)
<< ", " << static_cast<int>(a12) << ", " << static_cast<int>(a13)
<< ", " << static_cast<int>(a14) << ", " << static_cast<int>(a15)
<< ", " << static_cast<int>(a16) << ", " << static_cast<int>(a17)
<< ", " << static_cast<int>(a18) << ")"
<< ")\n";
Struct19BytesHomogeneousUint8 result =
f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
a16, a17, a18);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", "
<< static_cast<int>(result.a1) << ", "
<< static_cast<int>(result.a2) << ", "
<< static_cast<int>(result.a3) << ", "
<< static_cast<int>(result.a4) << ", "
<< static_cast<int>(result.a5) << ", "
<< static_cast<int>(result.a6) << ", "
<< static_cast<int>(result.a7) << ", "
<< static_cast<int>(result.a8) << ", "
<< static_cast<int>(result.a9) << ", "
<< static_cast<int>(result.a10) << ", "
<< static_cast<int>(result.a11) << ", "
<< static_cast<int>(result.a12) << ", "
<< static_cast<int>(result.a13) << ", "
<< static_cast<int>(result.a14) << ", "
<< static_cast<int>(result.a15) << ", "
<< static_cast<int>(result.a16) << ", "
<< static_cast<int>(result.a17) << ", "
<< static_cast<int>(result.a18) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
CHECK_EQ(a5, result.a5);
CHECK_EQ(a6, result.a6);
CHECK_EQ(a7, result.a7);
CHECK_EQ(a8, result.a8);
CHECK_EQ(a9, result.a9);
CHECK_EQ(a10, result.a10);
CHECK_EQ(a11, result.a11);
CHECK_EQ(a12, result.a12);
CHECK_EQ(a13, result.a13);
CHECK_EQ(a14, result.a14);
CHECK_EQ(a15, result.a15);
CHECK_EQ(a16, result.a16);
CHECK_EQ(a17, result.a17);
CHECK_EQ(a18, result.a18);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
a15, a16, a17, a18);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
CHECK_EQ(0, result.a9);
CHECK_EQ(0, result.a10);
CHECK_EQ(0, result.a11);
CHECK_EQ(0, result.a12);
CHECK_EQ(0, result.a13);
CHECK_EQ(0, result.a14);
CHECK_EQ(0, result.a15);
CHECK_EQ(0, result.a16);
CHECK_EQ(0, result.a17);
CHECK_EQ(0, result.a18);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
a15, a16, a17, a18);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
CHECK_EQ(0, result.a9);
CHECK_EQ(0, result.a10);
CHECK_EQ(0, result.a11);
CHECK_EQ(0, result.a12);
CHECK_EQ(0, result.a13);
CHECK_EQ(0, result.a14);
CHECK_EQ(0, result.a15);
CHECK_EQ(0, result.a16);
CHECK_EQ(0, result.a17);
CHECK_EQ(0, result.a18);
return 0;
}
// Used for testing structs by value.
// Return value too big to go in cpu registers on arm64.
DART_EXPORT intptr_t TestReturnStruct20BytesHomogeneousInt32(
// NOLINTNEXTLINE(whitespace/parens)
Struct20BytesHomogeneousInt32 (
*f)(int32_t a0, int32_t a1, int32_t a2, int32_t a3, int32_t a4)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4 = -5;
std::cout << "Calling TestReturnStruct20BytesHomogeneousInt32("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< ")\n";
Struct20BytesHomogeneousInt32 result = f(a0, a1, a2, a3, a4);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
return 0;
}
// Used for testing structs by value.
// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
DART_EXPORT intptr_t TestReturnStruct20BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct20BytesHomogeneousFloat (
*f)(float a0, float a1, float a2, float a3, float a4)) {
float a0;
float a1;
float a2;
float a3;
float a4;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4.0;
a4 = -5.0;
std::cout << "Calling TestReturnStruct20BytesHomogeneousFloat("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< ")\n";
Struct20BytesHomogeneousFloat result = f(a0, a1, a2, a3, a4);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_APPROX(a3, result.a3);
CHECK_APPROX(a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
CHECK_APPROX(0.0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
CHECK_APPROX(0.0, result.a4);
return 0;
}
// Used for testing structs by value.
// Return value in FPU registers on arm64.
DART_EXPORT intptr_t TestReturnStruct32BytesHomogeneousDouble(
// NOLINTNEXTLINE(whitespace/parens)
Struct32BytesHomogeneousDouble (
*f)(double a0, double a1, double a2, double a3)) {
double a0;
double a1;
double a2;
double a3;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4.0;
std::cout << "Calling TestReturnStruct32BytesHomogeneousDouble("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
<< ")\n";
Struct32BytesHomogeneousDouble result = f(a0, a1, a2, a3);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_APPROX(a3, result.a3);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
return 0;
}
// Used for testing structs by value.
// Return value too big to go in FPU registers on arm64.
DART_EXPORT intptr_t TestReturnStruct40BytesHomogeneousDouble(
// NOLINTNEXTLINE(whitespace/parens)
Struct40BytesHomogeneousDouble (
*f)(double a0, double a1, double a2, double a3, double a4)) {
double a0;
double a1;
double a2;
double a3;
double a4;
a0 = -1.0;
a1 = 2.0;
a2 = -3.0;
a3 = 4.0;
a4 = -5.0;
std::cout << "Calling TestReturnStruct40BytesHomogeneousDouble("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ")"
<< ")\n";
Struct40BytesHomogeneousDouble result = f(a0, a1, a2, a3, a4);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_APPROX(a0, result.a0);
CHECK_APPROX(a1, result.a1);
CHECK_APPROX(a2, result.a2);
CHECK_APPROX(a3, result.a3);
CHECK_APPROX(a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
CHECK_APPROX(0.0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
CHECK_APPROX(0.0, result.a2);
CHECK_APPROX(0.0, result.a3);
CHECK_APPROX(0.0, result.a4);
return 0;
}
// Used for testing structs by value.
// Test 1kb struct.
DART_EXPORT intptr_t TestReturnStruct1024BytesHomogeneousUint64(
// NOLINTNEXTLINE(whitespace/parens)
Struct1024BytesHomogeneousUint64 (*f)(uint64_t a0,
uint64_t a1,
uint64_t a2,
uint64_t a3,
uint64_t a4,
uint64_t a5,
uint64_t a6,
uint64_t a7,
uint64_t a8,
uint64_t a9,
uint64_t a10,
uint64_t a11,
uint64_t a12,
uint64_t a13,
uint64_t a14,
uint64_t a15,
uint64_t a16,
uint64_t a17,
uint64_t a18,
uint64_t a19,
uint64_t a20,
uint64_t a21,
uint64_t a22,
uint64_t a23,
uint64_t a24,
uint64_t a25,
uint64_t a26,
uint64_t a27,
uint64_t a28,
uint64_t a29,
uint64_t a30,
uint64_t a31,
uint64_t a32,
uint64_t a33,
uint64_t a34,
uint64_t a35,
uint64_t a36,
uint64_t a37,
uint64_t a38,
uint64_t a39,
uint64_t a40,
uint64_t a41,
uint64_t a42,
uint64_t a43,
uint64_t a44,
uint64_t a45,
uint64_t a46,
uint64_t a47,
uint64_t a48,
uint64_t a49,
uint64_t a50,
uint64_t a51,
uint64_t a52,
uint64_t a53,
uint64_t a54,
uint64_t a55,
uint64_t a56,
uint64_t a57,
uint64_t a58,
uint64_t a59,
uint64_t a60,
uint64_t a61,
uint64_t a62,
uint64_t a63,
uint64_t a64,
uint64_t a65,
uint64_t a66,
uint64_t a67,
uint64_t a68,
uint64_t a69,
uint64_t a70,
uint64_t a71,
uint64_t a72,
uint64_t a73,
uint64_t a74,
uint64_t a75,
uint64_t a76,
uint64_t a77,
uint64_t a78,
uint64_t a79,
uint64_t a80,
uint64_t a81,
uint64_t a82,
uint64_t a83,
uint64_t a84,
uint64_t a85,
uint64_t a86,
uint64_t a87,
uint64_t a88,
uint64_t a89,
uint64_t a90,
uint64_t a91,
uint64_t a92,
uint64_t a93,
uint64_t a94,
uint64_t a95,
uint64_t a96,
uint64_t a97,
uint64_t a98,
uint64_t a99,
uint64_t a100,
uint64_t a101,
uint64_t a102,
uint64_t a103,
uint64_t a104,
uint64_t a105,
uint64_t a106,
uint64_t a107,
uint64_t a108,
uint64_t a109,
uint64_t a110,
uint64_t a111,
uint64_t a112,
uint64_t a113,
uint64_t a114,
uint64_t a115,
uint64_t a116,
uint64_t a117,
uint64_t a118,
uint64_t a119,
uint64_t a120,
uint64_t a121,
uint64_t a122,
uint64_t a123,
uint64_t a124,
uint64_t a125,
uint64_t a126,
uint64_t a127)) {
uint64_t a0;
uint64_t a1;
uint64_t a2;
uint64_t a3;
uint64_t a4;
uint64_t a5;
uint64_t a6;
uint64_t a7;
uint64_t a8;
uint64_t a9;
uint64_t a10;
uint64_t a11;
uint64_t a12;
uint64_t a13;
uint64_t a14;
uint64_t a15;
uint64_t a16;
uint64_t a17;
uint64_t a18;
uint64_t a19;
uint64_t a20;
uint64_t a21;
uint64_t a22;
uint64_t a23;
uint64_t a24;
uint64_t a25;
uint64_t a26;
uint64_t a27;
uint64_t a28;
uint64_t a29;
uint64_t a30;
uint64_t a31;
uint64_t a32;
uint64_t a33;
uint64_t a34;
uint64_t a35;
uint64_t a36;
uint64_t a37;
uint64_t a38;
uint64_t a39;
uint64_t a40;
uint64_t a41;
uint64_t a42;
uint64_t a43;
uint64_t a44;
uint64_t a45;
uint64_t a46;
uint64_t a47;
uint64_t a48;
uint64_t a49;
uint64_t a50;
uint64_t a51;
uint64_t a52;
uint64_t a53;
uint64_t a54;
uint64_t a55;
uint64_t a56;
uint64_t a57;
uint64_t a58;
uint64_t a59;
uint64_t a60;
uint64_t a61;
uint64_t a62;
uint64_t a63;
uint64_t a64;
uint64_t a65;
uint64_t a66;
uint64_t a67;
uint64_t a68;
uint64_t a69;
uint64_t a70;
uint64_t a71;
uint64_t a72;
uint64_t a73;
uint64_t a74;
uint64_t a75;
uint64_t a76;
uint64_t a77;
uint64_t a78;
uint64_t a79;
uint64_t a80;
uint64_t a81;
uint64_t a82;
uint64_t a83;
uint64_t a84;
uint64_t a85;
uint64_t a86;
uint64_t a87;
uint64_t a88;
uint64_t a89;
uint64_t a90;
uint64_t a91;
uint64_t a92;
uint64_t a93;
uint64_t a94;
uint64_t a95;
uint64_t a96;
uint64_t a97;
uint64_t a98;
uint64_t a99;
uint64_t a100;
uint64_t a101;
uint64_t a102;
uint64_t a103;
uint64_t a104;
uint64_t a105;
uint64_t a106;
uint64_t a107;
uint64_t a108;
uint64_t a109;
uint64_t a110;
uint64_t a111;
uint64_t a112;
uint64_t a113;
uint64_t a114;
uint64_t a115;
uint64_t a116;
uint64_t a117;
uint64_t a118;
uint64_t a119;
uint64_t a120;
uint64_t a121;
uint64_t a122;
uint64_t a123;
uint64_t a124;
uint64_t a125;
uint64_t a126;
uint64_t a127;
a0 = 1;
a1 = 2;
a2 = 3;
a3 = 4;
a4 = 5;
a5 = 6;
a6 = 7;
a7 = 8;
a8 = 9;
a9 = 10;
a10 = 11;
a11 = 12;
a12 = 13;
a13 = 14;
a14 = 15;
a15 = 16;
a16 = 17;
a17 = 18;
a18 = 19;
a19 = 20;
a20 = 21;
a21 = 22;
a22 = 23;
a23 = 24;
a24 = 25;
a25 = 26;
a26 = 27;
a27 = 28;
a28 = 29;
a29 = 30;
a30 = 31;
a31 = 32;
a32 = 33;
a33 = 34;
a34 = 35;
a35 = 36;
a36 = 37;
a37 = 38;
a38 = 39;
a39 = 40;
a40 = 41;
a41 = 42;
a42 = 43;
a43 = 44;
a44 = 45;
a45 = 46;
a46 = 47;
a47 = 48;
a48 = 49;
a49 = 50;
a50 = 51;
a51 = 52;
a52 = 53;
a53 = 54;
a54 = 55;
a55 = 56;
a56 = 57;
a57 = 58;
a58 = 59;
a59 = 60;
a60 = 61;
a61 = 62;
a62 = 63;
a63 = 64;
a64 = 65;
a65 = 66;
a66 = 67;
a67 = 68;
a68 = 69;
a69 = 70;
a70 = 71;
a71 = 72;
a72 = 73;
a73 = 74;
a74 = 75;
a75 = 76;
a76 = 77;
a77 = 78;
a78 = 79;
a79 = 80;
a80 = 81;
a81 = 82;
a82 = 83;
a83 = 84;
a84 = 85;
a85 = 86;
a86 = 87;
a87 = 88;
a88 = 89;
a89 = 90;
a90 = 91;
a91 = 92;
a92 = 93;
a93 = 94;
a94 = 95;
a95 = 96;
a96 = 97;
a97 = 98;
a98 = 99;
a99 = 100;
a100 = 101;
a101 = 102;
a102 = 103;
a103 = 104;
a104 = 105;
a105 = 106;
a106 = 107;
a107 = 108;
a108 = 109;
a109 = 110;
a110 = 111;
a111 = 112;
a112 = 113;
a113 = 114;
a114 = 115;
a115 = 116;
a116 = 117;
a117 = 118;
a118 = 119;
a119 = 120;
a120 = 121;
a121 = 122;
a122 = 123;
a123 = 124;
a124 = 125;
a125 = 126;
a126 = 127;
a127 = 128;
std::cout << "Calling TestReturnStruct1024BytesHomogeneousUint64("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
<< a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
<< ", " << a14 << ", " << a15 << ", " << a16 << ", " << a17 << ", "
<< a18 << ", " << a19 << ", " << a20 << ", " << a21 << ", " << a22
<< ", " << a23 << ", " << a24 << ", " << a25 << ", " << a26 << ", "
<< a27 << ", " << a28 << ", " << a29 << ", " << a30 << ", " << a31
<< ", " << a32 << ", " << a33 << ", " << a34 << ", " << a35 << ", "
<< a36 << ", " << a37 << ", " << a38 << ", " << a39 << ", " << a40
<< ", " << a41 << ", " << a42 << ", " << a43 << ", " << a44 << ", "
<< a45 << ", " << a46 << ", " << a47 << ", " << a48 << ", " << a49
<< ", " << a50 << ", " << a51 << ", " << a52 << ", " << a53 << ", "
<< a54 << ", " << a55 << ", " << a56 << ", " << a57 << ", " << a58
<< ", " << a59 << ", " << a60 << ", " << a61 << ", " << a62 << ", "
<< a63 << ", " << a64 << ", " << a65 << ", " << a66 << ", " << a67
<< ", " << a68 << ", " << a69 << ", " << a70 << ", " << a71 << ", "
<< a72 << ", " << a73 << ", " << a74 << ", " << a75 << ", " << a76
<< ", " << a77 << ", " << a78 << ", " << a79 << ", " << a80 << ", "
<< a81 << ", " << a82 << ", " << a83 << ", " << a84 << ", " << a85
<< ", " << a86 << ", " << a87 << ", " << a88 << ", " << a89 << ", "
<< a90 << ", " << a91 << ", " << a92 << ", " << a93 << ", " << a94
<< ", " << a95 << ", " << a96 << ", " << a97 << ", " << a98 << ", "
<< a99 << ", " << a100 << ", " << a101 << ", " << a102 << ", "
<< a103 << ", " << a104 << ", " << a105 << ", " << a106 << ", "
<< a107 << ", " << a108 << ", " << a109 << ", " << a110 << ", "
<< a111 << ", " << a112 << ", " << a113 << ", " << a114 << ", "
<< a115 << ", " << a116 << ", " << a117 << ", " << a118 << ", "
<< a119 << ", " << a120 << ", " << a121 << ", " << a122 << ", "
<< a123 << ", " << a124 << ", " << a125 << ", " << a126 << ", "
<< a127 << ")"
<< ")\n";
Struct1024BytesHomogeneousUint64 result = f(
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31,
a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46,
a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61,
a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, a76,
a77, a78, a79, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, a91,
a92, a93, a94, a95, a96, a97, a98, a99, a100, a101, a102, a103, a104,
a105, a106, a107, a108, a109, a110, a111, a112, a113, a114, a115, a116,
a117, a118, a119, a120, a121, a122, a123, a124, a125, a126, a127);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ", " << result.a5
<< ", " << result.a6 << ", " << result.a7 << ", " << result.a8
<< ", " << result.a9 << ", " << result.a10 << ", " << result.a11
<< ", " << result.a12 << ", " << result.a13 << ", " << result.a14
<< ", " << result.a15 << ", " << result.a16 << ", " << result.a17
<< ", " << result.a18 << ", " << result.a19 << ", " << result.a20
<< ", " << result.a21 << ", " << result.a22 << ", " << result.a23
<< ", " << result.a24 << ", " << result.a25 << ", " << result.a26
<< ", " << result.a27 << ", " << result.a28 << ", " << result.a29
<< ", " << result.a30 << ", " << result.a31 << ", " << result.a32
<< ", " << result.a33 << ", " << result.a34 << ", " << result.a35
<< ", " << result.a36 << ", " << result.a37 << ", " << result.a38
<< ", " << result.a39 << ", " << result.a40 << ", " << result.a41
<< ", " << result.a42 << ", " << result.a43 << ", " << result.a44
<< ", " << result.a45 << ", " << result.a46 << ", " << result.a47
<< ", " << result.a48 << ", " << result.a49 << ", " << result.a50
<< ", " << result.a51 << ", " << result.a52 << ", " << result.a53
<< ", " << result.a54 << ", " << result.a55 << ", " << result.a56
<< ", " << result.a57 << ", " << result.a58 << ", " << result.a59
<< ", " << result.a60 << ", " << result.a61 << ", " << result.a62
<< ", " << result.a63 << ", " << result.a64 << ", " << result.a65
<< ", " << result.a66 << ", " << result.a67 << ", " << result.a68
<< ", " << result.a69 << ", " << result.a70 << ", " << result.a71
<< ", " << result.a72 << ", " << result.a73 << ", " << result.a74
<< ", " << result.a75 << ", " << result.a76 << ", " << result.a77
<< ", " << result.a78 << ", " << result.a79 << ", " << result.a80
<< ", " << result.a81 << ", " << result.a82 << ", " << result.a83
<< ", " << result.a84 << ", " << result.a85 << ", " << result.a86
<< ", " << result.a87 << ", " << result.a88 << ", " << result.a89
<< ", " << result.a90 << ", " << result.a91 << ", " << result.a92
<< ", " << result.a93 << ", " << result.a94 << ", " << result.a95
<< ", " << result.a96 << ", " << result.a97 << ", " << result.a98
<< ", " << result.a99 << ", " << result.a100 << ", " << result.a101
<< ", " << result.a102 << ", " << result.a103 << ", " << result.a104
<< ", " << result.a105 << ", " << result.a106 << ", " << result.a107
<< ", " << result.a108 << ", " << result.a109 << ", " << result.a110
<< ", " << result.a111 << ", " << result.a112 << ", " << result.a113
<< ", " << result.a114 << ", " << result.a115 << ", " << result.a116
<< ", " << result.a117 << ", " << result.a118 << ", " << result.a119
<< ", " << result.a120 << ", " << result.a121 << ", " << result.a122
<< ", " << result.a123 << ", " << result.a124 << ", " << result.a125
<< ", " << result.a126 << ", " << result.a127 << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
CHECK_EQ(a3, result.a3);
CHECK_EQ(a4, result.a4);
CHECK_EQ(a5, result.a5);
CHECK_EQ(a6, result.a6);
CHECK_EQ(a7, result.a7);
CHECK_EQ(a8, result.a8);
CHECK_EQ(a9, result.a9);
CHECK_EQ(a10, result.a10);
CHECK_EQ(a11, result.a11);
CHECK_EQ(a12, result.a12);
CHECK_EQ(a13, result.a13);
CHECK_EQ(a14, result.a14);
CHECK_EQ(a15, result.a15);
CHECK_EQ(a16, result.a16);
CHECK_EQ(a17, result.a17);
CHECK_EQ(a18, result.a18);
CHECK_EQ(a19, result.a19);
CHECK_EQ(a20, result.a20);
CHECK_EQ(a21, result.a21);
CHECK_EQ(a22, result.a22);
CHECK_EQ(a23, result.a23);
CHECK_EQ(a24, result.a24);
CHECK_EQ(a25, result.a25);
CHECK_EQ(a26, result.a26);
CHECK_EQ(a27, result.a27);
CHECK_EQ(a28, result.a28);
CHECK_EQ(a29, result.a29);
CHECK_EQ(a30, result.a30);
CHECK_EQ(a31, result.a31);
CHECK_EQ(a32, result.a32);
CHECK_EQ(a33, result.a33);
CHECK_EQ(a34, result.a34);
CHECK_EQ(a35, result.a35);
CHECK_EQ(a36, result.a36);
CHECK_EQ(a37, result.a37);
CHECK_EQ(a38, result.a38);
CHECK_EQ(a39, result.a39);
CHECK_EQ(a40, result.a40);
CHECK_EQ(a41, result.a41);
CHECK_EQ(a42, result.a42);
CHECK_EQ(a43, result.a43);
CHECK_EQ(a44, result.a44);
CHECK_EQ(a45, result.a45);
CHECK_EQ(a46, result.a46);
CHECK_EQ(a47, result.a47);
CHECK_EQ(a48, result.a48);
CHECK_EQ(a49, result.a49);
CHECK_EQ(a50, result.a50);
CHECK_EQ(a51, result.a51);
CHECK_EQ(a52, result.a52);
CHECK_EQ(a53, result.a53);
CHECK_EQ(a54, result.a54);
CHECK_EQ(a55, result.a55);
CHECK_EQ(a56, result.a56);
CHECK_EQ(a57, result.a57);
CHECK_EQ(a58, result.a58);
CHECK_EQ(a59, result.a59);
CHECK_EQ(a60, result.a60);
CHECK_EQ(a61, result.a61);
CHECK_EQ(a62, result.a62);
CHECK_EQ(a63, result.a63);
CHECK_EQ(a64, result.a64);
CHECK_EQ(a65, result.a65);
CHECK_EQ(a66, result.a66);
CHECK_EQ(a67, result.a67);
CHECK_EQ(a68, result.a68);
CHECK_EQ(a69, result.a69);
CHECK_EQ(a70, result.a70);
CHECK_EQ(a71, result.a71);
CHECK_EQ(a72, result.a72);
CHECK_EQ(a73, result.a73);
CHECK_EQ(a74, result.a74);
CHECK_EQ(a75, result.a75);
CHECK_EQ(a76, result.a76);
CHECK_EQ(a77, result.a77);
CHECK_EQ(a78, result.a78);
CHECK_EQ(a79, result.a79);
CHECK_EQ(a80, result.a80);
CHECK_EQ(a81, result.a81);
CHECK_EQ(a82, result.a82);
CHECK_EQ(a83, result.a83);
CHECK_EQ(a84, result.a84);
CHECK_EQ(a85, result.a85);
CHECK_EQ(a86, result.a86);
CHECK_EQ(a87, result.a87);
CHECK_EQ(a88, result.a88);
CHECK_EQ(a89, result.a89);
CHECK_EQ(a90, result.a90);
CHECK_EQ(a91, result.a91);
CHECK_EQ(a92, result.a92);
CHECK_EQ(a93, result.a93);
CHECK_EQ(a94, result.a94);
CHECK_EQ(a95, result.a95);
CHECK_EQ(a96, result.a96);
CHECK_EQ(a97, result.a97);
CHECK_EQ(a98, result.a98);
CHECK_EQ(a99, result.a99);
CHECK_EQ(a100, result.a100);
CHECK_EQ(a101, result.a101);
CHECK_EQ(a102, result.a102);
CHECK_EQ(a103, result.a103);
CHECK_EQ(a104, result.a104);
CHECK_EQ(a105, result.a105);
CHECK_EQ(a106, result.a106);
CHECK_EQ(a107, result.a107);
CHECK_EQ(a108, result.a108);
CHECK_EQ(a109, result.a109);
CHECK_EQ(a110, result.a110);
CHECK_EQ(a111, result.a111);
CHECK_EQ(a112, result.a112);
CHECK_EQ(a113, result.a113);
CHECK_EQ(a114, result.a114);
CHECK_EQ(a115, result.a115);
CHECK_EQ(a116, result.a116);
CHECK_EQ(a117, result.a117);
CHECK_EQ(a118, result.a118);
CHECK_EQ(a119, result.a119);
CHECK_EQ(a120, result.a120);
CHECK_EQ(a121, result.a121);
CHECK_EQ(a122, result.a122);
CHECK_EQ(a123, result.a123);
CHECK_EQ(a124, result.a124);
CHECK_EQ(a125, result.a125);
CHECK_EQ(a126, result.a126);
CHECK_EQ(a127, result.a127);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31,
a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46,
a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61,
a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, a76,
a77, a78, a79, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, a91,
a92, a93, a94, a95, a96, a97, a98, a99, a100, a101, a102, a103, a104,
a105, a106, a107, a108, a109, a110, a111, a112, a113, a114, a115, a116,
a117, a118, a119, a120, a121, a122, a123, a124, a125, a126, a127);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
CHECK_EQ(0, result.a9);
CHECK_EQ(0, result.a10);
CHECK_EQ(0, result.a11);
CHECK_EQ(0, result.a12);
CHECK_EQ(0, result.a13);
CHECK_EQ(0, result.a14);
CHECK_EQ(0, result.a15);
CHECK_EQ(0, result.a16);
CHECK_EQ(0, result.a17);
CHECK_EQ(0, result.a18);
CHECK_EQ(0, result.a19);
CHECK_EQ(0, result.a20);
CHECK_EQ(0, result.a21);
CHECK_EQ(0, result.a22);
CHECK_EQ(0, result.a23);
CHECK_EQ(0, result.a24);
CHECK_EQ(0, result.a25);
CHECK_EQ(0, result.a26);
CHECK_EQ(0, result.a27);
CHECK_EQ(0, result.a28);
CHECK_EQ(0, result.a29);
CHECK_EQ(0, result.a30);
CHECK_EQ(0, result.a31);
CHECK_EQ(0, result.a32);
CHECK_EQ(0, result.a33);
CHECK_EQ(0, result.a34);
CHECK_EQ(0, result.a35);
CHECK_EQ(0, result.a36);
CHECK_EQ(0, result.a37);
CHECK_EQ(0, result.a38);
CHECK_EQ(0, result.a39);
CHECK_EQ(0, result.a40);
CHECK_EQ(0, result.a41);
CHECK_EQ(0, result.a42);
CHECK_EQ(0, result.a43);
CHECK_EQ(0, result.a44);
CHECK_EQ(0, result.a45);
CHECK_EQ(0, result.a46);
CHECK_EQ(0, result.a47);
CHECK_EQ(0, result.a48);
CHECK_EQ(0, result.a49);
CHECK_EQ(0, result.a50);
CHECK_EQ(0, result.a51);
CHECK_EQ(0, result.a52);
CHECK_EQ(0, result.a53);
CHECK_EQ(0, result.a54);
CHECK_EQ(0, result.a55);
CHECK_EQ(0, result.a56);
CHECK_EQ(0, result.a57);
CHECK_EQ(0, result.a58);
CHECK_EQ(0, result.a59);
CHECK_EQ(0, result.a60);
CHECK_EQ(0, result.a61);
CHECK_EQ(0, result.a62);
CHECK_EQ(0, result.a63);
CHECK_EQ(0, result.a64);
CHECK_EQ(0, result.a65);
CHECK_EQ(0, result.a66);
CHECK_EQ(0, result.a67);
CHECK_EQ(0, result.a68);
CHECK_EQ(0, result.a69);
CHECK_EQ(0, result.a70);
CHECK_EQ(0, result.a71);
CHECK_EQ(0, result.a72);
CHECK_EQ(0, result.a73);
CHECK_EQ(0, result.a74);
CHECK_EQ(0, result.a75);
CHECK_EQ(0, result.a76);
CHECK_EQ(0, result.a77);
CHECK_EQ(0, result.a78);
CHECK_EQ(0, result.a79);
CHECK_EQ(0, result.a80);
CHECK_EQ(0, result.a81);
CHECK_EQ(0, result.a82);
CHECK_EQ(0, result.a83);
CHECK_EQ(0, result.a84);
CHECK_EQ(0, result.a85);
CHECK_EQ(0, result.a86);
CHECK_EQ(0, result.a87);
CHECK_EQ(0, result.a88);
CHECK_EQ(0, result.a89);
CHECK_EQ(0, result.a90);
CHECK_EQ(0, result.a91);
CHECK_EQ(0, result.a92);
CHECK_EQ(0, result.a93);
CHECK_EQ(0, result.a94);
CHECK_EQ(0, result.a95);
CHECK_EQ(0, result.a96);
CHECK_EQ(0, result.a97);
CHECK_EQ(0, result.a98);
CHECK_EQ(0, result.a99);
CHECK_EQ(0, result.a100);
CHECK_EQ(0, result.a101);
CHECK_EQ(0, result.a102);
CHECK_EQ(0, result.a103);
CHECK_EQ(0, result.a104);
CHECK_EQ(0, result.a105);
CHECK_EQ(0, result.a106);
CHECK_EQ(0, result.a107);
CHECK_EQ(0, result.a108);
CHECK_EQ(0, result.a109);
CHECK_EQ(0, result.a110);
CHECK_EQ(0, result.a111);
CHECK_EQ(0, result.a112);
CHECK_EQ(0, result.a113);
CHECK_EQ(0, result.a114);
CHECK_EQ(0, result.a115);
CHECK_EQ(0, result.a116);
CHECK_EQ(0, result.a117);
CHECK_EQ(0, result.a118);
CHECK_EQ(0, result.a119);
CHECK_EQ(0, result.a120);
CHECK_EQ(0, result.a121);
CHECK_EQ(0, result.a122);
CHECK_EQ(0, result.a123);
CHECK_EQ(0, result.a124);
CHECK_EQ(0, result.a125);
CHECK_EQ(0, result.a126);
CHECK_EQ(0, result.a127);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31,
a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46,
a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61,
a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, a76,
a77, a78, a79, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, a91,
a92, a93, a94, a95, a96, a97, a98, a99, a100, a101, a102, a103, a104,
a105, a106, a107, a108, a109, a110, a111, a112, a113, a114, a115, a116,
a117, a118, a119, a120, a121, a122, a123, a124, a125, a126, a127);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
CHECK_EQ(0, result.a5);
CHECK_EQ(0, result.a6);
CHECK_EQ(0, result.a7);
CHECK_EQ(0, result.a8);
CHECK_EQ(0, result.a9);
CHECK_EQ(0, result.a10);
CHECK_EQ(0, result.a11);
CHECK_EQ(0, result.a12);
CHECK_EQ(0, result.a13);
CHECK_EQ(0, result.a14);
CHECK_EQ(0, result.a15);
CHECK_EQ(0, result.a16);
CHECK_EQ(0, result.a17);
CHECK_EQ(0, result.a18);
CHECK_EQ(0, result.a19);
CHECK_EQ(0, result.a20);
CHECK_EQ(0, result.a21);
CHECK_EQ(0, result.a22);
CHECK_EQ(0, result.a23);
CHECK_EQ(0, result.a24);
CHECK_EQ(0, result.a25);
CHECK_EQ(0, result.a26);
CHECK_EQ(0, result.a27);
CHECK_EQ(0, result.a28);
CHECK_EQ(0, result.a29);
CHECK_EQ(0, result.a30);
CHECK_EQ(0, result.a31);
CHECK_EQ(0, result.a32);
CHECK_EQ(0, result.a33);
CHECK_EQ(0, result.a34);
CHECK_EQ(0, result.a35);
CHECK_EQ(0, result.a36);
CHECK_EQ(0, result.a37);
CHECK_EQ(0, result.a38);
CHECK_EQ(0, result.a39);
CHECK_EQ(0, result.a40);
CHECK_EQ(0, result.a41);
CHECK_EQ(0, result.a42);
CHECK_EQ(0, result.a43);
CHECK_EQ(0, result.a44);
CHECK_EQ(0, result.a45);
CHECK_EQ(0, result.a46);
CHECK_EQ(0, result.a47);
CHECK_EQ(0, result.a48);
CHECK_EQ(0, result.a49);
CHECK_EQ(0, result.a50);
CHECK_EQ(0, result.a51);
CHECK_EQ(0, result.a52);
CHECK_EQ(0, result.a53);
CHECK_EQ(0, result.a54);
CHECK_EQ(0, result.a55);
CHECK_EQ(0, result.a56);
CHECK_EQ(0, result.a57);
CHECK_EQ(0, result.a58);
CHECK_EQ(0, result.a59);
CHECK_EQ(0, result.a60);
CHECK_EQ(0, result.a61);
CHECK_EQ(0, result.a62);
CHECK_EQ(0, result.a63);
CHECK_EQ(0, result.a64);
CHECK_EQ(0, result.a65);
CHECK_EQ(0, result.a66);
CHECK_EQ(0, result.a67);
CHECK_EQ(0, result.a68);
CHECK_EQ(0, result.a69);
CHECK_EQ(0, result.a70);
CHECK_EQ(0, result.a71);
CHECK_EQ(0, result.a72);
CHECK_EQ(0, result.a73);
CHECK_EQ(0, result.a74);
CHECK_EQ(0, result.a75);
CHECK_EQ(0, result.a76);
CHECK_EQ(0, result.a77);
CHECK_EQ(0, result.a78);
CHECK_EQ(0, result.a79);
CHECK_EQ(0, result.a80);
CHECK_EQ(0, result.a81);
CHECK_EQ(0, result.a82);
CHECK_EQ(0, result.a83);
CHECK_EQ(0, result.a84);
CHECK_EQ(0, result.a85);
CHECK_EQ(0, result.a86);
CHECK_EQ(0, result.a87);
CHECK_EQ(0, result.a88);
CHECK_EQ(0, result.a89);
CHECK_EQ(0, result.a90);
CHECK_EQ(0, result.a91);
CHECK_EQ(0, result.a92);
CHECK_EQ(0, result.a93);
CHECK_EQ(0, result.a94);
CHECK_EQ(0, result.a95);
CHECK_EQ(0, result.a96);
CHECK_EQ(0, result.a97);
CHECK_EQ(0, result.a98);
CHECK_EQ(0, result.a99);
CHECK_EQ(0, result.a100);
CHECK_EQ(0, result.a101);
CHECK_EQ(0, result.a102);
CHECK_EQ(0, result.a103);
CHECK_EQ(0, result.a104);
CHECK_EQ(0, result.a105);
CHECK_EQ(0, result.a106);
CHECK_EQ(0, result.a107);
CHECK_EQ(0, result.a108);
CHECK_EQ(0, result.a109);
CHECK_EQ(0, result.a110);
CHECK_EQ(0, result.a111);
CHECK_EQ(0, result.a112);
CHECK_EQ(0, result.a113);
CHECK_EQ(0, result.a114);
CHECK_EQ(0, result.a115);
CHECK_EQ(0, result.a116);
CHECK_EQ(0, result.a117);
CHECK_EQ(0, result.a118);
CHECK_EQ(0, result.a119);
CHECK_EQ(0, result.a120);
CHECK_EQ(0, result.a121);
CHECK_EQ(0, result.a122);
CHECK_EQ(0, result.a123);
CHECK_EQ(0, result.a124);
CHECK_EQ(0, result.a125);
CHECK_EQ(0, result.a126);
CHECK_EQ(0, result.a127);
return 0;
}
// Used for testing structs by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed in int registers in most ABIs.
DART_EXPORT intptr_t TestReturnStructArgumentStruct1ByteInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct1ByteInt (*f)(Struct1ByteInt a0)) {
Struct1ByteInt a0;
a0.a0 = -1;
std::cout << "Calling TestReturnStructArgumentStruct1ByteInt("
<< "((" << static_cast<int>(a0.a0) << "))"
<< ")\n";
Struct1ByteInt result = f(a0);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
CHECK_EQ(a0.a0, result.a0);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result.a0);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result.a0);
return 0;
}
// Used for testing structs by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed on stack on all ABIs.
DART_EXPORT intptr_t TestReturnStructArgumentInt32x8Struct1ByteInt(
// NOLINTNEXTLINE(whitespace/parens)
Struct1ByteInt (*f)(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
Struct1ByteInt a8)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
int32_t a5;
int32_t a6;
int32_t a7;
Struct1ByteInt a8;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4 = -5;
a5 = 6;
a6 = -7;
a7 = 8;
a8.a0 = -9;
std::cout << "Calling TestReturnStructArgumentInt32x8Struct1ByteInt("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", ("
<< static_cast<int>(a8.a0) << "))"
<< ")\n";
Struct1ByteInt result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ")"
<< "\n";
CHECK_EQ(a8.a0, result.a0);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
return 0;
}
// Used for testing structs by value.
// Test that a struct passed in as argument can be returned.
// Especially for ffi callbacks.
// Struct is passed in float registers in most ABIs.
DART_EXPORT intptr_t TestReturnStructArgumentStruct8BytesHomogeneousFloat(
// NOLINTNEXTLINE(whitespace/parens)
Struct8BytesHomogeneousFloat (*f)(Struct8BytesHomogeneousFloat a0)) {
Struct8BytesHomogeneousFloat a0;
a0.a0 = -1.0;
a0.a1 = 2.0;
std::cout << "Calling TestReturnStructArgumentStruct8BytesHomogeneousFloat("
<< "((" << a0.a0 << ", " << a0.a1 << "))"
<< ")\n";
Struct8BytesHomogeneousFloat result = f(a0);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ")"
<< "\n";
CHECK_APPROX(a0.a0, result.a0);
CHECK_APPROX(a0.a1, result.a1);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_APPROX(0.0, result.a0);
CHECK_APPROX(0.0, result.a1);
return 0;
}
// Used for testing structs by value.
// On arm64, both argument and return value are passed in by pointer.
DART_EXPORT intptr_t TestReturnStructArgumentStruct20BytesHomogeneousInt32(
// NOLINTNEXTLINE(whitespace/parens)
Struct20BytesHomogeneousInt32 (*f)(Struct20BytesHomogeneousInt32 a0)) {
Struct20BytesHomogeneousInt32 a0;
a0.a0 = -1;
a0.a1 = 2;
a0.a2 = -3;
a0.a3 = 4;
a0.a4 = -5;
std::cout << "Calling TestReturnStructArgumentStruct20BytesHomogeneousInt32("
<< "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
<< ", " << a0.a4 << "))"
<< ")\n";
Struct20BytesHomogeneousInt32 result = f(a0);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_EQ(a0.a0, result.a0);
CHECK_EQ(a0.a1, result.a1);
CHECK_EQ(a0.a2, result.a2);
CHECK_EQ(a0.a3, result.a3);
CHECK_EQ(a0.a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0.a0 = 42;
result = f(a0);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
// Pass argument that will make the Dart callback return null.
a0.a0 = 84;
result = f(a0);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
return 0;
}
// Used for testing structs by value.
// On arm64, both argument and return value are passed in by pointer.
// Ints exhaust registers, so that pointer is passed on stack.
DART_EXPORT intptr_t TestReturnStructArgumentInt32x8Struct20BytesHomogeneou(
// NOLINTNEXTLINE(whitespace/parens)
Struct20BytesHomogeneousInt32 (*f)(int32_t a0,
int32_t a1,
int32_t a2,
int32_t a3,
int32_t a4,
int32_t a5,
int32_t a6,
int32_t a7,
Struct20BytesHomogeneousInt32 a8)) {
int32_t a0;
int32_t a1;
int32_t a2;
int32_t a3;
int32_t a4;
int32_t a5;
int32_t a6;
int32_t a7;
Struct20BytesHomogeneousInt32 a8;
a0 = -1;
a1 = 2;
a2 = -3;
a3 = 4;
a4 = -5;
a5 = 6;
a6 = -7;
a7 = 8;
a8.a0 = -9;
a8.a1 = 10;
a8.a2 = -11;
a8.a3 = 12;
a8.a4 = -13;
std::cout << "Calling TestReturnStructArgumentInt32x8Struct20BytesHomogeneou("
<< "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
<< ", " << a5 << ", " << a6 << ", " << a7 << ", (" << a8.a0 << ", "
<< a8.a1 << ", " << a8.a2 << ", " << a8.a3 << ", " << a8.a4 << "))"
<< ")\n";
Struct20BytesHomogeneousInt32 result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
std::cout << "result = "
<< "(" << result.a0 << ", " << result.a1 << ", " << result.a2
<< ", " << result.a3 << ", " << result.a4 << ")"
<< "\n";
CHECK_EQ(a8.a0, result.a0);
CHECK_EQ(a8.a1, result.a1);
CHECK_EQ(a8.a2, result.a2);
CHECK_EQ(a8.a3, result.a3);
CHECK_EQ(a8.a4, result.a4);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
CHECK_EQ(0, result.a3);
CHECK_EQ(0, result.a4);
return 0;
}
// Used for testing structs by value.
// Test alignment and padding of 16 byte int within struct.
DART_EXPORT intptr_t TestReturnStructAlignmentInt16(
// NOLINTNEXTLINE(whitespace/parens)
StructAlignmentInt16 (*f)(int8_t a0, int16_t a1, int8_t a2)) {
int8_t a0;
int16_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStructAlignmentInt16("
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< ")\n";
StructAlignmentInt16 result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs by value.
// Test alignment and padding of 32 byte int within struct.
DART_EXPORT intptr_t TestReturnStructAlignmentInt32(
// NOLINTNEXTLINE(whitespace/parens)
StructAlignmentInt32 (*f)(int8_t a0, int32_t a1, int8_t a2)) {
int8_t a0;
int32_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStructAlignmentInt32("
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< ")\n";
StructAlignmentInt32 result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
// Used for testing structs by value.
// Test alignment and padding of 64 byte int within struct.
DART_EXPORT intptr_t TestReturnStructAlignmentInt64(
// NOLINTNEXTLINE(whitespace/parens)
StructAlignmentInt64 (*f)(int8_t a0, int64_t a1, int8_t a2)) {
int8_t a0;
int64_t a1;
int8_t a2;
a0 = -1;
a1 = 2;
a2 = -3;
std::cout << "Calling TestReturnStructAlignmentInt64("
<< "(" << static_cast<int>(a0) << ", " << a1 << ", "
<< static_cast<int>(a2) << ")"
<< ")\n";
StructAlignmentInt64 result = f(a0, a1, a2);
std::cout << "result = "
<< "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
<< static_cast<int>(result.a2) << ")"
<< "\n";
CHECK_EQ(a0, result.a0);
CHECK_EQ(a1, result.a1);
CHECK_EQ(a2, result.a2);
// Pass argument that will make the Dart callback throw.
a0 = 42;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
// Pass argument that will make the Dart callback return null.
a0 = 84;
result = f(a0, a1, a2);
CHECK_EQ(0, result.a0);
CHECK_EQ(0, result.a1);
CHECK_EQ(0, result.a2);
return 0;
}
} // namespace dart