diff --git a/runtime/vm/compiler/ffi/native_calling_convention.cc b/runtime/vm/compiler/ffi/native_calling_convention.cc index a0c1f30cc82c..79d127a30d39 100644 --- a/runtime/vm/compiler/ffi/native_calling_convention.cc +++ b/runtime/vm/compiler/ffi/native_calling_convention.cc @@ -141,7 +141,7 @@ class ArgumentAllocator : public ValueObject { const NativeLocation& AllocateCompound( const NativeCompoundType& payload_type) { const intptr_t size = payload_type.SizeInBytes(); - if (size <= 16 && size > 0) { + if (size <= 16 && size > 0 && !payload_type.ContainsUnalignedMembers()) { intptr_t required_regs = payload_type.NumberOfWordSizeChunksNotOnlyFloat(); intptr_t required_xmm_regs = @@ -516,7 +516,7 @@ static const NativeLocation& CompoundResultLocation( Zone* zone, const NativeCompoundType& payload_type) { const intptr_t size = payload_type.SizeInBytes(); - if (size <= 16 && size > 0) { + if (size <= 16 && size > 0 && !payload_type.ContainsUnalignedMembers()) { // Allocate the same as argument, but use return registers instead of // argument registers. NativeLocations& multiple_locations = diff --git a/runtime/vm/compiler/ffi/native_calling_convention_test.cc b/runtime/vm/compiler/ffi/native_calling_convention_test.cc index 82db265f4627..0ac5e3f0d9b5 100644 --- a/runtime/vm/compiler/ffi/native_calling_convention_test.cc +++ b/runtime/vm/compiler/ffi/native_calling_convention_test.cc @@ -398,6 +398,77 @@ UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct8bytesx1) { RunSignatureTest(Z, "struct8bytesx1", arguments, struct_type); } +// The struct is only 8 bytes with packing enabled. +// +// Many calling conventions pass this struct in single registers or less +// stack slots because of this. +// +// Non-windows x64 passes this struct on the stack instead of in a single +// CPU register, because it contains a mis-aligned member. +// +// See the *.expect in ./unit_tests for this behavior. +UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_struct8bytesPackedx10) { + const auto& int8_type = *new (Z) NativePrimitiveType(kInt8); + const auto& int32_type = *new (Z) NativePrimitiveType(kInt32); + + auto& member_types = *new (Z) NativeTypes(Z, 5); + member_types.Add(&int8_type); + member_types.Add(&int32_type); + member_types.Add(&int8_type); + member_types.Add(&int8_type); + member_types.Add(&int8_type); + const auto& struct_type = + NativeCompoundType::FromNativeTypes(Z, member_types, /*packing=*/1); + EXPECT_EQ(8, struct_type.SizeInBytes()); + EXPECT(struct_type.ContainsUnalignedMembers()); + + auto& arguments = *new (Z) NativeTypes(Z, 10); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + + RunSignatureTest(Z, "struct8bytesPackedx10", arguments, struct_type); +} + +// Without packing, this would be a 16 byte struct. However, because of packing +// it's 9 bytes. +// +// #pragma pack(push,1) +// typedef struct { +// int8_t a0; +// double a1 +// } StructPacked; +// #pragma pack(pop) +// +// See the *.expect in ./unit_tests for this behavior. +UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_structPacked) { + const auto& int8_type = *new (Z) NativePrimitiveType(kInt8); + const auto& double_type = *new (Z) NativePrimitiveType(kDouble); + + auto& member_types = *new (Z) NativeTypes(Z, 2); + member_types.Add(&int8_type); + member_types.Add(&double_type); + const auto& struct_type = + NativeCompoundType::FromNativeTypes(Z, member_types, /*packing=*/1); + EXPECT_EQ(9, struct_type.SizeInBytes()); + EXPECT(struct_type.ContainsUnalignedMembers()); + + auto& arguments = *new (Z) NativeTypes(Z, 11); + arguments.Add(&struct_type); + arguments.Add(&struct_type); + arguments.Add(&int8_type); // Backfilling int registers. + arguments.Add(&double_type); // Backfilling float registers. + + RunSignatureTest(Z, "structPacked", arguments, struct_type); +} + } // namespace ffi } // namespace compiler } // namespace dart diff --git a/runtime/vm/compiler/ffi/native_type.cc b/runtime/vm/compiler/ffi/native_type.cc index 0e0d125d43ba..f36f8aff6e59 100644 --- a/runtime/vm/compiler/ffi/native_type.cc +++ b/runtime/vm/compiler/ffi/native_type.cc @@ -164,7 +164,8 @@ static bool ContainsHomogenuousFloatsInternal(const NativeTypes& types); // pkg/vm/lib/transformations/ffi_definitions.dart:_calculateStructLayout. NativeCompoundType& NativeCompoundType::FromNativeTypes( Zone* zone, - const NativeTypes& members) { + const NativeTypes& members, + intptr_t member_packing) { intptr_t offset = 0; const intptr_t kAtLeast1ByteAligned = 1; @@ -195,8 +196,13 @@ NativeCompoundType& NativeCompoundType::FromNativeTypes( for (intptr_t i = 0; i < members.length(); i++) { const NativeType& member = *members[i]; const intptr_t member_size = member.SizeInBytes(); - const intptr_t member_align_field = member.AlignmentInBytesField(); - const intptr_t member_align_stack = member.AlignmentInBytesStack(); + const intptr_t member_align_field = + Utils::Minimum(member.AlignmentInBytesField(), member_packing); + intptr_t member_align_stack = member.AlignmentInBytesStack(); + if (member_align_stack > member_packing && + member_packing < compiler::target::kWordSize) { + member_align_stack = compiler::target::kWordSize; + } offset = Utils::RoundUp(offset, member_align_field); member_offsets.Add(offset); offset += member_size; @@ -710,6 +716,29 @@ intptr_t NativeCompoundType::NumberOfWordSizeChunksNotOnlyFloat() const { } #endif // !defined(DART_PRECOMPILED_RUNTIME) +bool NativePrimitiveType::ContainsUnalignedMembers() const { + return false; +} + +bool NativeArrayType::ContainsUnalignedMembers() const { + return element_type_.ContainsUnalignedMembers(); +} + +bool NativeCompoundType::ContainsUnalignedMembers() const { + for (intptr_t i = 0; i < members_.length(); i++) { + const auto& member = *members_.At(i); + const intptr_t member_offset = member_offsets_.At(i); + const intptr_t member_alignment = member.AlignmentInBytesField(); + if (member_offset % member_alignment != 0) { + return true; + } + if (member.ContainsUnalignedMembers()) { + return true; + } + } + return false; +} + static void ContainsHomogenuousFloatsRecursive(const NativeTypes& types, bool* only_float, bool* only_double) { diff --git a/runtime/vm/compiler/ffi/native_type.h b/runtime/vm/compiler/ffi/native_type.h index 9b3df3f8407c..8fbcbc5bfb43 100644 --- a/runtime/vm/compiler/ffi/native_type.h +++ b/runtime/vm/compiler/ffi/native_type.h @@ -97,6 +97,9 @@ class NativeType : public ZoneAllocated { virtual bool ContainsOnlyFloats(Range range) const = 0; #endif // !defined(DART_PRECOMPILED_RUNTIME) + // True iff any members are misaligned recursively due to packing. + virtual bool ContainsUnalignedMembers() const = 0; + #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS) // NativeTypes which are available as unboxed Representations. virtual bool IsExpressibleAsRepresentation() const { return false; } @@ -185,6 +188,8 @@ class NativePrimitiveType : public NativeType { virtual bool ContainsOnlyFloats(Range range) const; #endif // !defined(DART_PRECOMPILED_RUNTIME) + virtual bool ContainsUnalignedMembers() const; + #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS) virtual bool IsExpressibleAsRepresentation() const; virtual Representation AsRepresentation() const; @@ -234,6 +239,8 @@ class NativeArrayType : public NativeType { virtual bool ContainsOnlyFloats(Range range) const; #endif // !defined(DART_PRECOMPILED_RUNTIME) + virtual bool ContainsUnalignedMembers() const; + virtual bool Equals(const NativeType& other) const; virtual void PrintTo(BaseTextBuffer* f, @@ -255,8 +262,10 @@ using NativeTypes = ZoneGrowableArray; // TODO(dartbug.com/38491): Support unions. class NativeCompoundType : public NativeType { public: - static NativeCompoundType& FromNativeTypes(Zone* zone, - const NativeTypes& members); + static NativeCompoundType& FromNativeTypes( + Zone* zone, + const NativeTypes& members, + intptr_t member_packing = kMaxInt32); const NativeTypes& members() const { return members_; } const ZoneGrowableArray& member_offsets() const { @@ -289,6 +298,8 @@ class NativeCompoundType : public NativeType { intptr_t NumberOfWordSizeChunksNotOnlyFloat() const; #endif // !defined(DART_PRECOMPILED_RUNTIME) + virtual bool ContainsUnalignedMembers() const; + // Whether this type has only same-size floating point members. // // Useful for determining whether struct is passed in FP registers in hardfp diff --git a/runtime/vm/compiler/ffi/native_type_test.cc b/runtime/vm/compiler/ffi/native_type_test.cc index d71e0e365d1b..d6d5ece42c95 100644 --- a/runtime/vm/compiler/ffi/native_type_test.cc +++ b/runtime/vm/compiler/ffi/native_type_test.cc @@ -14,9 +14,10 @@ namespace ffi { const NativeCompoundType& RunStructTest(dart::Zone* zone, const char* name, - const NativeTypes& member_types) { + const NativeTypes& member_types, + intptr_t packing = kMaxInt32) { const auto& struct_type = - NativeCompoundType::FromNativeTypes(zone, member_types); + NativeCompoundType::FromNativeTypes(zone, member_types, packing); const char* test_result = struct_type.ToCString(zone, /*multi_line=*/true); @@ -196,6 +197,23 @@ UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_floatarray) { struct_type.NumberOfWordSizeChunksOnlyFloat()); } +UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_packed) { + const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8); + const auto& uint16_type = *new (Z) NativePrimitiveType(kUint16); + + auto& members = *new (Z) NativeTypes(Z, 2); + members.Add(&uint8_type); + members.Add(&uint16_type); + const intptr_t packing = 1; + + const auto& struct_type = + NativeCompoundType::FromNativeTypes(Z, members, packing); + + // Should be 3 bytes on every platform. + EXPECT_EQ(3, struct_type.SizeInBytes()); + EXPECT(struct_type.ContainsUnalignedMembers()); +} + } // namespace ffi } // namespace compiler } // namespace dart diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_android.expect new file mode 100644 index 000000000000..e7b7d6e5f4ce --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_android.expect @@ -0,0 +1,12 @@ +M(r0 int64) Compound(size: 8) +M(r1 int64) Compound(size: 8) +M(r2 int64) Compound(size: 8) +M(r3 int64) Compound(size: 8) +M(r4 int64) Compound(size: 8) +M(r5 int64) Compound(size: 8) +M(r6 int64) Compound(size: 8) +M(r7 int64) Compound(size: 8) +S+0 Compound(size: 8) +S+8 Compound(size: 8) +=> +M(r0 int64) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_ios.expect new file mode 100644 index 000000000000..e7b7d6e5f4ce --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_ios.expect @@ -0,0 +1,12 @@ +M(r0 int64) Compound(size: 8) +M(r1 int64) Compound(size: 8) +M(r2 int64) Compound(size: 8) +M(r3 int64) Compound(size: 8) +M(r4 int64) Compound(size: 8) +M(r5 int64) Compound(size: 8) +M(r6 int64) Compound(size: 8) +M(r7 int64) Compound(size: 8) +S+0 Compound(size: 8) +S+8 Compound(size: 8) +=> +M(r0 int64) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_linux.expect new file mode 100644 index 000000000000..e7b7d6e5f4ce --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_linux.expect @@ -0,0 +1,12 @@ +M(r0 int64) Compound(size: 8) +M(r1 int64) Compound(size: 8) +M(r2 int64) Compound(size: 8) +M(r3 int64) Compound(size: 8) +M(r4 int64) Compound(size: 8) +M(r5 int64) Compound(size: 8) +M(r6 int64) Compound(size: 8) +M(r7 int64) Compound(size: 8) +S+0 Compound(size: 8) +S+8 Compound(size: 8) +=> +M(r0 int64) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_macos.expect new file mode 100644 index 000000000000..e7b7d6e5f4ce --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm64_macos.expect @@ -0,0 +1,12 @@ +M(r0 int64) Compound(size: 8) +M(r1 int64) Compound(size: 8) +M(r2 int64) Compound(size: 8) +M(r3 int64) Compound(size: 8) +M(r4 int64) Compound(size: 8) +M(r5 int64) Compound(size: 8) +M(r6 int64) Compound(size: 8) +M(r7 int64) Compound(size: 8) +S+0 Compound(size: 8) +S+8 Compound(size: 8) +=> +M(r0 int64) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_android.expect new file mode 100644 index 000000000000..49e6d408ee58 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_android.expect @@ -0,0 +1,12 @@ +M(r1 int32, r2 int32) Compound(size: 8) +M(r3 int32, S+0 int32) Compound(size: 8) +M(S+4 int32, S+8 int32) Compound(size: 8) +M(S+12 int32, S+16 int32) Compound(size: 8) +M(S+20 int32, S+24 int32) Compound(size: 8) +M(S+28 int32, S+32 int32) Compound(size: 8) +M(S+36 int32, S+40 int32) Compound(size: 8) +M(S+44 int32, S+48 int32) Compound(size: 8) +M(S+52 int32, S+56 int32) Compound(size: 8) +M(S+60 int32, S+64 int32) Compound(size: 8) +=> +P(r0 uint32) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_ios.expect new file mode 100644 index 000000000000..49e6d408ee58 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_ios.expect @@ -0,0 +1,12 @@ +M(r1 int32, r2 int32) Compound(size: 8) +M(r3 int32, S+0 int32) Compound(size: 8) +M(S+4 int32, S+8 int32) Compound(size: 8) +M(S+12 int32, S+16 int32) Compound(size: 8) +M(S+20 int32, S+24 int32) Compound(size: 8) +M(S+28 int32, S+32 int32) Compound(size: 8) +M(S+36 int32, S+40 int32) Compound(size: 8) +M(S+44 int32, S+48 int32) Compound(size: 8) +M(S+52 int32, S+56 int32) Compound(size: 8) +M(S+60 int32, S+64 int32) Compound(size: 8) +=> +P(r0 uint32) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_linux.expect new file mode 100644 index 000000000000..49e6d408ee58 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/arm_linux.expect @@ -0,0 +1,12 @@ +M(r1 int32, r2 int32) Compound(size: 8) +M(r3 int32, S+0 int32) Compound(size: 8) +M(S+4 int32, S+8 int32) Compound(size: 8) +M(S+12 int32, S+16 int32) Compound(size: 8) +M(S+20 int32, S+24 int32) Compound(size: 8) +M(S+28 int32, S+32 int32) Compound(size: 8) +M(S+36 int32, S+40 int32) Compound(size: 8) +M(S+44 int32, S+48 int32) Compound(size: 8) +M(S+52 int32, S+56 int32) Compound(size: 8) +M(S+60 int32, S+64 int32) Compound(size: 8) +=> +P(r0 uint32) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_android.expect new file mode 100644 index 000000000000..004cbab9e9d9 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_android.expect @@ -0,0 +1,12 @@ +S+4 Compound(size: 8) +S+12 Compound(size: 8) +S+20 Compound(size: 8) +S+28 Compound(size: 8) +S+36 Compound(size: 8) +S+44 Compound(size: 8) +S+52 Compound(size: 8) +S+60 Compound(size: 8) +S+68 Compound(size: 8) +S+76 Compound(size: 8) +=> +P(S+0 uint32, ret:eax uint32) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_linux.expect new file mode 100644 index 000000000000..004cbab9e9d9 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_linux.expect @@ -0,0 +1,12 @@ +S+4 Compound(size: 8) +S+12 Compound(size: 8) +S+20 Compound(size: 8) +S+28 Compound(size: 8) +S+36 Compound(size: 8) +S+44 Compound(size: 8) +S+52 Compound(size: 8) +S+60 Compound(size: 8) +S+68 Compound(size: 8) +S+76 Compound(size: 8) +=> +P(S+0 uint32, ret:eax uint32) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_win.expect new file mode 100644 index 000000000000..632981b988cf --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/ia32_win.expect @@ -0,0 +1,12 @@ +S+0 Compound(size: 8) +S+8 Compound(size: 8) +S+16 Compound(size: 8) +S+24 Compound(size: 8) +S+32 Compound(size: 8) +S+40 Compound(size: 8) +S+48 Compound(size: 8) +S+56 Compound(size: 8) +S+64 Compound(size: 8) +S+72 Compound(size: 8) +=> +M(eax uint32, edx uint32) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_ios.expect new file mode 100644 index 000000000000..b121f0244859 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_ios.expect @@ -0,0 +1,12 @@ +S+0 Compound(size: 8) +S+8 Compound(size: 8) +S+16 Compound(size: 8) +S+24 Compound(size: 8) +S+32 Compound(size: 8) +S+40 Compound(size: 8) +S+48 Compound(size: 8) +S+56 Compound(size: 8) +S+64 Compound(size: 8) +S+72 Compound(size: 8) +=> +P(rdi int64, ret:rax int64) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_linux.expect new file mode 100644 index 000000000000..b121f0244859 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_linux.expect @@ -0,0 +1,12 @@ +S+0 Compound(size: 8) +S+8 Compound(size: 8) +S+16 Compound(size: 8) +S+24 Compound(size: 8) +S+32 Compound(size: 8) +S+40 Compound(size: 8) +S+48 Compound(size: 8) +S+56 Compound(size: 8) +S+64 Compound(size: 8) +S+72 Compound(size: 8) +=> +P(rdi int64, ret:rax int64) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_macos.expect new file mode 100644 index 000000000000..b121f0244859 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_macos.expect @@ -0,0 +1,12 @@ +S+0 Compound(size: 8) +S+8 Compound(size: 8) +S+16 Compound(size: 8) +S+24 Compound(size: 8) +S+32 Compound(size: 8) +S+40 Compound(size: 8) +S+48 Compound(size: 8) +S+56 Compound(size: 8) +S+64 Compound(size: 8) +S+72 Compound(size: 8) +=> +P(rdi int64, ret:rax int64) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_win.expect new file mode 100644 index 000000000000..3504b4acc6b6 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/struct8bytesPackedx10/x64_win.expect @@ -0,0 +1,12 @@ +M(rcx int64) Compound(size: 8) +M(rdx int64) Compound(size: 8) +M(r8 int64) Compound(size: 8) +M(r9 int64) Compound(size: 8) +S+0 Compound(size: 8) +S+8 Compound(size: 8) +S+16 Compound(size: 8) +S+24 Compound(size: 8) +S+32 Compound(size: 8) +S+40 Compound(size: 8) +=> +M(rax int64) Compound(size: 8) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_android.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_android.expect new file mode 100644 index 000000000000..020f65e8ce78 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_android.expect @@ -0,0 +1,6 @@ +M(r0 int64, r1 int64) Compound(size: 9) +M(r2 int64, r3 int64) Compound(size: 9) +r4 int8 +v0 double +=> +M(r0 int64, r1 int64) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_ios.expect new file mode 100644 index 000000000000..0d234261e0e8 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_ios.expect @@ -0,0 +1,6 @@ +M(r0 int64, r1 int64) Compound(size: 9) +M(r2 int64, r3 int64) Compound(size: 9) +r4 int32[int8] +v0 double +=> +M(r0 int64, r1 int64) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_linux.expect new file mode 100644 index 000000000000..020f65e8ce78 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_linux.expect @@ -0,0 +1,6 @@ +M(r0 int64, r1 int64) Compound(size: 9) +M(r2 int64, r3 int64) Compound(size: 9) +r4 int8 +v0 double +=> +M(r0 int64, r1 int64) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_macos.expect new file mode 100644 index 000000000000..020f65e8ce78 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm64_macos.expect @@ -0,0 +1,6 @@ +M(r0 int64, r1 int64) Compound(size: 9) +M(r2 int64, r3 int64) Compound(size: 9) +r4 int8 +v0 double +=> +M(r0 int64, r1 int64) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_android.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_android.expect new file mode 100644 index 000000000000..d52d63e4a7f6 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_android.expect @@ -0,0 +1,6 @@ +M(r1 int32, r2 int32, r3 int32) Compound(size: 9) +M(S+0 int32, S+4 int32, S+8 int32) Compound(size: 9) +S+12 int32[int8] +S+16 double +=> +P(r0 uint32) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_ios.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_ios.expect new file mode 100644 index 000000000000..17492a209eb5 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_ios.expect @@ -0,0 +1,6 @@ +M(r1 int32, r2 int32, r3 int32) Compound(size: 9) +M(S+0 int32, S+4 int32, S+8 int32) Compound(size: 9) +S+12 int32[int8] +d0 double +=> +P(r0 uint32) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_linux.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_linux.expect new file mode 100644 index 000000000000..17492a209eb5 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/arm_linux.expect @@ -0,0 +1,6 @@ +M(r1 int32, r2 int32, r3 int32) Compound(size: 9) +M(S+0 int32, S+4 int32, S+8 int32) Compound(size: 9) +S+12 int32[int8] +d0 double +=> +P(r0 uint32) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_android.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_android.expect new file mode 100644 index 000000000000..33bf360e61ef --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_android.expect @@ -0,0 +1,6 @@ +S+4 Compound(size: 9) +S+16 Compound(size: 9) +S+28 int32[int8] +S+32 double +=> +P(S+0 uint32, ret:eax uint32) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_linux.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_linux.expect new file mode 100644 index 000000000000..33bf360e61ef --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_linux.expect @@ -0,0 +1,6 @@ +S+4 Compound(size: 9) +S+16 Compound(size: 9) +S+28 int32[int8] +S+32 double +=> +P(S+0 uint32, ret:eax uint32) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_win.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_win.expect new file mode 100644 index 000000000000..33bf360e61ef --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/ia32_win.expect @@ -0,0 +1,6 @@ +S+4 Compound(size: 9) +S+16 Compound(size: 9) +S+28 int32[int8] +S+32 double +=> +P(S+0 uint32, ret:eax uint32) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_ios.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_ios.expect new file mode 100644 index 000000000000..c4e54aa9f54f --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_ios.expect @@ -0,0 +1,6 @@ +S+0 Compound(size: 9) +S+16 Compound(size: 9) +rsi int32[int8] +xmm0 double +=> +P(rdi int64, ret:rax int64) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_linux.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_linux.expect new file mode 100644 index 000000000000..c4e54aa9f54f --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_linux.expect @@ -0,0 +1,6 @@ +S+0 Compound(size: 9) +S+16 Compound(size: 9) +rsi int32[int8] +xmm0 double +=> +P(rdi int64, ret:rax int64) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_macos.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_macos.expect new file mode 100644 index 000000000000..c4e54aa9f54f --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_macos.expect @@ -0,0 +1,6 @@ +S+0 Compound(size: 9) +S+16 Compound(size: 9) +rsi int32[int8] +xmm0 double +=> +P(rdi int64, ret:rax int64) Compound(size: 9) diff --git a/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_win.expect b/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_win.expect new file mode 100644 index 000000000000..b4ebbc612cd5 --- /dev/null +++ b/runtime/vm/compiler/ffi/unit_tests/structPacked/x64_win.expect @@ -0,0 +1,6 @@ +P(rdx int64) Compound(size: 9) +P(r8 int64) Compound(size: 9) +r9 int8 +S+0 double +=> +P(rcx int64, ret:rax int64) Compound(size: 9)