[test/ffi] Structs by value 1-byte aligned

The 3 and 7 byte tests in
https://dart-review.googlesource.com/c/sdk/+/168829
had their sizes rounded up to the next power of two due to alignment of
fields inside the structs.

In order to properly exercise behavior on win32, win64 and iOS, this CL
changes those structs to only have uint8 fields to prevent alignment
influencing the sizes.

Old tests are renamed to exercise the size rounding due to alignment.

This also swaps around the two 9byte structs to have consistent naming
with the new 3 and 7-byte tests.

structs_by_value_tests_confguration.dart is the only non-generated file.

The tests are tested in the dependent CL. Tests are ignored in status
file and are un-ignored in dependent CL.

Tests for https://github.com/dart-lang/sdk/issues/36730.

Change-Id: If47cfcaebe56f43d50265f0d6e2749c56fe7b195
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169101
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/runtime/bin/ffi_test/ffi_test_functions_generated.cc b/runtime/bin/ffi_test/ffi_test_functions_generated.cc
index 9c9789f..cbb631f 100644
--- a/runtime/bin/ffi_test/ffi_test_functions_generated.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions_generated.cc
@@ -40,7 +40,13 @@
   int8_t a0;
 };
 
-struct Struct3BytesInt {
+struct Struct3BytesHomogeneousUint8 {
+  uint8_t a0;
+  uint8_t a1;
+  uint8_t a2;
+};
+
+struct Struct3BytesInt2ByteAligned {
   int16_t a0;
   int8_t a1;
 };
@@ -50,7 +56,17 @@
   int16_t a1;
 };
 
-struct Struct7BytesInt {
+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;
@@ -73,12 +89,7 @@
   int16_t a2;
 };
 
-struct Struct9BytesInt {
-  int64_t a0;
-  int8_t a1;
-};
-
-struct Struct9BytesHomogeneousUint82 {
+struct Struct9BytesHomogeneousUint8 {
   uint8_t a0;
   uint8_t a1;
   uint8_t a2;
@@ -90,6 +101,11 @@
   uint8_t a8;
 };
 
+struct Struct9BytesInt4Or8ByteAligned {
+  int64_t a0;
+  int8_t a1;
+};
+
 struct Struct12BytesHomogeneousFloat {
   float a0;
   float a1;
@@ -367,17 +383,95 @@
 // 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 PassStruct3BytesIntx10(Struct3BytesInt a0,
-                                           Struct3BytesInt a1,
-                                           Struct3BytesInt a2,
-                                           Struct3BytesInt a3,
-                                           Struct3BytesInt a4,
-                                           Struct3BytesInt a5,
-                                           Struct3BytesInt a6,
-                                           Struct3BytesInt a7,
-                                           Struct3BytesInt a8,
-                                           Struct3BytesInt a9) {
-  std::cout << "PassStruct3BytesIntx10"
+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 << ", "
@@ -472,17 +566,151 @@
 // Used for testing structs by value.
 // Sub word size on 64 bit architectures.
 // 10 struct arguments will exhaust available registers.
-DART_EXPORT int64_t PassStruct7BytesIntx10(Struct7BytesInt a0,
-                                           Struct7BytesInt a1,
-                                           Struct7BytesInt a2,
-                                           Struct7BytesInt a3,
-                                           Struct7BytesInt a4,
-                                           Struct7BytesInt a5,
-                                           Struct7BytesInt a6,
-                                           Struct7BytesInt a7,
-                                           Struct7BytesInt a8,
-                                           Struct7BytesInt a9) {
-  std::cout << "PassStruct7BytesIntx10"
+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
@@ -715,77 +943,22 @@
 // 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 PassStruct9BytesIntx10(Struct9BytesInt a0,
-                                           Struct9BytesInt a1,
-                                           Struct9BytesInt a2,
-                                           Struct9BytesInt a3,
-                                           Struct9BytesInt a4,
-                                           Struct9BytesInt a5,
-                                           Struct9BytesInt a6,
-                                           Struct9BytesInt a7,
-                                           Struct9BytesInt a8,
-                                           Struct9BytesInt a9) {
-  std::cout << "PassStruct9BytesIntx10"
-            << "((" << 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.
-// 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.
-//
 DART_EXPORT int64_t
-PassStruct9BytesHomogeneousUint82x10(Struct9BytesHomogeneousUint82 a0,
-                                     Struct9BytesHomogeneousUint82 a1,
-                                     Struct9BytesHomogeneousUint82 a2,
-                                     Struct9BytesHomogeneousUint82 a3,
-                                     Struct9BytesHomogeneousUint82 a4,
-                                     Struct9BytesHomogeneousUint82 a5,
-                                     Struct9BytesHomogeneousUint82 a6,
-                                     Struct9BytesHomogeneousUint82 a7,
-                                     Struct9BytesHomogeneousUint82 a8,
-                                     Struct9BytesHomogeneousUint82 a9) {
+PassStruct9BytesHomogeneousUint8x10(Struct9BytesHomogeneousUint8 a0,
+                                    Struct9BytesHomogeneousUint8 a1,
+                                    Struct9BytesHomogeneousUint8 a2,
+                                    Struct9BytesHomogeneousUint8 a3,
+                                    Struct9BytesHomogeneousUint8 a4,
+                                    Struct9BytesHomogeneousUint8 a5,
+                                    Struct9BytesHomogeneousUint8 a6,
+                                    Struct9BytesHomogeneousUint8 a7,
+                                    Struct9BytesHomogeneousUint8 a8,
+                                    Struct9BytesHomogeneousUint8 a9) {
   std::cout
-      << "PassStruct9BytesHomogeneousUint82x10"
+      << "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)
@@ -933,6 +1106,63 @@
 }
 
 // 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.
@@ -2233,12 +2463,38 @@
 
 // Used for testing structs by value.
 // Smaller than word size return value on all architectures.
-DART_EXPORT Struct3BytesInt ReturnStruct3BytesInt(int16_t a0, int8_t a1) {
-  std::cout << "ReturnStruct3BytesInt"
+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";
 
-  Struct3BytesInt result;
+  Struct3BytesInt2ByteAligned result;
 
   result.a0 = a0;
   result.a1 = a1;
@@ -2272,14 +2528,54 @@
 
 // Used for testing structs by value.
 // Non-wordsize return value.
-DART_EXPORT Struct7BytesInt ReturnStruct7BytesInt(int32_t a0,
-                                                  int16_t a1,
-                                                  int8_t a2) {
-  std::cout << "ReturnStruct7BytesInt"
+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";
 
-  Struct7BytesInt result;
+  Struct7BytesInt4ByteAligned result;
 
   result.a0 = a0;
   result.a1 = a1;
@@ -2358,40 +2654,20 @@
 }
 
 // Used for testing structs by value.
-// Return value in two integer registers on x64.
-// The second register only contains a single byte.
-DART_EXPORT Struct9BytesInt ReturnStruct9BytesInt(int64_t a0, int8_t a1) {
-  std::cout << "ReturnStruct9BytesInt"
-            << "(" << a0 << ", " << static_cast<int>(a1) << ")"
-            << "\n";
-
-  Struct9BytesInt 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.
 // 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 Struct9BytesHomogeneousUint82
-ReturnStruct9BytesHomogeneousUint82(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 << "ReturnStruct9BytesHomogeneousUint82"
+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)
@@ -2399,7 +2675,7 @@
             << ", " << static_cast<int>(a8) << ")"
             << "\n";
 
-  Struct9BytesHomogeneousUint82 result;
+  Struct9BytesHomogeneousUint8 result;
 
   result.a0 = a0;
   result.a1 = a1;
@@ -2427,6 +2703,27 @@
 }
 
 // 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
@@ -3345,28 +3642,133 @@
 // 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 TestPassStruct3BytesIntx10(
+DART_EXPORT intptr_t TestPassStruct3BytesHomogeneousUint8x10(
     // NOLINTNEXTLINE(whitespace/parens)
-    int64_t (*f)(Struct3BytesInt a0,
-                 Struct3BytesInt a1,
-                 Struct3BytesInt a2,
-                 Struct3BytesInt a3,
-                 Struct3BytesInt a4,
-                 Struct3BytesInt a5,
-                 Struct3BytesInt a6,
-                 Struct3BytesInt a7,
-                 Struct3BytesInt a8,
-                 Struct3BytesInt a9)) {
-  Struct3BytesInt a0;
-  Struct3BytesInt a1;
-  Struct3BytesInt a2;
-  Struct3BytesInt a3;
-  Struct3BytesInt a4;
-  Struct3BytesInt a5;
-  Struct3BytesInt a6;
-  Struct3BytesInt a7;
-  Struct3BytesInt a8;
-  Struct3BytesInt a9;
+    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;
@@ -3389,7 +3791,7 @@
   a9.a0 = -19;
   a9.a1 = 20;
 
-  std::cout << "Calling TestPassStruct3BytesIntx10("
+  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 << ", "
@@ -3507,28 +3909,189 @@
 // Used for testing structs by value.
 // Sub word size on 64 bit architectures.
 // 10 struct arguments will exhaust available registers.
-DART_EXPORT intptr_t TestPassStruct7BytesIntx10(
+DART_EXPORT intptr_t TestPassStruct7BytesHomogeneousUint8x10(
     // NOLINTNEXTLINE(whitespace/parens)
-    int64_t (*f)(Struct7BytesInt a0,
-                 Struct7BytesInt a1,
-                 Struct7BytesInt a2,
-                 Struct7BytesInt a3,
-                 Struct7BytesInt a4,
-                 Struct7BytesInt a5,
-                 Struct7BytesInt a6,
-                 Struct7BytesInt a7,
-                 Struct7BytesInt a8,
-                 Struct7BytesInt a9)) {
-  Struct7BytesInt a0;
-  Struct7BytesInt a1;
-  Struct7BytesInt a2;
-  Struct7BytesInt a3;
-  Struct7BytesInt a4;
-  Struct7BytesInt a5;
-  Struct7BytesInt a6;
-  Struct7BytesInt a7;
-  Struct7BytesInt a8;
-  Struct7BytesInt a9;
+    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;
@@ -3561,7 +4124,7 @@
   a9.a1 = -29;
   a9.a2 = 30;
 
-  std::cout << "Calling TestPassStruct7BytesIntx10("
+  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
@@ -3865,115 +4428,31 @@
 // 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 TestPassStruct9BytesIntx10(
+DART_EXPORT intptr_t TestPassStruct9BytesHomogeneousUint8x10(
     // NOLINTNEXTLINE(whitespace/parens)
-    int64_t (*f)(Struct9BytesInt a0,
-                 Struct9BytesInt a1,
-                 Struct9BytesInt a2,
-                 Struct9BytesInt a3,
-                 Struct9BytesInt a4,
-                 Struct9BytesInt a5,
-                 Struct9BytesInt a6,
-                 Struct9BytesInt a7,
-                 Struct9BytesInt a8,
-                 Struct9BytesInt a9)) {
-  Struct9BytesInt a0;
-  Struct9BytesInt a1;
-  Struct9BytesInt a2;
-  Struct9BytesInt a3;
-  Struct9BytesInt a4;
-  Struct9BytesInt a5;
-  Struct9BytesInt a6;
-  Struct9BytesInt a7;
-  Struct9BytesInt a8;
-  Struct9BytesInt 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 TestPassStruct9BytesIntx10("
-            << "((" << 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.
-// 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.
-//
-DART_EXPORT intptr_t TestPassStruct9BytesHomogeneousUint82x10(
-    // NOLINTNEXTLINE(whitespace/parens)
-    int64_t (*f)(Struct9BytesHomogeneousUint82 a0,
-                 Struct9BytesHomogeneousUint82 a1,
-                 Struct9BytesHomogeneousUint82 a2,
-                 Struct9BytesHomogeneousUint82 a3,
-                 Struct9BytesHomogeneousUint82 a4,
-                 Struct9BytesHomogeneousUint82 a5,
-                 Struct9BytesHomogeneousUint82 a6,
-                 Struct9BytesHomogeneousUint82 a7,
-                 Struct9BytesHomogeneousUint82 a8,
-                 Struct9BytesHomogeneousUint82 a9)) {
-  Struct9BytesHomogeneousUint82 a0;
-  Struct9BytesHomogeneousUint82 a1;
-  Struct9BytesHomogeneousUint82 a2;
-  Struct9BytesHomogeneousUint82 a3;
-  Struct9BytesHomogeneousUint82 a4;
-  Struct9BytesHomogeneousUint82 a5;
-  Struct9BytesHomogeneousUint82 a6;
-  Struct9BytesHomogeneousUint82 a7;
-  Struct9BytesHomogeneousUint82 a8;
-  Struct9BytesHomogeneousUint82 a9;
+    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;
@@ -4067,7 +4546,7 @@
   a9.a8 = 90;
 
   std::cout
-      << "Calling TestPassStruct9BytesHomogeneousUint82x10("
+      << "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)
@@ -4140,6 +4619,91 @@
 }
 
 // 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.
@@ -5950,20 +6514,72 @@
 
 // Used for testing structs by value.
 // Smaller than word size return value on all architectures.
-DART_EXPORT intptr_t TestReturnStruct3BytesInt(
+DART_EXPORT intptr_t TestReturnStruct3BytesHomogeneousUint8(
     // NOLINTNEXTLINE(whitespace/parens)
-    Struct3BytesInt (*f)(int16_t a0, int8_t a1)) {
+    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 TestReturnStruct3BytesInt("
+  std::cout << "Calling TestReturnStruct3BytesInt2ByteAligned("
             << "(" << a0 << ", " << static_cast<int>(a1) << ")"
             << ")\n";
 
-  Struct3BytesInt result = f(a0, a1);
+  Struct3BytesInt2ByteAligned result = f(a0, a1);
 
   std::cout << "result = "
             << "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
@@ -6036,9 +6652,93 @@
 
 // Used for testing structs by value.
 // Non-wordsize return value.
-DART_EXPORT intptr_t TestReturnStruct7BytesInt(
+DART_EXPORT intptr_t TestReturnStruct7BytesHomogeneousUint8(
     // NOLINTNEXTLINE(whitespace/parens)
-    Struct7BytesInt (*f)(int32_t a0, int16_t a1, int8_t a2)) {
+    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;
@@ -6047,11 +6747,11 @@
   a1 = 2;
   a2 = -3;
 
-  std::cout << "Calling TestReturnStruct7BytesInt("
+  std::cout << "Calling TestReturnStruct7BytesInt4ByteAligned("
             << "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
             << ")\n";
 
-  Struct7BytesInt result = f(a0, a1, a2);
+  Struct7BytesInt4ByteAligned result = f(a0, a1, a2);
 
   std::cout << "result = "
             << "(" << result.a0 << ", " << result.a1 << ", "
@@ -6223,64 +6923,20 @@
 }
 
 // Used for testing structs by value.
-// Return value in two integer registers on x64.
-// The second register only contains a single byte.
-DART_EXPORT intptr_t TestReturnStruct9BytesInt(
-    // NOLINTNEXTLINE(whitespace/parens)
-    Struct9BytesInt (*f)(int64_t a0, int8_t a1)) {
-  int64_t a0;
-  int8_t a1;
-
-  a0 = -1;
-  a1 = 2;
-
-  std::cout << "Calling TestReturnStruct9BytesInt("
-            << "(" << a0 << ", " << static_cast<int>(a1) << ")"
-            << ")\n";
-
-  Struct9BytesInt 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.
 // 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 TestReturnStruct9BytesHomogeneousUint82(
+DART_EXPORT intptr_t TestReturnStruct9BytesHomogeneousUint8(
     // NOLINTNEXTLINE(whitespace/parens)
-    Struct9BytesHomogeneousUint82 (*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)) {
+    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;
@@ -6301,7 +6957,7 @@
   a7 = 8;
   a8 = 9;
 
-  std::cout << "Calling TestReturnStruct9BytesHomogeneousUint82("
+  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)
@@ -6309,7 +6965,7 @@
             << ", " << static_cast<int>(a8) << ")"
             << ")\n";
 
-  Struct9BytesHomogeneousUint82 result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+  Struct9BytesHomogeneousUint8 result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
 
   std::cout << "result = "
             << "(" << static_cast<int>(result.a0) << ", "
@@ -6367,6 +7023,50 @@
 }
 
 // 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(
diff --git a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
index 8499285..7985c51 100644
--- a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
@@ -33,20 +33,30 @@
       Pointer.fromFunction<PassStruct1ByteIntx10Type>(passStruct1ByteIntx10, 0),
       passStruct1ByteIntx10AfterCallback),
   CallbackTest.withCheck(
-      "PassStruct3BytesIntx10",
-      Pointer.fromFunction<PassStruct3BytesIntx10Type>(
-          passStruct3BytesIntx10, 0),
-      passStruct3BytesIntx10AfterCallback),
+      "PassStruct3BytesHomogeneousUint8x10",
+      Pointer.fromFunction<PassStruct3BytesHomogeneousUint8x10Type>(
+          passStruct3BytesHomogeneousUint8x10, 0),
+      passStruct3BytesHomogeneousUint8x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct3BytesInt2ByteAlignedx10",
+      Pointer.fromFunction<PassStruct3BytesInt2ByteAlignedx10Type>(
+          passStruct3BytesInt2ByteAlignedx10, 0),
+      passStruct3BytesInt2ByteAlignedx10AfterCallback),
   CallbackTest.withCheck(
       "PassStruct4BytesHomogeneousInt16x10",
       Pointer.fromFunction<PassStruct4BytesHomogeneousInt16x10Type>(
           passStruct4BytesHomogeneousInt16x10, 0),
       passStruct4BytesHomogeneousInt16x10AfterCallback),
   CallbackTest.withCheck(
-      "PassStruct7BytesIntx10",
-      Pointer.fromFunction<PassStruct7BytesIntx10Type>(
-          passStruct7BytesIntx10, 0),
-      passStruct7BytesIntx10AfterCallback),
+      "PassStruct7BytesHomogeneousUint8x10",
+      Pointer.fromFunction<PassStruct7BytesHomogeneousUint8x10Type>(
+          passStruct7BytesHomogeneousUint8x10, 0),
+      passStruct7BytesHomogeneousUint8x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct7BytesInt4ByteAlignedx10",
+      Pointer.fromFunction<PassStruct7BytesInt4ByteAlignedx10Type>(
+          passStruct7BytesInt4ByteAlignedx10, 0),
+      passStruct7BytesInt4ByteAlignedx10AfterCallback),
   CallbackTest.withCheck(
       "PassStruct8BytesIntx10",
       Pointer.fromFunction<PassStruct8BytesIntx10Type>(
@@ -63,15 +73,15 @@
           passStruct8BytesMixedx10, 0.0),
       passStruct8BytesMixedx10AfterCallback),
   CallbackTest.withCheck(
-      "PassStruct9BytesIntx10",
-      Pointer.fromFunction<PassStruct9BytesIntx10Type>(
-          passStruct9BytesIntx10, 0),
-      passStruct9BytesIntx10AfterCallback),
+      "PassStruct9BytesHomogeneousUint8x10",
+      Pointer.fromFunction<PassStruct9BytesHomogeneousUint8x10Type>(
+          passStruct9BytesHomogeneousUint8x10, 0),
+      passStruct9BytesHomogeneousUint8x10AfterCallback),
   CallbackTest.withCheck(
-      "PassStruct9BytesHomogeneousUint82x10",
-      Pointer.fromFunction<PassStruct9BytesHomogeneousUint82x10Type>(
-          passStruct9BytesHomogeneousUint82x10, 0),
-      passStruct9BytesHomogeneousUint82x10AfterCallback),
+      "PassStruct9BytesInt4Or8ByteAlignedx10",
+      Pointer.fromFunction<PassStruct9BytesInt4Or8ByteAlignedx10Type>(
+          passStruct9BytesInt4Or8ByteAlignedx10, 0),
+      passStruct9BytesInt4Or8ByteAlignedx10AfterCallback),
   CallbackTest.withCheck(
       "PassStruct12BytesHomogeneousFloatx6",
       Pointer.fromFunction<PassStruct12BytesHomogeneousFloatx6Type>(
@@ -181,18 +191,30 @@
       Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
       returnStruct1ByteIntAfterCallback),
   CallbackTest.withCheck(
-      "ReturnStruct3BytesInt",
-      Pointer.fromFunction<ReturnStruct3BytesIntType>(returnStruct3BytesInt),
-      returnStruct3BytesIntAfterCallback),
+      "ReturnStruct3BytesHomogeneousUint8",
+      Pointer.fromFunction<ReturnStruct3BytesHomogeneousUint8Type>(
+          returnStruct3BytesHomogeneousUint8),
+      returnStruct3BytesHomogeneousUint8AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct3BytesInt2ByteAligned",
+      Pointer.fromFunction<ReturnStruct3BytesInt2ByteAlignedType>(
+          returnStruct3BytesInt2ByteAligned),
+      returnStruct3BytesInt2ByteAlignedAfterCallback),
   CallbackTest.withCheck(
       "ReturnStruct4BytesHomogeneousInt16",
       Pointer.fromFunction<ReturnStruct4BytesHomogeneousInt16Type>(
           returnStruct4BytesHomogeneousInt16),
       returnStruct4BytesHomogeneousInt16AfterCallback),
   CallbackTest.withCheck(
-      "ReturnStruct7BytesInt",
-      Pointer.fromFunction<ReturnStruct7BytesIntType>(returnStruct7BytesInt),
-      returnStruct7BytesIntAfterCallback),
+      "ReturnStruct7BytesHomogeneousUint8",
+      Pointer.fromFunction<ReturnStruct7BytesHomogeneousUint8Type>(
+          returnStruct7BytesHomogeneousUint8),
+      returnStruct7BytesHomogeneousUint8AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct7BytesInt4ByteAligned",
+      Pointer.fromFunction<ReturnStruct7BytesInt4ByteAlignedType>(
+          returnStruct7BytesInt4ByteAligned),
+      returnStruct7BytesInt4ByteAlignedAfterCallback),
   CallbackTest.withCheck(
       "ReturnStruct8BytesInt",
       Pointer.fromFunction<ReturnStruct8BytesIntType>(returnStruct8BytesInt),
@@ -208,14 +230,15 @@
           returnStruct8BytesMixed),
       returnStruct8BytesMixedAfterCallback),
   CallbackTest.withCheck(
-      "ReturnStruct9BytesInt",
-      Pointer.fromFunction<ReturnStruct9BytesIntType>(returnStruct9BytesInt),
-      returnStruct9BytesIntAfterCallback),
+      "ReturnStruct9BytesHomogeneousUint8",
+      Pointer.fromFunction<ReturnStruct9BytesHomogeneousUint8Type>(
+          returnStruct9BytesHomogeneousUint8),
+      returnStruct9BytesHomogeneousUint8AfterCallback),
   CallbackTest.withCheck(
-      "ReturnStruct9BytesHomogeneousUint82",
-      Pointer.fromFunction<ReturnStruct9BytesHomogeneousUint82Type>(
-          returnStruct9BytesHomogeneousUint82),
-      returnStruct9BytesHomogeneousUint82AfterCallback),
+      "ReturnStruct9BytesInt4Or8ByteAligned",
+      Pointer.fromFunction<ReturnStruct9BytesInt4Or8ByteAlignedType>(
+          returnStruct9BytesInt4Or8ByteAligned),
+      returnStruct9BytesInt4Or8ByteAlignedAfterCallback),
   CallbackTest.withCheck(
       "ReturnStruct12BytesHomogeneousFloat",
       Pointer.fromFunction<ReturnStruct12BytesHomogeneousFloatType>(
@@ -410,106 +433,243 @@
   Expect.equals(5, result);
 }
 
-typedef PassStruct3BytesIntx10Type = Int64 Function(
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt);
+typedef PassStruct3BytesHomogeneousUint8x10Type = Int64 Function(
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8);
 
 // Global variables to be able to test inputs after callback returned.
-Struct3BytesInt passStruct3BytesIntx10_a0 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a1 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a2 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a3 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a4 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a5 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a6 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a7 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a8 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a9 = Struct3BytesInt();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a0 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a1 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a2 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a3 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a4 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a5 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a6 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a7 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a8 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a9 =
+    Struct3BytesHomogeneousUint8();
 
 // Result variable also global, so we can delete it after the callback.
-int passStruct3BytesIntx10Result = 0;
+int passStruct3BytesHomogeneousUint8x10Result = 0;
 
-int passStruct3BytesIntx10CalculateResult() {
+int passStruct3BytesHomogeneousUint8x10CalculateResult() {
   int result = 0;
 
-  result += passStruct3BytesIntx10_a0.a0;
-  result += passStruct3BytesIntx10_a0.a1;
-  result += passStruct3BytesIntx10_a1.a0;
-  result += passStruct3BytesIntx10_a1.a1;
-  result += passStruct3BytesIntx10_a2.a0;
-  result += passStruct3BytesIntx10_a2.a1;
-  result += passStruct3BytesIntx10_a3.a0;
-  result += passStruct3BytesIntx10_a3.a1;
-  result += passStruct3BytesIntx10_a4.a0;
-  result += passStruct3BytesIntx10_a4.a1;
-  result += passStruct3BytesIntx10_a5.a0;
-  result += passStruct3BytesIntx10_a5.a1;
-  result += passStruct3BytesIntx10_a6.a0;
-  result += passStruct3BytesIntx10_a6.a1;
-  result += passStruct3BytesIntx10_a7.a0;
-  result += passStruct3BytesIntx10_a7.a1;
-  result += passStruct3BytesIntx10_a8.a0;
-  result += passStruct3BytesIntx10_a8.a1;
-  result += passStruct3BytesIntx10_a9.a0;
-  result += passStruct3BytesIntx10_a9.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a0.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a0.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a0.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a1.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a1.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a1.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a2.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a2.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a2.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a3.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a3.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a3.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a4.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a4.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a4.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a5.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a5.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a5.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a6.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a6.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a6.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a7.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a7.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a7.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a8.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a8.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a8.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a9.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a9.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a9.a2;
 
-  passStruct3BytesIntx10Result = result;
+  passStruct3BytesHomogeneousUint8x10Result = result;
 
   return result;
 }
 
 /// Not a multiple of word size, not a power of two.
 /// 10 struct arguments will exhaust available registers.
-int passStruct3BytesIntx10(
-    Struct3BytesInt a0,
-    Struct3BytesInt a1,
-    Struct3BytesInt a2,
-    Struct3BytesInt a3,
-    Struct3BytesInt a4,
-    Struct3BytesInt a5,
-    Struct3BytesInt a6,
-    Struct3BytesInt a7,
-    Struct3BytesInt a8,
-    Struct3BytesInt a9) {
+int passStruct3BytesHomogeneousUint8x10(
+    Struct3BytesHomogeneousUint8 a0,
+    Struct3BytesHomogeneousUint8 a1,
+    Struct3BytesHomogeneousUint8 a2,
+    Struct3BytesHomogeneousUint8 a3,
+    Struct3BytesHomogeneousUint8 a4,
+    Struct3BytesHomogeneousUint8 a5,
+    Struct3BytesHomogeneousUint8 a6,
+    Struct3BytesHomogeneousUint8 a7,
+    Struct3BytesHomogeneousUint8 a8,
+    Struct3BytesHomogeneousUint8 a9) {
   print(
-      "passStruct3BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+      "passStruct3BytesHomogeneousUint8x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
 
   // In legacy mode, possibly return null.
 
   // In both nnbd and legacy mode, possibly throw.
   if (a0.a0 == 42 || a0.a0 == 84) {
     print("throwing!");
-    throw Exception("PassStruct3BytesIntx10 throwing on purpuse!");
+    throw Exception("PassStruct3BytesHomogeneousUint8x10 throwing on purpuse!");
   }
 
-  passStruct3BytesIntx10_a0 = a0;
-  passStruct3BytesIntx10_a1 = a1;
-  passStruct3BytesIntx10_a2 = a2;
-  passStruct3BytesIntx10_a3 = a3;
-  passStruct3BytesIntx10_a4 = a4;
-  passStruct3BytesIntx10_a5 = a5;
-  passStruct3BytesIntx10_a6 = a6;
-  passStruct3BytesIntx10_a7 = a7;
-  passStruct3BytesIntx10_a8 = a8;
-  passStruct3BytesIntx10_a9 = a9;
+  passStruct3BytesHomogeneousUint8x10_a0 = a0;
+  passStruct3BytesHomogeneousUint8x10_a1 = a1;
+  passStruct3BytesHomogeneousUint8x10_a2 = a2;
+  passStruct3BytesHomogeneousUint8x10_a3 = a3;
+  passStruct3BytesHomogeneousUint8x10_a4 = a4;
+  passStruct3BytesHomogeneousUint8x10_a5 = a5;
+  passStruct3BytesHomogeneousUint8x10_a6 = a6;
+  passStruct3BytesHomogeneousUint8x10_a7 = a7;
+  passStruct3BytesHomogeneousUint8x10_a8 = a8;
+  passStruct3BytesHomogeneousUint8x10_a9 = a9;
 
-  final result = passStruct3BytesIntx10CalculateResult();
+  final result = passStruct3BytesHomogeneousUint8x10CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void passStruct3BytesIntx10AfterCallback() {
-  final result = passStruct3BytesIntx10CalculateResult();
+void passStruct3BytesHomogeneousUint8x10AfterCallback() {
+  final result = passStruct3BytesHomogeneousUint8x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(465, result);
+}
+
+typedef PassStruct3BytesInt2ByteAlignedx10Type = Int64 Function(
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned);
+
+// Global variables to be able to test inputs after callback returned.
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a0 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a1 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a2 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a3 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a4 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a5 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a6 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a7 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a8 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a9 =
+    Struct3BytesInt2ByteAligned();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct3BytesInt2ByteAlignedx10Result = 0;
+
+int passStruct3BytesInt2ByteAlignedx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct3BytesInt2ByteAlignedx10_a0.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a0.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a1.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a1.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a2.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a2.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a3.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a3.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a4.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a4.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a5.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a5.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a6.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a6.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a7.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a7.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a8.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a8.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a9.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a9.a1;
+
+  passStruct3BytesInt2ByteAlignedx10Result = result;
+
+  return result;
+}
+
+/// 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.
+int passStruct3BytesInt2ByteAlignedx10(
+    Struct3BytesInt2ByteAligned a0,
+    Struct3BytesInt2ByteAligned a1,
+    Struct3BytesInt2ByteAligned a2,
+    Struct3BytesInt2ByteAligned a3,
+    Struct3BytesInt2ByteAligned a4,
+    Struct3BytesInt2ByteAligned a5,
+    Struct3BytesInt2ByteAligned a6,
+    Struct3BytesInt2ByteAligned a7,
+    Struct3BytesInt2ByteAligned a8,
+    Struct3BytesInt2ByteAligned a9) {
+  print(
+      "passStruct3BytesInt2ByteAlignedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct3BytesInt2ByteAlignedx10 throwing on purpuse!");
+  }
+
+  passStruct3BytesInt2ByteAlignedx10_a0 = a0;
+  passStruct3BytesInt2ByteAlignedx10_a1 = a1;
+  passStruct3BytesInt2ByteAlignedx10_a2 = a2;
+  passStruct3BytesInt2ByteAlignedx10_a3 = a3;
+  passStruct3BytesInt2ByteAlignedx10_a4 = a4;
+  passStruct3BytesInt2ByteAlignedx10_a5 = a5;
+  passStruct3BytesInt2ByteAlignedx10_a6 = a6;
+  passStruct3BytesInt2ByteAlignedx10_a7 = a7;
+  passStruct3BytesInt2ByteAlignedx10_a8 = a8;
+  passStruct3BytesInt2ByteAlignedx10_a9 = a9;
+
+  final result = passStruct3BytesInt2ByteAlignedx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct3BytesInt2ByteAlignedx10AfterCallback() {
+  final result = passStruct3BytesInt2ByteAlignedx10CalculateResult();
 
   print("after callback result = $result");
 
@@ -632,116 +792,293 @@
   Expect.equals(10, result);
 }
 
-typedef PassStruct7BytesIntx10Type = Int64 Function(
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt);
+typedef PassStruct7BytesHomogeneousUint8x10Type = Int64 Function(
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8);
 
 // Global variables to be able to test inputs after callback returned.
-Struct7BytesInt passStruct7BytesIntx10_a0 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a1 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a2 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a3 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a4 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a5 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a6 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a7 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a8 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a9 = Struct7BytesInt();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a0 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a1 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a2 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a3 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a4 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a5 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a6 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a7 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a8 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a9 =
+    Struct7BytesHomogeneousUint8();
 
 // Result variable also global, so we can delete it after the callback.
-int passStruct7BytesIntx10Result = 0;
+int passStruct7BytesHomogeneousUint8x10Result = 0;
 
-int passStruct7BytesIntx10CalculateResult() {
+int passStruct7BytesHomogeneousUint8x10CalculateResult() {
   int result = 0;
 
-  result += passStruct7BytesIntx10_a0.a0;
-  result += passStruct7BytesIntx10_a0.a1;
-  result += passStruct7BytesIntx10_a0.a2;
-  result += passStruct7BytesIntx10_a1.a0;
-  result += passStruct7BytesIntx10_a1.a1;
-  result += passStruct7BytesIntx10_a1.a2;
-  result += passStruct7BytesIntx10_a2.a0;
-  result += passStruct7BytesIntx10_a2.a1;
-  result += passStruct7BytesIntx10_a2.a2;
-  result += passStruct7BytesIntx10_a3.a0;
-  result += passStruct7BytesIntx10_a3.a1;
-  result += passStruct7BytesIntx10_a3.a2;
-  result += passStruct7BytesIntx10_a4.a0;
-  result += passStruct7BytesIntx10_a4.a1;
-  result += passStruct7BytesIntx10_a4.a2;
-  result += passStruct7BytesIntx10_a5.a0;
-  result += passStruct7BytesIntx10_a5.a1;
-  result += passStruct7BytesIntx10_a5.a2;
-  result += passStruct7BytesIntx10_a6.a0;
-  result += passStruct7BytesIntx10_a6.a1;
-  result += passStruct7BytesIntx10_a6.a2;
-  result += passStruct7BytesIntx10_a7.a0;
-  result += passStruct7BytesIntx10_a7.a1;
-  result += passStruct7BytesIntx10_a7.a2;
-  result += passStruct7BytesIntx10_a8.a0;
-  result += passStruct7BytesIntx10_a8.a1;
-  result += passStruct7BytesIntx10_a8.a2;
-  result += passStruct7BytesIntx10_a9.a0;
-  result += passStruct7BytesIntx10_a9.a1;
-  result += passStruct7BytesIntx10_a9.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a6;
 
-  passStruct7BytesIntx10Result = result;
+  passStruct7BytesHomogeneousUint8x10Result = result;
 
   return result;
 }
 
 /// Sub word size on 64 bit architectures.
 /// 10 struct arguments will exhaust available registers.
-int passStruct7BytesIntx10(
-    Struct7BytesInt a0,
-    Struct7BytesInt a1,
-    Struct7BytesInt a2,
-    Struct7BytesInt a3,
-    Struct7BytesInt a4,
-    Struct7BytesInt a5,
-    Struct7BytesInt a6,
-    Struct7BytesInt a7,
-    Struct7BytesInt a8,
-    Struct7BytesInt a9) {
+int passStruct7BytesHomogeneousUint8x10(
+    Struct7BytesHomogeneousUint8 a0,
+    Struct7BytesHomogeneousUint8 a1,
+    Struct7BytesHomogeneousUint8 a2,
+    Struct7BytesHomogeneousUint8 a3,
+    Struct7BytesHomogeneousUint8 a4,
+    Struct7BytesHomogeneousUint8 a5,
+    Struct7BytesHomogeneousUint8 a6,
+    Struct7BytesHomogeneousUint8 a7,
+    Struct7BytesHomogeneousUint8 a8,
+    Struct7BytesHomogeneousUint8 a9) {
   print(
-      "passStruct7BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+      "passStruct7BytesHomogeneousUint8x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
 
   // In legacy mode, possibly return null.
 
   // In both nnbd and legacy mode, possibly throw.
   if (a0.a0 == 42 || a0.a0 == 84) {
     print("throwing!");
-    throw Exception("PassStruct7BytesIntx10 throwing on purpuse!");
+    throw Exception("PassStruct7BytesHomogeneousUint8x10 throwing on purpuse!");
   }
 
-  passStruct7BytesIntx10_a0 = a0;
-  passStruct7BytesIntx10_a1 = a1;
-  passStruct7BytesIntx10_a2 = a2;
-  passStruct7BytesIntx10_a3 = a3;
-  passStruct7BytesIntx10_a4 = a4;
-  passStruct7BytesIntx10_a5 = a5;
-  passStruct7BytesIntx10_a6 = a6;
-  passStruct7BytesIntx10_a7 = a7;
-  passStruct7BytesIntx10_a8 = a8;
-  passStruct7BytesIntx10_a9 = a9;
+  passStruct7BytesHomogeneousUint8x10_a0 = a0;
+  passStruct7BytesHomogeneousUint8x10_a1 = a1;
+  passStruct7BytesHomogeneousUint8x10_a2 = a2;
+  passStruct7BytesHomogeneousUint8x10_a3 = a3;
+  passStruct7BytesHomogeneousUint8x10_a4 = a4;
+  passStruct7BytesHomogeneousUint8x10_a5 = a5;
+  passStruct7BytesHomogeneousUint8x10_a6 = a6;
+  passStruct7BytesHomogeneousUint8x10_a7 = a7;
+  passStruct7BytesHomogeneousUint8x10_a8 = a8;
+  passStruct7BytesHomogeneousUint8x10_a9 = a9;
 
-  final result = passStruct7BytesIntx10CalculateResult();
+  final result = passStruct7BytesHomogeneousUint8x10CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void passStruct7BytesIntx10AfterCallback() {
-  final result = passStruct7BytesIntx10CalculateResult();
+void passStruct7BytesHomogeneousUint8x10AfterCallback() {
+  final result = passStruct7BytesHomogeneousUint8x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(2485, result);
+}
+
+typedef PassStruct7BytesInt4ByteAlignedx10Type = Int64 Function(
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned);
+
+// Global variables to be able to test inputs after callback returned.
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a0 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a1 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a2 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a3 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a4 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a5 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a6 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a7 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a8 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a9 =
+    Struct7BytesInt4ByteAligned();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct7BytesInt4ByteAlignedx10Result = 0;
+
+int passStruct7BytesInt4ByteAlignedx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct7BytesInt4ByteAlignedx10_a0.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a0.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a0.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a1.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a1.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a1.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a2.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a2.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a2.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a3.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a3.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a3.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a4.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a4.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a4.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a5.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a5.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a5.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a6.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a6.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a6.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a7.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a7.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a7.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a8.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a8.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a8.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a9.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a9.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a9.a2;
+
+  passStruct7BytesInt4ByteAlignedx10Result = result;
+
+  return result;
+}
+
+/// Sub word size on 64 bit architectures.
+/// With alignment rules taken into account size is 8 bytes.
+/// 10 struct arguments will exhaust available registers.
+int passStruct7BytesInt4ByteAlignedx10(
+    Struct7BytesInt4ByteAligned a0,
+    Struct7BytesInt4ByteAligned a1,
+    Struct7BytesInt4ByteAligned a2,
+    Struct7BytesInt4ByteAligned a3,
+    Struct7BytesInt4ByteAligned a4,
+    Struct7BytesInt4ByteAligned a5,
+    Struct7BytesInt4ByteAligned a6,
+    Struct7BytesInt4ByteAligned a7,
+    Struct7BytesInt4ByteAligned a8,
+    Struct7BytesInt4ByteAligned a9) {
+  print(
+      "passStruct7BytesInt4ByteAlignedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct7BytesInt4ByteAlignedx10 throwing on purpuse!");
+  }
+
+  passStruct7BytesInt4ByteAlignedx10_a0 = a0;
+  passStruct7BytesInt4ByteAlignedx10_a1 = a1;
+  passStruct7BytesInt4ByteAlignedx10_a2 = a2;
+  passStruct7BytesInt4ByteAlignedx10_a3 = a3;
+  passStruct7BytesInt4ByteAlignedx10_a4 = a4;
+  passStruct7BytesInt4ByteAlignedx10_a5 = a5;
+  passStruct7BytesInt4ByteAlignedx10_a6 = a6;
+  passStruct7BytesInt4ByteAlignedx10_a7 = a7;
+  passStruct7BytesInt4ByteAlignedx10_a8 = a8;
+  passStruct7BytesInt4ByteAlignedx10_a9 = a9;
+
+  final result = passStruct7BytesInt4ByteAlignedx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct7BytesInt4ByteAlignedx10AfterCallback() {
+  final result = passStruct7BytesInt4ByteAlignedx10CalculateResult();
 
   print("after callback result = $result");
 
@@ -1096,246 +1433,138 @@
   Expect.approxEquals(15.0, result);
 }
 
-typedef PassStruct9BytesIntx10Type = Int64 Function(
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt);
+typedef PassStruct9BytesHomogeneousUint8x10Type = Int64 Function(
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8);
 
 // Global variables to be able to test inputs after callback returned.
-Struct9BytesInt passStruct9BytesIntx10_a0 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a1 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a2 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a3 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a4 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a5 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a6 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a7 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a8 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a9 = Struct9BytesInt();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a0 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a1 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a2 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a3 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a4 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a5 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a6 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a7 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a8 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a9 =
+    Struct9BytesHomogeneousUint8();
 
 // Result variable also global, so we can delete it after the callback.
-int passStruct9BytesIntx10Result = 0;
+int passStruct9BytesHomogeneousUint8x10Result = 0;
 
-int passStruct9BytesIntx10CalculateResult() {
+int passStruct9BytesHomogeneousUint8x10CalculateResult() {
   int result = 0;
 
-  result += passStruct9BytesIntx10_a0.a0;
-  result += passStruct9BytesIntx10_a0.a1;
-  result += passStruct9BytesIntx10_a1.a0;
-  result += passStruct9BytesIntx10_a1.a1;
-  result += passStruct9BytesIntx10_a2.a0;
-  result += passStruct9BytesIntx10_a2.a1;
-  result += passStruct9BytesIntx10_a3.a0;
-  result += passStruct9BytesIntx10_a3.a1;
-  result += passStruct9BytesIntx10_a4.a0;
-  result += passStruct9BytesIntx10_a4.a1;
-  result += passStruct9BytesIntx10_a5.a0;
-  result += passStruct9BytesIntx10_a5.a1;
-  result += passStruct9BytesIntx10_a6.a0;
-  result += passStruct9BytesIntx10_a6.a1;
-  result += passStruct9BytesIntx10_a7.a0;
-  result += passStruct9BytesIntx10_a7.a1;
-  result += passStruct9BytesIntx10_a8.a0;
-  result += passStruct9BytesIntx10_a8.a1;
-  result += passStruct9BytesIntx10_a9.a0;
-  result += passStruct9BytesIntx10_a9.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a8;
 
-  passStruct9BytesIntx10Result = result;
-
-  return result;
-}
-
-/// Argument is a single byte over a multiple of word size.
-/// 10 struct arguments will exhaust available registers.
-/// Tests upper bytes in the integer registers that are partly filled.
-/// Tests stack alignment of non word size stack arguments.
-int passStruct9BytesIntx10(
-    Struct9BytesInt a0,
-    Struct9BytesInt a1,
-    Struct9BytesInt a2,
-    Struct9BytesInt a3,
-    Struct9BytesInt a4,
-    Struct9BytesInt a5,
-    Struct9BytesInt a6,
-    Struct9BytesInt a7,
-    Struct9BytesInt a8,
-    Struct9BytesInt a9) {
-  print(
-      "passStruct9BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
-
-  // In legacy mode, possibly return null.
-
-  // In both nnbd and legacy mode, possibly throw.
-  if (a0.a0 == 42 || a0.a0 == 84) {
-    print("throwing!");
-    throw Exception("PassStruct9BytesIntx10 throwing on purpuse!");
-  }
-
-  passStruct9BytesIntx10_a0 = a0;
-  passStruct9BytesIntx10_a1 = a1;
-  passStruct9BytesIntx10_a2 = a2;
-  passStruct9BytesIntx10_a3 = a3;
-  passStruct9BytesIntx10_a4 = a4;
-  passStruct9BytesIntx10_a5 = a5;
-  passStruct9BytesIntx10_a6 = a6;
-  passStruct9BytesIntx10_a7 = a7;
-  passStruct9BytesIntx10_a8 = a8;
-  passStruct9BytesIntx10_a9 = a9;
-
-  final result = passStruct9BytesIntx10CalculateResult();
-
-  print("result = $result");
-
-  return result;
-}
-
-void passStruct9BytesIntx10AfterCallback() {
-  final result = passStruct9BytesIntx10CalculateResult();
-
-  print("after callback result = $result");
-
-  Expect.equals(10, result);
-}
-
-typedef PassStruct9BytesHomogeneousUint82x10Type = Int64 Function(
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82);
-
-// Global variables to be able to test inputs after callback returned.
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a0 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a1 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a2 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a3 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a4 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a5 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a6 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a7 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a8 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a9 =
-    Struct9BytesHomogeneousUint82();
-
-// Result variable also global, so we can delete it after the callback.
-int passStruct9BytesHomogeneousUint82x10Result = 0;
-
-int passStruct9BytesHomogeneousUint82x10CalculateResult() {
-  int result = 0;
-
-  result += passStruct9BytesHomogeneousUint82x10_a0.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a8;
-
-  passStruct9BytesHomogeneousUint82x10Result = result;
+  passStruct9BytesHomogeneousUint8x10Result = result;
 
   return result;
 }
@@ -1343,20 +1572,139 @@
 /// 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.
-///
-int passStruct9BytesHomogeneousUint82x10(
-    Struct9BytesHomogeneousUint82 a0,
-    Struct9BytesHomogeneousUint82 a1,
-    Struct9BytesHomogeneousUint82 a2,
-    Struct9BytesHomogeneousUint82 a3,
-    Struct9BytesHomogeneousUint82 a4,
-    Struct9BytesHomogeneousUint82 a5,
-    Struct9BytesHomogeneousUint82 a6,
-    Struct9BytesHomogeneousUint82 a7,
-    Struct9BytesHomogeneousUint82 a8,
-    Struct9BytesHomogeneousUint82 a9) {
+/// Tests upper bytes in the integer registers that are partly filled.
+/// Tests stack alignment of non word size stack arguments.
+int passStruct9BytesHomogeneousUint8x10(
+    Struct9BytesHomogeneousUint8 a0,
+    Struct9BytesHomogeneousUint8 a1,
+    Struct9BytesHomogeneousUint8 a2,
+    Struct9BytesHomogeneousUint8 a3,
+    Struct9BytesHomogeneousUint8 a4,
+    Struct9BytesHomogeneousUint8 a5,
+    Struct9BytesHomogeneousUint8 a6,
+    Struct9BytesHomogeneousUint8 a7,
+    Struct9BytesHomogeneousUint8 a8,
+    Struct9BytesHomogeneousUint8 a9) {
   print(
-      "passStruct9BytesHomogeneousUint82x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+      "passStruct9BytesHomogeneousUint8x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct9BytesHomogeneousUint8x10 throwing on purpuse!");
+  }
+
+  passStruct9BytesHomogeneousUint8x10_a0 = a0;
+  passStruct9BytesHomogeneousUint8x10_a1 = a1;
+  passStruct9BytesHomogeneousUint8x10_a2 = a2;
+  passStruct9BytesHomogeneousUint8x10_a3 = a3;
+  passStruct9BytesHomogeneousUint8x10_a4 = a4;
+  passStruct9BytesHomogeneousUint8x10_a5 = a5;
+  passStruct9BytesHomogeneousUint8x10_a6 = a6;
+  passStruct9BytesHomogeneousUint8x10_a7 = a7;
+  passStruct9BytesHomogeneousUint8x10_a8 = a8;
+  passStruct9BytesHomogeneousUint8x10_a9 = a9;
+
+  final result = passStruct9BytesHomogeneousUint8x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct9BytesHomogeneousUint8x10AfterCallback() {
+  final result = passStruct9BytesHomogeneousUint8x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(4095, result);
+}
+
+typedef PassStruct9BytesInt4Or8ByteAlignedx10Type = Int64 Function(
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned);
+
+// Global variables to be able to test inputs after callback returned.
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a0 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a1 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a2 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a3 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a4 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a5 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a6 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a7 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a8 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a9 =
+    Struct9BytesInt4Or8ByteAligned();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct9BytesInt4Or8ByteAlignedx10Result = 0;
+
+int passStruct9BytesInt4Or8ByteAlignedx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a0.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a0.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a1.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a1.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a2.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a2.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a3.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a3.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a4.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a4.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a5.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a5.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a6.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a6.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a7.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a7.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a8.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a8.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a9.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a9.a1;
+
+  passStruct9BytesInt4Or8ByteAlignedx10Result = result;
+
+  return result;
+}
+
+/// 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.
+///
+int passStruct9BytesInt4Or8ByteAlignedx10(
+    Struct9BytesInt4Or8ByteAligned a0,
+    Struct9BytesInt4Or8ByteAligned a1,
+    Struct9BytesInt4Or8ByteAligned a2,
+    Struct9BytesInt4Or8ByteAligned a3,
+    Struct9BytesInt4Or8ByteAligned a4,
+    Struct9BytesInt4Or8ByteAligned a5,
+    Struct9BytesInt4Or8ByteAligned a6,
+    Struct9BytesInt4Or8ByteAligned a7,
+    Struct9BytesInt4Or8ByteAligned a8,
+    Struct9BytesInt4Or8ByteAligned a9) {
+  print(
+      "passStruct9BytesInt4Or8ByteAlignedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
 
   // In legacy mode, possibly return null.
 
@@ -1364,33 +1712,33 @@
   if (a0.a0 == 42 || a0.a0 == 84) {
     print("throwing!");
     throw Exception(
-        "PassStruct9BytesHomogeneousUint82x10 throwing on purpuse!");
+        "PassStruct9BytesInt4Or8ByteAlignedx10 throwing on purpuse!");
   }
 
-  passStruct9BytesHomogeneousUint82x10_a0 = a0;
-  passStruct9BytesHomogeneousUint82x10_a1 = a1;
-  passStruct9BytesHomogeneousUint82x10_a2 = a2;
-  passStruct9BytesHomogeneousUint82x10_a3 = a3;
-  passStruct9BytesHomogeneousUint82x10_a4 = a4;
-  passStruct9BytesHomogeneousUint82x10_a5 = a5;
-  passStruct9BytesHomogeneousUint82x10_a6 = a6;
-  passStruct9BytesHomogeneousUint82x10_a7 = a7;
-  passStruct9BytesHomogeneousUint82x10_a8 = a8;
-  passStruct9BytesHomogeneousUint82x10_a9 = a9;
+  passStruct9BytesInt4Or8ByteAlignedx10_a0 = a0;
+  passStruct9BytesInt4Or8ByteAlignedx10_a1 = a1;
+  passStruct9BytesInt4Or8ByteAlignedx10_a2 = a2;
+  passStruct9BytesInt4Or8ByteAlignedx10_a3 = a3;
+  passStruct9BytesInt4Or8ByteAlignedx10_a4 = a4;
+  passStruct9BytesInt4Or8ByteAlignedx10_a5 = a5;
+  passStruct9BytesInt4Or8ByteAlignedx10_a6 = a6;
+  passStruct9BytesInt4Or8ByteAlignedx10_a7 = a7;
+  passStruct9BytesInt4Or8ByteAlignedx10_a8 = a8;
+  passStruct9BytesInt4Or8ByteAlignedx10_a9 = a9;
 
-  final result = passStruct9BytesHomogeneousUint82x10CalculateResult();
+  final result = passStruct9BytesInt4Or8ByteAlignedx10CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void passStruct9BytesHomogeneousUint82x10AfterCallback() {
-  final result = passStruct9BytesHomogeneousUint82x10CalculateResult();
+void passStruct9BytesInt4Or8ByteAlignedx10AfterCallback() {
+  final result = passStruct9BytesInt4Or8ByteAlignedx10CalculateResult();
 
   print("after callback result = $result");
 
-  Expect.equals(4095, result);
+  Expect.equals(10, result);
 }
 
 typedef PassStruct12BytesHomogeneousFloatx6Type = Float Function(
@@ -3552,56 +3900,120 @@
   free(returnStruct1ByteIntResult.addressOf);
 }
 
-typedef ReturnStruct3BytesIntType = Struct3BytesInt Function(Int16, Int8);
+typedef ReturnStruct3BytesHomogeneousUint8Type = Struct3BytesHomogeneousUint8
+    Function(Uint8, Uint8, Uint8);
 
 // Global variables to be able to test inputs after callback returned.
-int returnStruct3BytesInt_a0 = 0;
-int returnStruct3BytesInt_a1 = 0;
+int returnStruct3BytesHomogeneousUint8_a0 = 0;
+int returnStruct3BytesHomogeneousUint8_a1 = 0;
+int returnStruct3BytesHomogeneousUint8_a2 = 0;
 
 // Result variable also global, so we can delete it after the callback.
-Struct3BytesInt returnStruct3BytesIntResult = Struct3BytesInt();
+Struct3BytesHomogeneousUint8 returnStruct3BytesHomogeneousUint8Result =
+    Struct3BytesHomogeneousUint8();
 
-Struct3BytesInt returnStruct3BytesIntCalculateResult() {
-  Struct3BytesInt result = allocate<Struct3BytesInt>().ref;
+Struct3BytesHomogeneousUint8
+    returnStruct3BytesHomogeneousUint8CalculateResult() {
+  Struct3BytesHomogeneousUint8 result =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
 
-  result.a0 = returnStruct3BytesInt_a0;
-  result.a1 = returnStruct3BytesInt_a1;
+  result.a0 = returnStruct3BytesHomogeneousUint8_a0;
+  result.a1 = returnStruct3BytesHomogeneousUint8_a1;
+  result.a2 = returnStruct3BytesHomogeneousUint8_a2;
 
-  returnStruct3BytesIntResult = result;
+  returnStruct3BytesHomogeneousUint8Result = result;
 
   return result;
 }
 
 /// Smaller than word size return value on all architectures.
-Struct3BytesInt returnStruct3BytesInt(int a0, int a1) {
-  print("returnStruct3BytesInt(${a0}, ${a1})");
+Struct3BytesHomogeneousUint8 returnStruct3BytesHomogeneousUint8(
+    int a0, int a1, int a2) {
+  print("returnStruct3BytesHomogeneousUint8(${a0}, ${a1}, ${a2})");
 
   // In legacy mode, possibly return null.
 
   // In both nnbd and legacy mode, possibly throw.
   if (a0 == 42 || a0 == 84) {
     print("throwing!");
-    throw Exception("ReturnStruct3BytesInt throwing on purpuse!");
+    throw Exception("ReturnStruct3BytesHomogeneousUint8 throwing on purpuse!");
   }
 
-  returnStruct3BytesInt_a0 = a0;
-  returnStruct3BytesInt_a1 = a1;
+  returnStruct3BytesHomogeneousUint8_a0 = a0;
+  returnStruct3BytesHomogeneousUint8_a1 = a1;
+  returnStruct3BytesHomogeneousUint8_a2 = a2;
 
-  final result = returnStruct3BytesIntCalculateResult();
+  final result = returnStruct3BytesHomogeneousUint8CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void returnStruct3BytesIntAfterCallback() {
-  free(returnStruct3BytesIntResult.addressOf);
+void returnStruct3BytesHomogeneousUint8AfterCallback() {
+  free(returnStruct3BytesHomogeneousUint8Result.addressOf);
 
-  final result = returnStruct3BytesIntCalculateResult();
+  final result = returnStruct3BytesHomogeneousUint8CalculateResult();
 
   print("after callback result = $result");
 
-  free(returnStruct3BytesIntResult.addressOf);
+  free(returnStruct3BytesHomogeneousUint8Result.addressOf);
+}
+
+typedef ReturnStruct3BytesInt2ByteAlignedType = Struct3BytesInt2ByteAligned
+    Function(Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct3BytesInt2ByteAligned_a0 = 0;
+int returnStruct3BytesInt2ByteAligned_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct3BytesInt2ByteAligned returnStruct3BytesInt2ByteAlignedResult =
+    Struct3BytesInt2ByteAligned();
+
+Struct3BytesInt2ByteAligned returnStruct3BytesInt2ByteAlignedCalculateResult() {
+  Struct3BytesInt2ByteAligned result =
+      allocate<Struct3BytesInt2ByteAligned>().ref;
+
+  result.a0 = returnStruct3BytesInt2ByteAligned_a0;
+  result.a1 = returnStruct3BytesInt2ByteAligned_a1;
+
+  returnStruct3BytesInt2ByteAlignedResult = result;
+
+  return result;
+}
+
+/// Smaller than word size return value on all architectures.
+/// With alignment rules taken into account size is 4 bytes.
+Struct3BytesInt2ByteAligned returnStruct3BytesInt2ByteAligned(int a0, int a1) {
+  print("returnStruct3BytesInt2ByteAligned(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct3BytesInt2ByteAligned throwing on purpuse!");
+  }
+
+  returnStruct3BytesInt2ByteAligned_a0 = a0;
+  returnStruct3BytesInt2ByteAligned_a1 = a1;
+
+  final result = returnStruct3BytesInt2ByteAlignedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct3BytesInt2ByteAlignedAfterCallback() {
+  free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
+
+  final result = returnStruct3BytesInt2ByteAlignedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
 }
 
 typedef ReturnStruct4BytesHomogeneousInt16Type = Struct4BytesHomogeneousInt16
@@ -3661,60 +4073,137 @@
   free(returnStruct4BytesHomogeneousInt16Result.addressOf);
 }
 
-typedef ReturnStruct7BytesIntType = Struct7BytesInt Function(
-    Int32, Int16, Int8);
+typedef ReturnStruct7BytesHomogeneousUint8Type = Struct7BytesHomogeneousUint8
+    Function(Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8);
 
 // Global variables to be able to test inputs after callback returned.
-int returnStruct7BytesInt_a0 = 0;
-int returnStruct7BytesInt_a1 = 0;
-int returnStruct7BytesInt_a2 = 0;
+int returnStruct7BytesHomogeneousUint8_a0 = 0;
+int returnStruct7BytesHomogeneousUint8_a1 = 0;
+int returnStruct7BytesHomogeneousUint8_a2 = 0;
+int returnStruct7BytesHomogeneousUint8_a3 = 0;
+int returnStruct7BytesHomogeneousUint8_a4 = 0;
+int returnStruct7BytesHomogeneousUint8_a5 = 0;
+int returnStruct7BytesHomogeneousUint8_a6 = 0;
 
 // Result variable also global, so we can delete it after the callback.
-Struct7BytesInt returnStruct7BytesIntResult = Struct7BytesInt();
+Struct7BytesHomogeneousUint8 returnStruct7BytesHomogeneousUint8Result =
+    Struct7BytesHomogeneousUint8();
 
-Struct7BytesInt returnStruct7BytesIntCalculateResult() {
-  Struct7BytesInt result = allocate<Struct7BytesInt>().ref;
+Struct7BytesHomogeneousUint8
+    returnStruct7BytesHomogeneousUint8CalculateResult() {
+  Struct7BytesHomogeneousUint8 result =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
 
-  result.a0 = returnStruct7BytesInt_a0;
-  result.a1 = returnStruct7BytesInt_a1;
-  result.a2 = returnStruct7BytesInt_a2;
+  result.a0 = returnStruct7BytesHomogeneousUint8_a0;
+  result.a1 = returnStruct7BytesHomogeneousUint8_a1;
+  result.a2 = returnStruct7BytesHomogeneousUint8_a2;
+  result.a3 = returnStruct7BytesHomogeneousUint8_a3;
+  result.a4 = returnStruct7BytesHomogeneousUint8_a4;
+  result.a5 = returnStruct7BytesHomogeneousUint8_a5;
+  result.a6 = returnStruct7BytesHomogeneousUint8_a6;
 
-  returnStruct7BytesIntResult = result;
+  returnStruct7BytesHomogeneousUint8Result = result;
 
   return result;
 }
 
 /// Non-wordsize return value.
-Struct7BytesInt returnStruct7BytesInt(int a0, int a1, int a2) {
-  print("returnStruct7BytesInt(${a0}, ${a1}, ${a2})");
+Struct7BytesHomogeneousUint8 returnStruct7BytesHomogeneousUint8(
+    int a0, int a1, int a2, int a3, int a4, int a5, int a6) {
+  print(
+      "returnStruct7BytesHomogeneousUint8(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6})");
 
   // In legacy mode, possibly return null.
 
   // In both nnbd and legacy mode, possibly throw.
   if (a0 == 42 || a0 == 84) {
     print("throwing!");
-    throw Exception("ReturnStruct7BytesInt throwing on purpuse!");
+    throw Exception("ReturnStruct7BytesHomogeneousUint8 throwing on purpuse!");
   }
 
-  returnStruct7BytesInt_a0 = a0;
-  returnStruct7BytesInt_a1 = a1;
-  returnStruct7BytesInt_a2 = a2;
+  returnStruct7BytesHomogeneousUint8_a0 = a0;
+  returnStruct7BytesHomogeneousUint8_a1 = a1;
+  returnStruct7BytesHomogeneousUint8_a2 = a2;
+  returnStruct7BytesHomogeneousUint8_a3 = a3;
+  returnStruct7BytesHomogeneousUint8_a4 = a4;
+  returnStruct7BytesHomogeneousUint8_a5 = a5;
+  returnStruct7BytesHomogeneousUint8_a6 = a6;
 
-  final result = returnStruct7BytesIntCalculateResult();
+  final result = returnStruct7BytesHomogeneousUint8CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void returnStruct7BytesIntAfterCallback() {
-  free(returnStruct7BytesIntResult.addressOf);
+void returnStruct7BytesHomogeneousUint8AfterCallback() {
+  free(returnStruct7BytesHomogeneousUint8Result.addressOf);
 
-  final result = returnStruct7BytesIntCalculateResult();
+  final result = returnStruct7BytesHomogeneousUint8CalculateResult();
 
   print("after callback result = $result");
 
-  free(returnStruct7BytesIntResult.addressOf);
+  free(returnStruct7BytesHomogeneousUint8Result.addressOf);
+}
+
+typedef ReturnStruct7BytesInt4ByteAlignedType = Struct7BytesInt4ByteAligned
+    Function(Int32, Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct7BytesInt4ByteAligned_a0 = 0;
+int returnStruct7BytesInt4ByteAligned_a1 = 0;
+int returnStruct7BytesInt4ByteAligned_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct7BytesInt4ByteAligned returnStruct7BytesInt4ByteAlignedResult =
+    Struct7BytesInt4ByteAligned();
+
+Struct7BytesInt4ByteAligned returnStruct7BytesInt4ByteAlignedCalculateResult() {
+  Struct7BytesInt4ByteAligned result =
+      allocate<Struct7BytesInt4ByteAligned>().ref;
+
+  result.a0 = returnStruct7BytesInt4ByteAligned_a0;
+  result.a1 = returnStruct7BytesInt4ByteAligned_a1;
+  result.a2 = returnStruct7BytesInt4ByteAligned_a2;
+
+  returnStruct7BytesInt4ByteAlignedResult = result;
+
+  return result;
+}
+
+/// Non-wordsize return value.
+/// With alignment rules taken into account size is 8 bytes.
+Struct7BytesInt4ByteAligned returnStruct7BytesInt4ByteAligned(
+    int a0, int a1, int a2) {
+  print("returnStruct7BytesInt4ByteAligned(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct7BytesInt4ByteAligned throwing on purpuse!");
+  }
+
+  returnStruct7BytesInt4ByteAligned_a0 = a0;
+  returnStruct7BytesInt4ByteAligned_a1 = a1;
+  returnStruct7BytesInt4ByteAligned_a2 = a2;
+
+  final result = returnStruct7BytesInt4ByteAlignedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct7BytesInt4ByteAlignedAfterCallback() {
+  free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
+
+  final result = returnStruct7BytesInt4ByteAlignedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
 }
 
 typedef ReturnStruct8BytesIntType = Struct8BytesInt Function(
@@ -3886,93 +4375,40 @@
   free(returnStruct8BytesMixedResult.addressOf);
 }
 
-typedef ReturnStruct9BytesIntType = Struct9BytesInt Function(Int64, Int8);
-
-// Global variables to be able to test inputs after callback returned.
-int returnStruct9BytesInt_a0 = 0;
-int returnStruct9BytesInt_a1 = 0;
-
-// Result variable also global, so we can delete it after the callback.
-Struct9BytesInt returnStruct9BytesIntResult = Struct9BytesInt();
-
-Struct9BytesInt returnStruct9BytesIntCalculateResult() {
-  Struct9BytesInt result = allocate<Struct9BytesInt>().ref;
-
-  result.a0 = returnStruct9BytesInt_a0;
-  result.a1 = returnStruct9BytesInt_a1;
-
-  returnStruct9BytesIntResult = result;
-
-  return result;
-}
-
-/// Return value in two integer registers on x64.
-/// The second register only contains a single byte.
-Struct9BytesInt returnStruct9BytesInt(int a0, int a1) {
-  print("returnStruct9BytesInt(${a0}, ${a1})");
-
-  // In legacy mode, possibly return null.
-
-  // In both nnbd and legacy mode, possibly throw.
-  if (a0 == 42 || a0 == 84) {
-    print("throwing!");
-    throw Exception("ReturnStruct9BytesInt throwing on purpuse!");
-  }
-
-  returnStruct9BytesInt_a0 = a0;
-  returnStruct9BytesInt_a1 = a1;
-
-  final result = returnStruct9BytesIntCalculateResult();
-
-  print("result = $result");
-
-  return result;
-}
-
-void returnStruct9BytesIntAfterCallback() {
-  free(returnStruct9BytesIntResult.addressOf);
-
-  final result = returnStruct9BytesIntCalculateResult();
-
-  print("after callback result = $result");
-
-  free(returnStruct9BytesIntResult.addressOf);
-}
-
-typedef ReturnStruct9BytesHomogeneousUint82Type = Struct9BytesHomogeneousUint82
+typedef ReturnStruct9BytesHomogeneousUint8Type = Struct9BytesHomogeneousUint8
     Function(Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8);
 
 // Global variables to be able to test inputs after callback returned.
-int returnStruct9BytesHomogeneousUint82_a0 = 0;
-int returnStruct9BytesHomogeneousUint82_a1 = 0;
-int returnStruct9BytesHomogeneousUint82_a2 = 0;
-int returnStruct9BytesHomogeneousUint82_a3 = 0;
-int returnStruct9BytesHomogeneousUint82_a4 = 0;
-int returnStruct9BytesHomogeneousUint82_a5 = 0;
-int returnStruct9BytesHomogeneousUint82_a6 = 0;
-int returnStruct9BytesHomogeneousUint82_a7 = 0;
-int returnStruct9BytesHomogeneousUint82_a8 = 0;
+int returnStruct9BytesHomogeneousUint8_a0 = 0;
+int returnStruct9BytesHomogeneousUint8_a1 = 0;
+int returnStruct9BytesHomogeneousUint8_a2 = 0;
+int returnStruct9BytesHomogeneousUint8_a3 = 0;
+int returnStruct9BytesHomogeneousUint8_a4 = 0;
+int returnStruct9BytesHomogeneousUint8_a5 = 0;
+int returnStruct9BytesHomogeneousUint8_a6 = 0;
+int returnStruct9BytesHomogeneousUint8_a7 = 0;
+int returnStruct9BytesHomogeneousUint8_a8 = 0;
 
 // Result variable also global, so we can delete it after the callback.
-Struct9BytesHomogeneousUint82 returnStruct9BytesHomogeneousUint82Result =
-    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint8 returnStruct9BytesHomogeneousUint8Result =
+    Struct9BytesHomogeneousUint8();
 
-Struct9BytesHomogeneousUint82
-    returnStruct9BytesHomogeneousUint82CalculateResult() {
-  Struct9BytesHomogeneousUint82 result =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
+Struct9BytesHomogeneousUint8
+    returnStruct9BytesHomogeneousUint8CalculateResult() {
+  Struct9BytesHomogeneousUint8 result =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
 
-  result.a0 = returnStruct9BytesHomogeneousUint82_a0;
-  result.a1 = returnStruct9BytesHomogeneousUint82_a1;
-  result.a2 = returnStruct9BytesHomogeneousUint82_a2;
-  result.a3 = returnStruct9BytesHomogeneousUint82_a3;
-  result.a4 = returnStruct9BytesHomogeneousUint82_a4;
-  result.a5 = returnStruct9BytesHomogeneousUint82_a5;
-  result.a6 = returnStruct9BytesHomogeneousUint82_a6;
-  result.a7 = returnStruct9BytesHomogeneousUint82_a7;
-  result.a8 = returnStruct9BytesHomogeneousUint82_a8;
+  result.a0 = returnStruct9BytesHomogeneousUint8_a0;
+  result.a1 = returnStruct9BytesHomogeneousUint8_a1;
+  result.a2 = returnStruct9BytesHomogeneousUint8_a2;
+  result.a3 = returnStruct9BytesHomogeneousUint8_a3;
+  result.a4 = returnStruct9BytesHomogeneousUint8_a4;
+  result.a5 = returnStruct9BytesHomogeneousUint8_a5;
+  result.a6 = returnStruct9BytesHomogeneousUint8_a6;
+  result.a7 = returnStruct9BytesHomogeneousUint8_a7;
+  result.a8 = returnStruct9BytesHomogeneousUint8_a8;
 
-  returnStruct9BytesHomogeneousUint82Result = result;
+  returnStruct9BytesHomogeneousUint8Result = result;
 
   return result;
 }
@@ -3980,44 +4416,103 @@
 /// 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.
-Struct9BytesHomogeneousUint82 returnStruct9BytesHomogeneousUint82(
+Struct9BytesHomogeneousUint8 returnStruct9BytesHomogeneousUint8(
     int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
   print(
-      "returnStruct9BytesHomogeneousUint82(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+      "returnStruct9BytesHomogeneousUint8(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
 
   // In legacy mode, possibly return null.
 
   // In both nnbd and legacy mode, possibly throw.
   if (a0 == 42 || a0 == 84) {
     print("throwing!");
-    throw Exception("ReturnStruct9BytesHomogeneousUint82 throwing on purpuse!");
+    throw Exception("ReturnStruct9BytesHomogeneousUint8 throwing on purpuse!");
   }
 
-  returnStruct9BytesHomogeneousUint82_a0 = a0;
-  returnStruct9BytesHomogeneousUint82_a1 = a1;
-  returnStruct9BytesHomogeneousUint82_a2 = a2;
-  returnStruct9BytesHomogeneousUint82_a3 = a3;
-  returnStruct9BytesHomogeneousUint82_a4 = a4;
-  returnStruct9BytesHomogeneousUint82_a5 = a5;
-  returnStruct9BytesHomogeneousUint82_a6 = a6;
-  returnStruct9BytesHomogeneousUint82_a7 = a7;
-  returnStruct9BytesHomogeneousUint82_a8 = a8;
+  returnStruct9BytesHomogeneousUint8_a0 = a0;
+  returnStruct9BytesHomogeneousUint8_a1 = a1;
+  returnStruct9BytesHomogeneousUint8_a2 = a2;
+  returnStruct9BytesHomogeneousUint8_a3 = a3;
+  returnStruct9BytesHomogeneousUint8_a4 = a4;
+  returnStruct9BytesHomogeneousUint8_a5 = a5;
+  returnStruct9BytesHomogeneousUint8_a6 = a6;
+  returnStruct9BytesHomogeneousUint8_a7 = a7;
+  returnStruct9BytesHomogeneousUint8_a8 = a8;
 
-  final result = returnStruct9BytesHomogeneousUint82CalculateResult();
+  final result = returnStruct9BytesHomogeneousUint8CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void returnStruct9BytesHomogeneousUint82AfterCallback() {
-  free(returnStruct9BytesHomogeneousUint82Result.addressOf);
+void returnStruct9BytesHomogeneousUint8AfterCallback() {
+  free(returnStruct9BytesHomogeneousUint8Result.addressOf);
 
-  final result = returnStruct9BytesHomogeneousUint82CalculateResult();
+  final result = returnStruct9BytesHomogeneousUint8CalculateResult();
 
   print("after callback result = $result");
 
-  free(returnStruct9BytesHomogeneousUint82Result.addressOf);
+  free(returnStruct9BytesHomogeneousUint8Result.addressOf);
+}
+
+typedef ReturnStruct9BytesInt4Or8ByteAlignedType
+    = Struct9BytesInt4Or8ByteAligned Function(Int64, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct9BytesInt4Or8ByteAligned_a0 = 0;
+int returnStruct9BytesInt4Or8ByteAligned_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct9BytesInt4Or8ByteAligned returnStruct9BytesInt4Or8ByteAlignedResult =
+    Struct9BytesInt4Or8ByteAligned();
+
+Struct9BytesInt4Or8ByteAligned
+    returnStruct9BytesInt4Or8ByteAlignedCalculateResult() {
+  Struct9BytesInt4Or8ByteAligned result =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+
+  result.a0 = returnStruct9BytesInt4Or8ByteAligned_a0;
+  result.a1 = returnStruct9BytesInt4Or8ByteAligned_a1;
+
+  returnStruct9BytesInt4Or8ByteAlignedResult = result;
+
+  return result;
+}
+
+/// Return value in two integer registers on x64.
+/// With alignment rules taken into account size is 12 or 16 bytes.
+Struct9BytesInt4Or8ByteAligned returnStruct9BytesInt4Or8ByteAligned(
+    int a0, int a1) {
+  print("returnStruct9BytesInt4Or8ByteAligned(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStruct9BytesInt4Or8ByteAligned throwing on purpuse!");
+  }
+
+  returnStruct9BytesInt4Or8ByteAligned_a0 = a0;
+  returnStruct9BytesInt4Or8ByteAligned_a1 = a1;
+
+  final result = returnStruct9BytesInt4Or8ByteAlignedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct9BytesInt4Or8ByteAlignedAfterCallback() {
+  free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
+
+  final result = returnStruct9BytesInt4Or8ByteAlignedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
 }
 
 typedef ReturnStruct12BytesHomogeneousFloatType = Struct12BytesHomogeneousFloat
diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart
index 3cbdf98..26f48ea 100644
--- a/tests/ffi/function_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_test.dart
@@ -21,14 +21,16 @@
 void main() {
   for (int i = 0; i < 10; ++i) {
     testPassStruct1ByteIntx10();
-    testPassStruct3BytesIntx10();
+    testPassStruct3BytesHomogeneousUint8x10();
+    testPassStruct3BytesInt2ByteAlignedx10();
     testPassStruct4BytesHomogeneousInt16x10();
-    testPassStruct7BytesIntx10();
+    testPassStruct7BytesHomogeneousUint8x10();
+    testPassStruct7BytesInt4ByteAlignedx10();
     testPassStruct8BytesIntx10();
     testPassStruct8BytesHomogeneousFloatx10();
     testPassStruct8BytesMixedx10();
-    testPassStruct9BytesIntx10();
-    testPassStruct9BytesHomogeneousUint82x10();
+    testPassStruct9BytesHomogeneousUint8x10();
+    testPassStruct9BytesInt4Or8ByteAlignedx10();
     testPassStruct12BytesHomogeneousFloatx6();
     testPassStruct16BytesHomogeneousFloatx5();
     testPassStruct16BytesMixedx10();
@@ -50,14 +52,16 @@
     testPassStructAlignmentInt32();
     testPassStructAlignmentInt64();
     testReturnStruct1ByteInt();
-    testReturnStruct3BytesInt();
+    testReturnStruct3BytesHomogeneousUint8();
+    testReturnStruct3BytesInt2ByteAligned();
     testReturnStruct4BytesHomogeneousInt16();
-    testReturnStruct7BytesInt();
+    testReturnStruct7BytesHomogeneousUint8();
+    testReturnStruct7BytesInt4ByteAligned();
     testReturnStruct8BytesInt();
     testReturnStruct8BytesHomogeneousFloat();
     testReturnStruct8BytesMixed();
-    testReturnStruct9BytesInt();
-    testReturnStruct9BytesHomogeneousUint82();
+    testReturnStruct9BytesHomogeneousUint8();
+    testReturnStruct9BytesInt4Or8ByteAligned();
     testReturnStruct12BytesHomogeneousFloat();
     testReturnStruct16BytesHomogeneousFloat();
     testReturnStruct16BytesMixed();
@@ -91,7 +95,20 @@
   String toString() => "(${a0})";
 }
 
-class Struct3BytesInt extends Struct {
+class Struct3BytesHomogeneousUint8 extends Struct {
+  @Uint8()
+  external int a0;
+
+  @Uint8()
+  external int a1;
+
+  @Uint8()
+  external int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct3BytesInt2ByteAligned extends Struct {
   @Int16()
   external int a0;
 
@@ -111,7 +128,32 @@
   String toString() => "(${a0}, ${a1})";
 }
 
-class Struct7BytesInt extends Struct {
+class Struct7BytesHomogeneousUint8 extends Struct {
+  @Uint8()
+  external int a0;
+
+  @Uint8()
+  external int a1;
+
+  @Uint8()
+  external int a2;
+
+  @Uint8()
+  external int a3;
+
+  @Uint8()
+  external int a4;
+
+  @Uint8()
+  external int a5;
+
+  @Uint8()
+  external int a6;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6})";
+}
+
+class Struct7BytesInt4ByteAligned extends Struct {
   @Int32()
   external int a0;
 
@@ -160,17 +202,7 @@
   String toString() => "(${a0}, ${a1}, ${a2})";
 }
 
-class Struct9BytesInt extends Struct {
-  @Int64()
-  external int a0;
-
-  @Int8()
-  external int a1;
-
-  String toString() => "(${a0}, ${a1})";
-}
-
-class Struct9BytesHomogeneousUint82 extends Struct {
+class Struct9BytesHomogeneousUint8 extends Struct {
   @Uint8()
   external int a0;
 
@@ -202,6 +234,16 @@
       "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})";
 }
 
+class Struct9BytesInt4Or8ByteAligned extends Struct {
+  @Int64()
+  external int a0;
+
+  @Int8()
+  external int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
 class Struct12BytesHomogeneousFloat extends Struct {
   @Float()
   external double a0;
@@ -900,43 +942,142 @@
   free(a9.addressOf);
 }
 
-final passStruct3BytesIntx10 = ffiTestFunctions.lookupFunction<
+final passStruct3BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
     Int64 Function(
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt),
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8),
     int Function(
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt)>("PassStruct3BytesIntx10");
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8)>("PassStruct3BytesHomogeneousUint8x10");
 
 /// Not a multiple of word size, not a power of two.
 /// 10 struct arguments will exhaust available registers.
-void testPassStruct3BytesIntx10() {
-  Struct3BytesInt a0 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a1 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a2 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a3 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a4 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a5 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a6 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a7 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a8 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a9 = allocate<Struct3BytesInt>().ref;
+void testPassStruct3BytesHomogeneousUint8x10() {
+  Struct3BytesHomogeneousUint8 a0 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a1 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a2 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a3 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a4 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a5 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a6 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a7 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a8 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a9 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+
+  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;
+
+  final result = passStruct3BytesHomogeneousUint8x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(465, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct3BytesInt2ByteAlignedx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned),
+    int Function(
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned)>("PassStruct3BytesInt2ByteAlignedx10");
+
+/// 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.
+void testPassStruct3BytesInt2ByteAlignedx10() {
+  Struct3BytesInt2ByteAligned a0 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a1 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a2 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a3 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a4 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a5 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a6 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a7 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a8 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a9 = allocate<Struct3BytesInt2ByteAligned>().ref;
 
   a0.a0 = -1;
   a0.a1 = 2;
@@ -959,7 +1100,8 @@
   a9.a0 = -19;
   a9.a1 = 20;
 
-  final result = passStruct3BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  final result = passStruct3BytesInt2ByteAlignedx10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 
   print("result = $result");
 
@@ -1065,43 +1207,182 @@
   free(a9.addressOf);
 }
 
-final passStruct7BytesIntx10 = ffiTestFunctions.lookupFunction<
+final passStruct7BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
     Int64 Function(
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt),
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8),
     int Function(
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt)>("PassStruct7BytesIntx10");
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8)>("PassStruct7BytesHomogeneousUint8x10");
 
 /// Sub word size on 64 bit architectures.
 /// 10 struct arguments will exhaust available registers.
-void testPassStruct7BytesIntx10() {
-  Struct7BytesInt a0 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a1 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a2 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a3 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a4 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a5 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a6 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a7 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a8 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a9 = allocate<Struct7BytesInt>().ref;
+void testPassStruct7BytesHomogeneousUint8x10() {
+  Struct7BytesHomogeneousUint8 a0 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a1 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a2 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a3 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a4 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a5 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a6 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a7 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a8 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a9 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+
+  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;
+
+  final result = passStruct7BytesHomogeneousUint8x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(2485, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct7BytesInt4ByteAlignedx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned),
+    int Function(
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned)>("PassStruct7BytesInt4ByteAlignedx10");
+
+/// Sub word size on 64 bit architectures.
+/// With alignment rules taken into account size is 8 bytes.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct7BytesInt4ByteAlignedx10() {
+  Struct7BytesInt4ByteAligned a0 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a1 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a2 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a3 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a4 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a5 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a6 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a7 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a8 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a9 = allocate<Struct7BytesInt4ByteAligned>().ref;
 
   a0.a0 = -1;
   a0.a1 = 2;
@@ -1134,7 +1415,8 @@
   a9.a1 = -29;
   a9.a2 = 30;
 
-  final result = passStruct7BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  final result = passStruct7BytesInt4ByteAlignedx10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 
   print("result = $result");
 
@@ -1415,134 +1697,56 @@
   free(a9.addressOf);
 }
 
-final passStruct9BytesIntx10 = ffiTestFunctions.lookupFunction<
+final passStruct9BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
     Int64 Function(
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt),
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8),
     int Function(
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt)>("PassStruct9BytesIntx10");
-
-/// Argument is a single byte over a multiple of word size.
-/// 10 struct arguments will exhaust available registers.
-/// Tests upper bytes in the integer registers that are partly filled.
-/// Tests stack alignment of non word size stack arguments.
-void testPassStruct9BytesIntx10() {
-  Struct9BytesInt a0 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a1 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a2 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a3 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a4 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a5 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a6 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a7 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a8 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a9 = allocate<Struct9BytesInt>().ref;
-
-  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;
-
-  final result = passStruct9BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
-
-  print("result = $result");
-
-  Expect.equals(10, result);
-
-  free(a0.addressOf);
-  free(a1.addressOf);
-  free(a2.addressOf);
-  free(a3.addressOf);
-  free(a4.addressOf);
-  free(a5.addressOf);
-  free(a6.addressOf);
-  free(a7.addressOf);
-  free(a8.addressOf);
-  free(a9.addressOf);
-}
-
-final passStruct9BytesHomogeneousUint82x10 = ffiTestFunctions.lookupFunction<
-    Int64 Function(
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82),
-    int Function(
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82)>("PassStruct9BytesHomogeneousUint82x10");
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8)>("PassStruct9BytesHomogeneousUint8x10");
 
 /// 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.
-///
-void testPassStruct9BytesHomogeneousUint82x10() {
-  Struct9BytesHomogeneousUint82 a0 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a1 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a2 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a3 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a4 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a5 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a6 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a7 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a8 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a9 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
+/// Tests upper bytes in the integer registers that are partly filled.
+/// Tests stack alignment of non word size stack arguments.
+void testPassStruct9BytesHomogeneousUint8x10() {
+  Struct9BytesHomogeneousUint8 a0 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a1 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a2 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a3 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a4 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a5 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a6 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a7 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a8 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a9 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
 
   a0.a0 = 1;
   a0.a1 = 2;
@@ -1635,7 +1839,7 @@
   a9.a7 = 89;
   a9.a8 = 90;
 
-  final result = passStruct9BytesHomogeneousUint82x10(
+  final result = passStruct9BytesHomogeneousUint8x10(
       a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 
   print("result = $result");
@@ -1654,6 +1858,97 @@
   free(a9.addressOf);
 }
 
+final passStruct9BytesInt4Or8ByteAlignedx10 = ffiTestFunctions.lookupFunction<
+        Int64 Function(
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned),
+        int Function(
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned)>(
+    "PassStruct9BytesInt4Or8ByteAlignedx10");
+
+/// 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.
+///
+void testPassStruct9BytesInt4Or8ByteAlignedx10() {
+  Struct9BytesInt4Or8ByteAligned a0 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a1 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a2 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a3 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a4 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a5 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a6 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a7 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a8 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a9 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+
+  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;
+
+  final result = passStruct9BytesInt4Or8ByteAlignedx10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
 final passStruct12BytesHomogeneousFloatx6 = ffiTestFunctions.lookupFunction<
     Float Function(
         Struct12BytesHomogeneousFloat,
@@ -3142,19 +3437,45 @@
   Expect.equals(a0, result.a0);
 }
 
-final returnStruct3BytesInt = ffiTestFunctions.lookupFunction<
-    Struct3BytesInt Function(Int16, Int8),
-    Struct3BytesInt Function(int, int)>("ReturnStruct3BytesInt");
+final returnStruct3BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
+    Struct3BytesHomogeneousUint8 Function(Uint8, Uint8, Uint8),
+    Struct3BytesHomogeneousUint8 Function(
+        int, int, int)>("ReturnStruct3BytesHomogeneousUint8");
 
 /// Smaller than word size return value on all architectures.
-void testReturnStruct3BytesInt() {
+void testReturnStruct3BytesHomogeneousUint8() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+
+  final result = returnStruct3BytesHomogeneousUint8(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct3BytesInt2ByteAligned = ffiTestFunctions.lookupFunction<
+    Struct3BytesInt2ByteAligned Function(Int16, Int8),
+    Struct3BytesInt2ByteAligned Function(
+        int, int)>("ReturnStruct3BytesInt2ByteAligned");
+
+/// Smaller than word size return value on all architectures.
+/// With alignment rules taken into account size is 4 bytes.
+void testReturnStruct3BytesInt2ByteAligned() {
   int a0;
   int a1;
 
   a0 = -1;
   a1 = 2;
 
-  final result = returnStruct3BytesInt(a0, a1);
+  final result = returnStruct3BytesInt2ByteAligned(a0, a1);
 
   print("result = $result");
 
@@ -3183,12 +3504,51 @@
   Expect.equals(a1, result.a1);
 }
 
-final returnStruct7BytesInt = ffiTestFunctions.lookupFunction<
-    Struct7BytesInt Function(Int32, Int16, Int8),
-    Struct7BytesInt Function(int, int, int)>("ReturnStruct7BytesInt");
+final returnStruct7BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
+    Struct7BytesHomogeneousUint8 Function(
+        Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8),
+    Struct7BytesHomogeneousUint8 Function(int, int, int, int, int, int,
+        int)>("ReturnStruct7BytesHomogeneousUint8");
 
 /// Non-wordsize return value.
-void testReturnStruct7BytesInt() {
+void testReturnStruct7BytesHomogeneousUint8() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+
+  final result = returnStruct7BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+  Expect.equals(a5, result.a5);
+  Expect.equals(a6, result.a6);
+}
+
+final returnStruct7BytesInt4ByteAligned = ffiTestFunctions.lookupFunction<
+    Struct7BytesInt4ByteAligned Function(Int32, Int16, Int8),
+    Struct7BytesInt4ByteAligned Function(
+        int, int, int)>("ReturnStruct7BytesInt4ByteAligned");
+
+/// Non-wordsize return value.
+/// With alignment rules taken into account size is 8 bytes.
+void testReturnStruct7BytesInt4ByteAligned() {
   int a0;
   int a1;
   int a2;
@@ -3197,7 +3557,7 @@
   a1 = 2;
   a2 = -3;
 
-  final result = returnStruct7BytesInt(a0, a1, a2);
+  final result = returnStruct7BytesInt4ByteAligned(a0, a1, a2);
 
   print("result = $result");
 
@@ -3273,37 +3633,16 @@
   Expect.equals(a2, result.a2);
 }
 
-final returnStruct9BytesInt = ffiTestFunctions.lookupFunction<
-    Struct9BytesInt Function(Int64, Int8),
-    Struct9BytesInt Function(int, int)>("ReturnStruct9BytesInt");
-
-/// Return value in two integer registers on x64.
-/// The second register only contains a single byte.
-void testReturnStruct9BytesInt() {
-  int a0;
-  int a1;
-
-  a0 = -1;
-  a1 = 2;
-
-  final result = returnStruct9BytesInt(a0, a1);
-
-  print("result = $result");
-
-  Expect.equals(a0, result.a0);
-  Expect.equals(a1, result.a1);
-}
-
-final returnStruct9BytesHomogeneousUint82 = ffiTestFunctions.lookupFunction<
-    Struct9BytesHomogeneousUint82 Function(
+final returnStruct9BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
+    Struct9BytesHomogeneousUint8 Function(
         Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8),
-    Struct9BytesHomogeneousUint82 Function(int, int, int, int, int, int, int,
-        int, int)>("ReturnStruct9BytesHomogeneousUint82");
+    Struct9BytesHomogeneousUint8 Function(int, int, int, int, int, int, int,
+        int, int)>("ReturnStruct9BytesHomogeneousUint8");
 
 /// 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.
-void testReturnStruct9BytesHomogeneousUint82() {
+void testReturnStruct9BytesHomogeneousUint8() {
   int a0;
   int a1;
   int a2;
@@ -3325,7 +3664,7 @@
   a8 = 9;
 
   final result =
-      returnStruct9BytesHomogeneousUint82(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+      returnStruct9BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6, a7, a8);
 
   print("result = $result");
 
@@ -3340,6 +3679,28 @@
   Expect.equals(a8, result.a8);
 }
 
+final returnStruct9BytesInt4Or8ByteAligned = ffiTestFunctions.lookupFunction<
+    Struct9BytesInt4Or8ByteAligned Function(Int64, Int8),
+    Struct9BytesInt4Or8ByteAligned Function(
+        int, int)>("ReturnStruct9BytesInt4Or8ByteAligned");
+
+/// Return value in two integer registers on x64.
+/// With alignment rules taken into account size is 12 or 16 bytes.
+void testReturnStruct9BytesInt4Or8ByteAligned() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct9BytesInt4Or8ByteAligned(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
 final returnStruct12BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
     Struct12BytesHomogeneousFloat Function(Float, Float, Float),
     Struct12BytesHomogeneousFloat Function(
diff --git a/tests/ffi/generator/structs_by_value_tests_confguration.dart b/tests/ffi/generator/structs_by_value_tests_configuration.dart
similarity index 90%
rename from tests/ffi/generator/structs_by_value_tests_confguration.dart
rename to tests/ffi/generator/structs_by_value_tests_configuration.dart
index 487a68e..5ea4cff 100644
--- a/tests/ffi/generator/structs_by_value_tests_confguration.dart
+++ b/tests/ffi/generator/structs_by_value_tests_configuration.dart
@@ -11,12 +11,20 @@
   FunctionType(List.filled(10, struct3bytesInt), int64, """
 Not a multiple of word size, not a power of two.
 10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct3bytesInt2), int64, """
+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."""),
   FunctionType(List.filled(10, struct4bytesInt), int64, """
 Exactly word size on 32-bit architectures.
 10 struct arguments will exhaust available registers."""),
   FunctionType(List.filled(10, struct7bytesInt), int64, """
 Sub word size on 64 bit architectures.
 10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct7bytesInt2), int64, """
+Sub word size on 64 bit architectures.
+With alignment rules taken into account size is 8 bytes.
+10 struct arguments will exhaust available registers."""),
   FunctionType(List.filled(10, struct8bytesInt), int64, """
 Exactly word size struct on 64bit architectures.
 10 struct arguments will exhaust available registers."""),
@@ -29,12 +37,13 @@
   FunctionType(List.filled(10, struct9bytesInt), int64, """
 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."""),
   FunctionType(List.filled(10, struct9bytesInt2), int64, """
 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.
-Struct only has 1-byte aligned fields to test struct alignment itself.
 """),
   FunctionType(List.filled(6, struct12bytesFloat), float, """
 Arguments in FPU registers on arm hardfp and arm64.
@@ -198,10 +207,16 @@
 Smallest struct with data."""),
   FunctionType(struct3bytesInt.memberTypes, struct3bytesInt, """
 Smaller than word size return value on all architectures."""),
+  FunctionType(struct3bytesInt2.memberTypes, struct3bytesInt2, """
+Smaller than word size return value on all architectures.
+With alignment rules taken into account size is 4 bytes."""),
   FunctionType(struct4bytesInt.memberTypes, struct4bytesInt, """
 Word size return value on 32 bit architectures.."""),
   FunctionType(struct7bytesInt.memberTypes, struct7bytesInt, """
 Non-wordsize return value."""),
+  FunctionType(struct7bytesInt2.memberTypes, struct7bytesInt2, """
+Non-wordsize return value.
+With alignment rules taken into account size is 8 bytes."""),
   FunctionType(struct8bytesInt.memberTypes, struct8bytesInt, """
 Return value in integer registers on many architectures."""),
   FunctionType(struct8bytesFloat.memberTypes, struct8bytesFloat, """
@@ -209,12 +224,12 @@
   FunctionType(struct8BytesMixed.memberTypes, struct8BytesMixed, """
 Return value split over FP and integer register in x64."""),
   FunctionType(struct9bytesInt.memberTypes, struct9bytesInt, """
-Return value in two integer registers on x64.
-The second register only contains a single byte."""),
-  FunctionType(struct9bytesInt2.memberTypes, struct9bytesInt2, """
 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."""),
+  FunctionType(struct9bytesInt2.memberTypes, struct9bytesInt2, """
+Return value in two integer registers on x64.
+With alignment rules taken into account size is 12 or 16 bytes."""),
   FunctionType(struct12bytesFloat.memberTypes, struct12bytesFloat, """
 Return value in FPU registers, but does not use all registers on arm hardfp
 and arm64."""),
@@ -297,8 +312,10 @@
   struct0bytes,
   struct1byteInt,
   struct3bytesInt,
+  struct3bytesInt2,
   struct4bytesInt,
   struct7bytesInt,
+  struct7bytesInt2,
   struct8bytesInt,
   struct8bytesFloat,
   struct8BytesMixed,
@@ -324,14 +341,18 @@
 final struct0bytes = StructType([]);
 
 final struct1byteInt = StructType([int8]);
-final struct3bytesInt = StructType([int16, int8]);
+final struct3bytesInt = StructType(List.filled(3, uint8));
+final struct3bytesInt2 = StructType.disambiguate([int16, int8], "2ByteAligned");
 final struct4bytesInt = StructType([int16, int16]);
-final struct7bytesInt = StructType([int32, int16, int8]);
+final struct7bytesInt = StructType(List.filled(7, uint8));
+final struct7bytesInt2 =
+    StructType.disambiguate([int32, int16, int8], "4ByteAligned");
 final struct8bytesInt = StructType([int16, int16, int32]);
 final struct8bytesFloat = StructType([float, float]);
 final struct8BytesMixed = StructType([float, int16, int16]);
-final struct9bytesInt = StructType([int64, int8]);
-final struct9bytesInt2 = StructType.disambiguate(List.filled(9, uint8), "2");
+final struct9bytesInt = StructType(List.filled(9, uint8));
+final struct9bytesInt2 =
+    StructType.disambiguate([int64, int8], "4Or8ByteAligned");
 final struct12bytesFloat = StructType([float, float, float]);
 
 /// The largest homogenous float that goes into FPU registers on softfp and
diff --git a/tests/ffi/generator/structs_by_value_tests_generator.dart b/tests/ffi/generator/structs_by_value_tests_generator.dart
index e233753..f3f9f02 100644
--- a/tests/ffi/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi/generator/structs_by_value_tests_generator.dart
@@ -5,7 +5,7 @@
 import 'dart:io';
 
 import 'c_types.dart';
-import 'structs_by_value_tests_confguration.dart';
+import 'structs_by_value_tests_configuration.dart';
 import 'utils.dart';
 
 /// The test type determines how to convert the arguments into return values
diff --git a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
index 4db290f..76620d7 100644
--- a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
@@ -33,20 +33,30 @@
       Pointer.fromFunction<PassStruct1ByteIntx10Type>(passStruct1ByteIntx10, 0),
       passStruct1ByteIntx10AfterCallback),
   CallbackTest.withCheck(
-      "PassStruct3BytesIntx10",
-      Pointer.fromFunction<PassStruct3BytesIntx10Type>(
-          passStruct3BytesIntx10, 0),
-      passStruct3BytesIntx10AfterCallback),
+      "PassStruct3BytesHomogeneousUint8x10",
+      Pointer.fromFunction<PassStruct3BytesHomogeneousUint8x10Type>(
+          passStruct3BytesHomogeneousUint8x10, 0),
+      passStruct3BytesHomogeneousUint8x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct3BytesInt2ByteAlignedx10",
+      Pointer.fromFunction<PassStruct3BytesInt2ByteAlignedx10Type>(
+          passStruct3BytesInt2ByteAlignedx10, 0),
+      passStruct3BytesInt2ByteAlignedx10AfterCallback),
   CallbackTest.withCheck(
       "PassStruct4BytesHomogeneousInt16x10",
       Pointer.fromFunction<PassStruct4BytesHomogeneousInt16x10Type>(
           passStruct4BytesHomogeneousInt16x10, 0),
       passStruct4BytesHomogeneousInt16x10AfterCallback),
   CallbackTest.withCheck(
-      "PassStruct7BytesIntx10",
-      Pointer.fromFunction<PassStruct7BytesIntx10Type>(
-          passStruct7BytesIntx10, 0),
-      passStruct7BytesIntx10AfterCallback),
+      "PassStruct7BytesHomogeneousUint8x10",
+      Pointer.fromFunction<PassStruct7BytesHomogeneousUint8x10Type>(
+          passStruct7BytesHomogeneousUint8x10, 0),
+      passStruct7BytesHomogeneousUint8x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct7BytesInt4ByteAlignedx10",
+      Pointer.fromFunction<PassStruct7BytesInt4ByteAlignedx10Type>(
+          passStruct7BytesInt4ByteAlignedx10, 0),
+      passStruct7BytesInt4ByteAlignedx10AfterCallback),
   CallbackTest.withCheck(
       "PassStruct8BytesIntx10",
       Pointer.fromFunction<PassStruct8BytesIntx10Type>(
@@ -63,15 +73,15 @@
           passStruct8BytesMixedx10, 0.0),
       passStruct8BytesMixedx10AfterCallback),
   CallbackTest.withCheck(
-      "PassStruct9BytesIntx10",
-      Pointer.fromFunction<PassStruct9BytesIntx10Type>(
-          passStruct9BytesIntx10, 0),
-      passStruct9BytesIntx10AfterCallback),
+      "PassStruct9BytesHomogeneousUint8x10",
+      Pointer.fromFunction<PassStruct9BytesHomogeneousUint8x10Type>(
+          passStruct9BytesHomogeneousUint8x10, 0),
+      passStruct9BytesHomogeneousUint8x10AfterCallback),
   CallbackTest.withCheck(
-      "PassStruct9BytesHomogeneousUint82x10",
-      Pointer.fromFunction<PassStruct9BytesHomogeneousUint82x10Type>(
-          passStruct9BytesHomogeneousUint82x10, 0),
-      passStruct9BytesHomogeneousUint82x10AfterCallback),
+      "PassStruct9BytesInt4Or8ByteAlignedx10",
+      Pointer.fromFunction<PassStruct9BytesInt4Or8ByteAlignedx10Type>(
+          passStruct9BytesInt4Or8ByteAlignedx10, 0),
+      passStruct9BytesInt4Or8ByteAlignedx10AfterCallback),
   CallbackTest.withCheck(
       "PassStruct12BytesHomogeneousFloatx6",
       Pointer.fromFunction<PassStruct12BytesHomogeneousFloatx6Type>(
@@ -181,18 +191,30 @@
       Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
       returnStruct1ByteIntAfterCallback),
   CallbackTest.withCheck(
-      "ReturnStruct3BytesInt",
-      Pointer.fromFunction<ReturnStruct3BytesIntType>(returnStruct3BytesInt),
-      returnStruct3BytesIntAfterCallback),
+      "ReturnStruct3BytesHomogeneousUint8",
+      Pointer.fromFunction<ReturnStruct3BytesHomogeneousUint8Type>(
+          returnStruct3BytesHomogeneousUint8),
+      returnStruct3BytesHomogeneousUint8AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct3BytesInt2ByteAligned",
+      Pointer.fromFunction<ReturnStruct3BytesInt2ByteAlignedType>(
+          returnStruct3BytesInt2ByteAligned),
+      returnStruct3BytesInt2ByteAlignedAfterCallback),
   CallbackTest.withCheck(
       "ReturnStruct4BytesHomogeneousInt16",
       Pointer.fromFunction<ReturnStruct4BytesHomogeneousInt16Type>(
           returnStruct4BytesHomogeneousInt16),
       returnStruct4BytesHomogeneousInt16AfterCallback),
   CallbackTest.withCheck(
-      "ReturnStruct7BytesInt",
-      Pointer.fromFunction<ReturnStruct7BytesIntType>(returnStruct7BytesInt),
-      returnStruct7BytesIntAfterCallback),
+      "ReturnStruct7BytesHomogeneousUint8",
+      Pointer.fromFunction<ReturnStruct7BytesHomogeneousUint8Type>(
+          returnStruct7BytesHomogeneousUint8),
+      returnStruct7BytesHomogeneousUint8AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct7BytesInt4ByteAligned",
+      Pointer.fromFunction<ReturnStruct7BytesInt4ByteAlignedType>(
+          returnStruct7BytesInt4ByteAligned),
+      returnStruct7BytesInt4ByteAlignedAfterCallback),
   CallbackTest.withCheck(
       "ReturnStruct8BytesInt",
       Pointer.fromFunction<ReturnStruct8BytesIntType>(returnStruct8BytesInt),
@@ -208,14 +230,15 @@
           returnStruct8BytesMixed),
       returnStruct8BytesMixedAfterCallback),
   CallbackTest.withCheck(
-      "ReturnStruct9BytesInt",
-      Pointer.fromFunction<ReturnStruct9BytesIntType>(returnStruct9BytesInt),
-      returnStruct9BytesIntAfterCallback),
+      "ReturnStruct9BytesHomogeneousUint8",
+      Pointer.fromFunction<ReturnStruct9BytesHomogeneousUint8Type>(
+          returnStruct9BytesHomogeneousUint8),
+      returnStruct9BytesHomogeneousUint8AfterCallback),
   CallbackTest.withCheck(
-      "ReturnStruct9BytesHomogeneousUint82",
-      Pointer.fromFunction<ReturnStruct9BytesHomogeneousUint82Type>(
-          returnStruct9BytesHomogeneousUint82),
-      returnStruct9BytesHomogeneousUint82AfterCallback),
+      "ReturnStruct9BytesInt4Or8ByteAligned",
+      Pointer.fromFunction<ReturnStruct9BytesInt4Or8ByteAlignedType>(
+          returnStruct9BytesInt4Or8ByteAligned),
+      returnStruct9BytesInt4Or8ByteAlignedAfterCallback),
   CallbackTest.withCheck(
       "ReturnStruct12BytesHomogeneousFloat",
       Pointer.fromFunction<ReturnStruct12BytesHomogeneousFloatType>(
@@ -414,77 +437,97 @@
   Expect.equals(5, result);
 }
 
-typedef PassStruct3BytesIntx10Type = Int64 Function(
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt,
-    Struct3BytesInt);
+typedef PassStruct3BytesHomogeneousUint8x10Type = Int64 Function(
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8,
+    Struct3BytesHomogeneousUint8);
 
 // Global variables to be able to test inputs after callback returned.
-Struct3BytesInt passStruct3BytesIntx10_a0 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a1 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a2 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a3 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a4 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a5 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a6 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a7 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a8 = Struct3BytesInt();
-Struct3BytesInt passStruct3BytesIntx10_a9 = Struct3BytesInt();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a0 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a1 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a2 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a3 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a4 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a5 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a6 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a7 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a8 =
+    Struct3BytesHomogeneousUint8();
+Struct3BytesHomogeneousUint8 passStruct3BytesHomogeneousUint8x10_a9 =
+    Struct3BytesHomogeneousUint8();
 
 // Result variable also global, so we can delete it after the callback.
-int passStruct3BytesIntx10Result = 0;
+int passStruct3BytesHomogeneousUint8x10Result = 0;
 
-int passStruct3BytesIntx10CalculateResult() {
+int passStruct3BytesHomogeneousUint8x10CalculateResult() {
   int result = 0;
 
-  result += passStruct3BytesIntx10_a0.a0;
-  result += passStruct3BytesIntx10_a0.a1;
-  result += passStruct3BytesIntx10_a1.a0;
-  result += passStruct3BytesIntx10_a1.a1;
-  result += passStruct3BytesIntx10_a2.a0;
-  result += passStruct3BytesIntx10_a2.a1;
-  result += passStruct3BytesIntx10_a3.a0;
-  result += passStruct3BytesIntx10_a3.a1;
-  result += passStruct3BytesIntx10_a4.a0;
-  result += passStruct3BytesIntx10_a4.a1;
-  result += passStruct3BytesIntx10_a5.a0;
-  result += passStruct3BytesIntx10_a5.a1;
-  result += passStruct3BytesIntx10_a6.a0;
-  result += passStruct3BytesIntx10_a6.a1;
-  result += passStruct3BytesIntx10_a7.a0;
-  result += passStruct3BytesIntx10_a7.a1;
-  result += passStruct3BytesIntx10_a8.a0;
-  result += passStruct3BytesIntx10_a8.a1;
-  result += passStruct3BytesIntx10_a9.a0;
-  result += passStruct3BytesIntx10_a9.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a0.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a0.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a0.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a1.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a1.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a1.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a2.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a2.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a2.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a3.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a3.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a3.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a4.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a4.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a4.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a5.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a5.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a5.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a6.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a6.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a6.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a7.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a7.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a7.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a8.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a8.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a8.a2;
+  result += passStruct3BytesHomogeneousUint8x10_a9.a0;
+  result += passStruct3BytesHomogeneousUint8x10_a9.a1;
+  result += passStruct3BytesHomogeneousUint8x10_a9.a2;
 
-  passStruct3BytesIntx10Result = result;
+  passStruct3BytesHomogeneousUint8x10Result = result;
 
   return result;
 }
 
 /// Not a multiple of word size, not a power of two.
 /// 10 struct arguments will exhaust available registers.
-int passStruct3BytesIntx10(
-    Struct3BytesInt a0,
-    Struct3BytesInt a1,
-    Struct3BytesInt a2,
-    Struct3BytesInt a3,
-    Struct3BytesInt a4,
-    Struct3BytesInt a5,
-    Struct3BytesInt a6,
-    Struct3BytesInt a7,
-    Struct3BytesInt a8,
-    Struct3BytesInt a9) {
+int passStruct3BytesHomogeneousUint8x10(
+    Struct3BytesHomogeneousUint8 a0,
+    Struct3BytesHomogeneousUint8 a1,
+    Struct3BytesHomogeneousUint8 a2,
+    Struct3BytesHomogeneousUint8 a3,
+    Struct3BytesHomogeneousUint8 a4,
+    Struct3BytesHomogeneousUint8 a5,
+    Struct3BytesHomogeneousUint8 a6,
+    Struct3BytesHomogeneousUint8 a7,
+    Struct3BytesHomogeneousUint8 a8,
+    Struct3BytesHomogeneousUint8 a9) {
   print(
-      "passStruct3BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+      "passStruct3BytesHomogeneousUint8x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
 
   // In legacy mode, possibly return null.
   if (a0.a0 == 84) {
@@ -495,29 +538,150 @@
   // In both nnbd and legacy mode, possibly throw.
   if (a0.a0 == 42 || a0.a0 == 84) {
     print("throwing!");
-    throw Exception("PassStruct3BytesIntx10 throwing on purpuse!");
+    throw Exception("PassStruct3BytesHomogeneousUint8x10 throwing on purpuse!");
   }
 
-  passStruct3BytesIntx10_a0 = a0;
-  passStruct3BytesIntx10_a1 = a1;
-  passStruct3BytesIntx10_a2 = a2;
-  passStruct3BytesIntx10_a3 = a3;
-  passStruct3BytesIntx10_a4 = a4;
-  passStruct3BytesIntx10_a5 = a5;
-  passStruct3BytesIntx10_a6 = a6;
-  passStruct3BytesIntx10_a7 = a7;
-  passStruct3BytesIntx10_a8 = a8;
-  passStruct3BytesIntx10_a9 = a9;
+  passStruct3BytesHomogeneousUint8x10_a0 = a0;
+  passStruct3BytesHomogeneousUint8x10_a1 = a1;
+  passStruct3BytesHomogeneousUint8x10_a2 = a2;
+  passStruct3BytesHomogeneousUint8x10_a3 = a3;
+  passStruct3BytesHomogeneousUint8x10_a4 = a4;
+  passStruct3BytesHomogeneousUint8x10_a5 = a5;
+  passStruct3BytesHomogeneousUint8x10_a6 = a6;
+  passStruct3BytesHomogeneousUint8x10_a7 = a7;
+  passStruct3BytesHomogeneousUint8x10_a8 = a8;
+  passStruct3BytesHomogeneousUint8x10_a9 = a9;
 
-  final result = passStruct3BytesIntx10CalculateResult();
+  final result = passStruct3BytesHomogeneousUint8x10CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void passStruct3BytesIntx10AfterCallback() {
-  final result = passStruct3BytesIntx10CalculateResult();
+void passStruct3BytesHomogeneousUint8x10AfterCallback() {
+  final result = passStruct3BytesHomogeneousUint8x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(465, result);
+}
+
+typedef PassStruct3BytesInt2ByteAlignedx10Type = Int64 Function(
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned,
+    Struct3BytesInt2ByteAligned);
+
+// Global variables to be able to test inputs after callback returned.
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a0 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a1 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a2 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a3 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a4 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a5 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a6 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a7 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a8 =
+    Struct3BytesInt2ByteAligned();
+Struct3BytesInt2ByteAligned passStruct3BytesInt2ByteAlignedx10_a9 =
+    Struct3BytesInt2ByteAligned();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct3BytesInt2ByteAlignedx10Result = 0;
+
+int passStruct3BytesInt2ByteAlignedx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct3BytesInt2ByteAlignedx10_a0.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a0.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a1.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a1.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a2.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a2.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a3.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a3.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a4.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a4.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a5.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a5.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a6.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a6.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a7.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a7.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a8.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a8.a1;
+  result += passStruct3BytesInt2ByteAlignedx10_a9.a0;
+  result += passStruct3BytesInt2ByteAlignedx10_a9.a1;
+
+  passStruct3BytesInt2ByteAlignedx10Result = result;
+
+  return result;
+}
+
+/// 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.
+int passStruct3BytesInt2ByteAlignedx10(
+    Struct3BytesInt2ByteAligned a0,
+    Struct3BytesInt2ByteAligned a1,
+    Struct3BytesInt2ByteAligned a2,
+    Struct3BytesInt2ByteAligned a3,
+    Struct3BytesInt2ByteAligned a4,
+    Struct3BytesInt2ByteAligned a5,
+    Struct3BytesInt2ByteAligned a6,
+    Struct3BytesInt2ByteAligned a7,
+    Struct3BytesInt2ByteAligned a8,
+    Struct3BytesInt2ByteAligned a9) {
+  print(
+      "passStruct3BytesInt2ByteAlignedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct3BytesInt2ByteAlignedx10 throwing on purpuse!");
+  }
+
+  passStruct3BytesInt2ByteAlignedx10_a0 = a0;
+  passStruct3BytesInt2ByteAlignedx10_a1 = a1;
+  passStruct3BytesInt2ByteAlignedx10_a2 = a2;
+  passStruct3BytesInt2ByteAlignedx10_a3 = a3;
+  passStruct3BytesInt2ByteAlignedx10_a4 = a4;
+  passStruct3BytesInt2ByteAlignedx10_a5 = a5;
+  passStruct3BytesInt2ByteAlignedx10_a6 = a6;
+  passStruct3BytesInt2ByteAlignedx10_a7 = a7;
+  passStruct3BytesInt2ByteAlignedx10_a8 = a8;
+  passStruct3BytesInt2ByteAlignedx10_a9 = a9;
+
+  final result = passStruct3BytesInt2ByteAlignedx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct3BytesInt2ByteAlignedx10AfterCallback() {
+  final result = passStruct3BytesInt2ByteAlignedx10CalculateResult();
 
   print("after callback result = $result");
 
@@ -644,87 +808,137 @@
   Expect.equals(10, result);
 }
 
-typedef PassStruct7BytesIntx10Type = Int64 Function(
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt,
-    Struct7BytesInt);
+typedef PassStruct7BytesHomogeneousUint8x10Type = Int64 Function(
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8,
+    Struct7BytesHomogeneousUint8);
 
 // Global variables to be able to test inputs after callback returned.
-Struct7BytesInt passStruct7BytesIntx10_a0 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a1 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a2 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a3 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a4 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a5 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a6 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a7 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a8 = Struct7BytesInt();
-Struct7BytesInt passStruct7BytesIntx10_a9 = Struct7BytesInt();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a0 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a1 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a2 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a3 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a4 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a5 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a6 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a7 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a8 =
+    Struct7BytesHomogeneousUint8();
+Struct7BytesHomogeneousUint8 passStruct7BytesHomogeneousUint8x10_a9 =
+    Struct7BytesHomogeneousUint8();
 
 // Result variable also global, so we can delete it after the callback.
-int passStruct7BytesIntx10Result = 0;
+int passStruct7BytesHomogeneousUint8x10Result = 0;
 
-int passStruct7BytesIntx10CalculateResult() {
+int passStruct7BytesHomogeneousUint8x10CalculateResult() {
   int result = 0;
 
-  result += passStruct7BytesIntx10_a0.a0;
-  result += passStruct7BytesIntx10_a0.a1;
-  result += passStruct7BytesIntx10_a0.a2;
-  result += passStruct7BytesIntx10_a1.a0;
-  result += passStruct7BytesIntx10_a1.a1;
-  result += passStruct7BytesIntx10_a1.a2;
-  result += passStruct7BytesIntx10_a2.a0;
-  result += passStruct7BytesIntx10_a2.a1;
-  result += passStruct7BytesIntx10_a2.a2;
-  result += passStruct7BytesIntx10_a3.a0;
-  result += passStruct7BytesIntx10_a3.a1;
-  result += passStruct7BytesIntx10_a3.a2;
-  result += passStruct7BytesIntx10_a4.a0;
-  result += passStruct7BytesIntx10_a4.a1;
-  result += passStruct7BytesIntx10_a4.a2;
-  result += passStruct7BytesIntx10_a5.a0;
-  result += passStruct7BytesIntx10_a5.a1;
-  result += passStruct7BytesIntx10_a5.a2;
-  result += passStruct7BytesIntx10_a6.a0;
-  result += passStruct7BytesIntx10_a6.a1;
-  result += passStruct7BytesIntx10_a6.a2;
-  result += passStruct7BytesIntx10_a7.a0;
-  result += passStruct7BytesIntx10_a7.a1;
-  result += passStruct7BytesIntx10_a7.a2;
-  result += passStruct7BytesIntx10_a8.a0;
-  result += passStruct7BytesIntx10_a8.a1;
-  result += passStruct7BytesIntx10_a8.a2;
-  result += passStruct7BytesIntx10_a9.a0;
-  result += passStruct7BytesIntx10_a9.a1;
-  result += passStruct7BytesIntx10_a9.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a0.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a1.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a2.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a3.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a4.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a5.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a6.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a7.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a8.a6;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a0;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a1;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a2;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a3;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a4;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a5;
+  result += passStruct7BytesHomogeneousUint8x10_a9.a6;
 
-  passStruct7BytesIntx10Result = result;
+  passStruct7BytesHomogeneousUint8x10Result = result;
 
   return result;
 }
 
 /// Sub word size on 64 bit architectures.
 /// 10 struct arguments will exhaust available registers.
-int passStruct7BytesIntx10(
-    Struct7BytesInt a0,
-    Struct7BytesInt a1,
-    Struct7BytesInt a2,
-    Struct7BytesInt a3,
-    Struct7BytesInt a4,
-    Struct7BytesInt a5,
-    Struct7BytesInt a6,
-    Struct7BytesInt a7,
-    Struct7BytesInt a8,
-    Struct7BytesInt a9) {
+int passStruct7BytesHomogeneousUint8x10(
+    Struct7BytesHomogeneousUint8 a0,
+    Struct7BytesHomogeneousUint8 a1,
+    Struct7BytesHomogeneousUint8 a2,
+    Struct7BytesHomogeneousUint8 a3,
+    Struct7BytesHomogeneousUint8 a4,
+    Struct7BytesHomogeneousUint8 a5,
+    Struct7BytesHomogeneousUint8 a6,
+    Struct7BytesHomogeneousUint8 a7,
+    Struct7BytesHomogeneousUint8 a8,
+    Struct7BytesHomogeneousUint8 a9) {
   print(
-      "passStruct7BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+      "passStruct7BytesHomogeneousUint8x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
 
   // In legacy mode, possibly return null.
   if (a0.a0 == 84) {
@@ -735,29 +949,160 @@
   // In both nnbd and legacy mode, possibly throw.
   if (a0.a0 == 42 || a0.a0 == 84) {
     print("throwing!");
-    throw Exception("PassStruct7BytesIntx10 throwing on purpuse!");
+    throw Exception("PassStruct7BytesHomogeneousUint8x10 throwing on purpuse!");
   }
 
-  passStruct7BytesIntx10_a0 = a0;
-  passStruct7BytesIntx10_a1 = a1;
-  passStruct7BytesIntx10_a2 = a2;
-  passStruct7BytesIntx10_a3 = a3;
-  passStruct7BytesIntx10_a4 = a4;
-  passStruct7BytesIntx10_a5 = a5;
-  passStruct7BytesIntx10_a6 = a6;
-  passStruct7BytesIntx10_a7 = a7;
-  passStruct7BytesIntx10_a8 = a8;
-  passStruct7BytesIntx10_a9 = a9;
+  passStruct7BytesHomogeneousUint8x10_a0 = a0;
+  passStruct7BytesHomogeneousUint8x10_a1 = a1;
+  passStruct7BytesHomogeneousUint8x10_a2 = a2;
+  passStruct7BytesHomogeneousUint8x10_a3 = a3;
+  passStruct7BytesHomogeneousUint8x10_a4 = a4;
+  passStruct7BytesHomogeneousUint8x10_a5 = a5;
+  passStruct7BytesHomogeneousUint8x10_a6 = a6;
+  passStruct7BytesHomogeneousUint8x10_a7 = a7;
+  passStruct7BytesHomogeneousUint8x10_a8 = a8;
+  passStruct7BytesHomogeneousUint8x10_a9 = a9;
 
-  final result = passStruct7BytesIntx10CalculateResult();
+  final result = passStruct7BytesHomogeneousUint8x10CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void passStruct7BytesIntx10AfterCallback() {
-  final result = passStruct7BytesIntx10CalculateResult();
+void passStruct7BytesHomogeneousUint8x10AfterCallback() {
+  final result = passStruct7BytesHomogeneousUint8x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(2485, result);
+}
+
+typedef PassStruct7BytesInt4ByteAlignedx10Type = Int64 Function(
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned,
+    Struct7BytesInt4ByteAligned);
+
+// Global variables to be able to test inputs after callback returned.
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a0 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a1 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a2 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a3 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a4 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a5 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a6 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a7 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a8 =
+    Struct7BytesInt4ByteAligned();
+Struct7BytesInt4ByteAligned passStruct7BytesInt4ByteAlignedx10_a9 =
+    Struct7BytesInt4ByteAligned();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct7BytesInt4ByteAlignedx10Result = 0;
+
+int passStruct7BytesInt4ByteAlignedx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct7BytesInt4ByteAlignedx10_a0.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a0.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a0.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a1.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a1.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a1.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a2.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a2.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a2.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a3.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a3.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a3.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a4.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a4.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a4.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a5.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a5.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a5.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a6.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a6.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a6.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a7.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a7.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a7.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a8.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a8.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a8.a2;
+  result += passStruct7BytesInt4ByteAlignedx10_a9.a0;
+  result += passStruct7BytesInt4ByteAlignedx10_a9.a1;
+  result += passStruct7BytesInt4ByteAlignedx10_a9.a2;
+
+  passStruct7BytesInt4ByteAlignedx10Result = result;
+
+  return result;
+}
+
+/// Sub word size on 64 bit architectures.
+/// With alignment rules taken into account size is 8 bytes.
+/// 10 struct arguments will exhaust available registers.
+int passStruct7BytesInt4ByteAlignedx10(
+    Struct7BytesInt4ByteAligned a0,
+    Struct7BytesInt4ByteAligned a1,
+    Struct7BytesInt4ByteAligned a2,
+    Struct7BytesInt4ByteAligned a3,
+    Struct7BytesInt4ByteAligned a4,
+    Struct7BytesInt4ByteAligned a5,
+    Struct7BytesInt4ByteAligned a6,
+    Struct7BytesInt4ByteAligned a7,
+    Struct7BytesInt4ByteAligned a8,
+    Struct7BytesInt4ByteAligned a9) {
+  print(
+      "passStruct7BytesInt4ByteAlignedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct7BytesInt4ByteAlignedx10 throwing on purpuse!");
+  }
+
+  passStruct7BytesInt4ByteAlignedx10_a0 = a0;
+  passStruct7BytesInt4ByteAlignedx10_a1 = a1;
+  passStruct7BytesInt4ByteAlignedx10_a2 = a2;
+  passStruct7BytesInt4ByteAlignedx10_a3 = a3;
+  passStruct7BytesInt4ByteAlignedx10_a4 = a4;
+  passStruct7BytesInt4ByteAlignedx10_a5 = a5;
+  passStruct7BytesInt4ByteAlignedx10_a6 = a6;
+  passStruct7BytesInt4ByteAlignedx10_a7 = a7;
+  passStruct7BytesInt4ByteAlignedx10_a8 = a8;
+  passStruct7BytesInt4ByteAlignedx10_a9 = a9;
+
+  final result = passStruct7BytesInt4ByteAlignedx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct7BytesInt4ByteAlignedx10AfterCallback() {
+  final result = passStruct7BytesInt4ByteAlignedx10CalculateResult();
 
   print("after callback result = $result");
 
@@ -1124,79 +1469,160 @@
   Expect.approxEquals(15.0, result);
 }
 
-typedef PassStruct9BytesIntx10Type = Int64 Function(
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt,
-    Struct9BytesInt);
+typedef PassStruct9BytesHomogeneousUint8x10Type = Int64 Function(
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8,
+    Struct9BytesHomogeneousUint8);
 
 // Global variables to be able to test inputs after callback returned.
-Struct9BytesInt passStruct9BytesIntx10_a0 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a1 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a2 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a3 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a4 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a5 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a6 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a7 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a8 = Struct9BytesInt();
-Struct9BytesInt passStruct9BytesIntx10_a9 = Struct9BytesInt();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a0 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a1 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a2 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a3 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a4 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a5 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a6 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a7 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a8 =
+    Struct9BytesHomogeneousUint8();
+Struct9BytesHomogeneousUint8 passStruct9BytesHomogeneousUint8x10_a9 =
+    Struct9BytesHomogeneousUint8();
 
 // Result variable also global, so we can delete it after the callback.
-int passStruct9BytesIntx10Result = 0;
+int passStruct9BytesHomogeneousUint8x10Result = 0;
 
-int passStruct9BytesIntx10CalculateResult() {
+int passStruct9BytesHomogeneousUint8x10CalculateResult() {
   int result = 0;
 
-  result += passStruct9BytesIntx10_a0.a0;
-  result += passStruct9BytesIntx10_a0.a1;
-  result += passStruct9BytesIntx10_a1.a0;
-  result += passStruct9BytesIntx10_a1.a1;
-  result += passStruct9BytesIntx10_a2.a0;
-  result += passStruct9BytesIntx10_a2.a1;
-  result += passStruct9BytesIntx10_a3.a0;
-  result += passStruct9BytesIntx10_a3.a1;
-  result += passStruct9BytesIntx10_a4.a0;
-  result += passStruct9BytesIntx10_a4.a1;
-  result += passStruct9BytesIntx10_a5.a0;
-  result += passStruct9BytesIntx10_a5.a1;
-  result += passStruct9BytesIntx10_a6.a0;
-  result += passStruct9BytesIntx10_a6.a1;
-  result += passStruct9BytesIntx10_a7.a0;
-  result += passStruct9BytesIntx10_a7.a1;
-  result += passStruct9BytesIntx10_a8.a0;
-  result += passStruct9BytesIntx10_a8.a1;
-  result += passStruct9BytesIntx10_a9.a0;
-  result += passStruct9BytesIntx10_a9.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a0.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a1.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a2.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a3.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a4.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a5.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a6.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a7.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a8.a8;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a0;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a1;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a2;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a3;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a4;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a5;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a6;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a7;
+  result += passStruct9BytesHomogeneousUint8x10_a9.a8;
 
-  passStruct9BytesIntx10Result = result;
+  passStruct9BytesHomogeneousUint8x10Result = result;
 
   return result;
 }
 
 /// 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.
-int passStruct9BytesIntx10(
-    Struct9BytesInt a0,
-    Struct9BytesInt a1,
-    Struct9BytesInt a2,
-    Struct9BytesInt a3,
-    Struct9BytesInt a4,
-    Struct9BytesInt a5,
-    Struct9BytesInt a6,
-    Struct9BytesInt a7,
-    Struct9BytesInt a8,
-    Struct9BytesInt a9) {
+int passStruct9BytesHomogeneousUint8x10(
+    Struct9BytesHomogeneousUint8 a0,
+    Struct9BytesHomogeneousUint8 a1,
+    Struct9BytesHomogeneousUint8 a2,
+    Struct9BytesHomogeneousUint8 a3,
+    Struct9BytesHomogeneousUint8 a4,
+    Struct9BytesHomogeneousUint8 a5,
+    Struct9BytesHomogeneousUint8 a6,
+    Struct9BytesHomogeneousUint8 a7,
+    Struct9BytesHomogeneousUint8 a8,
+    Struct9BytesHomogeneousUint8 a9) {
   print(
-      "passStruct9BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+      "passStruct9BytesHomogeneousUint8x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
 
   // In legacy mode, possibly return null.
   if (a0.a0 == 84) {
@@ -1207,188 +1633,118 @@
   // In both nnbd and legacy mode, possibly throw.
   if (a0.a0 == 42 || a0.a0 == 84) {
     print("throwing!");
-    throw Exception("PassStruct9BytesIntx10 throwing on purpuse!");
+    throw Exception("PassStruct9BytesHomogeneousUint8x10 throwing on purpuse!");
   }
 
-  passStruct9BytesIntx10_a0 = a0;
-  passStruct9BytesIntx10_a1 = a1;
-  passStruct9BytesIntx10_a2 = a2;
-  passStruct9BytesIntx10_a3 = a3;
-  passStruct9BytesIntx10_a4 = a4;
-  passStruct9BytesIntx10_a5 = a5;
-  passStruct9BytesIntx10_a6 = a6;
-  passStruct9BytesIntx10_a7 = a7;
-  passStruct9BytesIntx10_a8 = a8;
-  passStruct9BytesIntx10_a9 = a9;
+  passStruct9BytesHomogeneousUint8x10_a0 = a0;
+  passStruct9BytesHomogeneousUint8x10_a1 = a1;
+  passStruct9BytesHomogeneousUint8x10_a2 = a2;
+  passStruct9BytesHomogeneousUint8x10_a3 = a3;
+  passStruct9BytesHomogeneousUint8x10_a4 = a4;
+  passStruct9BytesHomogeneousUint8x10_a5 = a5;
+  passStruct9BytesHomogeneousUint8x10_a6 = a6;
+  passStruct9BytesHomogeneousUint8x10_a7 = a7;
+  passStruct9BytesHomogeneousUint8x10_a8 = a8;
+  passStruct9BytesHomogeneousUint8x10_a9 = a9;
 
-  final result = passStruct9BytesIntx10CalculateResult();
+  final result = passStruct9BytesHomogeneousUint8x10CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void passStruct9BytesIntx10AfterCallback() {
-  final result = passStruct9BytesIntx10CalculateResult();
+void passStruct9BytesHomogeneousUint8x10AfterCallback() {
+  final result = passStruct9BytesHomogeneousUint8x10CalculateResult();
 
   print("after callback result = $result");
 
-  Expect.equals(10, result);
+  Expect.equals(4095, result);
 }
 
-typedef PassStruct9BytesHomogeneousUint82x10Type = Int64 Function(
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82,
-    Struct9BytesHomogeneousUint82);
+typedef PassStruct9BytesInt4Or8ByteAlignedx10Type = Int64 Function(
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned,
+    Struct9BytesInt4Or8ByteAligned);
 
 // Global variables to be able to test inputs after callback returned.
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a0 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a1 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a2 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a3 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a4 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a5 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a6 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a7 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a8 =
-    Struct9BytesHomogeneousUint82();
-Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a9 =
-    Struct9BytesHomogeneousUint82();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a0 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a1 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a2 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a3 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a4 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a5 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a6 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a7 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a8 =
+    Struct9BytesInt4Or8ByteAligned();
+Struct9BytesInt4Or8ByteAligned passStruct9BytesInt4Or8ByteAlignedx10_a9 =
+    Struct9BytesInt4Or8ByteAligned();
 
 // Result variable also global, so we can delete it after the callback.
-int passStruct9BytesHomogeneousUint82x10Result = 0;
+int passStruct9BytesInt4Or8ByteAlignedx10Result = 0;
 
-int passStruct9BytesHomogeneousUint82x10CalculateResult() {
+int passStruct9BytesInt4Or8ByteAlignedx10CalculateResult() {
   int result = 0;
 
-  result += passStruct9BytesHomogeneousUint82x10_a0.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a0.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a1.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a2.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a3.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a4.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a5.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a6.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a7.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a8.a8;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a0;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a1;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a2;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a3;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a4;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a5;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a6;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a7;
-  result += passStruct9BytesHomogeneousUint82x10_a9.a8;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a0.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a0.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a1.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a1.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a2.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a2.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a3.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a3.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a4.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a4.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a5.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a5.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a6.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a6.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a7.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a7.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a8.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a8.a1;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a9.a0;
+  result += passStruct9BytesInt4Or8ByteAlignedx10_a9.a1;
 
-  passStruct9BytesHomogeneousUint82x10Result = result;
+  passStruct9BytesInt4Or8ByteAlignedx10Result = result;
 
   return result;
 }
 
 /// 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.
-/// Struct only has 1-byte aligned fields to test struct alignment itself.
 ///
-int passStruct9BytesHomogeneousUint82x10(
-    Struct9BytesHomogeneousUint82 a0,
-    Struct9BytesHomogeneousUint82 a1,
-    Struct9BytesHomogeneousUint82 a2,
-    Struct9BytesHomogeneousUint82 a3,
-    Struct9BytesHomogeneousUint82 a4,
-    Struct9BytesHomogeneousUint82 a5,
-    Struct9BytesHomogeneousUint82 a6,
-    Struct9BytesHomogeneousUint82 a7,
-    Struct9BytesHomogeneousUint82 a8,
-    Struct9BytesHomogeneousUint82 a9) {
+int passStruct9BytesInt4Or8ByteAlignedx10(
+    Struct9BytesInt4Or8ByteAligned a0,
+    Struct9BytesInt4Or8ByteAligned a1,
+    Struct9BytesInt4Or8ByteAligned a2,
+    Struct9BytesInt4Or8ByteAligned a3,
+    Struct9BytesInt4Or8ByteAligned a4,
+    Struct9BytesInt4Or8ByteAligned a5,
+    Struct9BytesInt4Or8ByteAligned a6,
+    Struct9BytesInt4Or8ByteAligned a7,
+    Struct9BytesInt4Or8ByteAligned a8,
+    Struct9BytesInt4Or8ByteAligned a9) {
   print(
-      "passStruct9BytesHomogeneousUint82x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+      "passStruct9BytesInt4Or8ByteAlignedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
 
   // In legacy mode, possibly return null.
   if (a0.a0 == 84) {
@@ -1400,33 +1756,33 @@
   if (a0.a0 == 42 || a0.a0 == 84) {
     print("throwing!");
     throw Exception(
-        "PassStruct9BytesHomogeneousUint82x10 throwing on purpuse!");
+        "PassStruct9BytesInt4Or8ByteAlignedx10 throwing on purpuse!");
   }
 
-  passStruct9BytesHomogeneousUint82x10_a0 = a0;
-  passStruct9BytesHomogeneousUint82x10_a1 = a1;
-  passStruct9BytesHomogeneousUint82x10_a2 = a2;
-  passStruct9BytesHomogeneousUint82x10_a3 = a3;
-  passStruct9BytesHomogeneousUint82x10_a4 = a4;
-  passStruct9BytesHomogeneousUint82x10_a5 = a5;
-  passStruct9BytesHomogeneousUint82x10_a6 = a6;
-  passStruct9BytesHomogeneousUint82x10_a7 = a7;
-  passStruct9BytesHomogeneousUint82x10_a8 = a8;
-  passStruct9BytesHomogeneousUint82x10_a9 = a9;
+  passStruct9BytesInt4Or8ByteAlignedx10_a0 = a0;
+  passStruct9BytesInt4Or8ByteAlignedx10_a1 = a1;
+  passStruct9BytesInt4Or8ByteAlignedx10_a2 = a2;
+  passStruct9BytesInt4Or8ByteAlignedx10_a3 = a3;
+  passStruct9BytesInt4Or8ByteAlignedx10_a4 = a4;
+  passStruct9BytesInt4Or8ByteAlignedx10_a5 = a5;
+  passStruct9BytesInt4Or8ByteAlignedx10_a6 = a6;
+  passStruct9BytesInt4Or8ByteAlignedx10_a7 = a7;
+  passStruct9BytesInt4Or8ByteAlignedx10_a8 = a8;
+  passStruct9BytesInt4Or8ByteAlignedx10_a9 = a9;
 
-  final result = passStruct9BytesHomogeneousUint82x10CalculateResult();
+  final result = passStruct9BytesInt4Or8ByteAlignedx10CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void passStruct9BytesHomogeneousUint82x10AfterCallback() {
-  final result = passStruct9BytesHomogeneousUint82x10CalculateResult();
+void passStruct9BytesInt4Or8ByteAlignedx10AfterCallback() {
+  final result = passStruct9BytesInt4Or8ByteAlignedx10CalculateResult();
 
   print("after callback result = $result");
 
-  Expect.equals(4095, result);
+  Expect.equals(10, result);
 }
 
 typedef PassStruct12BytesHomogeneousFloatx6Type = Float Function(
@@ -3672,29 +4028,36 @@
   free(returnStruct1ByteIntResult.addressOf);
 }
 
-typedef ReturnStruct3BytesIntType = Struct3BytesInt Function(Int16, Int8);
+typedef ReturnStruct3BytesHomogeneousUint8Type = Struct3BytesHomogeneousUint8
+    Function(Uint8, Uint8, Uint8);
 
 // Global variables to be able to test inputs after callback returned.
-int returnStruct3BytesInt_a0 = 0;
-int returnStruct3BytesInt_a1 = 0;
+int returnStruct3BytesHomogeneousUint8_a0 = 0;
+int returnStruct3BytesHomogeneousUint8_a1 = 0;
+int returnStruct3BytesHomogeneousUint8_a2 = 0;
 
 // Result variable also global, so we can delete it after the callback.
-Struct3BytesInt returnStruct3BytesIntResult = Struct3BytesInt();
+Struct3BytesHomogeneousUint8 returnStruct3BytesHomogeneousUint8Result =
+    Struct3BytesHomogeneousUint8();
 
-Struct3BytesInt returnStruct3BytesIntCalculateResult() {
-  Struct3BytesInt result = allocate<Struct3BytesInt>().ref;
+Struct3BytesHomogeneousUint8
+    returnStruct3BytesHomogeneousUint8CalculateResult() {
+  Struct3BytesHomogeneousUint8 result =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
 
-  result.a0 = returnStruct3BytesInt_a0;
-  result.a1 = returnStruct3BytesInt_a1;
+  result.a0 = returnStruct3BytesHomogeneousUint8_a0;
+  result.a1 = returnStruct3BytesHomogeneousUint8_a1;
+  result.a2 = returnStruct3BytesHomogeneousUint8_a2;
 
-  returnStruct3BytesIntResult = result;
+  returnStruct3BytesHomogeneousUint8Result = result;
 
   return result;
 }
 
 /// Smaller than word size return value on all architectures.
-Struct3BytesInt returnStruct3BytesInt(int a0, int a1) {
-  print("returnStruct3BytesInt(${a0}, ${a1})");
+Struct3BytesHomogeneousUint8 returnStruct3BytesHomogeneousUint8(
+    int a0, int a1, int a2) {
+  print("returnStruct3BytesHomogeneousUint8(${a0}, ${a1}, ${a2})");
 
   // In legacy mode, possibly return null.
   if (a0 == 84) {
@@ -3705,27 +4068,88 @@
   // In both nnbd and legacy mode, possibly throw.
   if (a0 == 42 || a0 == 84) {
     print("throwing!");
-    throw Exception("ReturnStruct3BytesInt throwing on purpuse!");
+    throw Exception("ReturnStruct3BytesHomogeneousUint8 throwing on purpuse!");
   }
 
-  returnStruct3BytesInt_a0 = a0;
-  returnStruct3BytesInt_a1 = a1;
+  returnStruct3BytesHomogeneousUint8_a0 = a0;
+  returnStruct3BytesHomogeneousUint8_a1 = a1;
+  returnStruct3BytesHomogeneousUint8_a2 = a2;
 
-  final result = returnStruct3BytesIntCalculateResult();
+  final result = returnStruct3BytesHomogeneousUint8CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void returnStruct3BytesIntAfterCallback() {
-  free(returnStruct3BytesIntResult.addressOf);
+void returnStruct3BytesHomogeneousUint8AfterCallback() {
+  free(returnStruct3BytesHomogeneousUint8Result.addressOf);
 
-  final result = returnStruct3BytesIntCalculateResult();
+  final result = returnStruct3BytesHomogeneousUint8CalculateResult();
 
   print("after callback result = $result");
 
-  free(returnStruct3BytesIntResult.addressOf);
+  free(returnStruct3BytesHomogeneousUint8Result.addressOf);
+}
+
+typedef ReturnStruct3BytesInt2ByteAlignedType = Struct3BytesInt2ByteAligned
+    Function(Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct3BytesInt2ByteAligned_a0 = 0;
+int returnStruct3BytesInt2ByteAligned_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct3BytesInt2ByteAligned returnStruct3BytesInt2ByteAlignedResult =
+    Struct3BytesInt2ByteAligned();
+
+Struct3BytesInt2ByteAligned returnStruct3BytesInt2ByteAlignedCalculateResult() {
+  Struct3BytesInt2ByteAligned result =
+      allocate<Struct3BytesInt2ByteAligned>().ref;
+
+  result.a0 = returnStruct3BytesInt2ByteAligned_a0;
+  result.a1 = returnStruct3BytesInt2ByteAligned_a1;
+
+  returnStruct3BytesInt2ByteAlignedResult = result;
+
+  return result;
+}
+
+/// Smaller than word size return value on all architectures.
+/// With alignment rules taken into account size is 4 bytes.
+Struct3BytesInt2ByteAligned returnStruct3BytesInt2ByteAligned(int a0, int a1) {
+  print("returnStruct3BytesInt2ByteAligned(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct3BytesInt2ByteAligned throwing on purpuse!");
+  }
+
+  returnStruct3BytesInt2ByteAligned_a0 = a0;
+  returnStruct3BytesInt2ByteAligned_a1 = a1;
+
+  final result = returnStruct3BytesInt2ByteAlignedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct3BytesInt2ByteAlignedAfterCallback() {
+  free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
+
+  final result = returnStruct3BytesInt2ByteAlignedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
 }
 
 typedef ReturnStruct4BytesHomogeneousInt16Type = Struct4BytesHomogeneousInt16
@@ -3789,32 +4213,45 @@
   free(returnStruct4BytesHomogeneousInt16Result.addressOf);
 }
 
-typedef ReturnStruct7BytesIntType = Struct7BytesInt Function(
-    Int32, Int16, Int8);
+typedef ReturnStruct7BytesHomogeneousUint8Type = Struct7BytesHomogeneousUint8
+    Function(Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8);
 
 // Global variables to be able to test inputs after callback returned.
-int returnStruct7BytesInt_a0 = 0;
-int returnStruct7BytesInt_a1 = 0;
-int returnStruct7BytesInt_a2 = 0;
+int returnStruct7BytesHomogeneousUint8_a0 = 0;
+int returnStruct7BytesHomogeneousUint8_a1 = 0;
+int returnStruct7BytesHomogeneousUint8_a2 = 0;
+int returnStruct7BytesHomogeneousUint8_a3 = 0;
+int returnStruct7BytesHomogeneousUint8_a4 = 0;
+int returnStruct7BytesHomogeneousUint8_a5 = 0;
+int returnStruct7BytesHomogeneousUint8_a6 = 0;
 
 // Result variable also global, so we can delete it after the callback.
-Struct7BytesInt returnStruct7BytesIntResult = Struct7BytesInt();
+Struct7BytesHomogeneousUint8 returnStruct7BytesHomogeneousUint8Result =
+    Struct7BytesHomogeneousUint8();
 
-Struct7BytesInt returnStruct7BytesIntCalculateResult() {
-  Struct7BytesInt result = allocate<Struct7BytesInt>().ref;
+Struct7BytesHomogeneousUint8
+    returnStruct7BytesHomogeneousUint8CalculateResult() {
+  Struct7BytesHomogeneousUint8 result =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
 
-  result.a0 = returnStruct7BytesInt_a0;
-  result.a1 = returnStruct7BytesInt_a1;
-  result.a2 = returnStruct7BytesInt_a2;
+  result.a0 = returnStruct7BytesHomogeneousUint8_a0;
+  result.a1 = returnStruct7BytesHomogeneousUint8_a1;
+  result.a2 = returnStruct7BytesHomogeneousUint8_a2;
+  result.a3 = returnStruct7BytesHomogeneousUint8_a3;
+  result.a4 = returnStruct7BytesHomogeneousUint8_a4;
+  result.a5 = returnStruct7BytesHomogeneousUint8_a5;
+  result.a6 = returnStruct7BytesHomogeneousUint8_a6;
 
-  returnStruct7BytesIntResult = result;
+  returnStruct7BytesHomogeneousUint8Result = result;
 
   return result;
 }
 
 /// Non-wordsize return value.
-Struct7BytesInt returnStruct7BytesInt(int a0, int a1, int a2) {
-  print("returnStruct7BytesInt(${a0}, ${a1}, ${a2})");
+Struct7BytesHomogeneousUint8 returnStruct7BytesHomogeneousUint8(
+    int a0, int a1, int a2, int a3, int a4, int a5, int a6) {
+  print(
+      "returnStruct7BytesHomogeneousUint8(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6})");
 
   // In legacy mode, possibly return null.
   if (a0 == 84) {
@@ -3825,28 +4262,96 @@
   // In both nnbd and legacy mode, possibly throw.
   if (a0 == 42 || a0 == 84) {
     print("throwing!");
-    throw Exception("ReturnStruct7BytesInt throwing on purpuse!");
+    throw Exception("ReturnStruct7BytesHomogeneousUint8 throwing on purpuse!");
   }
 
-  returnStruct7BytesInt_a0 = a0;
-  returnStruct7BytesInt_a1 = a1;
-  returnStruct7BytesInt_a2 = a2;
+  returnStruct7BytesHomogeneousUint8_a0 = a0;
+  returnStruct7BytesHomogeneousUint8_a1 = a1;
+  returnStruct7BytesHomogeneousUint8_a2 = a2;
+  returnStruct7BytesHomogeneousUint8_a3 = a3;
+  returnStruct7BytesHomogeneousUint8_a4 = a4;
+  returnStruct7BytesHomogeneousUint8_a5 = a5;
+  returnStruct7BytesHomogeneousUint8_a6 = a6;
 
-  final result = returnStruct7BytesIntCalculateResult();
+  final result = returnStruct7BytesHomogeneousUint8CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void returnStruct7BytesIntAfterCallback() {
-  free(returnStruct7BytesIntResult.addressOf);
+void returnStruct7BytesHomogeneousUint8AfterCallback() {
+  free(returnStruct7BytesHomogeneousUint8Result.addressOf);
 
-  final result = returnStruct7BytesIntCalculateResult();
+  final result = returnStruct7BytesHomogeneousUint8CalculateResult();
 
   print("after callback result = $result");
 
-  free(returnStruct7BytesIntResult.addressOf);
+  free(returnStruct7BytesHomogeneousUint8Result.addressOf);
+}
+
+typedef ReturnStruct7BytesInt4ByteAlignedType = Struct7BytesInt4ByteAligned
+    Function(Int32, Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct7BytesInt4ByteAligned_a0 = 0;
+int returnStruct7BytesInt4ByteAligned_a1 = 0;
+int returnStruct7BytesInt4ByteAligned_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct7BytesInt4ByteAligned returnStruct7BytesInt4ByteAlignedResult =
+    Struct7BytesInt4ByteAligned();
+
+Struct7BytesInt4ByteAligned returnStruct7BytesInt4ByteAlignedCalculateResult() {
+  Struct7BytesInt4ByteAligned result =
+      allocate<Struct7BytesInt4ByteAligned>().ref;
+
+  result.a0 = returnStruct7BytesInt4ByteAligned_a0;
+  result.a1 = returnStruct7BytesInt4ByteAligned_a1;
+  result.a2 = returnStruct7BytesInt4ByteAligned_a2;
+
+  returnStruct7BytesInt4ByteAlignedResult = result;
+
+  return result;
+}
+
+/// Non-wordsize return value.
+/// With alignment rules taken into account size is 8 bytes.
+Struct7BytesInt4ByteAligned returnStruct7BytesInt4ByteAligned(
+    int a0, int a1, int a2) {
+  print("returnStruct7BytesInt4ByteAligned(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct7BytesInt4ByteAligned throwing on purpuse!");
+  }
+
+  returnStruct7BytesInt4ByteAligned_a0 = a0;
+  returnStruct7BytesInt4ByteAligned_a1 = a1;
+  returnStruct7BytesInt4ByteAligned_a2 = a2;
+
+  final result = returnStruct7BytesInt4ByteAlignedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct7BytesInt4ByteAlignedAfterCallback() {
+  free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
+
+  final result = returnStruct7BytesInt4ByteAlignedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
 }
 
 typedef ReturnStruct8BytesIntType = Struct8BytesInt Function(
@@ -4030,97 +4535,40 @@
   free(returnStruct8BytesMixedResult.addressOf);
 }
 
-typedef ReturnStruct9BytesIntType = Struct9BytesInt Function(Int64, Int8);
-
-// Global variables to be able to test inputs after callback returned.
-int returnStruct9BytesInt_a0 = 0;
-int returnStruct9BytesInt_a1 = 0;
-
-// Result variable also global, so we can delete it after the callback.
-Struct9BytesInt returnStruct9BytesIntResult = Struct9BytesInt();
-
-Struct9BytesInt returnStruct9BytesIntCalculateResult() {
-  Struct9BytesInt result = allocate<Struct9BytesInt>().ref;
-
-  result.a0 = returnStruct9BytesInt_a0;
-  result.a1 = returnStruct9BytesInt_a1;
-
-  returnStruct9BytesIntResult = result;
-
-  return result;
-}
-
-/// Return value in two integer registers on x64.
-/// The second register only contains a single byte.
-Struct9BytesInt returnStruct9BytesInt(int a0, int a1) {
-  print("returnStruct9BytesInt(${a0}, ${a1})");
-
-  // In legacy mode, possibly return null.
-  if (a0 == 84) {
-    print("returning null!");
-    return null;
-  }
-
-  // In both nnbd and legacy mode, possibly throw.
-  if (a0 == 42 || a0 == 84) {
-    print("throwing!");
-    throw Exception("ReturnStruct9BytesInt throwing on purpuse!");
-  }
-
-  returnStruct9BytesInt_a0 = a0;
-  returnStruct9BytesInt_a1 = a1;
-
-  final result = returnStruct9BytesIntCalculateResult();
-
-  print("result = $result");
-
-  return result;
-}
-
-void returnStruct9BytesIntAfterCallback() {
-  free(returnStruct9BytesIntResult.addressOf);
-
-  final result = returnStruct9BytesIntCalculateResult();
-
-  print("after callback result = $result");
-
-  free(returnStruct9BytesIntResult.addressOf);
-}
-
-typedef ReturnStruct9BytesHomogeneousUint82Type = Struct9BytesHomogeneousUint82
+typedef ReturnStruct9BytesHomogeneousUint8Type = Struct9BytesHomogeneousUint8
     Function(Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8);
 
 // Global variables to be able to test inputs after callback returned.
-int returnStruct9BytesHomogeneousUint82_a0 = 0;
-int returnStruct9BytesHomogeneousUint82_a1 = 0;
-int returnStruct9BytesHomogeneousUint82_a2 = 0;
-int returnStruct9BytesHomogeneousUint82_a3 = 0;
-int returnStruct9BytesHomogeneousUint82_a4 = 0;
-int returnStruct9BytesHomogeneousUint82_a5 = 0;
-int returnStruct9BytesHomogeneousUint82_a6 = 0;
-int returnStruct9BytesHomogeneousUint82_a7 = 0;
-int returnStruct9BytesHomogeneousUint82_a8 = 0;
+int returnStruct9BytesHomogeneousUint8_a0 = 0;
+int returnStruct9BytesHomogeneousUint8_a1 = 0;
+int returnStruct9BytesHomogeneousUint8_a2 = 0;
+int returnStruct9BytesHomogeneousUint8_a3 = 0;
+int returnStruct9BytesHomogeneousUint8_a4 = 0;
+int returnStruct9BytesHomogeneousUint8_a5 = 0;
+int returnStruct9BytesHomogeneousUint8_a6 = 0;
+int returnStruct9BytesHomogeneousUint8_a7 = 0;
+int returnStruct9BytesHomogeneousUint8_a8 = 0;
 
 // Result variable also global, so we can delete it after the callback.
-Struct9BytesHomogeneousUint82 returnStruct9BytesHomogeneousUint82Result =
-    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint8 returnStruct9BytesHomogeneousUint8Result =
+    Struct9BytesHomogeneousUint8();
 
-Struct9BytesHomogeneousUint82
-    returnStruct9BytesHomogeneousUint82CalculateResult() {
-  Struct9BytesHomogeneousUint82 result =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
+Struct9BytesHomogeneousUint8
+    returnStruct9BytesHomogeneousUint8CalculateResult() {
+  Struct9BytesHomogeneousUint8 result =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
 
-  result.a0 = returnStruct9BytesHomogeneousUint82_a0;
-  result.a1 = returnStruct9BytesHomogeneousUint82_a1;
-  result.a2 = returnStruct9BytesHomogeneousUint82_a2;
-  result.a3 = returnStruct9BytesHomogeneousUint82_a3;
-  result.a4 = returnStruct9BytesHomogeneousUint82_a4;
-  result.a5 = returnStruct9BytesHomogeneousUint82_a5;
-  result.a6 = returnStruct9BytesHomogeneousUint82_a6;
-  result.a7 = returnStruct9BytesHomogeneousUint82_a7;
-  result.a8 = returnStruct9BytesHomogeneousUint82_a8;
+  result.a0 = returnStruct9BytesHomogeneousUint8_a0;
+  result.a1 = returnStruct9BytesHomogeneousUint8_a1;
+  result.a2 = returnStruct9BytesHomogeneousUint8_a2;
+  result.a3 = returnStruct9BytesHomogeneousUint8_a3;
+  result.a4 = returnStruct9BytesHomogeneousUint8_a4;
+  result.a5 = returnStruct9BytesHomogeneousUint8_a5;
+  result.a6 = returnStruct9BytesHomogeneousUint8_a6;
+  result.a7 = returnStruct9BytesHomogeneousUint8_a7;
+  result.a8 = returnStruct9BytesHomogeneousUint8_a8;
 
-  returnStruct9BytesHomogeneousUint82Result = result;
+  returnStruct9BytesHomogeneousUint8Result = result;
 
   return result;
 }
@@ -4128,10 +4576,10 @@
 /// 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.
-Struct9BytesHomogeneousUint82 returnStruct9BytesHomogeneousUint82(
+Struct9BytesHomogeneousUint8 returnStruct9BytesHomogeneousUint8(
     int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
   print(
-      "returnStruct9BytesHomogeneousUint82(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+      "returnStruct9BytesHomogeneousUint8(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
 
   // In legacy mode, possibly return null.
   if (a0 == 84) {
@@ -4142,34 +4590,97 @@
   // In both nnbd and legacy mode, possibly throw.
   if (a0 == 42 || a0 == 84) {
     print("throwing!");
-    throw Exception("ReturnStruct9BytesHomogeneousUint82 throwing on purpuse!");
+    throw Exception("ReturnStruct9BytesHomogeneousUint8 throwing on purpuse!");
   }
 
-  returnStruct9BytesHomogeneousUint82_a0 = a0;
-  returnStruct9BytesHomogeneousUint82_a1 = a1;
-  returnStruct9BytesHomogeneousUint82_a2 = a2;
-  returnStruct9BytesHomogeneousUint82_a3 = a3;
-  returnStruct9BytesHomogeneousUint82_a4 = a4;
-  returnStruct9BytesHomogeneousUint82_a5 = a5;
-  returnStruct9BytesHomogeneousUint82_a6 = a6;
-  returnStruct9BytesHomogeneousUint82_a7 = a7;
-  returnStruct9BytesHomogeneousUint82_a8 = a8;
+  returnStruct9BytesHomogeneousUint8_a0 = a0;
+  returnStruct9BytesHomogeneousUint8_a1 = a1;
+  returnStruct9BytesHomogeneousUint8_a2 = a2;
+  returnStruct9BytesHomogeneousUint8_a3 = a3;
+  returnStruct9BytesHomogeneousUint8_a4 = a4;
+  returnStruct9BytesHomogeneousUint8_a5 = a5;
+  returnStruct9BytesHomogeneousUint8_a6 = a6;
+  returnStruct9BytesHomogeneousUint8_a7 = a7;
+  returnStruct9BytesHomogeneousUint8_a8 = a8;
 
-  final result = returnStruct9BytesHomogeneousUint82CalculateResult();
+  final result = returnStruct9BytesHomogeneousUint8CalculateResult();
 
   print("result = $result");
 
   return result;
 }
 
-void returnStruct9BytesHomogeneousUint82AfterCallback() {
-  free(returnStruct9BytesHomogeneousUint82Result.addressOf);
+void returnStruct9BytesHomogeneousUint8AfterCallback() {
+  free(returnStruct9BytesHomogeneousUint8Result.addressOf);
 
-  final result = returnStruct9BytesHomogeneousUint82CalculateResult();
+  final result = returnStruct9BytesHomogeneousUint8CalculateResult();
 
   print("after callback result = $result");
 
-  free(returnStruct9BytesHomogeneousUint82Result.addressOf);
+  free(returnStruct9BytesHomogeneousUint8Result.addressOf);
+}
+
+typedef ReturnStruct9BytesInt4Or8ByteAlignedType
+    = Struct9BytesInt4Or8ByteAligned Function(Int64, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct9BytesInt4Or8ByteAligned_a0 = 0;
+int returnStruct9BytesInt4Or8ByteAligned_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct9BytesInt4Or8ByteAligned returnStruct9BytesInt4Or8ByteAlignedResult =
+    Struct9BytesInt4Or8ByteAligned();
+
+Struct9BytesInt4Or8ByteAligned
+    returnStruct9BytesInt4Or8ByteAlignedCalculateResult() {
+  Struct9BytesInt4Or8ByteAligned result =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+
+  result.a0 = returnStruct9BytesInt4Or8ByteAligned_a0;
+  result.a1 = returnStruct9BytesInt4Or8ByteAligned_a1;
+
+  returnStruct9BytesInt4Or8ByteAlignedResult = result;
+
+  return result;
+}
+
+/// Return value in two integer registers on x64.
+/// With alignment rules taken into account size is 12 or 16 bytes.
+Struct9BytesInt4Or8ByteAligned returnStruct9BytesInt4Or8ByteAligned(
+    int a0, int a1) {
+  print("returnStruct9BytesInt4Or8ByteAligned(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStruct9BytesInt4Or8ByteAligned throwing on purpuse!");
+  }
+
+  returnStruct9BytesInt4Or8ByteAligned_a0 = a0;
+  returnStruct9BytesInt4Or8ByteAligned_a1 = a1;
+
+  final result = returnStruct9BytesInt4Or8ByteAlignedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct9BytesInt4Or8ByteAlignedAfterCallback() {
+  free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
+
+  final result = returnStruct9BytesInt4Or8ByteAlignedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
 }
 
 typedef ReturnStruct12BytesHomogeneousFloatType = Struct12BytesHomogeneousFloat
diff --git a/tests/ffi_2/function_structs_by_value_generated_test.dart b/tests/ffi_2/function_structs_by_value_generated_test.dart
index d2c34dd..a548274 100644
--- a/tests/ffi_2/function_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_test.dart
@@ -21,14 +21,16 @@
 void main() {
   for (int i = 0; i < 10; ++i) {
     testPassStruct1ByteIntx10();
-    testPassStruct3BytesIntx10();
+    testPassStruct3BytesHomogeneousUint8x10();
+    testPassStruct3BytesInt2ByteAlignedx10();
     testPassStruct4BytesHomogeneousInt16x10();
-    testPassStruct7BytesIntx10();
+    testPassStruct7BytesHomogeneousUint8x10();
+    testPassStruct7BytesInt4ByteAlignedx10();
     testPassStruct8BytesIntx10();
     testPassStruct8BytesHomogeneousFloatx10();
     testPassStruct8BytesMixedx10();
-    testPassStruct9BytesIntx10();
-    testPassStruct9BytesHomogeneousUint82x10();
+    testPassStruct9BytesHomogeneousUint8x10();
+    testPassStruct9BytesInt4Or8ByteAlignedx10();
     testPassStruct12BytesHomogeneousFloatx6();
     testPassStruct16BytesHomogeneousFloatx5();
     testPassStruct16BytesMixedx10();
@@ -50,14 +52,16 @@
     testPassStructAlignmentInt32();
     testPassStructAlignmentInt64();
     testReturnStruct1ByteInt();
-    testReturnStruct3BytesInt();
+    testReturnStruct3BytesHomogeneousUint8();
+    testReturnStruct3BytesInt2ByteAligned();
     testReturnStruct4BytesHomogeneousInt16();
-    testReturnStruct7BytesInt();
+    testReturnStruct7BytesHomogeneousUint8();
+    testReturnStruct7BytesInt4ByteAligned();
     testReturnStruct8BytesInt();
     testReturnStruct8BytesHomogeneousFloat();
     testReturnStruct8BytesMixed();
-    testReturnStruct9BytesInt();
-    testReturnStruct9BytesHomogeneousUint82();
+    testReturnStruct9BytesHomogeneousUint8();
+    testReturnStruct9BytesInt4Or8ByteAligned();
     testReturnStruct12BytesHomogeneousFloat();
     testReturnStruct16BytesHomogeneousFloat();
     testReturnStruct16BytesMixed();
@@ -91,7 +95,20 @@
   String toString() => "(${a0})";
 }
 
-class Struct3BytesInt extends Struct {
+class Struct3BytesHomogeneousUint8 extends Struct {
+  @Uint8()
+  int a0;
+
+  @Uint8()
+  int a1;
+
+  @Uint8()
+  int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct3BytesInt2ByteAligned extends Struct {
   @Int16()
   int a0;
 
@@ -111,7 +128,32 @@
   String toString() => "(${a0}, ${a1})";
 }
 
-class Struct7BytesInt extends Struct {
+class Struct7BytesHomogeneousUint8 extends Struct {
+  @Uint8()
+  int a0;
+
+  @Uint8()
+  int a1;
+
+  @Uint8()
+  int a2;
+
+  @Uint8()
+  int a3;
+
+  @Uint8()
+  int a4;
+
+  @Uint8()
+  int a5;
+
+  @Uint8()
+  int a6;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6})";
+}
+
+class Struct7BytesInt4ByteAligned extends Struct {
   @Int32()
   int a0;
 
@@ -160,17 +202,7 @@
   String toString() => "(${a0}, ${a1}, ${a2})";
 }
 
-class Struct9BytesInt extends Struct {
-  @Int64()
-  int a0;
-
-  @Int8()
-  int a1;
-
-  String toString() => "(${a0}, ${a1})";
-}
-
-class Struct9BytesHomogeneousUint82 extends Struct {
+class Struct9BytesHomogeneousUint8 extends Struct {
   @Uint8()
   int a0;
 
@@ -202,6 +234,16 @@
       "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})";
 }
 
+class Struct9BytesInt4Or8ByteAligned extends Struct {
+  @Int64()
+  int a0;
+
+  @Int8()
+  int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
 class Struct12BytesHomogeneousFloat extends Struct {
   @Float()
   double a0;
@@ -900,43 +942,142 @@
   free(a9.addressOf);
 }
 
-final passStruct3BytesIntx10 = ffiTestFunctions.lookupFunction<
+final passStruct3BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
     Int64 Function(
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt),
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8),
     int Function(
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt,
-        Struct3BytesInt)>("PassStruct3BytesIntx10");
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8,
+        Struct3BytesHomogeneousUint8)>("PassStruct3BytesHomogeneousUint8x10");
 
 /// Not a multiple of word size, not a power of two.
 /// 10 struct arguments will exhaust available registers.
-void testPassStruct3BytesIntx10() {
-  Struct3BytesInt a0 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a1 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a2 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a3 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a4 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a5 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a6 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a7 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a8 = allocate<Struct3BytesInt>().ref;
-  Struct3BytesInt a9 = allocate<Struct3BytesInt>().ref;
+void testPassStruct3BytesHomogeneousUint8x10() {
+  Struct3BytesHomogeneousUint8 a0 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a1 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a2 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a3 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a4 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a5 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a6 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a7 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a8 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+  Struct3BytesHomogeneousUint8 a9 =
+      allocate<Struct3BytesHomogeneousUint8>().ref;
+
+  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;
+
+  final result = passStruct3BytesHomogeneousUint8x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(465, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct3BytesInt2ByteAlignedx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned),
+    int Function(
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned,
+        Struct3BytesInt2ByteAligned)>("PassStruct3BytesInt2ByteAlignedx10");
+
+/// 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.
+void testPassStruct3BytesInt2ByteAlignedx10() {
+  Struct3BytesInt2ByteAligned a0 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a1 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a2 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a3 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a4 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a5 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a6 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a7 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a8 = allocate<Struct3BytesInt2ByteAligned>().ref;
+  Struct3BytesInt2ByteAligned a9 = allocate<Struct3BytesInt2ByteAligned>().ref;
 
   a0.a0 = -1;
   a0.a1 = 2;
@@ -959,7 +1100,8 @@
   a9.a0 = -19;
   a9.a1 = 20;
 
-  final result = passStruct3BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  final result = passStruct3BytesInt2ByteAlignedx10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 
   print("result = $result");
 
@@ -1065,43 +1207,182 @@
   free(a9.addressOf);
 }
 
-final passStruct7BytesIntx10 = ffiTestFunctions.lookupFunction<
+final passStruct7BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
     Int64 Function(
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt),
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8),
     int Function(
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt,
-        Struct7BytesInt)>("PassStruct7BytesIntx10");
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8,
+        Struct7BytesHomogeneousUint8)>("PassStruct7BytesHomogeneousUint8x10");
 
 /// Sub word size on 64 bit architectures.
 /// 10 struct arguments will exhaust available registers.
-void testPassStruct7BytesIntx10() {
-  Struct7BytesInt a0 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a1 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a2 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a3 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a4 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a5 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a6 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a7 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a8 = allocate<Struct7BytesInt>().ref;
-  Struct7BytesInt a9 = allocate<Struct7BytesInt>().ref;
+void testPassStruct7BytesHomogeneousUint8x10() {
+  Struct7BytesHomogeneousUint8 a0 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a1 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a2 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a3 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a4 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a5 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a6 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a7 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a8 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+  Struct7BytesHomogeneousUint8 a9 =
+      allocate<Struct7BytesHomogeneousUint8>().ref;
+
+  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;
+
+  final result = passStruct7BytesHomogeneousUint8x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(2485, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct7BytesInt4ByteAlignedx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned),
+    int Function(
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned,
+        Struct7BytesInt4ByteAligned)>("PassStruct7BytesInt4ByteAlignedx10");
+
+/// Sub word size on 64 bit architectures.
+/// With alignment rules taken into account size is 8 bytes.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct7BytesInt4ByteAlignedx10() {
+  Struct7BytesInt4ByteAligned a0 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a1 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a2 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a3 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a4 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a5 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a6 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a7 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a8 = allocate<Struct7BytesInt4ByteAligned>().ref;
+  Struct7BytesInt4ByteAligned a9 = allocate<Struct7BytesInt4ByteAligned>().ref;
 
   a0.a0 = -1;
   a0.a1 = 2;
@@ -1134,7 +1415,8 @@
   a9.a1 = -29;
   a9.a2 = 30;
 
-  final result = passStruct7BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  final result = passStruct7BytesInt4ByteAlignedx10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 
   print("result = $result");
 
@@ -1415,134 +1697,56 @@
   free(a9.addressOf);
 }
 
-final passStruct9BytesIntx10 = ffiTestFunctions.lookupFunction<
+final passStruct9BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
     Int64 Function(
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt),
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8),
     int Function(
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt,
-        Struct9BytesInt)>("PassStruct9BytesIntx10");
-
-/// Argument is a single byte over a multiple of word size.
-/// 10 struct arguments will exhaust available registers.
-/// Tests upper bytes in the integer registers that are partly filled.
-/// Tests stack alignment of non word size stack arguments.
-void testPassStruct9BytesIntx10() {
-  Struct9BytesInt a0 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a1 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a2 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a3 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a4 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a5 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a6 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a7 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a8 = allocate<Struct9BytesInt>().ref;
-  Struct9BytesInt a9 = allocate<Struct9BytesInt>().ref;
-
-  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;
-
-  final result = passStruct9BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
-
-  print("result = $result");
-
-  Expect.equals(10, result);
-
-  free(a0.addressOf);
-  free(a1.addressOf);
-  free(a2.addressOf);
-  free(a3.addressOf);
-  free(a4.addressOf);
-  free(a5.addressOf);
-  free(a6.addressOf);
-  free(a7.addressOf);
-  free(a8.addressOf);
-  free(a9.addressOf);
-}
-
-final passStruct9BytesHomogeneousUint82x10 = ffiTestFunctions.lookupFunction<
-    Int64 Function(
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82),
-    int Function(
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82,
-        Struct9BytesHomogeneousUint82)>("PassStruct9BytesHomogeneousUint82x10");
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8,
+        Struct9BytesHomogeneousUint8)>("PassStruct9BytesHomogeneousUint8x10");
 
 /// 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.
-///
-void testPassStruct9BytesHomogeneousUint82x10() {
-  Struct9BytesHomogeneousUint82 a0 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a1 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a2 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a3 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a4 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a5 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a6 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a7 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a8 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
-  Struct9BytesHomogeneousUint82 a9 =
-      allocate<Struct9BytesHomogeneousUint82>().ref;
+/// Tests upper bytes in the integer registers that are partly filled.
+/// Tests stack alignment of non word size stack arguments.
+void testPassStruct9BytesHomogeneousUint8x10() {
+  Struct9BytesHomogeneousUint8 a0 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a1 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a2 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a3 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a4 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a5 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a6 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a7 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a8 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
+  Struct9BytesHomogeneousUint8 a9 =
+      allocate<Struct9BytesHomogeneousUint8>().ref;
 
   a0.a0 = 1;
   a0.a1 = 2;
@@ -1635,7 +1839,7 @@
   a9.a7 = 89;
   a9.a8 = 90;
 
-  final result = passStruct9BytesHomogeneousUint82x10(
+  final result = passStruct9BytesHomogeneousUint8x10(
       a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 
   print("result = $result");
@@ -1654,6 +1858,97 @@
   free(a9.addressOf);
 }
 
+final passStruct9BytesInt4Or8ByteAlignedx10 = ffiTestFunctions.lookupFunction<
+        Int64 Function(
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned),
+        int Function(
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned,
+            Struct9BytesInt4Or8ByteAligned)>(
+    "PassStruct9BytesInt4Or8ByteAlignedx10");
+
+/// 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.
+///
+void testPassStruct9BytesInt4Or8ByteAlignedx10() {
+  Struct9BytesInt4Or8ByteAligned a0 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a1 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a2 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a3 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a4 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a5 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a6 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a7 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a8 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+  Struct9BytesInt4Or8ByteAligned a9 =
+      allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+
+  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;
+
+  final result = passStruct9BytesInt4Or8ByteAlignedx10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
 final passStruct12BytesHomogeneousFloatx6 = ffiTestFunctions.lookupFunction<
     Float Function(
         Struct12BytesHomogeneousFloat,
@@ -3142,19 +3437,45 @@
   Expect.equals(a0, result.a0);
 }
 
-final returnStruct3BytesInt = ffiTestFunctions.lookupFunction<
-    Struct3BytesInt Function(Int16, Int8),
-    Struct3BytesInt Function(int, int)>("ReturnStruct3BytesInt");
+final returnStruct3BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
+    Struct3BytesHomogeneousUint8 Function(Uint8, Uint8, Uint8),
+    Struct3BytesHomogeneousUint8 Function(
+        int, int, int)>("ReturnStruct3BytesHomogeneousUint8");
 
 /// Smaller than word size return value on all architectures.
-void testReturnStruct3BytesInt() {
+void testReturnStruct3BytesHomogeneousUint8() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+
+  final result = returnStruct3BytesHomogeneousUint8(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct3BytesInt2ByteAligned = ffiTestFunctions.lookupFunction<
+    Struct3BytesInt2ByteAligned Function(Int16, Int8),
+    Struct3BytesInt2ByteAligned Function(
+        int, int)>("ReturnStruct3BytesInt2ByteAligned");
+
+/// Smaller than word size return value on all architectures.
+/// With alignment rules taken into account size is 4 bytes.
+void testReturnStruct3BytesInt2ByteAligned() {
   int a0;
   int a1;
 
   a0 = -1;
   a1 = 2;
 
-  final result = returnStruct3BytesInt(a0, a1);
+  final result = returnStruct3BytesInt2ByteAligned(a0, a1);
 
   print("result = $result");
 
@@ -3183,12 +3504,51 @@
   Expect.equals(a1, result.a1);
 }
 
-final returnStruct7BytesInt = ffiTestFunctions.lookupFunction<
-    Struct7BytesInt Function(Int32, Int16, Int8),
-    Struct7BytesInt Function(int, int, int)>("ReturnStruct7BytesInt");
+final returnStruct7BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
+    Struct7BytesHomogeneousUint8 Function(
+        Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8),
+    Struct7BytesHomogeneousUint8 Function(int, int, int, int, int, int,
+        int)>("ReturnStruct7BytesHomogeneousUint8");
 
 /// Non-wordsize return value.
-void testReturnStruct7BytesInt() {
+void testReturnStruct7BytesHomogeneousUint8() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+
+  final result = returnStruct7BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+  Expect.equals(a5, result.a5);
+  Expect.equals(a6, result.a6);
+}
+
+final returnStruct7BytesInt4ByteAligned = ffiTestFunctions.lookupFunction<
+    Struct7BytesInt4ByteAligned Function(Int32, Int16, Int8),
+    Struct7BytesInt4ByteAligned Function(
+        int, int, int)>("ReturnStruct7BytesInt4ByteAligned");
+
+/// Non-wordsize return value.
+/// With alignment rules taken into account size is 8 bytes.
+void testReturnStruct7BytesInt4ByteAligned() {
   int a0;
   int a1;
   int a2;
@@ -3197,7 +3557,7 @@
   a1 = 2;
   a2 = -3;
 
-  final result = returnStruct7BytesInt(a0, a1, a2);
+  final result = returnStruct7BytesInt4ByteAligned(a0, a1, a2);
 
   print("result = $result");
 
@@ -3273,37 +3633,16 @@
   Expect.equals(a2, result.a2);
 }
 
-final returnStruct9BytesInt = ffiTestFunctions.lookupFunction<
-    Struct9BytesInt Function(Int64, Int8),
-    Struct9BytesInt Function(int, int)>("ReturnStruct9BytesInt");
-
-/// Return value in two integer registers on x64.
-/// The second register only contains a single byte.
-void testReturnStruct9BytesInt() {
-  int a0;
-  int a1;
-
-  a0 = -1;
-  a1 = 2;
-
-  final result = returnStruct9BytesInt(a0, a1);
-
-  print("result = $result");
-
-  Expect.equals(a0, result.a0);
-  Expect.equals(a1, result.a1);
-}
-
-final returnStruct9BytesHomogeneousUint82 = ffiTestFunctions.lookupFunction<
-    Struct9BytesHomogeneousUint82 Function(
+final returnStruct9BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
+    Struct9BytesHomogeneousUint8 Function(
         Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8),
-    Struct9BytesHomogeneousUint82 Function(int, int, int, int, int, int, int,
-        int, int)>("ReturnStruct9BytesHomogeneousUint82");
+    Struct9BytesHomogeneousUint8 Function(int, int, int, int, int, int, int,
+        int, int)>("ReturnStruct9BytesHomogeneousUint8");
 
 /// 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.
-void testReturnStruct9BytesHomogeneousUint82() {
+void testReturnStruct9BytesHomogeneousUint8() {
   int a0;
   int a1;
   int a2;
@@ -3325,7 +3664,7 @@
   a8 = 9;
 
   final result =
-      returnStruct9BytesHomogeneousUint82(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+      returnStruct9BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6, a7, a8);
 
   print("result = $result");
 
@@ -3340,6 +3679,28 @@
   Expect.equals(a8, result.a8);
 }
 
+final returnStruct9BytesInt4Or8ByteAligned = ffiTestFunctions.lookupFunction<
+    Struct9BytesInt4Or8ByteAligned Function(Int64, Int8),
+    Struct9BytesInt4Or8ByteAligned Function(
+        int, int)>("ReturnStruct9BytesInt4Or8ByteAligned");
+
+/// Return value in two integer registers on x64.
+/// With alignment rules taken into account size is 12 or 16 bytes.
+void testReturnStruct9BytesInt4Or8ByteAligned() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct9BytesInt4Or8ByteAligned(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
 final returnStruct12BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
     Struct12BytesHomogeneousFloat Function(Float, Float, Float),
     Struct12BytesHomogeneousFloat Function(
diff --git a/tests/ffi_2/generator/structs_by_value_tests_confguration.dart b/tests/ffi_2/generator/structs_by_value_tests_confguration.dart
deleted file mode 100644
index 487a68e..0000000
--- a/tests/ffi_2/generator/structs_by_value_tests_confguration.dart
+++ /dev/null
@@ -1,373 +0,0 @@
-// 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.
-
-import 'c_types.dart';
-
-final functions = [
-  FunctionType(List.filled(10, struct1byteInt), int64, """
-Smallest struct with data.
-10 struct arguments will exhaust available registers."""),
-  FunctionType(List.filled(10, struct3bytesInt), int64, """
-Not a multiple of word size, not a power of two.
-10 struct arguments will exhaust available registers."""),
-  FunctionType(List.filled(10, struct4bytesInt), int64, """
-Exactly word size on 32-bit architectures.
-10 struct arguments will exhaust available registers."""),
-  FunctionType(List.filled(10, struct7bytesInt), int64, """
-Sub word size on 64 bit architectures.
-10 struct arguments will exhaust available registers."""),
-  FunctionType(List.filled(10, struct8bytesInt), int64, """
-Exactly word size struct on 64bit architectures.
-10 struct arguments will exhaust available registers."""),
-  FunctionType(List.filled(10, struct8bytesFloat), float, """
-Arguments passed in FP registers as long as they fit.
-10 struct arguments will exhaust available registers."""),
-  FunctionType(List.filled(10, struct8BytesMixed), float, """
-On x64, arguments go in int registers because it is not only float.
-10 struct arguments will exhaust available registers."""),
-  FunctionType(List.filled(10, struct9bytesInt), int64, """
-Argument is a single byte over a multiple of word size.
-10 struct arguments will exhaust available registers.
-Tests upper bytes in the integer registers that are partly filled.
-Tests stack alignment of non word size stack arguments."""),
-  FunctionType(List.filled(10, struct9bytesInt2), int64, """
-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.
-"""),
-  FunctionType(List.filled(6, struct12bytesFloat), float, """
-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."""),
-  FunctionType(List.filled(5, struct16bytesFloat), float, """
-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."""),
-  FunctionType(List.filled(10, struct16bytesMixed), double_, """
-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."""),
-  FunctionType(List.filled(10, struct16bytesMixed2), float, """
-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."""),
-  FunctionType(List.filled(10, struct17bytesInt), int64, """
-Arguments are passed as pointer to copy on arm64.
-Tests that the memory allocated for copies are rounded up to word size."""),
-  FunctionType(List.filled(10, struct19bytesInt), int64, """
-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.
-"""),
-  FunctionType(List.filled(10, struct20bytesInt), int32, """
-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."""),
-  FunctionType(
-      [struct20bytesFloat],
-      float,
-      """
-Argument too big to go into FPU registers in hardfp and arm64."""),
-  FunctionType(List.filled(5, struct32bytesDouble), double_, """
-Arguments in FPU registers on arm64.
-5 struct arguments will exhaust available registers."""),
-  FunctionType(
-      [struct40bytesDouble],
-      double_,
-      """
-Argument too big to go into FPU registers in arm64."""),
-  FunctionType(
-      [struct1024bytesInt],
-      uint64,
-      """
-Test 1kb struct."""),
-  FunctionType(
-      [
-        float,
-        struct16bytesFloat,
-        float,
-        struct16bytesFloat,
-        float,
-        struct16bytesFloat,
-        float,
-        struct16bytesFloat,
-        float
-      ],
-      float,
-      """
-Tests the alignment of structs in FPU registers and backfilling."""),
-  FunctionType(
-      [
-        float,
-        struct32bytesDouble,
-        float,
-        struct32bytesDouble,
-        float,
-        struct32bytesDouble,
-        float,
-        struct32bytesDouble,
-        float
-      ],
-      double_,
-      """
-Tests the alignment of structs in FPU registers and backfilling."""),
-  FunctionType(
-      [
-        int8,
-        struct16bytesMixed,
-        int8,
-        struct16bytesMixed,
-        int8,
-        struct16bytesMixed,
-        int8,
-        struct16bytesMixed,
-        int8
-      ],
-      double_,
-      """
-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."""),
-  FunctionType(
-      [
-        double_,
-        double_,
-        double_,
-        double_,
-        double_,
-        double_,
-        struct16bytesMixed,
-        struct16bytesMixed,
-        struct16bytesMixed,
-        struct16bytesMixed,
-        int32,
-      ],
-      double_,
-      """
-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."""),
-  FunctionType(
-      [
-        int32,
-        int32,
-        int32,
-        int32,
-        struct16bytesMixed,
-        struct16bytesMixed,
-        struct16bytesMixed,
-        struct16bytesMixed,
-        double_,
-      ],
-      double_,
-      """
-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."""),
-  FunctionType(
-      [
-        struct40bytesDouble,
-        struct4bytesInt,
-        struct8bytesFloat,
-      ],
-      double_,
-      """
-On various architectures, first struct is allocated on stack.
-Check that the other two arguments are allocated on registers."""),
-  FunctionType(
-      [structAlignmentInt16],
-      int64,
-      """
-Test alignment and padding of 16 byte int within struct."""),
-  FunctionType(
-      [structAlignmentInt32],
-      int64,
-      """
-Test alignment and padding of 32 byte int within struct."""),
-  FunctionType(
-      [structAlignmentInt64],
-      int64,
-      """
-Test alignment and padding of 64 byte int within struct."""),
-  FunctionType(struct1byteInt.memberTypes, struct1byteInt, """
-Smallest struct with data."""),
-  FunctionType(struct3bytesInt.memberTypes, struct3bytesInt, """
-Smaller than word size return value on all architectures."""),
-  FunctionType(struct4bytesInt.memberTypes, struct4bytesInt, """
-Word size return value on 32 bit architectures.."""),
-  FunctionType(struct7bytesInt.memberTypes, struct7bytesInt, """
-Non-wordsize return value."""),
-  FunctionType(struct8bytesInt.memberTypes, struct8bytesInt, """
-Return value in integer registers on many architectures."""),
-  FunctionType(struct8bytesFloat.memberTypes, struct8bytesFloat, """
-Return value in FP registers on many architectures."""),
-  FunctionType(struct8BytesMixed.memberTypes, struct8BytesMixed, """
-Return value split over FP and integer register in x64."""),
-  FunctionType(struct9bytesInt.memberTypes, struct9bytesInt, """
-Return value in two integer registers on x64.
-The second register only contains a single byte."""),
-  FunctionType(struct9bytesInt2.memberTypes, struct9bytesInt2, """
-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."""),
-  FunctionType(struct12bytesFloat.memberTypes, struct12bytesFloat, """
-Return value in FPU registers, but does not use all registers on arm hardfp
-and arm64."""),
-  FunctionType(struct16bytesFloat.memberTypes, struct16bytesFloat, """
-Return value in FPU registers on arm hardfp and arm64."""),
-  FunctionType(struct16bytesMixed.memberTypes, struct16bytesMixed, """
-Return value split over FP and integer register in x64."""),
-  FunctionType(struct16bytesMixed2.memberTypes, struct16bytesMixed2, """
-Return value split over FP and integer register in x64.
-The integer register contains half float half int."""),
-  FunctionType(struct17bytesInt.memberTypes, struct17bytesInt, """
-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."""),
-  FunctionType(struct19bytesInt.memberTypes, struct19bytesInt, """
-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."""),
-  FunctionType(struct20bytesInt.memberTypes, struct20bytesInt, """
-Return value too big to go in cpu registers on arm64."""),
-  FunctionType(struct20bytesFloat.memberTypes, struct20bytesFloat, """
-Return value too big to go in FPU registers on x64, arm hardfp and arm64."""),
-  FunctionType(struct32bytesDouble.memberTypes, struct32bytesDouble, """
-Return value in FPU registers on arm64."""),
-  FunctionType(struct40bytesDouble.memberTypes, struct40bytesDouble, """
-Return value too big to go in FPU registers on arm64."""),
-  FunctionType(struct1024bytesInt.memberTypes, struct1024bytesInt, """
-Test 1kb struct."""),
-  FunctionType(
-      [struct1byteInt],
-      struct1byteInt,
-      """
-Test that a struct passed in as argument can be returned.
-Especially for ffi callbacks.
-Struct is passed in int registers in most ABIs."""),
-  FunctionType(
-      [int32, int32, int32, int32, int32, int32, int32, int32, struct1byteInt],
-      struct1byteInt,
-      """
-Test that a struct passed in as argument can be returned.
-Especially for ffi callbacks.
-Struct is passed on stack on all ABIs."""),
-  FunctionType(
-      [struct8bytesFloat],
-      struct8bytesFloat,
-      """
-Test that a struct passed in as argument can be returned.
-Especially for ffi callbacks.
-Struct is passed in float registers in most ABIs."""),
-  FunctionType(
-      [struct20bytesInt],
-      struct20bytesInt,
-      """
-On arm64, both argument and return value are passed in by pointer."""),
-  FunctionType(
-      [
-        int32,
-        int32,
-        int32,
-        int32,
-        int32,
-        int32,
-        int32,
-        int32,
-        struct20bytesInt
-      ],
-      struct20bytesInt,
-      """
-On arm64, both argument and return value are passed in by pointer.
-Ints exhaust registers, so that pointer is passed on stack."""),
-  FunctionType(structAlignmentInt16.memberTypes, structAlignmentInt16, """
-Test alignment and padding of 16 byte int within struct."""),
-  FunctionType(structAlignmentInt32.memberTypes, structAlignmentInt32, """
-Test alignment and padding of 32 byte int within struct."""),
-  FunctionType(structAlignmentInt64.memberTypes, structAlignmentInt64, """
-Test alignment and padding of 64 byte int within struct."""),
-];
-
-final structs = [
-  struct0bytes,
-  struct1byteInt,
-  struct3bytesInt,
-  struct4bytesInt,
-  struct7bytesInt,
-  struct8bytesInt,
-  struct8bytesFloat,
-  struct8BytesMixed,
-  struct9bytesInt,
-  struct9bytesInt2,
-  struct12bytesFloat,
-  struct16bytesFloat,
-  struct16bytesMixed,
-  struct16bytesMixed2,
-  struct17bytesInt,
-  struct19bytesInt,
-  struct20bytesInt,
-  struct20bytesFloat,
-  struct32bytesDouble,
-  struct40bytesDouble,
-  struct1024bytesInt,
-  structAlignmentInt16,
-  structAlignmentInt32,
-  structAlignmentInt64,
-];
-
-/// Using empty structs is undefined behavior in C.
-final struct0bytes = StructType([]);
-
-final struct1byteInt = StructType([int8]);
-final struct3bytesInt = StructType([int16, int8]);
-final struct4bytesInt = StructType([int16, int16]);
-final struct7bytesInt = StructType([int32, int16, int8]);
-final struct8bytesInt = StructType([int16, int16, int32]);
-final struct8bytesFloat = StructType([float, float]);
-final struct8BytesMixed = StructType([float, int16, int16]);
-final struct9bytesInt = StructType([int64, int8]);
-final struct9bytesInt2 = StructType.disambiguate(List.filled(9, uint8), "2");
-final struct12bytesFloat = StructType([float, float, float]);
-
-/// The largest homogenous float that goes into FPU registers on softfp and
-/// arm64.
-final struct16bytesFloat = StructType([float, float, float, float]);
-
-/// This struct will be 8 byte aligned on arm.
-final struct16bytesMixed = StructType([double_, int64]);
-
-/// This struct will be 4 byte aligned on arm.
-final struct16bytesMixed2 =
-    StructType.disambiguate([float, float, float, int32], "2");
-
-final struct17bytesInt = StructType([int64, int64, int8]);
-
-/// This struct has only 1 byte field-alignmnent requirements.
-final struct19bytesInt = StructType(List.filled(19, uint8));
-
-/// The first homogenous integer struct that does not go into registers
-/// anymore on arm64.
-final struct20bytesInt = StructType([int32, int32, int32, int32, int32]);
-
-/// The first homogenous float that does not go into FPU registers anymore on
-/// softfp and arm64.
-final struct20bytesFloat = StructType([float, float, float, float, float]);
-
-/// Largest homogenous doubles in arm64 that goes into FPU registers.
-final struct32bytesDouble = StructType([double_, double_, double_, double_]);
-
-/// The first homogenous doubles that does not go into FPU registers anymore on
-/// arm64.
-final struct40bytesDouble =
-    StructType([double_, double_, double_, double_, double_]);
-
-final struct1024bytesInt = StructType(List.filled(128, uint64));
-
-final structAlignmentInt16 = StructType([int8, int16, int8]);
-final structAlignmentInt32 = StructType([int8, int32, int8]);
-final structAlignmentInt64 = StructType([int8, int64, int8]);
diff --git a/tests/ffi/generator/structs_by_value_tests_confguration.dart b/tests/ffi_2/generator/structs_by_value_tests_configuration.dart
similarity index 90%
copy from tests/ffi/generator/structs_by_value_tests_confguration.dart
copy to tests/ffi_2/generator/structs_by_value_tests_configuration.dart
index 487a68e..5ea4cff 100644
--- a/tests/ffi/generator/structs_by_value_tests_confguration.dart
+++ b/tests/ffi_2/generator/structs_by_value_tests_configuration.dart
@@ -11,12 +11,20 @@
   FunctionType(List.filled(10, struct3bytesInt), int64, """
 Not a multiple of word size, not a power of two.
 10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct3bytesInt2), int64, """
+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."""),
   FunctionType(List.filled(10, struct4bytesInt), int64, """
 Exactly word size on 32-bit architectures.
 10 struct arguments will exhaust available registers."""),
   FunctionType(List.filled(10, struct7bytesInt), int64, """
 Sub word size on 64 bit architectures.
 10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct7bytesInt2), int64, """
+Sub word size on 64 bit architectures.
+With alignment rules taken into account size is 8 bytes.
+10 struct arguments will exhaust available registers."""),
   FunctionType(List.filled(10, struct8bytesInt), int64, """
 Exactly word size struct on 64bit architectures.
 10 struct arguments will exhaust available registers."""),
@@ -29,12 +37,13 @@
   FunctionType(List.filled(10, struct9bytesInt), int64, """
 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."""),
   FunctionType(List.filled(10, struct9bytesInt2), int64, """
 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.
-Struct only has 1-byte aligned fields to test struct alignment itself.
 """),
   FunctionType(List.filled(6, struct12bytesFloat), float, """
 Arguments in FPU registers on arm hardfp and arm64.
@@ -198,10 +207,16 @@
 Smallest struct with data."""),
   FunctionType(struct3bytesInt.memberTypes, struct3bytesInt, """
 Smaller than word size return value on all architectures."""),
+  FunctionType(struct3bytesInt2.memberTypes, struct3bytesInt2, """
+Smaller than word size return value on all architectures.
+With alignment rules taken into account size is 4 bytes."""),
   FunctionType(struct4bytesInt.memberTypes, struct4bytesInt, """
 Word size return value on 32 bit architectures.."""),
   FunctionType(struct7bytesInt.memberTypes, struct7bytesInt, """
 Non-wordsize return value."""),
+  FunctionType(struct7bytesInt2.memberTypes, struct7bytesInt2, """
+Non-wordsize return value.
+With alignment rules taken into account size is 8 bytes."""),
   FunctionType(struct8bytesInt.memberTypes, struct8bytesInt, """
 Return value in integer registers on many architectures."""),
   FunctionType(struct8bytesFloat.memberTypes, struct8bytesFloat, """
@@ -209,12 +224,12 @@
   FunctionType(struct8BytesMixed.memberTypes, struct8BytesMixed, """
 Return value split over FP and integer register in x64."""),
   FunctionType(struct9bytesInt.memberTypes, struct9bytesInt, """
-Return value in two integer registers on x64.
-The second register only contains a single byte."""),
-  FunctionType(struct9bytesInt2.memberTypes, struct9bytesInt2, """
 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."""),
+  FunctionType(struct9bytesInt2.memberTypes, struct9bytesInt2, """
+Return value in two integer registers on x64.
+With alignment rules taken into account size is 12 or 16 bytes."""),
   FunctionType(struct12bytesFloat.memberTypes, struct12bytesFloat, """
 Return value in FPU registers, but does not use all registers on arm hardfp
 and arm64."""),
@@ -297,8 +312,10 @@
   struct0bytes,
   struct1byteInt,
   struct3bytesInt,
+  struct3bytesInt2,
   struct4bytesInt,
   struct7bytesInt,
+  struct7bytesInt2,
   struct8bytesInt,
   struct8bytesFloat,
   struct8BytesMixed,
@@ -324,14 +341,18 @@
 final struct0bytes = StructType([]);
 
 final struct1byteInt = StructType([int8]);
-final struct3bytesInt = StructType([int16, int8]);
+final struct3bytesInt = StructType(List.filled(3, uint8));
+final struct3bytesInt2 = StructType.disambiguate([int16, int8], "2ByteAligned");
 final struct4bytesInt = StructType([int16, int16]);
-final struct7bytesInt = StructType([int32, int16, int8]);
+final struct7bytesInt = StructType(List.filled(7, uint8));
+final struct7bytesInt2 =
+    StructType.disambiguate([int32, int16, int8], "4ByteAligned");
 final struct8bytesInt = StructType([int16, int16, int32]);
 final struct8bytesFloat = StructType([float, float]);
 final struct8BytesMixed = StructType([float, int16, int16]);
-final struct9bytesInt = StructType([int64, int8]);
-final struct9bytesInt2 = StructType.disambiguate(List.filled(9, uint8), "2");
+final struct9bytesInt = StructType(List.filled(9, uint8));
+final struct9bytesInt2 =
+    StructType.disambiguate([int64, int8], "4Or8ByteAligned");
 final struct12bytesFloat = StructType([float, float, float]);
 
 /// The largest homogenous float that goes into FPU registers on softfp and
diff --git a/tests/ffi_2/generator/structs_by_value_tests_generator.dart b/tests/ffi_2/generator/structs_by_value_tests_generator.dart
index e233753..f3f9f02 100644
--- a/tests/ffi_2/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi_2/generator/structs_by_value_tests_generator.dart
@@ -5,7 +5,7 @@
 import 'dart:io';
 
 import 'c_types.dart';
-import 'structs_by_value_tests_confguration.dart';
+import 'structs_by_value_tests_configuration.dart';
 import 'utils.dart';
 
 /// The test type determines how to convert the arguments into return values