aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog133
-rw-r--r--gcc/testsuite/c-c++-common/pr60439.c96
-rw-r--r--gcc/testsuite/c-c++-common/pr66322.c144
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-friend-3.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/udlit-utf8char.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/utf8-neg.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/utf8.C15
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/tls1.C7
-rw-r--r--gcc/testsuite/g++.dg/eh/scope1.C2
-rw-r--r--gcc/testsuite/g++.dg/template/pr66686.C15
-rw-r--r--gcc/testsuite/g++.dg/tls/tls_model1.C8
-rw-r--r--gcc/testsuite/gcc.dg/fold-ior-2.c47
-rw-r--r--gcc/testsuite/gcc.dg/fold-ior-3.c35
-rw-r--r--gcc/testsuite/gcc.dg/fold-minus-6.c42
-rw-r--r--gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-5.c22
-rw-r--r--gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-6.c22
-rw-r--r--gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-7.c22
-rw-r--r--gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c31
-rw-r--r--gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c21
-rw-r--r--gcc/testsuite/gcc.target/arm/armv8-sync-comp-swap.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/armv8-sync-op-acquire.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/armv8-sync-op-full.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/armv8-sync-op-release.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/asm-flag-0.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/asm-flag-1.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/asm-flag-2.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/asm-flag-3.c22
-rw-r--r--gcc/testsuite/gcc.target/i386/asm-flag-4.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/asm-flag-5.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/abi-iamcu.exp42
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/args.h77
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/asm-support.S302
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/defines.h110
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/macros.h53
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_3_element_struct_and_unions.c521
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_basic_64bit_returning.c57
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_basic_alignment.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_basic_array_size_and_align.c32
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_basic_returning.c52
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_basic_sizes.c36
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_basic_struct_size_and_align.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_basic_union_size_and_align.c32
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_bitfields.c162
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_complex_returning.c83
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_passing_floats.c608
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_passing_integers.c182
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c237
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs_and_unions.c97
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_passing_unions.c221
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_struct_returning.c362
-rw-r--r--gcc/testsuite/gcc.target/i386/iamcu/test_varargs.c101
-rw-r--r--gcc/testsuite/gcc.target/i386/pr66691.c64
-rw-r--r--gcc/testsuite/gfortran.dg/wunused-parameter.f9015
-rw-r--r--gcc/testsuite/gnat.dg/lto17.adb12
-rw-r--r--gcc/testsuite/gnat.dg/lto17.ads20
-rw-r--r--gcc/testsuite/jit.dg/all-non-failing-tests.h17
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c66
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c83
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c95
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c80
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c81
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c80
-rw-r--r--gcc/testsuite/jit.dg/test-extra-options.c136
-rw-r--r--gcc/testsuite/jit.dg/test-switch.c147
-rw-r--r--gcc/testsuite/jit.dg/test-switch.cc118
-rw-r--r--gcc/testsuite/jit.dg/test-validly-unreachable-block.c51
68 files changed, 5323 insertions, 35 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b4bd5dae784..aca88862aa9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,136 @@
+2015-07-01 Patrick Palka <ppalka@gcc.gnu.org>
+
+ PR c++/66686
+ * g++.dg/template/pr66686.C: New test.
+
+2015-06-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/lto17.ad[sb]: New test.
+
+2015-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ * jit.dg/all-non-failing-tests.h: Add test-switch.c.
+ * jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c: New
+ testcase.
+ * jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c:
+ New testcase.
+ * jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c:
+ New testcase.
+ * jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c:
+ New testcase.
+ * jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c:
+ New testcase.
+ * jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c:
+ New testcase.
+ * jit.dg/test-switch.c: New testcase.
+ * jit.dg/test-switch.cc: New testcase.
+
+2015-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR jit/66546
+ * jit.dg/all-non-failing-tests.h: Add note about
+ test-validly-unreachable-block.c.
+ * jit.dg/test-validly-unreachable-block.c: New file.
+
+2015-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR jit/66628
+ * jit.dg/all-non-failing-tests.h: Add note about
+ test-extra-options.c.
+ * jit.dg/test-extra-options.c: New testcase.
+
+2015-06-30 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR debug/66691
+ * gcc.target/i386/pr66691.c: New.
+
+2015-06-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.target/i386/iamcu/abi-iamcu.exp: New file.
+ * gcc.target/i386/iamcu/args.h: Likewise.
+ * gcc.target/i386/iamcu/asm-support.S: Likewise.
+ * gcc.target/i386/iamcu/defines.h: Likewise.
+ * gcc.target/i386/iamcu/macros.h: Likewise.
+ * gcc.target/i386/iamcu/test_3_element_struct_and_unions.c: Likewise.
+ * gcc.target/i386/iamcu/test_basic_64bit_returning.c: Likewise.
+ * gcc.target/i386/iamcu/test_basic_alignment.c: Likewise.
+ * gcc.target/i386/iamcu/test_basic_array_size_and_align.c: Likewise.
+ * gcc.target/i386/iamcu/test_basic_returning.c: Likewise.
+ * gcc.target/i386/iamcu/test_basic_sizes.c: Likewise.
+ * gcc.target/i386/iamcu/test_basic_struct_size_and_align.c: Likewise.
+ * gcc.target/i386/iamcu/test_basic_union_size_and_align.c: Likewise.
+ * gcc.target/i386/iamcu/test_bitfields.c: Likewise.
+ * gcc.target/i386/iamcu/test_complex_returning.c: Likewise.
+ * gcc.target/i386/iamcu/test_passing_floats.c: Likewise.
+ * gcc.target/i386/iamcu/test_passing_integers.c: Likewise.
+ * gcc.target/i386/iamcu/test_passing_structs.c: Likewise.
+ * gcc.target/i386/iamcu/test_passing_structs_and_unions.c: Likewise.
+ * gcc.target/i386/iamcu/test_passing_unions.c: Likewise.
+ * gcc.target/i386/iamcu/test_struct_returning.c: Likewise.
+ * gcc.target/i386/iamcu/test_varargs.c: Likewise.
+
+2015-06-30 Marek Polacek <polacek@redhat.com>
+
+ * gcc.dg/fold-minus-6.c: New test.
+
+ * gcc.dg/fold-ior-3.c: New test.
+
+2015-06-30 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement N4197 - Adding u8 character literals
+ * g++.dg/cpp1z/utf8.C: New.
+ * g++.dg/cpp1z/utf8-neg.C: New.
+ * g++.dg/cpp1z/udlit-utf8char.C: New.
+
+2015-06-30 Marek Polacek <polacek@redhat.com>
+
+ * gcc.dg/fold-ior-2.c (fn4): Swap operands.
+
+2015-06-30 Tom de Vries <tom@codesourcery.com>
+
+ * gcc.dg/parloops-exit-first-loop-alt-5.c: New test.
+ * gcc.dg/parloops-exit-first-loop-alt-6.c: New test.
+ * gcc.dg/parloops-exit-first-loop-alt-7.c: New test.
+ * gcc.dg/parloops-exit-first-loop-alt.c: Update comment.
+
+2015-06-30 Marek Polacek <polacek@redhat.com>
+
+ * gcc.dg/fold-ior-2.c: New test.
+
+2015-06-30 Tom de Vries <tom@codesourcery.com>
+
+ PR tree-optimization/66652
+ * gcc.dg/parloops-exit-first-loop-alt-pr66652.c: New test.
+ * gcc.dg/parloops-exit-first-loop-alt-3.c (f): Rewrite using restrict
+ pointers.
+ * gcc.dg/parloops-exit-first-loop-alt.c: Same.
+
+2015-06-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/65977
+ * g++.dg/cpp0x/constexpr-friend-3.C: New.
+ * g++.dg/cpp0x/constexpr-friend-2.C: Adjust.
+
+2015-06-29 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR fortran/66605
+ * gfortran.dg/wunused-parameter.f90: New test.
+
+2015-06-29 Richard Henderson <rth@redhat.com>
+
+ * gcc.target/i386/asm-flag-1.c: New.
+ * gcc.target/i386/asm-flag-2.c: New.
+ * gcc.target/i386/asm-flag-3.c: New.
+ * gcc.target/i386/asm-flag-4.c: New.
+ * gcc.target/i386/asm-flag-5.c: New.
+
+2015-06-29 Marek Polacek <polacek@redhat.com>
+
+ PR c/66322
+ * c-c++-common/pr60439.c: Add dg-prune-output and add switch cases.
+ * c-c++-common/pr66322.c: New test.
+ * g++.dg/eh/scope1.C: Remove dg-warning.
+
2015-06-29 Richard Biener <rguenther@suse.de>
PR tree-optimization/66677
diff --git a/gcc/testsuite/c-c++-common/pr60439.c b/gcc/testsuite/c-c++-common/pr60439.c
index 3368a0b944d..68bd33c22cb 100644
--- a/gcc/testsuite/c-c++-common/pr60439.c
+++ b/gcc/testsuite/c-c++-common/pr60439.c
@@ -1,5 +1,6 @@
/* PR c/60439 */
/* { dg-do compile } */
+/* { dg-prune-output "case label value exceeds" } */
#ifndef __cplusplus
# define bool _Bool
@@ -11,18 +12,30 @@ void
f1 (bool b)
{
switch (b) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
}
void
f2 (int a, int b)
{
switch (a && b) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch ((bool) (a && b)) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch ((a && b) || a) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
/* No warnings on following. */
switch ((int) (a && b))
break;
@@ -38,35 +51,65 @@ void
f3 (int a)
{
switch (!!a) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (!a) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
}
void
f4 (void)
{
switch (foo ()) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
}
void
f5 (int a)
{
switch (a == 3) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (a != 3) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (a > 3) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (a < 3) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (a <= 3) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (a >= 3) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (foo (), foo (), a >= 42) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (a == 3, a & 4, a ^ 5, a)
break;
switch ((int) (a == 3))
@@ -79,11 +122,20 @@ void
f6 (bool b)
{
switch (b) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (!b) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
switch (b++) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
}
void
@@ -91,7 +143,10 @@ f7 (void)
{
bool b;
switch (b = 1) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 3:
+ break;
+ }
}
void
@@ -104,5 +159,8 @@ f8 (int i)
switch ((unsigned int) i)
break;
switch ((bool) i) /* { dg-warning "switch condition has" } */
- break;
+ {
+ case 11:
+ break;
+ }
}
diff --git a/gcc/testsuite/c-c++-common/pr66322.c b/gcc/testsuite/c-c++-common/pr66322.c
new file mode 100644
index 00000000000..eb1e9e4a2ed
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr66322.c
@@ -0,0 +1,144 @@
+/* PR c/66322 */
+/* { dg-do compile } */
+
+#ifndef __cplusplus
+# define bool _Bool
+# define true 1
+# define false 0
+#endif
+
+void
+nowarn (bool b)
+{
+ switch (b)
+ ;
+
+ switch (b)
+ {
+ case true:
+ case false:
+ break;
+ }
+
+ switch (b)
+ {
+ case true:
+ break;
+ }
+
+ switch (b)
+ {
+ case true:
+ default:
+ break;
+ }
+
+ switch (b)
+ {
+ case false:
+ break;
+ }
+
+ switch (b)
+ {
+ case false:
+ default:
+ break;
+ }
+
+ switch (b)
+ {
+ default:
+ break;
+ }
+
+ switch (b)
+ {
+ case false ... true:
+ break;
+ }
+
+ switch (b)
+ {
+ case 1:
+ switch (b)
+ {
+ case true:
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void
+warn (bool b)
+{
+ switch (b) /* { dg-warning "switch condition has" } */
+ {
+ case true:
+ case false:
+ default:
+ break;
+ }
+
+ switch (b) /* { dg-warning "switch condition has" } */
+ {
+ case false ... true:
+ default:
+ break;
+ }
+}
+
+void
+warn2 (int n)
+{
+ switch (n == 2) /* { dg-warning "switch condition has" } */
+ {
+ case 0 ... 2: /* { dg-warning "upper value" "" { target c++ } } */
+ default:
+ break;
+ }
+
+ switch (n == 2) /* { dg-warning "switch condition has" } */
+ {
+ case 1 ... 10: /* { dg-warning "upper value" "" { target c++ } } */
+ default:
+ break;
+ }
+
+ switch (n == 2) /* { dg-warning "switch condition has" } */
+ {
+ case 2: /* { dg-warning "case label" "" { target c++ } } */
+ break;
+ }
+
+ switch (n == 2) /* { dg-warning "switch condition has" } */
+ {
+ case 0:
+ case 1:
+ case -1: /* { dg-warning "case label" "" { target c++ } } */
+ break;
+ }
+
+ switch (n == 2) /* { dg-warning "switch condition has" } */
+ {
+ case -1 ... 1: /* { dg-warning "lower value" "" { target c++ } } */
+ break;
+ }
+
+ switch (n == 2) /* { dg-warning "switch condition has" } */
+ {
+ case -1 ... 0: /* { dg-warning "lower value" "" { target c++ } } */
+ default:
+ break;
+ }
+
+ switch (n == 2) /* { dg-warning "switch condition has" } */
+ {
+ case -10 ... -1: /* { dg-warning "case label" "" { target c++ } } */
+ default:
+ break;
+ }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C
index 36799b43587..b2ddc218d4a 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C
@@ -3,5 +3,5 @@
template<typename T> void f(T);
template <class T> class A {
- friend constexpr void f<>(int); // { dg-error "'constexpr' is not allowed" }
+ friend constexpr void f<>(int);
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-3.C
new file mode 100644
index 00000000000..aec38eb68ff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-3.C
@@ -0,0 +1,21 @@
+// PR c++/65977
+// { dg-do compile { target c++11 } }
+
+template<__SIZE_TYPE__>
+class bitset;
+
+template<__SIZE_TYPE__ N>
+constexpr bool operator==(const bitset<N>&, const bitset<N>&) noexcept;
+
+template<__SIZE_TYPE__ N>
+class bitset
+{
+ friend constexpr bool operator== <>(const bitset<N>&,
+ const bitset<N>&) noexcept;
+};
+
+template<__SIZE_TYPE__ N>
+constexpr bool operator==(const bitset<N>&, const bitset<N>&) noexcept
+{
+ return true;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/udlit-utf8char.C b/gcc/testsuite/g++.dg/cpp1z/udlit-utf8char.C
new file mode 100644
index 00000000000..fb9cdf18fd2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/udlit-utf8char.C
@@ -0,0 +1,8 @@
+// { dg-do compile }
+// { dg-options "-std=c++1z" }
+
+constexpr int
+operator""_foo(char c)
+{ return c * 100; }
+
+auto cc = u8'8'_foo;
diff --git a/gcc/testsuite/g++.dg/cpp1z/utf8-neg.C b/gcc/testsuite/g++.dg/cpp1z/utf8-neg.C
new file mode 100644
index 00000000000..339f0e3c029
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/utf8-neg.C
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c++1z" } */
+
+const static char c0 = u8''; // { dg-error "empty character" }
+const static char c1 = u8'ab'; // { dg-warning "multi-character character constant" }
+const static char c2 = u8'\u0124'; // { dg-warning "multi-character character constant" }
+const static char c3 = u8'\U00064321'; // { dg-warning "multi-character character constant" }
diff --git a/gcc/testsuite/g++.dg/cpp1z/utf8.C b/gcc/testsuite/g++.dg/cpp1z/utf8.C
new file mode 100644
index 00000000000..52816f85918
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/utf8.C
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-options "-std=c++1z" }
+
+#include <cassert>
+#include <experimental/type_traits>
+
+auto c = 'c';
+auto u8c = u8'c';
+
+static_assert(std::experimental::is_same_v<decltype(u8c), decltype(c)>, "");
+
+auto u8s = u8"c";
+auto x = u8s[0];
+
+static_assert(std::experimental::is_same_v<decltype(u8c), decltype(x)>, "");
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/tls1.C b/gcc/testsuite/g++.dg/debug/dwarf2/tls1.C
new file mode 100644
index 00000000000..6286d7b27ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/tls1.C
@@ -0,0 +1,7 @@
+// PR c++/66653
+// { dg-options "-gdwarf" }
+
+template <typename T> class A
+{
+ static __thread T a;
+};
diff --git a/gcc/testsuite/g++.dg/eh/scope1.C b/gcc/testsuite/g++.dg/eh/scope1.C
index 8d553d8295b..276e0d6e588 100644
--- a/gcc/testsuite/g++.dg/eh/scope1.C
+++ b/gcc/testsuite/g++.dg/eh/scope1.C
@@ -31,7 +31,7 @@ void f3 ()
void f4 ()
{
- switch (C br = C()) /* { dg-warning "switch condition has" } */
+ switch (C br = C())
{
default:
abort ();
diff --git a/gcc/testsuite/g++.dg/template/pr66686.C b/gcc/testsuite/g++.dg/template/pr66686.C
new file mode 100644
index 00000000000..d8aea625d46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr66686.C
@@ -0,0 +1,15 @@
+// PR c++/66686
+
+template <int>
+struct Y { };
+
+template <class B, template <template <B> class Z> class C>
+struct X
+{
+ C<Y> a; // { dg-bogus "mismatch" }
+};
+
+template <template <int> class>
+struct A { };
+
+X<int, A> a;
diff --git a/gcc/testsuite/g++.dg/tls/tls_model1.C b/gcc/testsuite/g++.dg/tls/tls_model1.C
new file mode 100644
index 00000000000..a1520a1ba2f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/tls_model1.C
@@ -0,0 +1,8 @@
+// { dg-require-effective-target tls }
+// { dg-options "-g" }
+
+template <class T>
+void f()
+{
+ static __thread int i __attribute ((tls_model ("local-exec")));
+}
diff --git a/gcc/testsuite/gcc.dg/fold-ior-2.c b/gcc/testsuite/gcc.dg/fold-ior-2.c
new file mode 100644
index 00000000000..41b372d06fa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-ior-2.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-cddce1" } */
+
+int
+fn1 (int x)
+{
+ return ~x | x;
+}
+
+int
+fn2 (int x)
+{
+ return x | ~x;
+}
+
+unsigned int
+fn3 (unsigned int x)
+{
+ return ~x | x;
+}
+
+unsigned int
+fn4 (unsigned int x)
+{
+ return x | ~x;
+}
+
+int
+fn5 (int x)
+{
+ return ~x | (unsigned) x;
+}
+
+int
+fn6 (int x)
+{
+ return (unsigned) ~x | x;
+}
+
+int
+fn7 (int x)
+{
+ return ~(unsigned) x | x;
+}
+
+/* { dg-final { scan-tree-dump-not "~" "cddce1" } } */
+/* { dg-final { scan-tree-dump-not " \\| " "cddce1" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-ior-3.c b/gcc/testsuite/gcc.dg/fold-ior-3.c
new file mode 100644
index 00000000000..ed89ff9188c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-ior-3.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-cddce1" } */
+
+int
+fn1 (_Bool a)
+{
+ return ((int) a) | ((int) ~a);
+}
+
+int
+fn2 (unsigned char a)
+{
+ return ((int) a) | ((int) ~a);
+}
+
+int
+fn3 (unsigned short a)
+{
+ return ((int) a) | ((int) ~a);
+}
+
+int
+fn4 (signed char a)
+{
+ return ((int) a) | ((int) ~a);
+}
+
+int
+fn5 (signed short a)
+{
+ return ((int) a) | ((int) ~a);
+}
+
+/* { dg-final { scan-tree-dump-not "~" "cddce1" } } */
+/* { dg-final { scan-tree-dump-not " \\| " "cddce1" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-minus-6.c b/gcc/testsuite/gcc.dg/fold-minus-6.c
new file mode 100644
index 00000000000..1c22c252f72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-minus-6.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-cddce1" } */
+
+int
+fn1 (int x)
+{
+ return 42L - (42 / x) * x;
+}
+
+long
+fn2 (int x)
+{
+ return 42L - (42 / x) * x;
+}
+
+int
+fn3 (long int x)
+{
+ return 42L - (42 / x) * x;
+}
+
+int
+fn4 (int a, int b)
+{
+ return a - (unsigned) ((a / b) * b);
+}
+
+int
+fn5 (int a, unsigned int b)
+{
+ return a - ((a / b) * b);
+}
+
+unsigned int
+fn6 (int a, int b)
+{
+ return a - ((a / b) * b);
+}
+
+/* { dg-final { scan-tree-dump-not " / " "cddce1" } } */
+/* { dg-final { scan-tree-dump-not " - " "cddce1" } } */
+/* { dg-final { scan-tree-dump-not " \\+ " "cddce1" } } */
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c
index b0fde372a14..fec53a19628 100644
--- a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-3.c
@@ -7,7 +7,7 @@
unsigned int *a;
unsigned int
-f (unsigned int n)
+f (unsigned int n, unsigned int *__restrict__ a)
{
int i;
unsigned int sum = 1;
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-5.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-5.c
new file mode 100644
index 00000000000..3f799cf234d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-5.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target pthread } */
+/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops" } */
+
+/* Variable bound, vector addition, unsigned loop counter, unsigned bound. */
+
+void
+f (unsigned int n, unsigned int *__restrict__ a, unsigned int *__restrict__ b,
+ unsigned int *__restrict__ c)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; ++i)
+ c[i] = a[i] + b[i];
+}
+
+/* Three times a store:
+ - one in f._loopfn.0
+ - one in the parallel
+ - one in the low iteration count loop
+ Crucially, none for a peeled off last iteration following the parallel. */
+/* { dg-final { scan-tree-dump-times "(?n)^ \\*_\[0-9\]*" 3 "parloops" } } */
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-6.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-6.c
new file mode 100644
index 00000000000..ee19a55849a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-6.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target pthread } */
+/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops" } */
+
+/* Variable bound, vector addition, unsigned loop counter, signed bound. */
+
+void
+f (int n, unsigned int *__restrict__ a, unsigned int *__restrict__ b,
+ unsigned int *__restrict__ c)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; ++i)
+ c[i] = a[i] + b[i];
+}
+
+/* Three times a store:
+ - one in f._loopfn.0
+ - one in the parallel
+ - one in the low iteration count loop
+ Crucially, none for a peeled off last iteration following the parallel. */
+/* { dg-final { scan-tree-dump-times "(?n)^ \\*_\[0-9\]*" 3 "parloops" } } */
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-7.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-7.c
new file mode 100644
index 00000000000..c3373425281
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-7.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target pthread } */
+/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops" } */
+
+/* Variable bound, vector addition, signed loop counter, signed bound. */
+
+void
+f (int n, unsigned int *__restrict__ a, unsigned int *__restrict__ b,
+ unsigned int *__restrict__ c)
+{
+ int i;
+
+ for (i = 0; i < n; ++i)
+ c[i] = a[i] + b[i];
+}
+
+/* Three times a store:
+ - one in f._loopfn.0
+ - one in the parallel
+ - one in the low iteration count loop
+ Crucially, none for a peeled off last iteration following the parallel. */
+/* { dg-final { scan-tree-dump-times "(?n)^ \\*_\[0-9\]*" 3 "parloops" } } */
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c
new file mode 100644
index 00000000000..2ea097d06f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt-pr66652.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target pthread } */
+/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops" } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+unsigned int
+f (unsigned int n, unsigned int sum)
+{
+ unsigned int i;
+
+ i = UINT_MAX;
+ do
+ {
+ sum += i % 13;
+ i++;
+ }
+ while (i < n - 1);
+
+ return sum;
+}
+
+/* Four times % 13:
+ - once in f._loopfn.0
+ - once in the parallel
+ - once in the low iteration count loop
+ - once for a peeled off last iteration following the parallel.
+ In other words, we want try_transform_to_exit_first_loop_alt to fail. */
+/* { dg-final { scan-tree-dump-times "(?n)% 13" 4 "parloops" } } */
diff --git a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c
index b36f01b8f8f..0b6916507f4 100644
--- a/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c
+++ b/gcc/testsuite/gcc.dg/parloops-exit-first-loop-alt.c
@@ -2,16 +2,11 @@
/* { dg-require-effective-target pthread } */
/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops" } */
-/* Variable bound, vector addition. */
-
-#define N 1000
-
-unsigned int a[N];
-unsigned int b[N];
-unsigned int c[N];
+/* Variable bound, vector addition, signed loop counter, unsigned bound. */
void
-f (unsigned int n)
+f (unsigned int n, unsigned int *__restrict__ a, unsigned int *__restrict__ b,
+ unsigned int *__restrict__ c)
{
int i;
@@ -19,9 +14,9 @@ f (unsigned int n)
c[i] = a[i] + b[i];
}
-/* Three times three array accesses:
- - three in f._loopfn.0
- - three in the parallel
- - three in the low iteration count loop
+/* Three times a store:
+ - one in f._loopfn.0
+ - one in the parallel
+ - one in the low iteration count loop
Crucially, none for a peeled off last iteration following the parallel. */
-/* { dg-final { scan-tree-dump-times "(?n)\\\[i" 9 "parloops" } } */
+/* { dg-final { scan-tree-dump-times "(?n)^ \\*_\[0-9\]*" 3 "parloops" } } */
diff --git a/gcc/testsuite/gcc.target/arm/armv8-sync-comp-swap.c b/gcc/testsuite/gcc.target/arm/armv8-sync-comp-swap.c
new file mode 100644
index 00000000000..f96c81a8a9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/armv8-sync-comp-swap.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { do-require-effective-target arm_arch_v8a_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_arch_v8a } */
+
+#include "../aarch64/sync-comp-swap.x"
+
+/* { dg-final { scan-assembler-times "ldrex" 2 } } */
+/* { dg-final { scan-assembler-times "stlex" 2 } } */
+/* { dg-final { scan-assembler-times "dmb" 2 } } */
diff --git a/gcc/testsuite/gcc.target/arm/armv8-sync-op-acquire.c b/gcc/testsuite/gcc.target/arm/armv8-sync-op-acquire.c
new file mode 100644
index 00000000000..8d6659b70de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/armv8-sync-op-acquire.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { do-require-effective-target arm_arch_v8a_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_arch_v8a } */
+
+#include "../aarch64/sync-op-acquire.x"
+
+/* { dg-final { scan-assembler-times "ldrex" 1 } } */
+/* { dg-final { scan-assembler-times "stlex" 1 } } */
+/* { dg-final { scan-assembler-times "dmb" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/armv8-sync-op-full.c b/gcc/testsuite/gcc.target/arm/armv8-sync-op-full.c
new file mode 100644
index 00000000000..a5ad3bd822f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/armv8-sync-op-full.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { do-require-effective-target arm_arch_v8a_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_arch_v8a } */
+
+#include "../aarch64/sync-op-full.x"
+
+/* { dg-final { scan-assembler-times "ldrex" 12 } } */
+/* { dg-final { scan-assembler-times "stlex" 12 } } */
+/* { dg-final { scan-assembler-times "dmb" 12 } } */
diff --git a/gcc/testsuite/gcc.target/arm/armv8-sync-op-release.c b/gcc/testsuite/gcc.target/arm/armv8-sync-op-release.c
new file mode 100644
index 00000000000..0d3be7b8c0e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/armv8-sync-op-release.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { do-require-effective-target arm_arch_v8a_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_arch_v8a } */
+
+#include "../aarch64/sync-op-release.x"
+
+/* { dg-final { scan-assembler-times "stl" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/asm-flag-0.c b/gcc/testsuite/gcc.target/i386/asm-flag-0.c
new file mode 100644
index 00000000000..b0c05239b01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/asm-flag-0.c
@@ -0,0 +1,15 @@
+/* Test error conditions of asm flag outputs. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void a(void)
+{
+ char x;
+ asm("" : "=@cca,@ccc"(x)); /* { dg-error "alternatives not allowed" } */
+}
+
+void b(void)
+{
+ char x;
+ asm("" : "=@ccbad"(x)); /* { dg-error "unknown asm flag output" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/asm-flag-1.c b/gcc/testsuite/gcc.target/i386/asm-flag-1.c
new file mode 100644
index 00000000000..bcc4952239c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/asm-flag-1.c
@@ -0,0 +1,18 @@
+/* Test some of the valid @cc<cc> asm flag outputs. */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void f(char *out)
+{
+ asm("" : "=@cca"(out[0]), "=@ccc"(out[1]), "=@cce"(out[2]),
+ "=@ccg"(out[3]), "=@cco"(out[4]), "=@ccp"(out[5]),
+ "=@ccs"(out[6]));
+}
+
+/* { dg-final { scan-assembler "seta" } } */
+/* { dg-final { scan-assembler "setc" } } */
+/* { dg-final { scan-assembler "sete" } } */
+/* { dg-final { scan-assembler "setg" } } */
+/* { dg-final { scan-assembler "seto" } } */
+/* { dg-final { scan-assembler "setp" } } */
+/* { dg-final { scan-assembler "sets" } } */
diff --git a/gcc/testsuite/gcc.target/i386/asm-flag-2.c b/gcc/testsuite/gcc.target/i386/asm-flag-2.c
new file mode 100644
index 00000000000..5f8fa13da98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/asm-flag-2.c
@@ -0,0 +1,16 @@
+/* Test some of the valid @cc<cc> asm flag outputs. */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void f(char *out)
+{
+ asm("" : "=@ccb"(out[0]), "=@ccl"(out[1]), "=@ccz"(out[2]),
+ "=@ccbe"(out[4]), "=@ccge"(out[5]), "=@ccle"(out[6]));
+}
+
+/* { dg-final { scan-assembler "setc" } } */
+/* { dg-final { scan-assembler "setl" } } */
+/* { dg-final { scan-assembler "sete" } } */
+/* { dg-final { scan-assembler "setna" } } */
+/* { dg-final { scan-assembler "setge" } } */
+/* { dg-final { scan-assembler "setle" } } */
diff --git a/gcc/testsuite/gcc.target/i386/asm-flag-3.c b/gcc/testsuite/gcc.target/i386/asm-flag-3.c
new file mode 100644
index 00000000000..220c07cb867
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/asm-flag-3.c
@@ -0,0 +1,22 @@
+/* Test some of the valid @cc<cc> asm flag outputs. */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+#define DO(C) \
+void f##C(int *y) { char x; asm("" : "=@cc"#C(x)); if (!x) *y = 0; }
+
+DO(a)
+DO(c)
+DO(e)
+DO(g)
+DO(o)
+DO(p)
+DO(s)
+
+/* { dg-final { scan-assembler "ja" } } */
+/* { dg-final { scan-assembler "jc" } } */
+/* { dg-final { scan-assembler "je" } } */
+/* { dg-final { scan-assembler "jg" } } */
+/* { dg-final { scan-assembler "jo" } } */
+/* { dg-final { scan-assembler "jp" } } */
+/* { dg-final { scan-assembler "js" } } */
diff --git a/gcc/testsuite/gcc.target/i386/asm-flag-4.c b/gcc/testsuite/gcc.target/i386/asm-flag-4.c
new file mode 100644
index 00000000000..b84b7dfdb1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/asm-flag-4.c
@@ -0,0 +1,20 @@
+/* Test some of the valid @cc<cc> asm flag outputs. */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+#define DO(C) \
+void f##C(int *y) { char x; asm("" : "=@cc"#C(x)); if (!x) *y = 0; }
+
+DO(b)
+DO(l)
+DO(z)
+DO(be)
+DO(ge)
+DO(le)
+
+/* { dg-final { scan-assembler "jc" } } */
+/* { dg-final { scan-assembler "jl" } } */
+/* { dg-final { scan-assembler "je" } } */
+/* { dg-final { scan-assembler "jna" } } */
+/* { dg-final { scan-assembler "jge" } } */
+/* { dg-final { scan-assembler "jle" } } */
diff --git a/gcc/testsuite/gcc.target/i386/asm-flag-5.c b/gcc/testsuite/gcc.target/i386/asm-flag-5.c
new file mode 100644
index 00000000000..151157daf41
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/asm-flag-5.c
@@ -0,0 +1,29 @@
+/* Test error conditions of asm flag outputs. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void f_B(void) { _Bool x; asm("" : "=@ccc"(x)); }
+void f_c(void) { char x; asm("" : "=@ccc"(x)); }
+void f_s(void) { short x; asm("" : "=@ccc"(x)); }
+void f_i(void) { int x; asm("" : "=@ccc"(x)); }
+void f_l(void) { long x; asm("" : "=@ccc"(x)); }
+
+void f_f(void)
+{
+ float x;
+ asm("" : "=@ccc"(x)); /* { dg-error invalid type } */
+}
+
+void f_d(void)
+{
+ double x;
+ asm("" : "=@ccc"(x)); /* { dg-error invalid type } */
+}
+
+struct S { int x[3]; };
+
+void f_S(void)
+{
+ struct S x;
+ asm("" : "=@ccc"(x)); /* { dg-error invalid type } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/abi-iamcu.exp b/gcc/testsuite/gcc.target/i386/iamcu/abi-iamcu.exp
new file mode 100644
index 00000000000..b5b3261039a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/abi-iamcu.exp
@@ -0,0 +1,42 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# The Intel MCU psABI testsuite needs one additional assembler file for
+# most testcases. For simplicity we will just link it into each test.
+
+load_lib c-torture.exp
+load_lib target-supports.exp
+load_lib torture-options.exp
+
+if { (![istarget x86_64-*-linux*] && ![istarget i?86-*-linux*])
+ || ![is-effective-target ia32] } then {
+ return
+}
+
+
+torture-init
+set-torture-options $C_TORTURE_OPTIONS
+set additional_flags "-miamcu -W -Wall -Wno-abi"
+
+foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
+ if {[runtest_file_p $runtests $src]} {
+ c-torture-execute [list $src \
+ $srcdir/$subdir/asm-support.S] \
+ $additional_flags
+ }
+}
+
+torture-finish
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/args.h b/gcc/testsuite/gcc.target/i386/iamcu/args.h
new file mode 100644
index 00000000000..f8abde40155
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/args.h
@@ -0,0 +1,77 @@
+#ifndef INCLUDED_ARGS_H
+#define INCLUDED_ARGS_H
+
+/* This defines the calling sequences for integers and floats. */
+#define I0 eax
+#define I1 edx
+#define I2 ecx
+
+typedef unsigned int size_t;
+
+extern void (*callthis)(void);
+extern unsigned long eax,ebx,ecx,edx,esi,edi,esp,ebp;
+extern unsigned long sret_eax;
+extern volatile unsigned long volatile_var;
+extern void snapshot (void);
+extern void snapshot_ret (void);
+extern void *iamcu_memset (void *, int, size_t);
+#define WRAP_CALL(N) \
+ (callthis = (void (*)()) (N), (typeof (&N)) snapshot)
+#define WRAP_RET(N) \
+ (callthis = (void (*)()) (N), (typeof (&N)) snapshot_ret)
+
+/* Clear all scratch integer registers. */
+#define clear_int_hardware_registers \
+ asm __volatile__ ("xor %%eax, %%eax\n\t" \
+ "xor %%edx, %%edx\n\t" \
+ "xor %%ecx, %%ecx\n\t" \
+ ::: "eax", "edx", "ecx");
+
+/* Clear all scratch integer registers, excluding the one used to return
+ aggregate. */
+#define clear_non_sret_int_hardware_registers \
+ asm __volatile__ ("xor %%edx, %%ebx\n\t" \
+ "xor %%ecx, %%ecx\n\t" \
+ ::: "edx", "ecx");
+
+/* This is the list of registers available for passing arguments. Not all of
+ these are used or even really available. */
+struct IntegerRegisters
+{
+ unsigned long eax, ebx, ecx, edx, esi, edi;
+};
+
+/* Implemented in scalarargs.c */
+extern struct IntegerRegisters iregs, iregbits;
+extern unsigned int num_iregs;
+
+#define check_int_arguments do { \
+ assert (num_iregs <= 0 || (iregs.I0 & iregbits.I0) == (I0 & iregbits.I0)); \
+ assert (num_iregs <= 1 || (iregs.I1 & iregbits.I1) == (I1 & iregbits.I1)); \
+ assert (num_iregs <= 2 || (iregs.I2 & iregbits.I2) == (I2 & iregbits.I2)); \
+ } while (0)
+
+#define check_char_arguments check_int_arguments
+#define check_short_arguments check_int_arguments
+#define check_long_arguments check_int_arguments
+#define check_float_arguments check_int_arguments
+#define check_double_arguments check_int_arguments
+#define check_ldouble_arguments check_int_arguments
+
+/* Clear register struct. */
+#define clear_struct_registers \
+ eax = edx = ecx = 0; \
+ iamcu_memset (&iregs, 0, sizeof iregs);
+
+/* Clear both hardware and register structs for integers. */
+#define clear_int_registers \
+ clear_struct_registers \
+ clear_int_hardware_registers
+
+/* Clear both hardware and register structs for integers, excluding the
+ one used to return aggregate. */
+#define clear_non_sret_int_registers \
+ clear_struct_registers \
+ clear_non_sret_int_hardware_registers
+
+#endif /* INCLUDED_ARGS_H */
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/asm-support.S b/gcc/testsuite/gcc.target/i386/iamcu/asm-support.S
new file mode 100644
index 00000000000..b4a4a140e54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/asm-support.S
@@ -0,0 +1,302 @@
+ .comm callthis,4,4
+ .comm eax,4,4
+ .comm ebx,4,4
+ .comm ecx,4,4
+ .comm edx,4,4
+ .comm esi,4,4
+ .comm edi,4,4
+ .comm esp,4,4
+ .comm ebp,4,4
+ .comm sret_eax,4,4
+ .comm volatile_var,4,4
+
+ .text
+ .p2align 4,,15
+.globl snapshot
+ .type snapshot, @function
+snapshot:
+ movl %eax, eax
+ movl %ebx, ebx
+ movl %ecx, ecx
+ movl %edx, edx
+ movl %edi, edi
+ movl %esi, esi
+ movl %ebp, ebp
+ movl %esp, esp
+ jmp *callthis
+ .size snapshot, .-snapshot
+
+ .p2align 4,,15
+.globl snapshot_ret
+ .type snapshot_ret, @function
+snapshot_ret:
+ movl %eax, sret_eax
+ call *callthis
+ movl %eax, eax
+ movl %edx, edx
+ ret
+ .size snapshot_ret, .-snapshot_ret
+
+ .p2align 4,,15
+ .globl __nesf2
+ .type __nesf2, @function
+__nesf2:
+ .cfi_startproc
+ subl $4, %esp
+ .cfi_def_cfa_offset 8
+ movl %eax, (%esp)
+ movl $1, %eax
+ fildl (%esp)
+ movl %edx, (%esp)
+ xorl %edx, %edx
+ fildl (%esp)
+ fucomip %st(1), %st
+ fstp %st(0)
+ setp %dl
+ cmove %edx, %eax
+ addl $4, %esp
+ .cfi_def_cfa_offset 4
+ ret
+ .cfi_endproc
+ .size __nesf2, .-__nesf2
+
+ .p2align 4,,15
+ .globl __nedf2
+ .type __nedf2, @function
+__nedf2:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ andl $-8, %esp
+ subl $8, %esp
+ movl %eax, (%esp)
+ movl $1, %eax
+ movl %edx, 4(%esp)
+ xorl %edx, %edx
+ fildq (%esp)
+ fildq 8(%ebp)
+ fucomip %st(1), %st
+ fstp %st(0)
+ setp %dl
+ cmove %edx, %eax
+ leave
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+ .size __nedf2, .-__nedf2
+
+ .p2align 4,,15
+ .globl __addsf3
+ .type __addsf3, @function
+__addsf3:
+ .cfi_startproc
+ subl $4, %esp
+ .cfi_def_cfa_offset 8
+ movl %eax, (%esp)
+ flds (%esp)
+ movl %edx, (%esp)
+ flds (%esp)
+ faddp %st, %st(1)
+ fstps (%esp)
+ movl (%esp), %eax
+ addl $4, %esp
+ .cfi_def_cfa_offset 4
+ ret
+ .cfi_endproc
+ .size __addsf3, .-__addsf3
+
+ .p2align 4,,15
+ .globl __adddf3
+ .type __adddf3, @function
+__adddf3:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ andl $-8, %esp
+ subl $8, %esp
+ movl %eax, (%esp)
+ movl %edx, 4(%esp)
+ fldl (%esp)
+ faddl 8(%ebp)
+ fstpl (%esp)
+ movl (%esp), %eax
+ movl 4(%esp), %edx
+ leave
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+ .size __adddf3, .-__adddf3
+
+ .p2align 4,,15
+ .globl __floatsisf
+ .type __floatsisf, @function
+__floatsisf:
+ .cfi_startproc
+ subl $4, %esp
+ .cfi_def_cfa_offset 8
+ movl %eax, (%esp)
+ fildl (%esp)
+ addl $4, %esp
+ .cfi_def_cfa_offset 4
+ ret
+ .cfi_endproc
+ .size __floatsisf, .-__floatsisf
+
+ .p2align 4,,15
+ .globl __floatunsisf
+ .type __floatunsisf, @function
+__floatunsisf:
+ .cfi_startproc
+ subl $8, %esp
+ .cfi_def_cfa_offset 12
+ xorl %edx, %edx
+ movl %eax, (%esp)
+ movl %edx, 4(%esp)
+ fildq (%esp)
+ addl $8, %esp
+ .cfi_def_cfa_offset 4
+ ret
+ .cfi_endproc
+ .size __floatunsisf, .-__floatunsisf
+
+ .globl __extendsfdf2
+ .type __extendsfdf2, @function
+__extendsfdf2:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ andl $-8, %esp
+ subl $8, %esp
+ movl %eax, (%esp)
+ flds (%esp)
+ fstpl (%esp)
+ movl (%esp), %eax
+ movl 4(%esp), %edx
+ leave
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+ .size __extendsfdf2, .-__extendsfdf2
+
+ .p2align 4,,15
+ .globl __truncdfsf2
+ .type __truncdfsf2, @function
+__truncdfsf2:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ andl $-8, %esp
+ subl $12, %esp
+ movl %eax, (%esp)
+ movl %edx, 4(%esp)
+ fldl (%esp)
+ fstps (%esp)
+ movl (%esp), %eax
+ leave
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+ .size __truncdfsf2, .-__truncdfsf2
+
+ .p2align 4,,15
+ .globl iamcu_memset
+ .type iamcu_memset, @function
+iamcu_memset:
+ .cfi_startproc
+ pushl %edi
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset %edi, 0
+ movl %eax, %edi
+ movzbl %dl, %eax
+ movl %edi, %edx
+ rep stosb
+ movl %edx, %eax
+ popl %edi
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore %edi
+ ret
+ .cfi_endproc
+ .size iamcu_memset, .-iamcu_memset
+
+ .p2align 4,,15
+ .globl iamcu_noprintf
+ .type iamcu_noprintf, @function
+iamcu_noprintf:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ cmpl $-1414676753, 8(%ebp)
+ fldl 16(%ebp)
+ fldl 28(%ebp)
+ jne 7f
+ cmpl $256, 12(%ebp)
+ jne 8f
+ flds .LCiamcu_noprintf0
+ movl $1, %eax
+ fucomip %st(2), %st
+ fstp %st(1)
+ setp %dl
+ cmovne %eax, %edx
+ testb %dl, %dl
+ jne 9f
+ cmpl $-1146241297, 24(%ebp)
+ jne 10f
+ flds .LCiamcu_noprintf1
+ fucomip %st(1), %st
+ fstp %st(0)
+ setp %dl
+ cmove %edx, %eax
+ testb %al, %al
+ jne 2f
+ cmpl $259, 36(%ebp)
+ jne 2f
+ popl %ebp
+ .cfi_remember_state
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+7:
+ .cfi_restore_state
+ fstp %st(0)
+ fstp %st(0)
+ jmp 2f
+8:
+ fstp %st(0)
+ fstp %st(0)
+ .p2align 4,,3
+ jmp 2f
+9:
+ fstp %st(0)
+ jmp 2f
+10:
+ fstp %st(0)
+2:
+ call abort
+ .cfi_endproc
+ .size iamcu_noprintf, .-iamcu_noprintf
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 4
+.LCiamcu_noprintf0:
+ .long 1132494848
+ .align 4
+.LCiamcu_noprintf1:
+ .long 1132527616
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/defines.h b/gcc/testsuite/gcc.target/i386/iamcu/defines.h
new file mode 100644
index 00000000000..e715f4247f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/defines.h
@@ -0,0 +1,110 @@
+#ifndef DEFINED_DEFINES_H
+#define DEFINED_DEFINES_H
+
+typedef unsigned long long ulonglong;
+typedef long double ldouble;
+
+/* These defines determines what part of the test should be run. When
+ GCC implements these parts, the defines should be uncommented to
+ enable testing. */
+
+/* Scalar type long double. */
+#define CHECK_LONG_DOUBLE
+
+/* Scalar type __float128. */
+#define CHECK_FLOAT128
+
+/* Returning of complex type. */
+#define CHECK_COMPLEX
+
+/* Structs with size > 8. */
+#define CHECK_LARGER_STRUCTS
+
+/* Checks for passing floats and doubles. */
+#define CHECK_FLOAT_DOUBLE_PASSING
+
+/* Union passing with not-extremely-simple unions. */
+#define CHECK_LARGER_UNION_PASSING
+
+/* Variable args. */
+#define CHECK_VARARGS
+
+/* Check argument passing and returning for scalar types with sizeof > 8. */
+#define CHECK_LARGE_SCALAR_PASSING
+
+/* Defines for sizing and alignment. */
+
+#define TYPE_SIZE_CHAR 1
+#define TYPE_SIZE_SHORT 2
+#define TYPE_SIZE_INT 4
+#define TYPE_SIZE_LONG 4
+#define TYPE_SIZE_LONG_LONG 8
+#define TYPE_SIZE_FLOAT 4
+#define TYPE_SIZE_DOUBLE 8
+#define TYPE_SIZE_LONG_DOUBLE 8
+#define TYPE_SIZE_FLOAT128 16
+#define TYPE_SIZE_ENUM 4
+#define TYPE_SIZE_POINTER 4
+
+#define TYPE_ALIGN_CHAR 1
+#define TYPE_ALIGN_SHORT 2
+#define TYPE_ALIGN_INT 4
+#define TYPE_ALIGN_LONG 4
+#define TYPE_ALIGN_LONG_LONG 4
+#define TYPE_ALIGN_FLOAT 4
+#define TYPE_ALIGN_DOUBLE 4
+#define TYPE_ALIGN_LONG_DOUBLE 4
+#define TYPE_ALIGN_FLOAT128 4
+#define TYPE_ALIGN_ENUM 4
+#define TYPE_ALIGN_POINTER 4
+
+/* These defines control the building of the list of types to check. There
+ is a string identifying the type (with a comma after), a size of the type
+ (also with a comma and an integer for adding to the total amount of types)
+ and an alignment of the type (which is currently not really needed since
+ the abi specifies that alignof == sizeof for all scalar types). */
+#ifdef CHECK_LONG_DOUBLE
+#define CLD_STR "long double",
+#define CLD_SIZ TYPE_SIZE_LONG_DOUBLE,
+#define CLD_ALI TYPE_ALIGN_LONG_DOUBLE,
+#define CLD_RET "???",
+#else
+#define CLD_STR
+#define CLD_SIZ
+#define CLD_ALI
+#define CLD_RET
+#endif
+#ifdef CHECK_FLOAT128
+#define CF128_STR "__float128",
+#define CF128_SIZ TYPE_SIZE_FLOAT128,
+#define CF128_ALI TYPE_ALIGN_FLOAT128,
+#define CF128_RET "???",
+#else
+#define CF128_STR
+#define CF128_SIZ
+#define CF128_ALI
+#define CF128_RET
+#endif
+
+/* Used in size and alignment tests. */
+enum dummytype { enumtype };
+
+extern void abort (void);
+
+/* Assertion macro. */
+#define assert(test) if (!(test)) abort()
+
+#ifdef __GNUC__
+#define ATTRIBUTE_UNUSED __attribute__((__unused__))
+#else
+#define ATTRIBUTE_UNUSED
+#endif
+
+#ifdef __GNUC__
+#define PACKED __attribute__((__packed__))
+#else
+#warning Some tests will fail due to missing __packed__ support
+#define PACKED
+#endif
+
+#endif /* DEFINED_DEFINES_H */
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/macros.h b/gcc/testsuite/gcc.target/i386/iamcu/macros.h
new file mode 100644
index 00000000000..98fbc660f27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/macros.h
@@ -0,0 +1,53 @@
+#ifndef MACROS_H
+
+#define check_size(_t, _size) assert(sizeof(_t) == (_size))
+
+#define check_align(_t, _align) assert(__alignof__(_t) == (_align))
+
+#define check_align_lv(_t, _align) assert(__alignof__(_t) == (_align) \
+ && (((unsigned long)&(_t)) & ((_align) - 1) ) == 0)
+
+#define check_basic_struct_size_and_align(_type, _size, _align) { \
+ struct _str { _type dummy; } _t; \
+ check_size(_t, _size); \
+ check_align_lv(_t, _align); \
+}
+
+#define check_array_size_and_align(_type, _size, _align) { \
+ _type _a[1]; _type _b[2]; _type _c[16]; \
+ struct _str { _type _a[1]; } _s; \
+ check_align_lv(_a[0], _align); \
+ check_size(_a, _size); \
+ check_size(_b, (_size*2)); \
+ check_size(_c, (_size*16)); \
+ check_size(_s, _size); \
+ check_align_lv(_s._a[0], _align); \
+}
+
+#define check_basic_union_size_and_align(_type, _size, _align) { \
+ union _union { _type dummy; } _u; \
+ check_size(_u, _size); \
+ check_align_lv(_u, _align); \
+}
+
+#define run_signed_tests2(_function, _arg1, _arg2) \
+ _function(_arg1, _arg2); \
+ _function(signed _arg1, _arg2); \
+ _function(unsigned _arg1, _arg2);
+
+#define run_signed_tests3(_function, _arg1, _arg2, _arg3) \
+ _function(_arg1, _arg2, _arg3); \
+ _function(signed _arg1, _arg2, _arg3); \
+ _function(unsigned _arg1, _arg2, _arg3);
+
+/* Check size of a struct and a union of three types. */
+
+#define check_struct_and_union3(type1, type2, type3, struct_size, align_size) \
+{ \
+ struct _str { type1 t1; type2 t2; type3 t3; } _t; \
+ union _uni { type1 t1; type2 t2; type3 t3; } _u; \
+ check_size(_t, struct_size); \
+ check_size(_u, align_size); \
+}
+
+#endif // MACROS_H
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_3_element_struct_and_unions.c b/gcc/testsuite/gcc.target/i386/iamcu/test_3_element_struct_and_unions.c
new file mode 100644
index 00000000000..7bec2119934
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_3_element_struct_and_unions.c
@@ -0,0 +1,521 @@
+#include "defines.h"
+#include "macros.h"
+
+/* Check structs and unions of all permutations of 3 basic types. */
+int
+main (void)
+{
+ check_struct_and_union3(char, char, char, 3, 1);
+ check_struct_and_union3(char, char, short, 4, 2);
+ check_struct_and_union3(char, char, int, 8, 4);
+ check_struct_and_union3(char, char, long, 8, 4);
+ check_struct_and_union3(char, char, long long, 12, 8);
+ check_struct_and_union3(char, char, float, 8, 4);
+ check_struct_and_union3(char, char, double, 12, 8);
+ check_struct_and_union3(char, char, long double, 12, 8);
+ check_struct_and_union3(char, short, char, 6, 2);
+ check_struct_and_union3(char, short, short, 6, 2);
+ check_struct_and_union3(char, short, int, 8, 4);
+ check_struct_and_union3(char, short, long, 8, 4);
+ check_struct_and_union3(char, short, long long, 12, 8);
+ check_struct_and_union3(char, short, float, 8, 4);
+ check_struct_and_union3(char, short, double, 12, 8);
+ check_struct_and_union3(char, short, long double, 12, 8);
+ check_struct_and_union3(char, int, char, 12, 4);
+ check_struct_and_union3(char, int, short, 12, 4);
+ check_struct_and_union3(char, int, int, 12, 4);
+ check_struct_and_union3(char, int, long, 12, 4);
+ check_struct_and_union3(char, int, long long, 16, 8);
+ check_struct_and_union3(char, int, float, 12, 4);
+ check_struct_and_union3(char, int, double, 16, 8);
+ check_struct_and_union3(char, int, long double, 16, 8);
+ check_struct_and_union3(char, long, char, 12, 4);
+ check_struct_and_union3(char, long, short, 12, 4);
+ check_struct_and_union3(char, long, int, 12, 4);
+ check_struct_and_union3(char, long, long, 12, 4);
+ check_struct_and_union3(char, long, long long, 16, 8);
+ check_struct_and_union3(char, long, float, 12, 4);
+ check_struct_and_union3(char, long, double, 16, 8);
+ check_struct_and_union3(char, long, long double, 16, 8);
+ check_struct_and_union3(char, long long, char, 16, 8);
+ check_struct_and_union3(char, long long, short, 16, 8);
+ check_struct_and_union3(char, long long, int, 16, 8);
+ check_struct_and_union3(char, long long, long, 16, 8);
+ check_struct_and_union3(char, long long, long long, 20, 8);
+ check_struct_and_union3(char, long long, float, 16, 8);
+ check_struct_and_union3(char, long long, double, 20, 8);
+ check_struct_and_union3(char, long long, long double, 20, 8);
+ check_struct_and_union3(char, float, char, 12, 4);
+ check_struct_and_union3(char, float, short, 12, 4);
+ check_struct_and_union3(char, float, int, 12, 4);
+ check_struct_and_union3(char, float, long, 12, 4);
+ check_struct_and_union3(char, float, long long, 16, 8);
+ check_struct_and_union3(char, float, float, 12, 4);
+ check_struct_and_union3(char, float, double, 16, 8);
+ check_struct_and_union3(char, float, long double, 16, 8);
+ check_struct_and_union3(char, double, char, 16, 8);
+ check_struct_and_union3(char, double, short, 16, 8);
+ check_struct_and_union3(char, double, int, 16, 8);
+ check_struct_and_union3(char, double, long, 16, 8);
+ check_struct_and_union3(char, double, long long, 20, 8);
+ check_struct_and_union3(char, double, float, 16, 8);
+ check_struct_and_union3(char, double, double, 20, 8);
+ check_struct_and_union3(char, double, long double, 20, 8);
+ check_struct_and_union3(char, long double, char, 16, 8);
+ check_struct_and_union3(char, long double, short, 16, 8);
+ check_struct_and_union3(char, long double, int, 16, 8);
+ check_struct_and_union3(char, long double, long, 16, 8);
+ check_struct_and_union3(char, long double, long long, 20, 8);
+ check_struct_and_union3(char, long double, float, 16, 8);
+ check_struct_and_union3(char, long double, double, 20, 8);
+ check_struct_and_union3(char, long double, long double, 20, 8);
+ check_struct_and_union3(short, char, char, 4, 2);
+ check_struct_and_union3(short, char, short, 6, 2);
+ check_struct_and_union3(short, char, int, 8, 4);
+ check_struct_and_union3(short, char, long, 8, 4);
+ check_struct_and_union3(short, char, long long, 12, 8);
+ check_struct_and_union3(short, char, float, 8, 4);
+ check_struct_and_union3(short, char, double, 12, 8);
+ check_struct_and_union3(short, char, long double, 12, 8);
+ check_struct_and_union3(short, short, char, 6, 2);
+ check_struct_and_union3(short, short, short, 6, 2);
+ check_struct_and_union3(short, short, int, 8, 4);
+ check_struct_and_union3(short, short, long, 8, 4);
+ check_struct_and_union3(short, short, long long, 12, 8);
+ check_struct_and_union3(short, short, float, 8, 4);
+ check_struct_and_union3(short, short, double, 12, 8);
+ check_struct_and_union3(short, short, long double, 12, 8);
+ check_struct_and_union3(short, int, char, 12, 4);
+ check_struct_and_union3(short, int, short, 12, 4);
+ check_struct_and_union3(short, int, int, 12, 4);
+ check_struct_and_union3(short, int, long, 12, 4);
+ check_struct_and_union3(short, int, long long, 16, 8);
+ check_struct_and_union3(short, int, float, 12, 4);
+ check_struct_and_union3(short, int, double, 16, 8);
+ check_struct_and_union3(short, int, long double, 16, 8);
+ check_struct_and_union3(short, long, char, 12, 4);
+ check_struct_and_union3(short, long, short, 12, 4);
+ check_struct_and_union3(short, long, int, 12, 4);
+ check_struct_and_union3(short, long, long, 12, 4);
+ check_struct_and_union3(short, long, long long, 16, 8);
+ check_struct_and_union3(short, long, float, 12, 4);
+ check_struct_and_union3(short, long, double, 16, 8);
+ check_struct_and_union3(short, long, long double, 16, 8);
+ check_struct_and_union3(short, long long, char, 16, 8);
+ check_struct_and_union3(short, long long, short, 16, 8);
+ check_struct_and_union3(short, long long, int, 16, 8);
+ check_struct_and_union3(short, long long, long, 16, 8);
+ check_struct_and_union3(short, long long, long long, 20, 8);
+ check_struct_and_union3(short, long long, float, 16, 8);
+ check_struct_and_union3(short, long long, double, 20, 8);
+ check_struct_and_union3(short, long long, long double, 20, 8);
+ check_struct_and_union3(short, float, char, 12, 4);
+ check_struct_and_union3(short, float, short, 12, 4);
+ check_struct_and_union3(short, float, int, 12, 4);
+ check_struct_and_union3(short, float, long, 12, 4);
+ check_struct_and_union3(short, float, long long, 16, 8);
+ check_struct_and_union3(short, float, float, 12, 4);
+ check_struct_and_union3(short, float, double, 16, 8);
+ check_struct_and_union3(short, float, long double, 16, 8);
+ check_struct_and_union3(short, double, char, 16, 8);
+ check_struct_and_union3(short, double, short, 16, 8);
+ check_struct_and_union3(short, double, int, 16, 8);
+ check_struct_and_union3(short, double, long, 16, 8);
+ check_struct_and_union3(short, double, long long, 20, 8);
+ check_struct_and_union3(short, double, float, 16, 8);
+ check_struct_and_union3(short, double, double, 20, 8);
+ check_struct_and_union3(short, double, long double, 20, 8);
+ check_struct_and_union3(short, long double, char, 16, 8);
+ check_struct_and_union3(short, long double, short, 16, 8);
+ check_struct_and_union3(short, long double, int, 16, 8);
+ check_struct_and_union3(short, long double, long, 16, 8);
+ check_struct_and_union3(short, long double, long long, 20, 8);
+ check_struct_and_union3(short, long double, float, 16, 8);
+ check_struct_and_union3(short, long double, double, 20, 8);
+ check_struct_and_union3(short, long double, long double, 20, 8);
+ check_struct_and_union3(int, char, char, 8, 4);
+ check_struct_and_union3(int, char, short, 8, 4);
+ check_struct_and_union3(int, char, int, 12, 4);
+ check_struct_and_union3(int, char, long, 12, 4);
+ check_struct_and_union3(int, char, long long, 16, 8);
+ check_struct_and_union3(int, char, float, 12, 4);
+ check_struct_and_union3(int, char, double, 16, 8);
+ check_struct_and_union3(int, char, long double, 16, 8);
+ check_struct_and_union3(int, short, char, 8, 4);
+ check_struct_and_union3(int, short, short, 8, 4);
+ check_struct_and_union3(int, short, int, 12, 4);
+ check_struct_and_union3(int, short, long, 12, 4);
+ check_struct_and_union3(int, short, long long, 16, 8);
+ check_struct_and_union3(int, short, float, 12, 4);
+ check_struct_and_union3(int, short, double, 16, 8);
+ check_struct_and_union3(int, short, long double, 16, 8);
+ check_struct_and_union3(int, int, char, 12, 4);
+ check_struct_and_union3(int, int, short, 12, 4);
+ check_struct_and_union3(int, int, int, 12, 4);
+ check_struct_and_union3(int, int, long, 12, 4);
+ check_struct_and_union3(int, int, long long, 16, 8);
+ check_struct_and_union3(int, int, float, 12, 4);
+ check_struct_and_union3(int, int, double, 16, 8);
+ check_struct_and_union3(int, int, long double, 16, 8);
+ check_struct_and_union3(int, long, char, 12, 4);
+ check_struct_and_union3(int, long, short, 12, 4);
+ check_struct_and_union3(int, long, int, 12, 4);
+ check_struct_and_union3(int, long, long, 12, 4);
+ check_struct_and_union3(int, long, long long, 16, 8);
+ check_struct_and_union3(int, long, float, 12, 4);
+ check_struct_and_union3(int, long, double, 16, 8);
+ check_struct_and_union3(int, long, long double, 16, 8);
+ check_struct_and_union3(int, long long, char, 16, 8);
+ check_struct_and_union3(int, long long, short, 16, 8);
+ check_struct_and_union3(int, long long, int, 16, 8);
+ check_struct_and_union3(int, long long, long, 16, 8);
+ check_struct_and_union3(int, long long, long long, 20, 8);
+ check_struct_and_union3(int, long long, float, 16, 8);
+ check_struct_and_union3(int, long long, double, 20, 8);
+ check_struct_and_union3(int, long long, long double, 20, 8);
+ check_struct_and_union3(int, float, char, 12, 4);
+ check_struct_and_union3(int, float, short, 12, 4);
+ check_struct_and_union3(int, float, int, 12, 4);
+ check_struct_and_union3(int, float, long, 12, 4);
+ check_struct_and_union3(int, float, long long, 16, 8);
+ check_struct_and_union3(int, float, float, 12, 4);
+ check_struct_and_union3(int, float, double, 16, 8);
+ check_struct_and_union3(int, float, long double, 16, 8);
+ check_struct_and_union3(int, double, char, 16, 8);
+ check_struct_and_union3(int, double, short, 16, 8);
+ check_struct_and_union3(int, double, int, 16, 8);
+ check_struct_and_union3(int, double, long, 16, 8);
+ check_struct_and_union3(int, double, long long, 20, 8);
+ check_struct_and_union3(int, double, float, 16, 8);
+ check_struct_and_union3(int, double, double, 20, 8);
+ check_struct_and_union3(int, double, long double, 20, 8);
+ check_struct_and_union3(int, long double, char, 16, 8);
+ check_struct_and_union3(int, long double, short, 16, 8);
+ check_struct_and_union3(int, long double, int, 16, 8);
+ check_struct_and_union3(int, long double, long, 16, 8);
+ check_struct_and_union3(int, long double, long long, 20, 8);
+ check_struct_and_union3(int, long double, float, 16, 8);
+ check_struct_and_union3(int, long double, double, 20, 8);
+ check_struct_and_union3(int, long double, long double, 20, 8);
+ check_struct_and_union3(long, char, char, 8, 4);
+ check_struct_and_union3(long, char, short, 8, 4);
+ check_struct_and_union3(long, char, int, 12, 4);
+ check_struct_and_union3(long, char, long, 12, 4);
+ check_struct_and_union3(long, char, long long, 16, 8);
+ check_struct_and_union3(long, char, float, 12, 4);
+ check_struct_and_union3(long, char, double, 16, 8);
+ check_struct_and_union3(long, char, long double, 16, 8);
+ check_struct_and_union3(long, short, char, 8, 4);
+ check_struct_and_union3(long, short, short, 8, 4);
+ check_struct_and_union3(long, short, int, 12, 4);
+ check_struct_and_union3(long, short, long, 12, 4);
+ check_struct_and_union3(long, short, long long, 16, 8);
+ check_struct_and_union3(long, short, float, 12, 4);
+ check_struct_and_union3(long, short, double, 16, 8);
+ check_struct_and_union3(long, short, long double, 16, 8);
+ check_struct_and_union3(long, int, char, 12, 4);
+ check_struct_and_union3(long, int, short, 12, 4);
+ check_struct_and_union3(long, int, int, 12, 4);
+ check_struct_and_union3(long, int, long, 12, 4);
+ check_struct_and_union3(long, int, long long, 16, 8);
+ check_struct_and_union3(long, int, float, 12, 4);
+ check_struct_and_union3(long, int, double, 16, 8);
+ check_struct_and_union3(long, int, long double, 16, 8);
+ check_struct_and_union3(long, long, char, 12, 4);
+ check_struct_and_union3(long, long, short, 12, 4);
+ check_struct_and_union3(long, long, int, 12, 4);
+ check_struct_and_union3(long, long, long, 12, 4);
+ check_struct_and_union3(long, long, long long, 16, 8);
+ check_struct_and_union3(long, long, float, 12, 4);
+ check_struct_and_union3(long, long, double, 16, 8);
+ check_struct_and_union3(long, long, long double, 16, 8);
+ check_struct_and_union3(long, long long, char, 16, 8);
+ check_struct_and_union3(long, long long, short, 16, 8);
+ check_struct_and_union3(long, long long, int, 16, 8);
+ check_struct_and_union3(long, long long, long, 16, 8);
+ check_struct_and_union3(long, long long, long long, 20, 8);
+ check_struct_and_union3(long, long long, float, 16, 8);
+ check_struct_and_union3(long, long long, double, 20, 8);
+ check_struct_and_union3(long, long long, long double, 20, 8);
+ check_struct_and_union3(long, float, char, 12, 4);
+ check_struct_and_union3(long, float, short, 12, 4);
+ check_struct_and_union3(long, float, int, 12, 4);
+ check_struct_and_union3(long, float, long, 12, 4);
+ check_struct_and_union3(long, float, long long, 16, 8);
+ check_struct_and_union3(long, float, float, 12, 4);
+ check_struct_and_union3(long, float, double, 16, 8);
+ check_struct_and_union3(long, float, long double, 16, 8);
+ check_struct_and_union3(long, double, char, 16, 8);
+ check_struct_and_union3(long, double, short, 16, 8);
+ check_struct_and_union3(long, double, int, 16, 8);
+ check_struct_and_union3(long, double, long, 16, 8);
+ check_struct_and_union3(long, double, long long, 20, 8);
+ check_struct_and_union3(long, double, float, 16, 8);
+ check_struct_and_union3(long, double, double, 20, 8);
+ check_struct_and_union3(long, double, long double, 20, 8);
+ check_struct_and_union3(long, long double, char, 16, 8);
+ check_struct_and_union3(long, long double, short, 16, 8);
+ check_struct_and_union3(long, long double, int, 16, 8);
+ check_struct_and_union3(long, long double, long, 16, 8);
+ check_struct_and_union3(long, long double, long long, 20, 8);
+ check_struct_and_union3(long, long double, float, 16, 8);
+ check_struct_and_union3(long, long double, double, 20, 8);
+ check_struct_and_union3(long, long double, long double, 20, 8);
+ check_struct_and_union3(long long, char, char, 12, 8);
+ check_struct_and_union3(long long, char, short, 12, 8);
+ check_struct_and_union3(long long, char, int, 16, 8);
+ check_struct_and_union3(long long, char, long, 16, 8);
+ check_struct_and_union3(long long, char, long long, 20, 8);
+ check_struct_and_union3(long long, char, float, 16, 8);
+ check_struct_and_union3(long long, char, double, 20, 8);
+ check_struct_and_union3(long long, char, long double, 20, 8);
+ check_struct_and_union3(long long, short, char, 12, 8);
+ check_struct_and_union3(long long, short, short, 12, 8);
+ check_struct_and_union3(long long, short, int, 16, 8);
+ check_struct_and_union3(long long, short, long, 16, 8);
+ check_struct_and_union3(long long, short, long long, 20, 8);
+ check_struct_and_union3(long long, short, float, 16, 8);
+ check_struct_and_union3(long long, short, double, 20, 8);
+ check_struct_and_union3(long long, short, long double, 20, 8);
+ check_struct_and_union3(long long, int, char, 16, 8);
+ check_struct_and_union3(long long, int, short, 16, 8);
+ check_struct_and_union3(long long, int, int, 16, 8);
+ check_struct_and_union3(long long, int, long, 16, 8);
+ check_struct_and_union3(long long, int, long long, 20, 8);
+ check_struct_and_union3(long long, int, float, 16, 8);
+ check_struct_and_union3(long long, int, double, 20, 8);
+ check_struct_and_union3(long long, int, long double, 20, 8);
+ check_struct_and_union3(long long, long, char, 16, 8);
+ check_struct_and_union3(long long, long, short, 16, 8);
+ check_struct_and_union3(long long, long, int, 16, 8);
+ check_struct_and_union3(long long, long, long, 16, 8);
+ check_struct_and_union3(long long, long, long long, 20, 8);
+ check_struct_and_union3(long long, long, float, 16, 8);
+ check_struct_and_union3(long long, long, double, 20, 8);
+ check_struct_and_union3(long long, long, long double, 20, 8);
+ check_struct_and_union3(long long, long long, char, 20, 8);
+ check_struct_and_union3(long long, long long, short, 20, 8);
+ check_struct_and_union3(long long, long long, int, 20, 8);
+ check_struct_and_union3(long long, long long, long, 20, 8);
+ check_struct_and_union3(long long, long long, long long, 24, 8);
+ check_struct_and_union3(long long, long long, float, 20, 8);
+ check_struct_and_union3(long long, long long, double, 24, 8);
+ check_struct_and_union3(long long, long long, long double, 24, 8);
+ check_struct_and_union3(long long, float, char, 16, 8);
+ check_struct_and_union3(long long, float, short, 16, 8);
+ check_struct_and_union3(long long, float, int, 16, 8);
+ check_struct_and_union3(long long, float, long, 16, 8);
+ check_struct_and_union3(long long, float, long long, 20, 8);
+ check_struct_and_union3(long long, float, float, 16, 8);
+ check_struct_and_union3(long long, float, double, 20, 8);
+ check_struct_and_union3(long long, float, long double, 20, 8);
+ check_struct_and_union3(long long, double, char, 20, 8);
+ check_struct_and_union3(long long, double, short, 20, 8);
+ check_struct_and_union3(long long, double, int, 20, 8);
+ check_struct_and_union3(long long, double, long, 20, 8);
+ check_struct_and_union3(long long, double, long long, 24, 8);
+ check_struct_and_union3(long long, double, float, 20, 8);
+ check_struct_and_union3(long long, double, double, 24, 8);
+ check_struct_and_union3(long long, double, long double, 24, 8);
+ check_struct_and_union3(long long, long double, char, 20, 8);
+ check_struct_and_union3(long long, long double, short, 20, 8);
+ check_struct_and_union3(long long, long double, int, 20, 8);
+ check_struct_and_union3(long long, long double, long, 20, 8);
+ check_struct_and_union3(long long, long double, long long, 24, 8);
+ check_struct_and_union3(long long, long double, float, 20, 8);
+ check_struct_and_union3(long long, long double, double, 24, 8);
+ check_struct_and_union3(long long, long double, long double, 24, 8);
+ check_struct_and_union3(float, char, char, 8, 4);
+ check_struct_and_union3(float, char, short, 8, 4);
+ check_struct_and_union3(float, char, int, 12, 4);
+ check_struct_and_union3(float, char, long, 12, 4);
+ check_struct_and_union3(float, char, long long, 16, 8);
+ check_struct_and_union3(float, char, float, 12, 4);
+ check_struct_and_union3(float, char, double, 16, 8);
+ check_struct_and_union3(float, char, long double, 16, 8);
+ check_struct_and_union3(float, short, char, 8, 4);
+ check_struct_and_union3(float, short, short, 8, 4);
+ check_struct_and_union3(float, short, int, 12, 4);
+ check_struct_and_union3(float, short, long, 12, 4);
+ check_struct_and_union3(float, short, long long, 16, 8);
+ check_struct_and_union3(float, short, float, 12, 4);
+ check_struct_and_union3(float, short, double, 16, 8);
+ check_struct_and_union3(float, short, long double, 16, 8);
+ check_struct_and_union3(float, int, char, 12, 4);
+ check_struct_and_union3(float, int, short, 12, 4);
+ check_struct_and_union3(float, int, int, 12, 4);
+ check_struct_and_union3(float, int, long, 12, 4);
+ check_struct_and_union3(float, int, long long, 16, 8);
+ check_struct_and_union3(float, int, float, 12, 4);
+ check_struct_and_union3(float, int, double, 16, 8);
+ check_struct_and_union3(float, int, long double, 16, 8);
+ check_struct_and_union3(float, long, char, 12, 4);
+ check_struct_and_union3(float, long, short, 12, 4);
+ check_struct_and_union3(float, long, int, 12, 4);
+ check_struct_and_union3(float, long, long, 12, 4);
+ check_struct_and_union3(float, long, long long, 16, 8);
+ check_struct_and_union3(float, long, float, 12, 4);
+ check_struct_and_union3(float, long, double, 16, 8);
+ check_struct_and_union3(float, long, long double, 16, 8);
+ check_struct_and_union3(float, long long, char, 16, 8);
+ check_struct_and_union3(float, long long, short, 16, 8);
+ check_struct_and_union3(float, long long, int, 16, 8);
+ check_struct_and_union3(float, long long, long, 16, 8);
+ check_struct_and_union3(float, long long, long long, 20, 8);
+ check_struct_and_union3(float, long long, float, 16, 8);
+ check_struct_and_union3(float, long long, double, 20, 8);
+ check_struct_and_union3(float, long long, long double, 20, 8);
+ check_struct_and_union3(float, float, char, 12, 4);
+ check_struct_and_union3(float, float, short, 12, 4);
+ check_struct_and_union3(float, float, int, 12, 4);
+ check_struct_and_union3(float, float, long, 12, 4);
+ check_struct_and_union3(float, float, long long, 16, 8);
+ check_struct_and_union3(float, float, float, 12, 4);
+ check_struct_and_union3(float, float, double, 16, 8);
+ check_struct_and_union3(float, float, long double, 16, 8);
+ check_struct_and_union3(float, double, char, 16, 8);
+ check_struct_and_union3(float, double, short, 16, 8);
+ check_struct_and_union3(float, double, int, 16, 8);
+ check_struct_and_union3(float, double, long, 16, 8);
+ check_struct_and_union3(float, double, long long, 20, 8);
+ check_struct_and_union3(float, double, float, 16, 8);
+ check_struct_and_union3(float, double, double, 20, 8);
+ check_struct_and_union3(float, double, long double, 20, 8);
+ check_struct_and_union3(float, long double, char, 16, 8);
+ check_struct_and_union3(float, long double, short, 16, 8);
+ check_struct_and_union3(float, long double, int, 16, 8);
+ check_struct_and_union3(float, long double, long, 16, 8);
+ check_struct_and_union3(float, long double, long long, 20, 8);
+ check_struct_and_union3(float, long double, float, 16, 8);
+ check_struct_and_union3(float, long double, double, 20, 8);
+ check_struct_and_union3(float, long double, long double, 20, 8);
+ check_struct_and_union3(double, char, char, 12, 8);
+ check_struct_and_union3(double, char, short, 12, 8);
+ check_struct_and_union3(double, char, int, 16, 8);
+ check_struct_and_union3(double, char, long, 16, 8);
+ check_struct_and_union3(double, char, long long, 20, 8);
+ check_struct_and_union3(double, char, float, 16, 8);
+ check_struct_and_union3(double, char, double, 20, 8);
+ check_struct_and_union3(double, char, long double, 20, 8);
+ check_struct_and_union3(double, short, char, 12, 8);
+ check_struct_and_union3(double, short, short, 12, 8);
+ check_struct_and_union3(double, short, int, 16, 8);
+ check_struct_and_union3(double, short, long, 16, 8);
+ check_struct_and_union3(double, short, long long, 20, 8);
+ check_struct_and_union3(double, short, float, 16, 8);
+ check_struct_and_union3(double, short, double, 20, 8);
+ check_struct_and_union3(double, short, long double, 20, 8);
+ check_struct_and_union3(double, int, char, 16, 8);
+ check_struct_and_union3(double, int, short, 16, 8);
+ check_struct_and_union3(double, int, int, 16, 8);
+ check_struct_and_union3(double, int, long, 16, 8);
+ check_struct_and_union3(double, int, long long, 20, 8);
+ check_struct_and_union3(double, int, float, 16, 8);
+ check_struct_and_union3(double, int, double, 20, 8);
+ check_struct_and_union3(double, int, long double, 20, 8);
+ check_struct_and_union3(double, long, char, 16, 8);
+ check_struct_and_union3(double, long, short, 16, 8);
+ check_struct_and_union3(double, long, int, 16, 8);
+ check_struct_and_union3(double, long, long, 16, 8);
+ check_struct_and_union3(double, long, long long, 20, 8);
+ check_struct_and_union3(double, long, float, 16, 8);
+ check_struct_and_union3(double, long, double, 20, 8);
+ check_struct_and_union3(double, long, long double, 20, 8);
+ check_struct_and_union3(double, long long, char, 20, 8);
+ check_struct_and_union3(double, long long, short, 20, 8);
+ check_struct_and_union3(double, long long, int, 20, 8);
+ check_struct_and_union3(double, long long, long, 20, 8);
+ check_struct_and_union3(double, long long, long long, 24, 8);
+ check_struct_and_union3(double, long long, float, 20, 8);
+ check_struct_and_union3(double, long long, double, 24, 8);
+ check_struct_and_union3(double, long long, long double, 24, 8);
+ check_struct_and_union3(double, float, char, 16, 8);
+ check_struct_and_union3(double, float, short, 16, 8);
+ check_struct_and_union3(double, float, int, 16, 8);
+ check_struct_and_union3(double, float, long, 16, 8);
+ check_struct_and_union3(double, float, long long, 20, 8);
+ check_struct_and_union3(double, float, float, 16, 8);
+ check_struct_and_union3(double, float, double, 20, 8);
+ check_struct_and_union3(double, float, long double, 20, 8);
+ check_struct_and_union3(double, double, char, 20, 8);
+ check_struct_and_union3(double, double, short, 20, 8);
+ check_struct_and_union3(double, double, int, 20, 8);
+ check_struct_and_union3(double, double, long, 20, 8);
+ check_struct_and_union3(double, double, long long, 24, 8);
+ check_struct_and_union3(double, double, float, 20, 8);
+ check_struct_and_union3(double, double, double, 24, 8);
+ check_struct_and_union3(double, double, long double, 24, 8);
+ check_struct_and_union3(double, long double, char, 20, 8);
+ check_struct_and_union3(double, long double, short, 20, 8);
+ check_struct_and_union3(double, long double, int, 20, 8);
+ check_struct_and_union3(double, long double, long, 20, 8);
+ check_struct_and_union3(double, long double, long long, 24, 8);
+ check_struct_and_union3(double, long double, float, 20, 8);
+ check_struct_and_union3(double, long double, double, 24, 8);
+ check_struct_and_union3(double, long double, long double, 24, 8);
+ check_struct_and_union3(long double, char, char, 12, 8);
+ check_struct_and_union3(long double, char, short, 12, 8);
+ check_struct_and_union3(long double, char, int, 16, 8);
+ check_struct_and_union3(long double, char, long, 16, 8);
+ check_struct_and_union3(long double, char, long long, 20, 8);
+ check_struct_and_union3(long double, char, float, 16, 8);
+ check_struct_and_union3(long double, char, double, 20, 8);
+ check_struct_and_union3(long double, char, long double, 20, 8);
+ check_struct_and_union3(long double, short, char, 12, 8);
+ check_struct_and_union3(long double, short, short, 12, 8);
+ check_struct_and_union3(long double, short, int, 16, 8);
+ check_struct_and_union3(long double, short, long, 16, 8);
+ check_struct_and_union3(long double, short, long long, 20, 8);
+ check_struct_and_union3(long double, short, float, 16, 8);
+ check_struct_and_union3(long double, short, double, 20, 8);
+ check_struct_and_union3(long double, short, long double, 20, 8);
+ check_struct_and_union3(long double, int, char, 16, 8);
+ check_struct_and_union3(long double, int, short, 16, 8);
+ check_struct_and_union3(long double, int, int, 16, 8);
+ check_struct_and_union3(long double, int, long, 16, 8);
+ check_struct_and_union3(long double, int, long long, 20, 8);
+ check_struct_and_union3(long double, int, float, 16, 8);
+ check_struct_and_union3(long double, int, double, 20, 8);
+ check_struct_and_union3(long double, int, long double, 20, 8);
+ check_struct_and_union3(long double, long, char, 16, 8);
+ check_struct_and_union3(long double, long, short, 16, 8);
+ check_struct_and_union3(long double, long, int, 16, 8);
+ check_struct_and_union3(long double, long, long, 16, 8);
+ check_struct_and_union3(long double, long, long long, 20, 8);
+ check_struct_and_union3(long double, long, float, 16, 8);
+ check_struct_and_union3(long double, long, double, 20, 8);
+ check_struct_and_union3(long double, long, long double, 20, 8);
+ check_struct_and_union3(long double, long long, char, 20, 8);
+ check_struct_and_union3(long double, long long, short, 20, 8);
+ check_struct_and_union3(long double, long long, int, 20, 8);
+ check_struct_and_union3(long double, long long, long, 20, 8);
+ check_struct_and_union3(long double, long long, long long, 24, 8);
+ check_struct_and_union3(long double, long long, float, 20, 8);
+ check_struct_and_union3(long double, long long, double, 24, 8);
+ check_struct_and_union3(long double, long long, long double, 24, 8);
+ check_struct_and_union3(long double, float, char, 16, 8);
+ check_struct_and_union3(long double, float, short, 16, 8);
+ check_struct_and_union3(long double, float, int, 16, 8);
+ check_struct_and_union3(long double, float, long, 16, 8);
+ check_struct_and_union3(long double, float, long long, 20, 8);
+ check_struct_and_union3(long double, float, float, 16, 8);
+ check_struct_and_union3(long double, float, double, 20, 8);
+ check_struct_and_union3(long double, float, long double, 20, 8);
+ check_struct_and_union3(long double, double, char, 20, 8);
+ check_struct_and_union3(long double, double, short, 20, 8);
+ check_struct_and_union3(long double, double, int, 20, 8);
+ check_struct_and_union3(long double, double, long, 20, 8);
+ check_struct_and_union3(long double, double, long long, 24, 8);
+ check_struct_and_union3(long double, double, float, 20, 8);
+ check_struct_and_union3(long double, double, double, 24, 8);
+ check_struct_and_union3(long double, double, long double, 24, 8);
+ check_struct_and_union3(long double, long double, char, 20, 8);
+ check_struct_and_union3(long double, long double, short, 20, 8);
+ check_struct_and_union3(long double, long double, int, 20, 8);
+ check_struct_and_union3(long double, long double, long, 20, 8);
+ check_struct_and_union3(long double, long double, long long, 24, 8);
+ check_struct_and_union3(long double, long double, float, 20, 8);
+ check_struct_and_union3(long double, long double, double, 24, 8);
+ check_struct_and_union3(long double, long double, long double, 24, 8);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_basic_64bit_returning.c b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_64bit_returning.c
new file mode 100644
index 00000000000..ecece94b793
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_64bit_returning.c
@@ -0,0 +1,57 @@
+#include "defines.h"
+#include "macros.h"
+#include "args.h"
+
+struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
+struct IntegerRegisters iregs;
+unsigned int num_iregs;
+
+long long
+fun_test_returning_long_long (void)
+{
+ volatile_var++;
+ return (long long) 0xabadbeefabadbeefLL;
+}
+
+double
+fun_test_returning_double (void)
+{
+ volatile_var++;
+ return (double) 12345678.0;
+}
+
+union
+{
+ long long ll;
+ double d;
+} test_64;
+
+int
+main (void)
+{
+ unsigned failed = 0;
+ long long ll;
+ double d;
+
+ clear_struct_registers;
+ test_64.ll = 0xabadbeefabadbeefLL;
+
+ ll = WRAP_RET (fun_test_returning_long_long)();
+ if (ll != test_64.ll
+ || (test_64.ll & 0xffffffff) != eax
+ || ((test_64.ll >> 32) & 0xffffffff) != edx)
+ failed++;
+
+ clear_struct_registers;
+ test_64.d = 12345678.0;
+
+ d = WRAP_RET (fun_test_returning_double)();
+ if (d != test_64.d
+ || (test_64.ll & 0xffffffff) != eax
+ || ((test_64.ll >> 32) & 0xffffffff) != edx)
+ printf ("fail double\n"), failed++;
+
+ if (failed)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_basic_alignment.c b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_alignment.c
new file mode 100644
index 00000000000..f14cf170236
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_alignment.c
@@ -0,0 +1,33 @@
+/* This checks alignment of basic types. */
+
+#include "defines.h"
+#include "macros.h"
+
+
+int
+main (void)
+{
+ /* Integral types. */
+ run_signed_tests2(check_align, char, TYPE_ALIGN_CHAR);
+ run_signed_tests2(check_align, short, TYPE_ALIGN_SHORT);
+ run_signed_tests2(check_align, int, TYPE_ALIGN_INT);
+ run_signed_tests2(check_align, long, TYPE_ALIGN_LONG);
+ run_signed_tests2(check_align, long long, TYPE_ALIGN_LONG_LONG);
+ check_align(enumtype, TYPE_ALIGN_ENUM);
+
+ /* Floating point types. */
+ check_align(float, TYPE_ALIGN_FLOAT);
+ check_align(double, TYPE_ALIGN_DOUBLE);
+#ifdef CHECK_LONG_DOUBLE
+ check_align(long double, TYPE_ALIGN_LONG_DOUBLE);
+#endif
+#ifdef CHECK_FLOAT128
+ check_align(__float128, TYPE_ALIGN_FLOAT128);
+#endif
+
+ /* Pointer types. */
+ check_align(void *, TYPE_ALIGN_POINTER);
+ check_align(void (*)(), TYPE_ALIGN_POINTER);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_basic_array_size_and_align.c b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_array_size_and_align.c
new file mode 100644
index 00000000000..e4b6369c19a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_array_size_and_align.c
@@ -0,0 +1,32 @@
+/* Test of simple arrays, size and alignment. */
+
+#include "defines.h"
+#include "macros.h"
+
+
+int
+main (void)
+{
+ /* Integral types. */
+ run_signed_tests3(check_array_size_and_align, char, TYPE_SIZE_CHAR, TYPE_ALIGN_CHAR);
+ run_signed_tests3(check_array_size_and_align, short, TYPE_SIZE_SHORT, TYPE_ALIGN_SHORT);
+ run_signed_tests3(check_array_size_and_align, int, TYPE_SIZE_INT, TYPE_ALIGN_INT);
+ run_signed_tests3(check_array_size_and_align, long, TYPE_SIZE_LONG, TYPE_ALIGN_LONG);
+ run_signed_tests3(check_array_size_and_align, long long, TYPE_SIZE_LONG_LONG, TYPE_ALIGN_LONG_LONG);
+ check_array_size_and_align(enum dummytype, TYPE_SIZE_ENUM, TYPE_ALIGN_ENUM);
+
+ /* Floating point types. */
+ check_array_size_and_align(float, TYPE_SIZE_FLOAT, TYPE_ALIGN_FLOAT);
+ check_array_size_and_align(double, TYPE_SIZE_DOUBLE, TYPE_ALIGN_DOUBLE);
+#ifdef CHECK_LONG_DOUBLE
+ check_array_size_and_align(long double, TYPE_SIZE_LONG_DOUBLE, TYPE_ALIGN_LONG_DOUBLE);
+#endif
+#ifdef CHECK_FLOAT128
+ check_array_size_and_align(__float128, TYPE_SIZE_FLOAT128, TYPE_ALIGN_FLOAT128);
+#endif
+
+ /* Pointer types. The function pointer doesn't work with these macros. */
+ check_array_size_and_align(void *, TYPE_SIZE_POINTER, TYPE_ALIGN_POINTER);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_basic_returning.c b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_returning.c
new file mode 100644
index 00000000000..23efa6e5c01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_returning.c
@@ -0,0 +1,52 @@
+#include "defines.h"
+#include "macros.h"
+#include "args.h"
+
+char
+fun_test_returning_char (void)
+{
+ volatile_var++;
+ return 64;
+}
+
+short
+fun_test_returning_short (void)
+{
+ volatile_var++;
+ return 65;
+}
+
+int
+fun_test_returning_int (void)
+{
+ volatile_var++;
+ return 66;
+}
+
+long
+fun_test_returning_long (void)
+{
+ volatile_var++;
+ return 67;
+}
+
+float
+fun_test_returning_float (void)
+{
+ volatile_var++;
+ return 68;
+}
+
+#define def_test_returning_type(fun, type, ret, reg) \
+ { type var = WRAP_RET (fun) (); \
+ assert (ret == (type) reg && ret == var); }
+int
+main (void)
+{
+ def_test_returning_type(fun_test_returning_char, char, 64, eax);
+ def_test_returning_type(fun_test_returning_short, short, 65, eax);
+ def_test_returning_type(fun_test_returning_int, int, 66, eax);
+ def_test_returning_type(fun_test_returning_long, long, 67, eax);
+ def_test_returning_type(fun_test_returning_float, float, 68, eax);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_basic_sizes.c b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_sizes.c
new file mode 100644
index 00000000000..6582fc638a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_sizes.c
@@ -0,0 +1,36 @@
+/* This checks sizes of basic types. */
+
+#include "defines.h"
+#include "macros.h"
+
+
+int
+main (void)
+{
+ /* Integral types. */
+ run_signed_tests2(check_size, char, TYPE_SIZE_CHAR);
+ run_signed_tests2(check_size, short, TYPE_SIZE_SHORT);
+ run_signed_tests2(check_size, int, TYPE_SIZE_INT);
+ run_signed_tests2(check_size, long, TYPE_SIZE_LONG);
+ run_signed_tests2(check_size, long long, TYPE_SIZE_LONG_LONG);
+#ifdef CHECK_INT128
+ run_signed_tests2(check_size, __int128, TYPE_SIZE_INT128);
+#endif
+ check_size(enumtype, TYPE_SIZE_ENUM);
+
+ /* Floating point types. */
+ check_size(float, TYPE_SIZE_FLOAT);
+ check_size(double, TYPE_SIZE_DOUBLE);
+#ifdef CHECK_LONG_DOUBLE
+ check_size(long double, TYPE_SIZE_LONG_DOUBLE);
+#endif
+#ifdef CHECK_FLOAT128
+ check_size(__float128, TYPE_SIZE_FLOAT128);
+#endif
+
+ /* Pointer types. */
+ check_size(void *, TYPE_SIZE_POINTER);
+ check_size(void (*)(), TYPE_SIZE_POINTER);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_basic_struct_size_and_align.c b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_struct_size_and_align.c
new file mode 100644
index 00000000000..3b5027ffaaf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_struct_size_and_align.c
@@ -0,0 +1,33 @@
+/* This checks size and alignment of structs with a single basic type
+ element. All basic types are checked. */
+
+#include "defines.h"
+#include "macros.h"
+
+
+int
+main (void)
+{
+ /* Integral types. */
+ run_signed_tests3(check_basic_struct_size_and_align, char, TYPE_SIZE_CHAR, TYPE_ALIGN_CHAR);
+ run_signed_tests3(check_basic_struct_size_and_align, short, TYPE_SIZE_SHORT, TYPE_ALIGN_SHORT);
+ run_signed_tests3(check_basic_struct_size_and_align, int, TYPE_SIZE_INT, TYPE_ALIGN_INT);
+ run_signed_tests3(check_basic_struct_size_and_align, long, TYPE_SIZE_LONG, TYPE_ALIGN_LONG);
+ run_signed_tests3(check_basic_struct_size_and_align, long long, TYPE_SIZE_LONG_LONG, TYPE_ALIGN_LONG_LONG);
+ check_basic_struct_size_and_align(enum dummytype, TYPE_SIZE_ENUM, TYPE_ALIGN_ENUM);
+
+ /* Floating point types. */
+ check_basic_struct_size_and_align(float, TYPE_SIZE_FLOAT, TYPE_ALIGN_FLOAT);
+ check_basic_struct_size_and_align(double, TYPE_SIZE_DOUBLE, TYPE_ALIGN_DOUBLE);
+#ifdef CHECK_LONG_DOUBLE
+ check_basic_struct_size_and_align(long double, TYPE_SIZE_LONG_DOUBLE, TYPE_ALIGN_LONG_DOUBLE);
+#endif
+#ifdef CHECK_FLOAT128
+ check_basic_struct_size_and_align(__float128, TYPE_SIZE_FLOAT128, TYPE_ALIGN_FLOAT128);
+#endif
+
+ /* Pointer types. The function pointer doesn't work with these macros. */
+ check_basic_struct_size_and_align(void *, TYPE_SIZE_POINTER, TYPE_ALIGN_POINTER);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_basic_union_size_and_align.c b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_union_size_and_align.c
new file mode 100644
index 00000000000..93ba5ffb8d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_basic_union_size_and_align.c
@@ -0,0 +1,32 @@
+/* Test of simple unions, size and alignment. */
+
+#include "defines.h"
+#include "macros.h"
+
+
+int
+main (void)
+{
+ /* Integral types. */
+ run_signed_tests3(check_basic_union_size_and_align, char, TYPE_SIZE_CHAR, TYPE_ALIGN_CHAR);
+ run_signed_tests3(check_basic_union_size_and_align, short, TYPE_SIZE_SHORT, TYPE_ALIGN_SHORT);
+ run_signed_tests3(check_basic_union_size_and_align, int, TYPE_SIZE_INT, TYPE_ALIGN_INT);
+ run_signed_tests3(check_basic_union_size_and_align, long, TYPE_SIZE_LONG, TYPE_ALIGN_LONG);
+ run_signed_tests3(check_basic_union_size_and_align, long long, TYPE_SIZE_LONG_LONG, TYPE_ALIGN_LONG_LONG);
+ check_basic_union_size_and_align(enum dummytype, TYPE_SIZE_ENUM, TYPE_ALIGN_ENUM);
+
+ /* Floating point types. */
+ check_basic_union_size_and_align(float, TYPE_SIZE_FLOAT, TYPE_ALIGN_FLOAT);
+ check_basic_union_size_and_align(double, TYPE_SIZE_DOUBLE, TYPE_ALIGN_DOUBLE);
+#ifdef CHECK_LONG_DOUBLE
+ check_basic_union_size_and_align(long double, TYPE_SIZE_LONG_DOUBLE, TYPE_ALIGN_LONG_DOUBLE);
+#endif
+#ifdef CHECK_FLOAT128
+ check_basic_union_size_and_align(__float128, TYPE_SIZE_FLOAT128, TYPE_ALIGN_FLOAT128);
+#endif
+
+ /* Pointer types. The function pointer doesn't work with these macros. */
+ check_basic_union_size_and_align(void *, TYPE_SIZE_POINTER, TYPE_ALIGN_POINTER);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_bitfields.c b/gcc/testsuite/gcc.target/i386/iamcu/test_bitfields.c
new file mode 100644
index 00000000000..0b1c29333dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_bitfields.c
@@ -0,0 +1,162 @@
+/* This is a small test to see if bitfields are working. It is only a
+ few structs and a union and a test to see if they have the correct
+ size, if values can be read and written and a couple of argument
+ passing tests. No alignment testing is done. */
+
+#include "defines.h"
+#include "macros.h"
+
+
+/* These five bitfields are taken from the System V ABI, Intel 386
+ architecture supplement. */
+
+/* Word aligned, sizeof is 4. */
+struct RightToLeft
+{
+ int j:5;
+ int k:6;
+ int m:7;
+};
+
+/* Word aligned, sizeof is 12. */
+struct BoundaryAlignment
+{
+ short s:9;
+ int j:9;
+ char c;
+ short t:9;
+ short u:9;
+ char d;
+};
+
+/* Halfword aligned, sizeof is 2. */
+struct StorageUnitSharing
+{
+ char c;
+ short s:8;
+};
+
+/* Halfword aligned, sizeof is 2. */
+union Allocation
+{
+ char c;
+ short s:8;
+};
+
+/* Byte aligned, sizeof is 9. */
+struct Unnamed
+{
+ char c;
+ int :0;
+ char d;
+ short :9;
+ char e;
+ char :0;
+};
+
+/* Extra struct testing bitfields in larger types.
+ Doubleword aligned, sizeof is 8. */
+struct LargerTypes
+{
+ long long l:33;
+ int i:31;
+};
+
+
+void
+passing1 (struct RightToLeft str, int j, int k, int m)
+{
+ assert (str.j == j);
+ assert (str.k == k);
+ assert (str.m == m);
+}
+
+void
+passing2 (struct BoundaryAlignment str, short s, int j, char c, short t,
+ short u, char d)
+{
+ assert (str.s == s);
+ assert (str.j == j);
+ assert (str.c == c);
+ assert (str.t == t);
+ assert (str.u == u);
+ assert (str.d == d);
+}
+
+void
+passing3 (struct StorageUnitSharing str, char c, short s)
+{
+ assert (str.c == c);
+ assert (str.s == s);
+}
+
+void
+passing4 (struct Unnamed str, char c, char d, char e)
+{
+ assert (str.c == c);
+ assert (str.d == d);
+ assert (str.e == e);
+}
+
+void
+passing5 (struct LargerTypes str, long long l, int i)
+{
+ assert (str.l == l);
+ assert (str.i == i);
+}
+
+
+void
+passingU (union Allocation u, char c)
+{
+ assert (u.c == c);
+ assert (u.s == c);
+}
+
+
+int
+main (void)
+{
+ struct RightToLeft str1;
+ struct BoundaryAlignment str2;
+ struct StorageUnitSharing str3;
+ struct Unnamed str4;
+ struct LargerTypes str5;
+ union Allocation u;
+
+ /* Check sizeof's. */
+ check_size(str1, 4);
+ check_size(str2, 12);
+ check_size(str3, 2);
+ check_size(str4, 9);
+ check_size(str5, 8);
+ check_size(u, 2);
+
+ /* Check alignof's. */
+ check_align_lv(str1, 4);
+ check_align_lv(str2, 4);
+ check_align_lv(str3, 2);
+ check_align_lv(str4, 1);
+ check_align_lv(str5, 4);
+ check_align_lv(u, 2);
+
+ /* Check passing. */
+ str1.j = str2.s = str3.c = str4.c = str5.l = 4;
+ str1.k = str2.j = str3.s = str4.d = str5.i = 5;
+ str1.m = str2.c = str4.e = 6;
+ str2.t = 7;
+ str2.u = 8;
+ str2.d = 9;
+ passing1 (str1, 4, 5, 6);
+ passing2 (str2, 4, 5, 6, 7, 8, 9);
+ passing3 (str3, 4, 5);
+ passing4 (str4, 4, 5, 6);
+ passing5 (str5, 4, 5);
+
+ u.c = 5;
+ passingU (u, 5);
+ u.s = 6;
+ passingU (u, 6);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_complex_returning.c b/gcc/testsuite/gcc.target/i386/iamcu/test_complex_returning.c
new file mode 100644
index 00000000000..9e9678d7b02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_complex_returning.c
@@ -0,0 +1,83 @@
+/* This is a small test case for returning a complex number. Written by
+ Andreas Jaeger. */
+
+#include "defines.h"
+
+
+#define BUILD_F_COMPLEX(real, imag) \
+ ({ __complex__ float __retval; \
+ __real__ __retval = (real); \
+ __imag__ __retval = (imag); \
+ __retval; })
+
+#define BUILD_D_COMPLEX(real, imag) \
+ ({ __complex__ double __retval; \
+ __real__ __retval = (real); \
+ __imag__ __retval = (imag); \
+ __retval; })
+
+#define BUILD_LD_COMPLEX(real, imag) \
+ ({ __complex__ long double __retval; \
+ __real__ __retval = (real); \
+ __imag__ __retval = (imag); \
+ __retval; })
+
+__complex__ float
+aj_f_times2 (__complex__ float x)
+{
+ __complex__ float res;
+
+ __real__ res = (2.0 * __real__ x);
+ __imag__ res = (2.0 * __imag__ x);
+
+ return res;
+}
+
+__complex__ double
+aj_d_times2 (__complex__ double x)
+{
+ __complex__ double res;
+
+ __real__ res = (2.0 * __real__ x);
+ __imag__ res = (2.0 * __imag__ x);
+
+ return res;
+}
+
+__complex__ long double
+aj_ld_times2 (__complex__ long double x)
+{
+ __complex__ long double res;
+
+ __real__ res = (2.0 * __real__ x);
+ __imag__ res = (2.0 * __imag__ x);
+
+ return res;
+}
+
+int
+main (void)
+{
+#ifdef CHECK_COMPLEX
+ _Complex float fc, fd;
+ _Complex double dc, dd;
+ _Complex long double ldc, ldd;
+
+ fc = BUILD_LD_COMPLEX (2.0f, 3.0f);
+ fd = aj_f_times2 (fc);
+
+ assert (__real__ fd == 4.0f && __imag__ fd == 6.0f);
+
+ dc = BUILD_LD_COMPLEX (2.0, 3.0);
+ dd = aj_ld_times2 (dc);
+
+ assert (__real__ dd == 4.0 && __imag__ dd == 6.0);
+
+ ldc = BUILD_LD_COMPLEX (2.0L, 3.0L);
+ ldd = aj_ld_times2 (ldc);
+
+ assert (__real__ ldd == 4.0L && __imag__ ldd == 6.0L);
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_passing_floats.c b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_floats.c
new file mode 100644
index 00000000000..6bb24ccd75c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_floats.c
@@ -0,0 +1,608 @@
+#include "defines.h"
+#include "macros.h"
+#include "args.h"
+
+struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
+struct IntegerRegisters iregs;
+unsigned int num_iregs;
+
+/* This struct holds values for argument checking. */
+struct
+{
+ float f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23;
+} values_float;
+
+struct
+{
+ double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23;
+} values_double;
+
+struct
+{
+ ldouble f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23;
+} values_ldouble;
+
+void
+fun_check_float_passing_float8_values (float f0 ATTRIBUTE_UNUSED, float f1 ATTRIBUTE_UNUSED, float f2 ATTRIBUTE_UNUSED, float f3 ATTRIBUTE_UNUSED, float f4 ATTRIBUTE_UNUSED, float f5 ATTRIBUTE_UNUSED, float f6 ATTRIBUTE_UNUSED, float f7 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_float.f0 == f0);
+ assert (values_float.f1 == f1);
+ assert (values_float.f2 == f2);
+ assert (values_float.f3 == f3);
+ assert (values_float.f4 == f4);
+ assert (values_float.f5 == f5);
+ assert (values_float.f6 == f6);
+ assert (values_float.f7 == f7);
+
+}
+
+void
+fun_check_float_passing_float8_regs (float f0 ATTRIBUTE_UNUSED, float f1 ATTRIBUTE_UNUSED, float f2 ATTRIBUTE_UNUSED, float f3 ATTRIBUTE_UNUSED, float f4 ATTRIBUTE_UNUSED, float f5 ATTRIBUTE_UNUSED, float f6 ATTRIBUTE_UNUSED, float f7 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_float_arguments;
+}
+
+void
+fun_check_float_passing_float16_values (float f0 ATTRIBUTE_UNUSED, float f1 ATTRIBUTE_UNUSED, float f2 ATTRIBUTE_UNUSED, float f3 ATTRIBUTE_UNUSED, float f4 ATTRIBUTE_UNUSED, float f5 ATTRIBUTE_UNUSED, float f6 ATTRIBUTE_UNUSED, float f7 ATTRIBUTE_UNUSED, float f8 ATTRIBUTE_UNUSED, float f9 ATTRIBUTE_UNUSED, float f10 ATTRIBUTE_UNUSED, float f11 ATTRIBUTE_UNUSED, float f12 ATTRIBUTE_UNUSED, float f13 ATTRIBUTE_UNUSED, float f14 ATTRIBUTE_UNUSED, float f15 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_float.f0 == f0);
+ assert (values_float.f1 == f1);
+ assert (values_float.f2 == f2);
+ assert (values_float.f3 == f3);
+ assert (values_float.f4 == f4);
+ assert (values_float.f5 == f5);
+ assert (values_float.f6 == f6);
+ assert (values_float.f7 == f7);
+ assert (values_float.f8 == f8);
+ assert (values_float.f9 == f9);
+ assert (values_float.f10 == f10);
+ assert (values_float.f11 == f11);
+ assert (values_float.f12 == f12);
+ assert (values_float.f13 == f13);
+ assert (values_float.f14 == f14);
+ assert (values_float.f15 == f15);
+
+}
+
+void
+fun_check_float_passing_float16_regs (float f0 ATTRIBUTE_UNUSED, float f1 ATTRIBUTE_UNUSED, float f2 ATTRIBUTE_UNUSED, float f3 ATTRIBUTE_UNUSED, float f4 ATTRIBUTE_UNUSED, float f5 ATTRIBUTE_UNUSED, float f6 ATTRIBUTE_UNUSED, float f7 ATTRIBUTE_UNUSED, float f8 ATTRIBUTE_UNUSED, float f9 ATTRIBUTE_UNUSED, float f10 ATTRIBUTE_UNUSED, float f11 ATTRIBUTE_UNUSED, float f12 ATTRIBUTE_UNUSED, float f13 ATTRIBUTE_UNUSED, float f14 ATTRIBUTE_UNUSED, float f15 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_float_arguments;
+}
+
+void
+fun_check_float_passing_float20_values (float f0 ATTRIBUTE_UNUSED, float f1 ATTRIBUTE_UNUSED, float f2 ATTRIBUTE_UNUSED, float f3 ATTRIBUTE_UNUSED, float f4 ATTRIBUTE_UNUSED, float f5 ATTRIBUTE_UNUSED, float f6 ATTRIBUTE_UNUSED, float f7 ATTRIBUTE_UNUSED, float f8 ATTRIBUTE_UNUSED, float f9 ATTRIBUTE_UNUSED, float f10 ATTRIBUTE_UNUSED, float f11 ATTRIBUTE_UNUSED, float f12 ATTRIBUTE_UNUSED, float f13 ATTRIBUTE_UNUSED, float f14 ATTRIBUTE_UNUSED, float f15 ATTRIBUTE_UNUSED, float f16 ATTRIBUTE_UNUSED, float f17 ATTRIBUTE_UNUSED, float f18 ATTRIBUTE_UNUSED, float f19 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_float.f0 == f0);
+ assert (values_float.f1 == f1);
+ assert (values_float.f2 == f2);
+ assert (values_float.f3 == f3);
+ assert (values_float.f4 == f4);
+ assert (values_float.f5 == f5);
+ assert (values_float.f6 == f6);
+ assert (values_float.f7 == f7);
+ assert (values_float.f8 == f8);
+ assert (values_float.f9 == f9);
+ assert (values_float.f10 == f10);
+ assert (values_float.f11 == f11);
+ assert (values_float.f12 == f12);
+ assert (values_float.f13 == f13);
+ assert (values_float.f14 == f14);
+ assert (values_float.f15 == f15);
+ assert (values_float.f16 == f16);
+ assert (values_float.f17 == f17);
+ assert (values_float.f18 == f18);
+ assert (values_float.f19 == f19);
+
+}
+
+void
+fun_check_float_passing_float20_regs (float f0 ATTRIBUTE_UNUSED, float f1 ATTRIBUTE_UNUSED, float f2 ATTRIBUTE_UNUSED, float f3 ATTRIBUTE_UNUSED, float f4 ATTRIBUTE_UNUSED, float f5 ATTRIBUTE_UNUSED, float f6 ATTRIBUTE_UNUSED, float f7 ATTRIBUTE_UNUSED, float f8 ATTRIBUTE_UNUSED, float f9 ATTRIBUTE_UNUSED, float f10 ATTRIBUTE_UNUSED, float f11 ATTRIBUTE_UNUSED, float f12 ATTRIBUTE_UNUSED, float f13 ATTRIBUTE_UNUSED, float f14 ATTRIBUTE_UNUSED, float f15 ATTRIBUTE_UNUSED, float f16 ATTRIBUTE_UNUSED, float f17 ATTRIBUTE_UNUSED, float f18 ATTRIBUTE_UNUSED, float f19 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_float_arguments;
+}
+
+void
+fun_check_float_passing_double8_values (double f0 ATTRIBUTE_UNUSED, double f1 ATTRIBUTE_UNUSED, double f2 ATTRIBUTE_UNUSED, double f3 ATTRIBUTE_UNUSED, double f4 ATTRIBUTE_UNUSED, double f5 ATTRIBUTE_UNUSED, double f6 ATTRIBUTE_UNUSED, double f7 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_double.f0 == f0);
+ assert (values_double.f1 == f1);
+ assert (values_double.f2 == f2);
+ assert (values_double.f3 == f3);
+ assert (values_double.f4 == f4);
+ assert (values_double.f5 == f5);
+ assert (values_double.f6 == f6);
+ assert (values_double.f7 == f7);
+
+}
+
+void
+fun_check_float_passing_double8_regs (double f0 ATTRIBUTE_UNUSED, double f1 ATTRIBUTE_UNUSED, double f2 ATTRIBUTE_UNUSED, double f3 ATTRIBUTE_UNUSED, double f4 ATTRIBUTE_UNUSED, double f5 ATTRIBUTE_UNUSED, double f6 ATTRIBUTE_UNUSED, double f7 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_double_arguments;
+}
+
+void
+fun_check_float_passing_double16_values (double f0 ATTRIBUTE_UNUSED, double f1 ATTRIBUTE_UNUSED, double f2 ATTRIBUTE_UNUSED, double f3 ATTRIBUTE_UNUSED, double f4 ATTRIBUTE_UNUSED, double f5 ATTRIBUTE_UNUSED, double f6 ATTRIBUTE_UNUSED, double f7 ATTRIBUTE_UNUSED, double f8 ATTRIBUTE_UNUSED, double f9 ATTRIBUTE_UNUSED, double f10 ATTRIBUTE_UNUSED, double f11 ATTRIBUTE_UNUSED, double f12 ATTRIBUTE_UNUSED, double f13 ATTRIBUTE_UNUSED, double f14 ATTRIBUTE_UNUSED, double f15 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_double.f0 == f0);
+ assert (values_double.f1 == f1);
+ assert (values_double.f2 == f2);
+ assert (values_double.f3 == f3);
+ assert (values_double.f4 == f4);
+ assert (values_double.f5 == f5);
+ assert (values_double.f6 == f6);
+ assert (values_double.f7 == f7);
+ assert (values_double.f8 == f8);
+ assert (values_double.f9 == f9);
+ assert (values_double.f10 == f10);
+ assert (values_double.f11 == f11);
+ assert (values_double.f12 == f12);
+ assert (values_double.f13 == f13);
+ assert (values_double.f14 == f14);
+ assert (values_double.f15 == f15);
+
+}
+
+void
+fun_check_float_passing_double16_regs (double f0 ATTRIBUTE_UNUSED, double f1 ATTRIBUTE_UNUSED, double f2 ATTRIBUTE_UNUSED, double f3 ATTRIBUTE_UNUSED, double f4 ATTRIBUTE_UNUSED, double f5 ATTRIBUTE_UNUSED, double f6 ATTRIBUTE_UNUSED, double f7 ATTRIBUTE_UNUSED, double f8 ATTRIBUTE_UNUSED, double f9 ATTRIBUTE_UNUSED, double f10 ATTRIBUTE_UNUSED, double f11 ATTRIBUTE_UNUSED, double f12 ATTRIBUTE_UNUSED, double f13 ATTRIBUTE_UNUSED, double f14 ATTRIBUTE_UNUSED, double f15 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_double_arguments;
+}
+
+void
+fun_check_float_passing_double20_values (double f0 ATTRIBUTE_UNUSED, double f1 ATTRIBUTE_UNUSED, double f2 ATTRIBUTE_UNUSED, double f3 ATTRIBUTE_UNUSED, double f4 ATTRIBUTE_UNUSED, double f5 ATTRIBUTE_UNUSED, double f6 ATTRIBUTE_UNUSED, double f7 ATTRIBUTE_UNUSED, double f8 ATTRIBUTE_UNUSED, double f9 ATTRIBUTE_UNUSED, double f10 ATTRIBUTE_UNUSED, double f11 ATTRIBUTE_UNUSED, double f12 ATTRIBUTE_UNUSED, double f13 ATTRIBUTE_UNUSED, double f14 ATTRIBUTE_UNUSED, double f15 ATTRIBUTE_UNUSED, double f16 ATTRIBUTE_UNUSED, double f17 ATTRIBUTE_UNUSED, double f18 ATTRIBUTE_UNUSED, double f19 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_double.f0 == f0);
+ assert (values_double.f1 == f1);
+ assert (values_double.f2 == f2);
+ assert (values_double.f3 == f3);
+ assert (values_double.f4 == f4);
+ assert (values_double.f5 == f5);
+ assert (values_double.f6 == f6);
+ assert (values_double.f7 == f7);
+ assert (values_double.f8 == f8);
+ assert (values_double.f9 == f9);
+ assert (values_double.f10 == f10);
+ assert (values_double.f11 == f11);
+ assert (values_double.f12 == f12);
+ assert (values_double.f13 == f13);
+ assert (values_double.f14 == f14);
+ assert (values_double.f15 == f15);
+ assert (values_double.f16 == f16);
+ assert (values_double.f17 == f17);
+ assert (values_double.f18 == f18);
+ assert (values_double.f19 == f19);
+
+}
+
+void
+fun_check_float_passing_double20_regs (double f0 ATTRIBUTE_UNUSED, double f1 ATTRIBUTE_UNUSED, double f2 ATTRIBUTE_UNUSED, double f3 ATTRIBUTE_UNUSED, double f4 ATTRIBUTE_UNUSED, double f5 ATTRIBUTE_UNUSED, double f6 ATTRIBUTE_UNUSED, double f7 ATTRIBUTE_UNUSED, double f8 ATTRIBUTE_UNUSED, double f9 ATTRIBUTE_UNUSED, double f10 ATTRIBUTE_UNUSED, double f11 ATTRIBUTE_UNUSED, double f12 ATTRIBUTE_UNUSED, double f13 ATTRIBUTE_UNUSED, double f14 ATTRIBUTE_UNUSED, double f15 ATTRIBUTE_UNUSED, double f16 ATTRIBUTE_UNUSED, double f17 ATTRIBUTE_UNUSED, double f18 ATTRIBUTE_UNUSED, double f19 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_double_arguments;
+}
+
+void
+fun_check_x87_passing_ldouble8_values (ldouble f0 ATTRIBUTE_UNUSED, ldouble f1 ATTRIBUTE_UNUSED, ldouble f2 ATTRIBUTE_UNUSED, ldouble f3 ATTRIBUTE_UNUSED, ldouble f4 ATTRIBUTE_UNUSED, ldouble f5 ATTRIBUTE_UNUSED, ldouble f6 ATTRIBUTE_UNUSED, ldouble f7 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_ldouble.f0 == f0);
+ assert (values_ldouble.f1 == f1);
+ assert (values_ldouble.f2 == f2);
+ assert (values_ldouble.f3 == f3);
+ assert (values_ldouble.f4 == f4);
+ assert (values_ldouble.f5 == f5);
+ assert (values_ldouble.f6 == f6);
+ assert (values_ldouble.f7 == f7);
+
+}
+
+void
+fun_check_x87_passing_ldouble8_regs (ldouble f0 ATTRIBUTE_UNUSED, ldouble f1 ATTRIBUTE_UNUSED, ldouble f2 ATTRIBUTE_UNUSED, ldouble f3 ATTRIBUTE_UNUSED, ldouble f4 ATTRIBUTE_UNUSED, ldouble f5 ATTRIBUTE_UNUSED, ldouble f6 ATTRIBUTE_UNUSED, ldouble f7 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_ldouble_arguments;
+}
+
+void
+fun_check_x87_passing_ldouble16_values (ldouble f0 ATTRIBUTE_UNUSED, ldouble f1 ATTRIBUTE_UNUSED, ldouble f2 ATTRIBUTE_UNUSED, ldouble f3 ATTRIBUTE_UNUSED, ldouble f4 ATTRIBUTE_UNUSED, ldouble f5 ATTRIBUTE_UNUSED, ldouble f6 ATTRIBUTE_UNUSED, ldouble f7 ATTRIBUTE_UNUSED, ldouble f8 ATTRIBUTE_UNUSED, ldouble f9 ATTRIBUTE_UNUSED, ldouble f10 ATTRIBUTE_UNUSED, ldouble f11 ATTRIBUTE_UNUSED, ldouble f12 ATTRIBUTE_UNUSED, ldouble f13 ATTRIBUTE_UNUSED, ldouble f14 ATTRIBUTE_UNUSED, ldouble f15 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_ldouble.f0 == f0);
+ assert (values_ldouble.f1 == f1);
+ assert (values_ldouble.f2 == f2);
+ assert (values_ldouble.f3 == f3);
+ assert (values_ldouble.f4 == f4);
+ assert (values_ldouble.f5 == f5);
+ assert (values_ldouble.f6 == f6);
+ assert (values_ldouble.f7 == f7);
+ assert (values_ldouble.f8 == f8);
+ assert (values_ldouble.f9 == f9);
+ assert (values_ldouble.f10 == f10);
+ assert (values_ldouble.f11 == f11);
+ assert (values_ldouble.f12 == f12);
+ assert (values_ldouble.f13 == f13);
+ assert (values_ldouble.f14 == f14);
+ assert (values_ldouble.f15 == f15);
+
+}
+
+void
+fun_check_x87_passing_ldouble16_regs (ldouble f0 ATTRIBUTE_UNUSED, ldouble f1 ATTRIBUTE_UNUSED, ldouble f2 ATTRIBUTE_UNUSED, ldouble f3 ATTRIBUTE_UNUSED, ldouble f4 ATTRIBUTE_UNUSED, ldouble f5 ATTRIBUTE_UNUSED, ldouble f6 ATTRIBUTE_UNUSED, ldouble f7 ATTRIBUTE_UNUSED, ldouble f8 ATTRIBUTE_UNUSED, ldouble f9 ATTRIBUTE_UNUSED, ldouble f10 ATTRIBUTE_UNUSED, ldouble f11 ATTRIBUTE_UNUSED, ldouble f12 ATTRIBUTE_UNUSED, ldouble f13 ATTRIBUTE_UNUSED, ldouble f14 ATTRIBUTE_UNUSED, ldouble f15 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_ldouble_arguments;
+}
+
+void
+fun_check_x87_passing_ldouble20_values (ldouble f0 ATTRIBUTE_UNUSED, ldouble f1 ATTRIBUTE_UNUSED, ldouble f2 ATTRIBUTE_UNUSED, ldouble f3 ATTRIBUTE_UNUSED, ldouble f4 ATTRIBUTE_UNUSED, ldouble f5 ATTRIBUTE_UNUSED, ldouble f6 ATTRIBUTE_UNUSED, ldouble f7 ATTRIBUTE_UNUSED, ldouble f8 ATTRIBUTE_UNUSED, ldouble f9 ATTRIBUTE_UNUSED, ldouble f10 ATTRIBUTE_UNUSED, ldouble f11 ATTRIBUTE_UNUSED, ldouble f12 ATTRIBUTE_UNUSED, ldouble f13 ATTRIBUTE_UNUSED, ldouble f14 ATTRIBUTE_UNUSED, ldouble f15 ATTRIBUTE_UNUSED, ldouble f16 ATTRIBUTE_UNUSED, ldouble f17 ATTRIBUTE_UNUSED, ldouble f18 ATTRIBUTE_UNUSED, ldouble f19 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_ldouble.f0 == f0);
+ assert (values_ldouble.f1 == f1);
+ assert (values_ldouble.f2 == f2);
+ assert (values_ldouble.f3 == f3);
+ assert (values_ldouble.f4 == f4);
+ assert (values_ldouble.f5 == f5);
+ assert (values_ldouble.f6 == f6);
+ assert (values_ldouble.f7 == f7);
+ assert (values_ldouble.f8 == f8);
+ assert (values_ldouble.f9 == f9);
+ assert (values_ldouble.f10 == f10);
+ assert (values_ldouble.f11 == f11);
+ assert (values_ldouble.f12 == f12);
+ assert (values_ldouble.f13 == f13);
+ assert (values_ldouble.f14 == f14);
+ assert (values_ldouble.f15 == f15);
+ assert (values_ldouble.f16 == f16);
+ assert (values_ldouble.f17 == f17);
+ assert (values_ldouble.f18 == f18);
+ assert (values_ldouble.f19 == f19);
+
+}
+
+void
+fun_check_x87_passing_ldouble20_regs (ldouble f0 ATTRIBUTE_UNUSED, ldouble f1 ATTRIBUTE_UNUSED, ldouble f2 ATTRIBUTE_UNUSED, ldouble f3 ATTRIBUTE_UNUSED, ldouble f4 ATTRIBUTE_UNUSED, ldouble f5 ATTRIBUTE_UNUSED, ldouble f6 ATTRIBUTE_UNUSED, ldouble f7 ATTRIBUTE_UNUSED, ldouble f8 ATTRIBUTE_UNUSED, ldouble f9 ATTRIBUTE_UNUSED, ldouble f10 ATTRIBUTE_UNUSED, ldouble f11 ATTRIBUTE_UNUSED, ldouble f12 ATTRIBUTE_UNUSED, ldouble f13 ATTRIBUTE_UNUSED, ldouble f14 ATTRIBUTE_UNUSED, ldouble f15 ATTRIBUTE_UNUSED, ldouble f16 ATTRIBUTE_UNUSED, ldouble f17 ATTRIBUTE_UNUSED, ldouble f18 ATTRIBUTE_UNUSED, ldouble f19 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_ldouble_arguments;
+}
+
+#define def_check_float_passing8(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _func1, _func2, TYPE) \
+ values_ ## TYPE .f0 = _f0; \
+ values_ ## TYPE .f1 = _f1; \
+ values_ ## TYPE .f2 = _f2; \
+ values_ ## TYPE .f3 = _f3; \
+ values_ ## TYPE .f4 = _f4; \
+ values_ ## TYPE .f5 = _f5; \
+ values_ ## TYPE .f6 = _f6; \
+ values_ ## TYPE .f7 = _f7; \
+ WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7); \
+ \
+ clear_int_registers; \
+ if (sizeof (TYPE) == 4) \
+ { \
+ u.f = _f0; \
+ iregs.I0 = u.i[0]; \
+ u.f = _f1; \
+ iregs.I1 = u.i[0]; \
+ u.f = _f2; \
+ iregs.I2 = u.i[0]; \
+ num_iregs = 3; \
+ } \
+ else \
+ { \
+ u.d = _f0; \
+ iregs.I0 = u.i[0]; \
+ iregs.I1 = u.i[1]; \
+ num_iregs = 2; \
+ } \
+ WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7);
+
+#define def_check_float_passing16(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _func1, _func2, TYPE) \
+ values_ ## TYPE .f0 = _f0; \
+ values_ ## TYPE .f1 = _f1; \
+ values_ ## TYPE .f2 = _f2; \
+ values_ ## TYPE .f3 = _f3; \
+ values_ ## TYPE .f4 = _f4; \
+ values_ ## TYPE .f5 = _f5; \
+ values_ ## TYPE .f6 = _f6; \
+ values_ ## TYPE .f7 = _f7; \
+ values_ ## TYPE .f8 = _f8; \
+ values_ ## TYPE .f9 = _f9; \
+ values_ ## TYPE .f10 = _f10; \
+ values_ ## TYPE .f11 = _f11; \
+ values_ ## TYPE .f12 = _f12; \
+ values_ ## TYPE .f13 = _f13; \
+ values_ ## TYPE .f14 = _f14; \
+ values_ ## TYPE .f15 = _f15; \
+ WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15); \
+ \
+ clear_int_registers; \
+ if (sizeof (TYPE) == 4) \
+ { \
+ u.f = _f0; \
+ iregs.I0 = u.i[0]; \
+ u.f = _f1; \
+ iregs.I1 = u.i[0]; \
+ u.f = _f2; \
+ iregs.I2 = u.i[0]; \
+ num_iregs = 3; \
+ } \
+ else \
+ { \
+ u.d = _f0; \
+ iregs.I0 = u.i[0]; \
+ iregs.I1 = u.i[1]; \
+ num_iregs = 2; \
+ } \
+ WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15);
+
+#define def_check_float_passing20(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, _f17, _f18, _f19, _func1, _func2, TYPE) \
+ values_ ## TYPE .f0 = _f0; \
+ values_ ## TYPE .f1 = _f1; \
+ values_ ## TYPE .f2 = _f2; \
+ values_ ## TYPE .f3 = _f3; \
+ values_ ## TYPE .f4 = _f4; \
+ values_ ## TYPE .f5 = _f5; \
+ values_ ## TYPE .f6 = _f6; \
+ values_ ## TYPE .f7 = _f7; \
+ values_ ## TYPE .f8 = _f8; \
+ values_ ## TYPE .f9 = _f9; \
+ values_ ## TYPE .f10 = _f10; \
+ values_ ## TYPE .f11 = _f11; \
+ values_ ## TYPE .f12 = _f12; \
+ values_ ## TYPE .f13 = _f13; \
+ values_ ## TYPE .f14 = _f14; \
+ values_ ## TYPE .f15 = _f15; \
+ values_ ## TYPE .f16 = _f16; \
+ values_ ## TYPE .f17 = _f17; \
+ values_ ## TYPE .f18 = _f18; \
+ values_ ## TYPE .f19 = _f19; \
+ WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, _f17, _f18, _f19); \
+ \
+ clear_int_registers; \
+ if (sizeof (TYPE) == 4) \
+ { \
+ u.f = _f0; \
+ iregs.I0 = u.i[0]; \
+ u.f = _f1; \
+ iregs.I1 = u.i[0]; \
+ u.f = _f2; \
+ iregs.I2 = u.i[0]; \
+ num_iregs = 3; \
+ } \
+ else \
+ { \
+ u.d = _f0; \
+ iregs.I0 = u.i[0]; \
+ iregs.I1 = u.i[1]; \
+ num_iregs = 2; \
+ } \
+ WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, _f17, _f18, _f19);
+
+#define def_check_x87_passing8(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _func1, _func2, TYPE) \
+ values_ ## TYPE .f0 = _f0; \
+ values_ ## TYPE .f1 = _f1; \
+ values_ ## TYPE .f2 = _f2; \
+ values_ ## TYPE .f3 = _f3; \
+ values_ ## TYPE .f4 = _f4; \
+ values_ ## TYPE .f5 = _f5; \
+ values_ ## TYPE .f6 = _f6; \
+ values_ ## TYPE .f7 = _f7; \
+ WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7); \
+ \
+ clear_int_registers; \
+ if (sizeof (TYPE) == 4) \
+ { \
+ u.f = _f0; \
+ iregs.I0 = u.i[0]; \
+ u.f = _f1; \
+ iregs.I1 = u.i[0]; \
+ u.f = _f2; \
+ iregs.I2 = u.i[0]; \
+ num_iregs = 3; \
+ } \
+ else \
+ { \
+ u.d = _f0; \
+ iregs.I0 = u.i[0]; \
+ iregs.I1 = u.i[1]; \
+ num_iregs = 2; \
+ } \
+ WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7);
+
+#define def_check_x87_passing16(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _func1, _func2, TYPE) \
+ values_ ## TYPE .f0 = _f0; \
+ values_ ## TYPE .f1 = _f1; \
+ values_ ## TYPE .f2 = _f2; \
+ values_ ## TYPE .f3 = _f3; \
+ values_ ## TYPE .f4 = _f4; \
+ values_ ## TYPE .f5 = _f5; \
+ values_ ## TYPE .f6 = _f6; \
+ values_ ## TYPE .f7 = _f7; \
+ values_ ## TYPE .f8 = _f8; \
+ values_ ## TYPE .f9 = _f9; \
+ values_ ## TYPE .f10 = _f10; \
+ values_ ## TYPE .f11 = _f11; \
+ values_ ## TYPE .f12 = _f12; \
+ values_ ## TYPE .f13 = _f13; \
+ values_ ## TYPE .f14 = _f14; \
+ values_ ## TYPE .f15 = _f15; \
+ WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15); \
+ \
+ clear_int_registers; \
+ if (sizeof (TYPE) == 4) \
+ { \
+ u.f = _f0; \
+ iregs.I0 = u.i[0]; \
+ u.f = _f1; \
+ iregs.I1 = u.i[0]; \
+ u.f = _f2; \
+ iregs.I2 = u.i[0]; \
+ num_iregs = 3; \
+ } \
+ else \
+ { \
+ u.d = _f0; \
+ iregs.I0 = u.i[0]; \
+ iregs.I1 = u.i[1]; \
+ num_iregs = 2; \
+ } \
+ WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15);
+
+#define def_check_x87_passing20(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, _f17, _f18, _f19, _func1, _func2, TYPE) \
+ values_ ## TYPE .f0 = _f0; \
+ values_ ## TYPE .f1 = _f1; \
+ values_ ## TYPE .f2 = _f2; \
+ values_ ## TYPE .f3 = _f3; \
+ values_ ## TYPE .f4 = _f4; \
+ values_ ## TYPE .f5 = _f5; \
+ values_ ## TYPE .f6 = _f6; \
+ values_ ## TYPE .f7 = _f7; \
+ values_ ## TYPE .f8 = _f8; \
+ values_ ## TYPE .f9 = _f9; \
+ values_ ## TYPE .f10 = _f10; \
+ values_ ## TYPE .f11 = _f11; \
+ values_ ## TYPE .f12 = _f12; \
+ values_ ## TYPE .f13 = _f13; \
+ values_ ## TYPE .f14 = _f14; \
+ values_ ## TYPE .f15 = _f15; \
+ values_ ## TYPE .f16 = _f16; \
+ values_ ## TYPE .f17 = _f17; \
+ values_ ## TYPE .f18 = _f18; \
+ values_ ## TYPE .f19 = _f19; \
+ WRAP_CALL(_func1) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, _f17, _f18, _f19); \
+ \
+ clear_int_registers; \
+ if (sizeof (TYPE) == 4) \
+ { \
+ u.f = _f0; \
+ iregs.I0 = u.i[0]; \
+ u.f = _f1; \
+ iregs.I1 = u.i[0]; \
+ u.f = _f2; \
+ iregs.I2 = u.i[0]; \
+ num_iregs = 3; \
+ } \
+ else \
+ { \
+ u.d = _f0; \
+ iregs.I0 = u.i[0]; \
+ iregs.I1 = u.i[1]; \
+ num_iregs = 2; \
+ } \
+ WRAP_CALL(_func2) (_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, _f17, _f18, _f19);
+
+void
+test_floats_on_stack ()
+{
+ union
+ {
+ float f;
+ double d;
+ int i[2];
+ } u;
+ def_check_float_passing8(32, 33, 34, 35, 36, 37, 38, 39, fun_check_float_passing_float8_values, fun_check_float_passing_float8_regs, float);
+
+ def_check_float_passing16(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, fun_check_float_passing_float16_values, fun_check_float_passing_float16_regs, float);
+}
+
+void
+test_too_many_floats ()
+{
+ union
+ {
+ float f;
+ double d;
+ int i[2];
+ } u;
+ def_check_float_passing20(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, fun_check_float_passing_float20_values, fun_check_float_passing_float20_regs, float);
+}
+
+void
+test_doubles_on_stack ()
+{
+ union
+ {
+ float f;
+ double d;
+ int i[2];
+ } u;
+ def_check_float_passing8(32, 33, 34, 35, 36, 37, 38, 39, fun_check_float_passing_double8_values, fun_check_float_passing_double8_regs, double);
+
+ def_check_float_passing16(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, fun_check_float_passing_double16_values, fun_check_float_passing_double16_regs, double);
+}
+
+void
+test_too_many_doubles ()
+{
+ union
+ {
+ float f;
+ double d;
+ int i[2];
+ } u;
+ def_check_float_passing20(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, fun_check_float_passing_double20_values, fun_check_float_passing_double20_regs, double);
+}
+
+void
+test_long_doubles_on_stack ()
+{
+ union
+ {
+ float f;
+ double d;
+ int i[2];
+ } u;
+ def_check_x87_passing8(32, 33, 34, 35, 36, 37, 38, 39, fun_check_x87_passing_ldouble8_values, fun_check_x87_passing_ldouble8_regs, ldouble);
+}
+
+void
+test_too_many_long_doubles ()
+{
+ union
+ {
+ float f;
+ double d;
+ int i[2];
+ } u;
+ def_check_x87_passing20(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, fun_check_x87_passing_ldouble20_values, fun_check_x87_passing_ldouble20_regs, ldouble);
+}
+
+void
+test_float128s_on_stack ()
+{
+}
+
+void
+test_too_many_float128s ()
+{
+}
+
+
+int
+main (void)
+{
+ test_floats_on_stack ();
+ test_too_many_floats ();
+ test_doubles_on_stack ();
+ test_too_many_doubles ();
+ test_long_doubles_on_stack ();
+ test_too_many_long_doubles ();
+ test_float128s_on_stack ();
+ test_too_many_float128s ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_passing_integers.c b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_integers.c
new file mode 100644
index 00000000000..046e14037ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_integers.c
@@ -0,0 +1,182 @@
+#include "defines.h"
+#include "macros.h"
+#include "args.h"
+
+struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
+struct IntegerRegisters iregs;
+unsigned int num_iregs;
+
+/* This struct holds values for argument checking. */
+struct
+{
+ int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23;
+} values_int;
+
+struct
+{
+ long i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23;
+} values_long;
+
+void
+fun_check_int_passing_int6_values (int i0 ATTRIBUTE_UNUSED, int i1 ATTRIBUTE_UNUSED, int i2 ATTRIBUTE_UNUSED, int i3 ATTRIBUTE_UNUSED, int i4 ATTRIBUTE_UNUSED, int i5 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_int.i0 == i0);
+ assert (values_int.i1 == i1);
+ assert (values_int.i2 == i2);
+ assert (values_int.i3 == i3);
+ assert (values_int.i4 == i4);
+ assert (values_int.i5 == i5);
+
+}
+
+void
+fun_check_int_passing_int6_regs (int i0 ATTRIBUTE_UNUSED, int i1 ATTRIBUTE_UNUSED, int i2 ATTRIBUTE_UNUSED, int i3 ATTRIBUTE_UNUSED, int i4 ATTRIBUTE_UNUSED, int i5 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_int_arguments;
+}
+
+void
+fun_check_int_passing_int12_values (int i0 ATTRIBUTE_UNUSED, int i1 ATTRIBUTE_UNUSED, int i2 ATTRIBUTE_UNUSED, int i3 ATTRIBUTE_UNUSED, int i4 ATTRIBUTE_UNUSED, int i5 ATTRIBUTE_UNUSED, int i6 ATTRIBUTE_UNUSED, int i7 ATTRIBUTE_UNUSED, int i8 ATTRIBUTE_UNUSED, int i9 ATTRIBUTE_UNUSED, int i10 ATTRIBUTE_UNUSED, int i11 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_int.i0 == i0);
+ assert (values_int.i1 == i1);
+ assert (values_int.i2 == i2);
+ assert (values_int.i3 == i3);
+ assert (values_int.i4 == i4);
+ assert (values_int.i5 == i5);
+ assert (values_int.i6 == i6);
+ assert (values_int.i7 == i7);
+ assert (values_int.i8 == i8);
+ assert (values_int.i9 == i9);
+ assert (values_int.i10 == i10);
+ assert (values_int.i11 == i11);
+
+}
+
+void
+fun_check_int_passing_int12_regs (int i0 ATTRIBUTE_UNUSED, int i1 ATTRIBUTE_UNUSED, int i2 ATTRIBUTE_UNUSED, int i3 ATTRIBUTE_UNUSED, int i4 ATTRIBUTE_UNUSED, int i5 ATTRIBUTE_UNUSED, int i6 ATTRIBUTE_UNUSED, int i7 ATTRIBUTE_UNUSED, int i8 ATTRIBUTE_UNUSED, int i9 ATTRIBUTE_UNUSED, int i10 ATTRIBUTE_UNUSED, int i11 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_int_arguments;
+}
+
+void
+fun_check_int_passing_long6_values (long i0 ATTRIBUTE_UNUSED, long i1 ATTRIBUTE_UNUSED, long i2 ATTRIBUTE_UNUSED, long i3 ATTRIBUTE_UNUSED, long i4 ATTRIBUTE_UNUSED, long i5 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_long.i0 == i0);
+ assert (values_long.i1 == i1);
+ assert (values_long.i2 == i2);
+ assert (values_long.i3 == i3);
+ assert (values_long.i4 == i4);
+ assert (values_long.i5 == i5);
+
+}
+
+void
+fun_check_int_passing_long6_regs (long i0 ATTRIBUTE_UNUSED, long i1 ATTRIBUTE_UNUSED, long i2 ATTRIBUTE_UNUSED, long i3 ATTRIBUTE_UNUSED, long i4 ATTRIBUTE_UNUSED, long i5 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_long_arguments;
+}
+
+void
+fun_check_int_passing_long12_values (long i0 ATTRIBUTE_UNUSED, long i1 ATTRIBUTE_UNUSED, long i2 ATTRIBUTE_UNUSED, long i3 ATTRIBUTE_UNUSED, long i4 ATTRIBUTE_UNUSED, long i5 ATTRIBUTE_UNUSED, long i6 ATTRIBUTE_UNUSED, long i7 ATTRIBUTE_UNUSED, long i8 ATTRIBUTE_UNUSED, long i9 ATTRIBUTE_UNUSED, long i10 ATTRIBUTE_UNUSED, long i11 ATTRIBUTE_UNUSED)
+{
+ /* Check argument values. */
+ assert (values_long.i0 == i0);
+ assert (values_long.i1 == i1);
+ assert (values_long.i2 == i2);
+ assert (values_long.i3 == i3);
+ assert (values_long.i4 == i4);
+ assert (values_long.i5 == i5);
+ assert (values_long.i6 == i6);
+ assert (values_long.i7 == i7);
+ assert (values_long.i8 == i8);
+ assert (values_long.i9 == i9);
+ assert (values_long.i10 == i10);
+ assert (values_long.i11 == i11);
+
+}
+
+void
+fun_check_int_passing_long12_regs (long i0 ATTRIBUTE_UNUSED, long i1 ATTRIBUTE_UNUSED, long i2 ATTRIBUTE_UNUSED, long i3 ATTRIBUTE_UNUSED, long i4 ATTRIBUTE_UNUSED, long i5 ATTRIBUTE_UNUSED, long i6 ATTRIBUTE_UNUSED, long i7 ATTRIBUTE_UNUSED, long i8 ATTRIBUTE_UNUSED, long i9 ATTRIBUTE_UNUSED, long i10 ATTRIBUTE_UNUSED, long i11 ATTRIBUTE_UNUSED)
+{
+ /* Check register contents. */
+ check_long_arguments;
+}
+
+#define def_check_int_passing6(_i0, _i1, _i2, _i3, _i4, _i5, _func1, _func2, TYPE) \
+ values_ ## TYPE .i0 = _i0; \
+ values_ ## TYPE .i1 = _i1; \
+ values_ ## TYPE .i2 = _i2; \
+ values_ ## TYPE .i3 = _i3; \
+ values_ ## TYPE .i4 = _i4; \
+ values_ ## TYPE .i5 = _i5; \
+ WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5); \
+ \
+ clear_int_registers; \
+ iregs.I0 = _i0; \
+ iregs.I1 = _i1; \
+ iregs.I2 = _i2; \
+ num_iregs = 3; \
+ WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5);
+
+#define def_check_int_passing12(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11, _func1, _func2, TYPE) \
+ values_ ## TYPE .i0 = _i0; \
+ values_ ## TYPE .i1 = _i1; \
+ values_ ## TYPE .i2 = _i2; \
+ values_ ## TYPE .i3 = _i3; \
+ values_ ## TYPE .i4 = _i4; \
+ values_ ## TYPE .i5 = _i5; \
+ values_ ## TYPE .i6 = _i6; \
+ values_ ## TYPE .i7 = _i7; \
+ values_ ## TYPE .i8 = _i8; \
+ values_ ## TYPE .i9 = _i9; \
+ values_ ## TYPE .i10 = _i10; \
+ values_ ## TYPE .i11 = _i11; \
+ WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11); \
+ \
+ clear_int_registers; \
+ iregs.I0 = _i0; \
+ iregs.I1 = _i1; \
+ iregs.I2 = _i2; \
+ num_iregs = 3; \
+ WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11);
+
+void
+test_ints_on_stack ()
+{
+ def_check_int_passing6(32, 33, 34, 35, 36, 37, fun_check_int_passing_int6_values, fun_check_int_passing_int6_regs, int);
+}
+
+void
+test_too_many_ints ()
+{
+ def_check_int_passing12(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, fun_check_int_passing_int12_values, fun_check_int_passing_int12_regs, int);
+}
+
+void
+test_longs_on_stack ()
+{
+ def_check_int_passing6(32, 33, 34, 35, 36, 37, fun_check_int_passing_long6_values, fun_check_int_passing_long6_regs, long);
+}
+
+void
+test_too_many_longs ()
+{
+ def_check_int_passing12(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, fun_check_int_passing_long12_values, fun_check_int_passing_long12_regs, long);
+}
+
+int
+main (void)
+{
+ test_ints_on_stack ();
+ test_too_many_ints ();
+ test_longs_on_stack ();
+ test_too_many_longs ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c
new file mode 100644
index 00000000000..1660a4d430b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c
@@ -0,0 +1,237 @@
+/* This tests passing of structs. */
+
+#include "defines.h"
+#include "args.h"
+#include <complex.h>
+
+struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
+struct IntegerRegisters iregs;
+unsigned int num_iregs;
+
+struct int_struct
+{
+ int i;
+};
+
+struct long_struct
+{
+ long l;
+};
+
+struct longlong2_struct
+{
+ long long ll1, ll2;
+};
+
+struct longlong3_struct
+{
+ long long ll1, ll2, ll3;
+};
+
+/* Check that the struct is passed as the individual members in iregs. */
+void
+check_struct_passing1 (struct int_struct is ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+void
+check_struct_passing2 (struct long_struct ls ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+void
+check_struct_passing3 (struct longlong2_struct ls ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+void
+check_struct_passing4 (struct longlong3_struct ls ATTRIBUTE_UNUSED)
+{
+ /* Check the passing on the stack by comparing the address of the
+ stack elements to the expected place on the stack. */
+ assert ((unsigned long)&ls.ll1 == esp+4);
+ assert ((unsigned long)&ls.ll2 == esp+12);
+ assert ((unsigned long)&ls.ll3 == esp+20);
+}
+
+struct flex1_struct
+{
+ long i;
+ long flex[];
+};
+
+struct flex2_struct
+{
+ long i;
+ long flex[0];
+};
+
+void
+check_struct_passing7 (struct flex1_struct is ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+void
+check_struct_passing8 (struct flex2_struct is ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+struct complex1_struct
+{
+ __complex__ float x;
+};
+
+struct complex1a_struct
+{
+ long l;
+ union
+ {
+ float f;
+ int i;
+ } u;
+};
+
+void
+check_struct_passing9 (struct complex1_struct is ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+struct long3_struct
+{
+ long l1, l2, l3;
+};
+
+void
+check_struct_passing10 (struct long3_struct ls ATTRIBUTE_UNUSED)
+{
+ /* Check the passing on the stack by comparing the address of the
+ stack elements to the expected place on the stack. */
+ assert ((unsigned long)&ls.l1 == esp+4);
+ assert ((unsigned long)&ls.l2 == esp+8);
+ assert ((unsigned long)&ls.l3 == esp+12);
+}
+
+struct char3_struct
+{
+ char c1, c2, c3;
+};
+
+void
+check_struct_passing11 (struct char3_struct is ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+struct char7_struct
+{
+ char c1, c2, c3, c4, c5, c6, c7;
+};
+
+void
+check_struct_passing12 (struct char7_struct is ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+static struct flex1_struct f1s = { 60, { } };
+static struct flex2_struct f2s = { 61, { } };
+
+int
+main (void)
+{
+ struct int_struct is = { 48 };
+ struct long_struct ls = { 49 };
+#ifdef CHECK_LARGER_STRUCTS
+ struct longlong2_struct ll2s = { 50, 51 };
+ struct longlong3_struct ll3s = { 52, 53, 54 };
+ struct long3_struct l3s = { 60, 61, 62 };
+#endif
+ struct complex1_struct c1s = { ( -13.4 + 3.5*I ) };
+ union
+ {
+ struct complex1_struct c;
+ struct complex1a_struct u;
+ } c1u;
+ struct char3_struct c3 = { 0x12, 0x34, 0x56 };
+ union
+ {
+ struct char3_struct c;
+ int i;
+ } c3u;
+ struct char7_struct c7 = { 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56 };
+ union
+ {
+ struct char7_struct c;
+ struct
+ {
+ int i0, i1;
+ } i;
+ } c7u;
+
+ clear_struct_registers;
+ iregs.I0 = is.i;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_struct_passing1)(is);
+
+ clear_struct_registers;
+ iregs.I0 = ls.l;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_struct_passing2)(ls);
+
+#ifdef CHECK_LARGER_STRUCTS
+ clear_struct_registers;
+ num_iregs = 0;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_struct_passing3)(ll2s);
+ WRAP_CALL (check_struct_passing4)(ll3s);
+ WRAP_CALL (check_struct_passing10)(l3s);
+#endif
+
+ clear_struct_registers;
+ iregs.I0 = f1s.i;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_struct_passing7)(f1s);
+
+ clear_struct_registers;
+ iregs.I0 = f2s.i;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_struct_passing8)(f2s);
+
+ clear_struct_registers;
+ c1u.c = c1s;
+ iregs.I0 = c1u.u.l;
+ iregs.I1 = c1u.u.u.i;
+ num_iregs = 2;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_struct_passing9)(c1s);
+
+ clear_struct_registers;
+ c3u.c = c3;
+ iregs.I0 = c3u.i;
+ iregbits.I0 = 0xffffff;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_struct_passing11)(c3);
+
+ clear_struct_registers;
+ c7u.c = c7;
+ iregs.I0 = c7u.i.i0;
+ iregs.I1 = c7u.i.i1;
+ iregbits.I0 = 0xffffffff;
+ iregbits.I1 = 0xffffff;
+ num_iregs = 2;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_struct_passing12)(c7);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs_and_unions.c b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs_and_unions.c
new file mode 100644
index 00000000000..ff6354cd6fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs_and_unions.c
@@ -0,0 +1,97 @@
+/* This tests passing of structs. Only integers are tested. */
+
+#include "defines.h"
+#include "args.h"
+
+struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
+struct IntegerRegisters iregs;
+unsigned int num_iregs;
+
+struct int_struct
+{
+ int i;
+};
+
+struct longlong_struct
+{
+ long long ll;
+};
+
+struct long2_struct
+{
+ long long ll1, ll2;
+};
+
+struct long3_struct
+{
+ long l1, l2, l3;
+};
+
+union un1
+{
+ char c;
+ int i;
+};
+
+union un2
+{
+ char c1;
+ long l;
+ char c2;
+};
+
+union un3
+{
+ struct int_struct is;
+ struct longlong_struct ls;
+ union un1 un;
+};
+
+
+void
+check_mixed_passing1 (char c1 ATTRIBUTE_UNUSED, struct int_struct is ATTRIBUTE_UNUSED, char c2 ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+void
+check_mixed_passing2 (char c1 ATTRIBUTE_UNUSED, struct long3_struct ls ATTRIBUTE_UNUSED, char c2 ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+
+ /* Check the passing on the stack by comparing the address of the
+ stack elements to the expected place on the stack. */
+ assert ((unsigned long)&ls.l1 == esp+4);
+ assert ((unsigned long)&ls.l2 == esp+8);
+ assert ((unsigned long)&ls.l3 == esp+12);
+}
+
+int
+main (void)
+{
+ struct int_struct is = { 64 };
+#ifdef CHECK_LARGER_STRUCTS
+ struct long3_struct l3s = { 65, 66, 67 };
+#endif
+
+ clear_struct_registers;
+ iregs.I0 = 8;
+ iregs.I1 = 64;
+ iregs.I2 = 9;
+ num_iregs = 3;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_mixed_passing1)(8, is, 9);
+
+#ifdef CHECK_LARGER_STRUCTS
+ clear_struct_registers;
+ iregs.I0 = 10;
+ iregbits.I0 = 0xff;
+ iregs.I1 = 11;
+ iregbits.I1 = 0xff;
+ num_iregs = 2;
+ clear_int_hardware_registers;
+ WRAP_CALL (check_mixed_passing2)(10, l3s, 11);
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_passing_unions.c b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_unions.c
new file mode 100644
index 00000000000..534fc8505ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_unions.c
@@ -0,0 +1,221 @@
+/* This tests passing of structs. */
+
+#include "defines.h"
+#include "args.h"
+
+struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
+struct IntegerRegisters iregs;
+unsigned int num_iregs;
+
+struct int_struct
+{
+ int i;
+};
+
+struct long_struct
+{
+ long l;
+};
+
+union un1
+{
+ char c;
+ int i;
+};
+
+union un2
+{
+ char c1;
+ long l;
+ char c2;
+};
+
+union un3
+{
+ struct int_struct is;
+ struct long_struct ls;
+ union un1 un;
+};
+
+
+void
+check_union_passing1(union un1 u ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+void
+check_union_passing2(union un2 u1 ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+void
+check_union_passing3(union un3 u ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+#define check_union_passing1 WRAP_CALL(check_union_passing1)
+#define check_union_passing2 WRAP_CALL(check_union_passing2)
+#define check_union_passing3 WRAP_CALL(check_union_passing3)
+
+union un4
+{
+ int i;
+ float f;
+};
+
+union un5
+{
+ long long ll;
+ double d;
+};
+
+void
+check_union_passing4(union un4 u1 ATTRIBUTE_UNUSED,
+ union un4 u2 ATTRIBUTE_UNUSED,
+ union un4 u3 ATTRIBUTE_UNUSED,
+ union un4 u4 ATTRIBUTE_UNUSED,
+ union un4 u5 ATTRIBUTE_UNUSED,
+ union un4 u6 ATTRIBUTE_UNUSED,
+ union un4 u7 ATTRIBUTE_UNUSED,
+ union un4 u8 ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+void
+check_union_passing5(union un5 u ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+}
+
+#define check_union_passing4 WRAP_CALL(check_union_passing4)
+#define check_union_passing5 WRAP_CALL(check_union_passing5)
+
+union un6
+{
+ __float128 f128;
+ int i;
+};
+
+
+void
+check_union_passing6(union un6 u ATTRIBUTE_UNUSED)
+{
+ /* Check the passing on the stack by comparing the address of the
+ stack elements to the expected place on the stack. */
+ assert ((unsigned long)&u.f128 == esp+4);
+ assert ((unsigned long)&u.i == esp+4);
+}
+
+#define check_union_passing6 WRAP_CALL(check_union_passing6)
+
+int
+main (void)
+{
+ union un1 u1;
+#ifdef CHECK_LARGER_UNION_PASSING
+ union un2 u2;
+ union un3 u3;
+ struct int_struct is;
+ struct long_struct ls;
+#endif /* CHECK_LARGER_UNION_PASSING */
+ union un4 u4[8];
+ union un5 u5 = { { 48.394, 39.3, -397.9, 3484.9 } };
+ int i;
+ union un6 u6;
+
+ /* Check a union with char, int. */
+ clear_struct_registers;
+ u1.i = 0; /* clear the struct to not have high bits left */
+ u1.c = 32;
+ iregs.I0 = 32;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing1(u1);
+ u1.i = 0; /* clear the struct to not have high bits left */
+ u1.i = 33;
+ iregs.I0 = 33;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing1(u1);
+
+ /* Check a union with char, long, char. */
+#ifdef CHECK_LARGER_UNION_PASSING
+ clear_struct_registers;
+ u2.l = 0; /* clear the struct to not have high bits left */
+ u2.c1 = 34;
+ iregs.I0 = 34;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing2(u2);
+ u2.l = 0; /* clear the struct to not have high bits left */
+ u2.l = 35;
+ iregs.I0 = 35;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing2(u2);
+ u2.l = 0; /* clear the struct to not have high bits left */
+ u2.c2 = 36;
+ iregs.I0 = 36;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing2(u2);
+
+ /* check a union containing two structs and a union. */
+ clear_struct_registers;
+ is.i = 37;
+ u3.ls.l = 0; /* clear the struct to not have high bits left */
+ u3.is = is;
+ iregs.I0 = 37;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing3(u3);
+ ls.l = 38;
+ u3.ls.l = 0; /* clear the struct to not have high bits left */
+ u3.ls = ls;
+ iregs.I0 = 38;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing3(u3);
+ u1.c = 39;
+ u3.ls.l = 0; /* clear the struct to not have high bits left */
+ u3.un = u1;
+ iregs.I0 = 39;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing3(u3);
+ u1.i = 40;
+ u3.ls.l = 0; /* clear the struct to not have high bits left */
+ u3.un = u1;
+ iregs.I0 = 40;
+ num_iregs = 1;
+ clear_int_hardware_registers;
+ check_union_passing3(u3);
+#endif /* CHECK_LARGER_UNION_PASSING */
+
+ clear_struct_registers;
+ for (i = 0; i < 8; i++)
+ u4[i].f = 32 + i;
+ iregs.I0 = u4[0].i;
+ iregs.I1 = u4[1].i;
+ iregs.I2 = u4[2].i;
+ num_iregs = 3;
+ clear_int_hardware_registers;
+ check_union_passing4(u4[0], u4[1], u4[2], u4[3],
+ u4[4], u4[5], u4[6], u4[7]);
+
+ clear_struct_registers;
+ iregs.I0 = u5.ll & 0xffffffff;
+ iregs.I1 = (u5.ll >> 32) & 0xffffffff;
+ num_iregs = 2;
+ clear_int_hardware_registers;
+ check_union_passing5(u5);
+
+ u6.i = 2;
+ check_union_passing6(u6);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_struct_returning.c b/gcc/testsuite/gcc.target/i386/iamcu/test_struct_returning.c
new file mode 100644
index 00000000000..49a6b1f0a6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_struct_returning.c
@@ -0,0 +1,362 @@
+/* This tests returning of structures. */
+
+#include "defines.h"
+#include "macros.h"
+#include "args.h"
+
+struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
+struct IntegerRegisters iregs;
+unsigned int num_iregs;
+
+int current_test;
+int num_failed = 0;
+
+typedef enum {
+ EAX = 0,
+ EAX_EDX,
+ LONG_LONG,
+ FLOAT,
+ DOUBLE,
+ FLOAT_FLOAT,
+ EAX_FLOAT,
+ FLOAT_EDX,
+ MEM
+} Type;
+
+/* Structures which should be returned in EAX/LONG_LONG/EAX_EDX. */
+#define D(I,MEMBERS,C,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = C; \
+struct S_ ## I f_ ## I (void) { struct S_ ## I s; iamcu_memset (&s, 0, sizeof(s)); B; return s; }
+
+D(1,char m1, EAX, s.m1=42)
+D(2,short m1, EAX, s.m1=42)
+D(3,int m1, EAX, s.m1=42)
+D(4,char m1[3], EAX, s.m1[0]=42)
+D(5,char m1[4], EAX, s.m1[0]=42)
+D(6,char m1;char m2; char m3, EAX, s.m1=42)
+D(7,char m1;short m2, EAX, s.m1=42)
+
+D(30,long long m1, LONG_LONG, s.m1=0xadadbeefadadbeefLL)
+
+D(50,short m1;int m2, EAX_EDX, s.m1=42; s.m2=43)
+D(51,char m1;int m2, EAX_EDX, s.m1=42; s.m2=43)
+D(52,char m1[5], EAX_EDX, s.m1[0]=42; s.m1[4]=43)
+D(53,char m1[6], EAX_EDX, s.m1[0]=42; s.m1[4]=43)
+D(54,char m1[7], EAX_EDX, s.m1[0]=42; s.m1[4]=43)
+D(55,char m1[8], EAX_EDX, s.m1[0]=42; s.m1[4]=43)
+D(56,char m1;short m2[2], EAX_EDX, s.m1=42; s.m2[1]=43)
+D(57,short m1[4], EAX_EDX, s.m1[0]=42; s.m1[2]=43)
+D(58,int m1[2], EAX_EDX, s.m1[0]=42; s.m1[1]=43)
+D(59,int m1;char m2, EAX_EDX, s.m1=42; s.m2=43)
+D(60,int m1;short m2, EAX_EDX, s.m1=42; s.m2=43)
+D(61,int m1;short m2; char m3, EAX_EDX, s.m1=42; s.m2=43)
+D(62,int m1;char m2; short m3, EAX_EDX, s.m1=42; s.m2=43)
+
+/* Packed members. */
+D(100,short m1[1];int m2 PACKED, EAX_EDX, s.m1[0]=42; s.m2=43)
+D(101,char m1; short m2 PACKED; char m3, EAX_EDX, s.m1=42; s.m3=43)
+
+/* Structures which should be returned in FLOAT/DOUBLE. */
+#undef D
+#define D(I,MEMBERS,C,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = C; \
+struct S_ ## I f_ ## I (void) { struct S_ ## I s; iamcu_memset (&s, 0, sizeof(s)); B; return s; }
+
+D(200,float f, FLOAT, s.f=42)
+D(201,double d, DOUBLE, s.d=42)
+
+D(300,float m;char m2, FLOAT_EDX, s.m=42; s.m2=43)
+D(301,float m;short m2, FLOAT_EDX, s.m=42; s.m2=43)
+D(302,float m;int m2, FLOAT_EDX, s.m=42; s.m2=43)
+
+D(400,char m1; float m2, EAX_FLOAT, s.m1=42; s.m2=43)
+D(401,short m1; float m2, EAX_FLOAT, s.m1=42; s.m2=43)
+D(402,int m1; float m2, EAX_FLOAT, s.m1=42; s.m2=43)
+
+D(500,float m;float m2, FLOAT_FLOAT, s.m=42; s.m2=43)
+D(501,float f[2], FLOAT, s.f[0]=42; s.f[1]=43)
+
+/* Structures which should be returned in MEM. */
+void *struct_addr;
+#undef D
+#define D(I,MEMBERS) struct S_ ## I { MEMBERS ; }; Type class_ ## I = MEM; \
+struct S_ ## I f_ ## I (void) { union {unsigned char c; struct S_ ## I s;} u; iamcu_memset (&u.s, 0, sizeof(u.s)); u.c = 42; return u.s; }
+
+/* Too large. */
+D(600,char m1[17])
+D(601,short m1[9])
+D(602,int m1[5])
+D(603,long m1[3])
+D(604,short m1[8];char c)
+D(605,char m1[1];int i[4])
+D(606,float m1[5])
+D(607,double m1[3])
+D(608,char m1[1];float f[4])
+D(609,char m1[1];double d[2])
+D(610,__complex long double m1[1])
+
+/* Too large due to padding. */
+D(611,char m1[1]; int i; char c2)
+
+/* Special tests. */
+#undef D
+#define D(I,MEMBERS,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = MEM; \
+struct S_ ## I f_ ## I (void) { struct S_ ## I s; B; return s; }
+D(700,float f[4], s.f[0] = s.f[1] = s.f[2] = s.f[3] = 42)
+
+void
+check_eax (void)
+{
+ switch (current_test)
+ {
+ case 1:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ eax &= 0xff;
+ break;
+ case 2:
+ eax &= 0xffff;
+ break;
+ case 3:
+ eax &= 0xffff;
+ break;
+ default:
+ abort ();
+ }
+ if (eax != 42)
+ num_failed++;
+}
+
+void
+check_eax_edx (void)
+{
+ unsigned long long ll = eax | ((unsigned long long) edx) << 32;
+ switch (current_test)
+ {
+ case 50:
+ eax &= 0xffff;
+ break;
+ case 52:
+ case 53:
+ case 54:
+ case 55:
+ edx &= 0xff;
+ case 51:
+ eax &= 0xff;
+ break;
+ case 56:
+ eax &= 0xff;
+ edx &= 0xffff;
+ break;
+ case 57:
+ eax &= 0xffff;
+ edx &= 0xffff;
+ break;
+ case 58:
+ break;
+ case 59:
+ case 62:
+ edx &= 0xff;
+ break;
+ case 60:
+ case 61:
+ edx &= 0xffff;
+ break;
+ case 100:
+ eax &= 0xffff;
+ edx = (ll >> 16) & 0xffffffff;
+ break;
+ case 101:
+ edx = (eax >> 24) & 0xff;
+ eax &= 0xff;
+ break;
+ default:
+ abort ();
+ }
+ if (eax != 42 || edx != 43)
+ num_failed++;
+}
+
+void
+check_float_edx (void)
+{
+ union
+ {
+ unsigned long l;
+ float f;
+ } ueax;
+ switch (current_test)
+ {
+ case 300:
+ edx &= 0xff;
+ break;
+ case 301:
+ edx &= 0xffff;
+ break;
+ case 302:
+ edx &= 0xffff;
+ break;
+ default:
+ abort ();
+ }
+ ueax.l = eax;
+ if (ueax.f != 42 || edx != 43)
+ num_failed++;
+}
+
+void
+check_eax_float (void)
+{
+ union
+ {
+ unsigned long l;
+ float f;
+ } uedx;
+ switch (current_test)
+ {
+ case 400:
+ eax &= 0xff;
+ break;
+ case 401:
+ eax &= 0xffff;
+ break;
+ case 402:
+ eax &= 0xffff;
+ break;
+ default:
+ abort ();
+ }
+ uedx.l = edx;
+ if (eax != 42 || uedx.f != 43)
+ num_failed++;
+}
+
+void
+check_float_float (void)
+{
+ union
+ {
+ unsigned long l;
+ float f;
+ } ueax, uedx;
+ switch (current_test)
+ {
+ case 500:
+ case 501:
+ break;
+ default:
+ abort ();
+ }
+ ueax.l = eax;
+ uedx.l = edx;
+ if (ueax.f != 42 || uedx.f != 43)
+ num_failed++;
+}
+
+void
+check_all (Type class, unsigned long size)
+{
+ union
+ {
+ struct
+ {
+ unsigned long eax;
+ unsigned long edx;
+ } eax_edx;
+ unsigned long long ll;
+ float f;
+ double d;
+ } u;
+
+ switch (class)
+ {
+ case EAX:
+ check_eax ();
+ break;
+ case LONG_LONG:
+ if (0xadadbeefL != eax || 0xadadbeefL != edx)
+ num_failed++;
+ break;
+ case EAX_EDX:
+ check_eax_edx ();
+ break;
+ case FLOAT:
+ u.eax_edx.eax = eax;
+ if (u.f != 42)
+ num_failed++;
+ break;
+ case DOUBLE:
+ u.eax_edx.eax = eax;
+ u.eax_edx.edx = edx;
+ if (u.d != 42)
+ num_failed++;
+ break;
+ case FLOAT_EDX:
+ check_float_edx ();
+ break;
+ case FLOAT_FLOAT:
+ check_float_float ();
+ break;
+ case EAX_FLOAT:
+ check_eax_float ();
+ break;
+ case MEM:
+ /* sret_eax contains a slot whose address is given to the f_*
+ functions. The slot may be a temporary one on stack. When
+ this function is called, hopefully this slot hasn't be
+ overriden. */
+ if (sret_eax != eax)
+ num_failed++;
+ else if (current_test < 700)
+ {
+ if (*(unsigned char*)sret_eax != 42
+ || *(unsigned char*)struct_addr != 42)
+ num_failed++;
+ }
+ else
+ {
+ if (*(float *)sret_eax != 42
+ || *(float *)struct_addr != 42)
+ num_failed++;
+ }
+ break;
+ }
+}
+
+#undef D
+#define D(I) { static struct S_ ## I s; current_test = I; struct_addr = (void*)&s; \
+ clear_non_sret_int_registers; \
+ s = WRAP_RET(f_ ## I) (); \
+ check_all(class_ ## I, sizeof(s)); \
+}
+
+int
+main (void)
+{
+ D(1) D(2) D(3) D(4) D(5) D(6) D(7)
+
+ D(30)
+
+ D(50) D(51) D(52) D(53) D(54) D(55) D(56) D(57) D(58) D(59)
+ D(60) D(61) D(62)
+
+ D(100) D(101)
+
+ D(200) D(201)
+
+ D(300) D(301) D(302)
+
+ D(400) D(401) D(402)
+
+ D(500) D(501)
+
+ D(600) D(601) D(602) D(603) D(604) D(605) D(606) D(607) D(608) D(609)
+ D(610) D(611)
+
+ D(700)
+
+ if (num_failed)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_varargs.c b/gcc/testsuite/gcc.target/i386/iamcu/test_varargs.c
new file mode 100644
index 00000000000..124bef17c62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/iamcu/test_varargs.c
@@ -0,0 +1,101 @@
+/* Test variable number of arguments passed to functions. */
+
+#include <stdarg.h>
+#include "defines.h"
+
+
+#define ARG_INT 1
+#define ARG_DOUBLE 2
+#define ARG_POINTER 3
+
+union types
+{
+ int ivalue;
+ double dvalue;
+ void *pvalue;
+};
+
+struct arg
+{
+ int type;
+ union types value;
+};
+
+struct arg *arglist;
+
+/* This tests the argumentlist to see if it matches the format string which
+ is printf-like. Nothing will be printed of course. It can handle ints,
+ doubles and void pointers. The given value will be tested against the
+ values given in arglist.
+ This test only assures that the variable argument passing is working.
+ No attempt is made to see if argument passing is done the right way. */
+void
+__attribute__ ((noinline))
+noprintf (char *format, ...)
+{
+ va_list va_arglist;
+ char *c;
+
+ int ivalue;
+ double dvalue;
+ void *pvalue;
+ struct arg *argp = arglist;
+
+ va_start (va_arglist, format);
+ for (c = format; *c; c++)
+ if (*c == '%')
+ {
+ switch (*++c)
+ {
+ case 'd':
+ assert (argp->type == ARG_INT);
+ ivalue = va_arg (va_arglist, int);
+ assert (argp->value.ivalue == ivalue);
+ break;
+ case 'f':
+ assert (argp->type == ARG_DOUBLE);
+ dvalue = va_arg (va_arglist, double);
+ assert (argp->value.dvalue == dvalue);
+ break;
+ case 'p':
+ assert (argp->type == ARG_POINTER);
+ pvalue = va_arg (va_arglist, void *);
+ assert (argp->value.pvalue == pvalue);
+ break;
+ default:
+ abort ();
+ }
+
+ argp++;
+ }
+}
+
+extern void iamcu_noprintf (char *, ...);
+
+int
+main (void)
+{
+#ifdef CHECK_VARARGS
+ float f = 258.0;
+ struct arg al[5];
+
+ al[0].type = ARG_INT;
+ al[0].value.ivalue = 256;
+ al[1].type = ARG_DOUBLE;
+ al[1].value.dvalue = 257.0;
+ al[2].type = ARG_POINTER;
+ al[2].value.pvalue = al;
+ al[3].type = ARG_DOUBLE;
+ al[3].value.dvalue = f;
+ al[4].type = ARG_INT;
+ al[4].value.ivalue = 259;
+
+ arglist = al;
+ noprintf("%d%f%p%f%d", 256, 257.0, al, f, 259);
+
+ iamcu_noprintf ((char *) 0xabadbeef, 256, 257.0,
+ (void *) 0xbbadbeef, f, 259);
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr66691.c b/gcc/testsuite/gcc.target/i386/pr66691.c
new file mode 100644
index 00000000000..407aba908bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66691.c
@@ -0,0 +1,64 @@
+/* PR target/66691 */
+/* { dg-do compile } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-O3 -g -mtune=generic -march=i686" } */
+
+unsigned int a;
+int b[2], c, d, e, f, g, h, i, k[8], l, m, s, t, w;
+static int j;
+
+void
+fn1 (long long p)
+{
+ int t = p;
+ c = c ^ b[c ^ (t & 1)];
+}
+
+static void
+fn2 (long long p)
+{
+ c = c ^ b[1 ^ (d & 1)];
+ fn1 (p >> 1 & 1);
+ fn1 (p >> 2);
+}
+
+static void
+fn3 ()
+{
+ unsigned char p;
+ f = g = 0;
+ for (h = 0; h < 6; h++)
+ {
+ for (s = 0; s < 7; s++)
+ if (k[s+1])
+ g = 0;
+ else
+ for (j = 0; j < 2; j++)
+ ;
+ t = j > 2 ? 0 : 1 >> j;
+ }
+ if (l)
+ {
+ short q[2];
+ q[0] = q[1] = 0;
+ if (m)
+ for (i = 0; i < 2; i++)
+ {
+ unsigned char r = q[i];
+ p = f ? r % f : r;
+ e = ((p > 0) <= (q[i] ^ 1)) + a;
+ if (k[1])
+ for (e = 0; e != 18; ++e)
+ k[0] = 0;
+ }
+ }
+}
+
+int
+main ()
+{
+ fn3 ();
+ fn2 (w);
+ fn2 (j);
+ return 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/wunused-parameter.f90 b/gcc/testsuite/gfortran.dg/wunused-parameter.f90
new file mode 100644
index 00000000000..df39af8aa57
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/wunused-parameter.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-Wunused-parameter" }
+! PR66605
+MODULE test
+ IMPLICIT NONE
+ INTEGER, PARAMETER :: wp = KIND(1.0D0)
+CONTAINS
+SUBROUTINE sub (neq, time, y, dydt)
+ IMPLICIT NONE
+ INTEGER :: neq
+ REAL(WP) :: time, y(neq), dydt(neq)
+
+ dydt(1) = 1.0 / y(1)
+END SUBROUTINE sub
+END MODULE
diff --git a/gcc/testsuite/gnat.dg/lto17.adb b/gcc/testsuite/gnat.dg/lto17.adb
new file mode 100644
index 00000000000..af42e8d85d8
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/lto17.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+-- { dg-options "-flto" }
+-- { dg-require-effective-target lto }
+
+package body Lto17 is
+
+ function To_Chunk_List(C : Chunk) return Chunk_List is
+ begin
+ return new Chunk_List_Element'(C.Size, C, null);
+ end;
+
+end Lto17;
diff --git a/gcc/testsuite/gnat.dg/lto17.ads b/gcc/testsuite/gnat.dg/lto17.ads
new file mode 100644
index 00000000000..19b8a9c7c16
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/lto17.ads
@@ -0,0 +1,20 @@
+package Lto17 is
+
+ type Chunk_List_Element;
+ type Chunk_List is access Chunk_List_Element;
+
+ type Arr is array (Natural range <>) of Integer;
+
+ type Chunk(Size : Natural) is record
+ Data : Arr(1 .. Size);
+ Where : Natural;
+ end record;
+
+ type Chunk_List_Element(Size : Natural) is record
+ Chnk : Chunk(Size);
+ Link : Chunk_List;
+ end record;
+
+ function To_Chunk_List(C : Chunk) return Chunk_List;
+
+end Lto17;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 389e1c63ff0..36a616018d5 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -95,6 +95,9 @@
#undef create_code
#undef verify_code
+/* test-extra-options.c: We don't use this one, since the extra options
+ affect the whole context. */
+
/* test-factorial.c */
#define create_code create_code_factorial
#define verify_code verify_code_factorial
@@ -172,6 +175,13 @@
#undef create_code
#undef verify_code
+/* test-switch.c */
+#define create_code create_code_switch
+#define verify_code verify_code_switch
+#include "test-switch.c"
+#undef create_code
+#undef verify_code
+
/* test-types.c */
#define create_code create_code_types
#define verify_code verify_code_types
@@ -186,6 +196,10 @@
#undef create_code
#undef verify_code
+/* test-validly-unreachable-block.c: We don't use this one, since the use
+ of gcc_jit_context_set_bool_allow_unreachable_blocks affects the whole
+ context. */
+
/* test-volatile.c */
#define create_code create_code_volatile
#define verify_code verify_code_volatile
@@ -274,6 +288,9 @@ const struct testcase testcases[] = {
{"sum_of_squares",
create_code_sum_of_squares,
verify_code_sum_of_squares},
+ {"switch",
+ create_code_switch,
+ verify_code_switch},
{"types",
create_code_types,
verify_code_types},
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c
new file mode 100644
index 00000000000..07a98480693
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c
@@ -0,0 +1,66 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int
+ test_switch (int x)
+ {
+ switch (x)
+ {
+ case x:
+ return 3;
+
+ default:
+ return 10;
+ }
+ }
+ and verify that we get a sane error about the non-const
+ case.
+ */
+ gcc_jit_type *t_int =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *return_type = t_int;
+ gcc_jit_param *x =
+ gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
+ gcc_jit_param *params[1] = {x};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "test_switch",
+ 1, params, 0);
+
+ gcc_jit_block *b_initial =
+ gcc_jit_function_new_block (func, "initial");
+
+ gcc_jit_block *b_default =
+ gcc_jit_function_new_block (func, "default");
+
+ gcc_jit_case *cases[1] = {
+ NULL
+ };
+
+ gcc_jit_block_end_with_switch (
+ b_initial, NULL,
+ gcc_jit_param_as_rvalue (x),
+ b_default,
+ 1,
+ cases);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_block_end_with_switch: NULL case 0");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c
new file mode 100644
index 00000000000..cc907cea1d8
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c
@@ -0,0 +1,83 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int
+ test_switch (int x)
+ {
+ switch (x)
+ {
+ case (long long)0 ... (long long)5:
+ return 3;
+ default:
+ return 10;
+ }
+ }
+ and verify that the floating-point case is an error.
+ */
+ gcc_jit_type *t_int =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *t_long_long =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG_LONG);
+ gcc_jit_type *return_type = t_int;
+ gcc_jit_param *x =
+ gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
+ gcc_jit_param *params[1] = {x};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "test_switch",
+ 1, params, 0);
+
+ gcc_jit_block *b_initial =
+ gcc_jit_function_new_block (func, "initial");
+
+ gcc_jit_block *b_default =
+ gcc_jit_function_new_block (func, "default");
+ gcc_jit_block *b_case_0 =
+ gcc_jit_function_new_block (func, "case_0");
+
+ /* Note the erroneous use of "t_float" here. */
+ gcc_jit_case *cases[1] = {
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_long_long, 0),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_long_long, 5),
+ b_case_0)
+ };
+
+ gcc_jit_block_end_with_switch (
+ b_initial, NULL,
+ gcc_jit_param_as_rvalue (x),
+ b_default,
+ 1,
+ cases);
+
+ gcc_jit_block_end_with_return (
+ b_case_0, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
+ gcc_jit_block_end_with_return (
+ b_default, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_block_end_with_switch:"
+ " mismatching types between case and expression:"
+ " cases[0]->min_value: (long long)0 (type: long long)"
+ " expr: x (type: int)");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c
new file mode 100644
index 00000000000..40655c244a0
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c
@@ -0,0 +1,95 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int
+ test_switch (int x)
+ {
+ switch (x)
+ {
+ case 0 ... 5:
+ return 3;
+
+ case 5 ... 10:
+ return 4;
+
+ default:
+ return 10;
+ }
+ }
+ and verify that we get an error about the overlapping
+ ranges.
+ */
+ gcc_jit_type *t_int =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *return_type = t_int;
+ gcc_jit_param *x =
+ gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
+ gcc_jit_param *params[1] = {x};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "test_switch",
+ 1, params, 0);
+
+ gcc_jit_block *b_initial =
+ gcc_jit_function_new_block (func, "initial");
+
+ gcc_jit_block *b_default =
+ gcc_jit_function_new_block (func, "default");
+ gcc_jit_block *b_case_0_5 =
+ gcc_jit_function_new_block (func, "case_0_5");
+ gcc_jit_block *b_case_5_10 =
+ gcc_jit_function_new_block (func, "case_5_10");
+
+ gcc_jit_case *cases[2] = {
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5),
+ b_case_0_5),
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10),
+ b_case_5_10)
+ };
+
+ gcc_jit_block_end_with_switch (
+ b_initial, NULL,
+ gcc_jit_param_as_rvalue (x),
+ b_default,
+ 2,
+ cases);
+
+ gcc_jit_block_end_with_return (
+ b_case_0_5, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
+ gcc_jit_block_end_with_return (
+ b_case_5_10, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4));
+ gcc_jit_block_end_with_return (
+ b_default, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_block_end_with_switch:"
+ " duplicate (or overlapping) cases values:"
+ " case 1: case (int)5 ... (int)10: goto case_5_10;"
+ " overlaps case (int)0 ... (int)5: goto case_0_5;");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c
new file mode 100644
index 00000000000..39538183f00
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c
@@ -0,0 +1,80 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int
+ test_switch (int x)
+ {
+ switch (x)
+ {
+ case x:
+ return 3;
+
+ default:
+ return 10;
+ }
+ }
+ and verify that we get a sane error about the non-const
+ case.
+ */
+ gcc_jit_type *t_int =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *return_type = t_int;
+ gcc_jit_param *x =
+ gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
+ gcc_jit_param *params[1] = {x};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "test_switch",
+ 1, params, 0);
+
+ gcc_jit_block *b_initial =
+ gcc_jit_function_new_block (func, "initial");
+
+ gcc_jit_block *b_default =
+ gcc_jit_function_new_block (func, "default");
+ gcc_jit_block *b_case_x =
+ gcc_jit_function_new_block (func, "case_x");
+
+ /* Erroneous use of non-const x for a case. */
+ gcc_jit_case *cases[1] = {
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_param_as_rvalue (x),
+ gcc_jit_param_as_rvalue (x),
+ b_case_x)
+ };
+
+ gcc_jit_block_end_with_switch (
+ b_initial, NULL,
+ gcc_jit_param_as_rvalue (x),
+ b_default,
+ 1,
+ cases);
+ gcc_jit_block_end_with_return (
+ b_case_x, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
+ gcc_jit_block_end_with_return (
+ b_default, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_context_new_case:"
+ " min_value is not a constant: x");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c
new file mode 100644
index 00000000000..5d442862c08
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c
@@ -0,0 +1,81 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int
+ test_switch (int x)
+ {
+ switch (x)
+ {
+ case 0.f ... 5.f:
+ return 3;
+ default:
+ return 10;
+ }
+ }
+ and verify that the floating-point case is an error.
+ */
+ gcc_jit_type *t_int =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *t_float =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
+ gcc_jit_type *return_type = t_int;
+ gcc_jit_param *x =
+ gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
+ gcc_jit_param *params[1] = {x};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "test_switch",
+ 1, params, 0);
+
+ gcc_jit_block *b_initial =
+ gcc_jit_function_new_block (func, "initial");
+
+ gcc_jit_block *b_default =
+ gcc_jit_function_new_block (func, "default");
+ gcc_jit_block *b_case_0 =
+ gcc_jit_function_new_block (func, "case_0");
+
+ /* Note the erroneous use of "t_float" here. */
+ gcc_jit_case *cases[1] = {
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_float, 0),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_float, 5),
+ b_case_0)
+ };
+
+ gcc_jit_block_end_with_switch (
+ b_initial, NULL,
+ gcc_jit_param_as_rvalue (x),
+ b_default,
+ 1,
+ cases);
+
+ gcc_jit_block_end_with_return (
+ b_case_0, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
+ gcc_jit_block_end_with_return (
+ b_default, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_context_new_case:"
+ " min_value: (float)0 (type: float) is not of integer type");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c
new file mode 100644
index 00000000000..a84d9f33f3d
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c
@@ -0,0 +1,80 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int
+ test_switch (int x)
+ {
+ switch (x)
+ {
+ case 5 ... 0:
+ return 3;
+
+ default:
+ return 10;
+ }
+ }
+ and verify that we get an error about the reversed endpoints
+ in the range.
+ */
+ gcc_jit_type *t_int =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *return_type = t_int;
+ gcc_jit_param *x =
+ gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
+ gcc_jit_param *params[1] = {x};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "test_switch",
+ 1, params, 0);
+
+ gcc_jit_block *b_initial =
+ gcc_jit_function_new_block (func, "initial");
+
+ gcc_jit_block *b_default =
+ gcc_jit_function_new_block (func, "default");
+ gcc_jit_block *b_case_5_0 =
+ gcc_jit_function_new_block (func, "case_5_0");
+
+ gcc_jit_case *cases[1] = {
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0),
+ b_case_5_0)
+ };
+
+ gcc_jit_block_end_with_switch (
+ b_initial, NULL,
+ gcc_jit_param_as_rvalue (x),
+ b_default,
+ 1,
+ cases);
+
+ gcc_jit_block_end_with_return (
+ b_case_5_0, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
+ gcc_jit_block_end_with_return (
+ b_default, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_context_new_case:"
+ " min_value: (int)5 > max_value: (int)0");
+}
diff --git a/gcc/testsuite/jit.dg/test-extra-options.c b/gcc/testsuite/jit.dg/test-extra-options.c
new file mode 100644
index 00000000000..37398349fed
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-extra-options.c
@@ -0,0 +1,136 @@
+/* Testcase for gcc_jit_context_add_command_line_option (PR jit/66628). */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+#ifndef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
+#error LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option was not defined
+#endif
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_context_add_command_line_option (ctxt, "-ffast-math");
+ gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm");
+
+ /* Let's try to inject the equivalent of:
+
+ double
+ my_dot_product (int n, double *a, double *b)
+ {
+ double result = 0.;
+ for (int i = 0; i < n; i++)
+ result += a[i] * b[i];
+ return result
+ }
+
+ and see what the optimizer can do. */
+ gcc_jit_type *val_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
+ gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (val_type);
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+ gcc_jit_type *return_type = val_type;
+ gcc_jit_param *param_n =
+ gcc_jit_context_new_param (ctxt, NULL, int_type, "n");
+ gcc_jit_param *param_a =
+ gcc_jit_context_new_param (ctxt, NULL, ptr_type, "a");
+ gcc_jit_param *param_b =
+ gcc_jit_context_new_param (ctxt, NULL, ptr_type, "b");
+ gcc_jit_param *params[3] = {param_n, param_a, param_b};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "my_dot_product",
+ 3, params, 0);
+
+ gcc_jit_block *initial = gcc_jit_function_new_block (func, "initial");
+ gcc_jit_block *loop_test = gcc_jit_function_new_block (func, "loop_test");
+ gcc_jit_block *loop_body = gcc_jit_function_new_block (func, "loop_body");
+ gcc_jit_block *final = gcc_jit_function_new_block (func, "final");
+
+ /* Build: "double result = 0.;" */
+ gcc_jit_lvalue *result =
+ gcc_jit_function_new_local (func, NULL, val_type, "result");
+
+ gcc_jit_block_add_assignment (initial, NULL,
+ result, gcc_jit_context_zero (ctxt, val_type));
+
+ /* Build: "for (int i = 0; i < n; i++)" */
+ gcc_jit_lvalue *i =
+ gcc_jit_function_new_local (func, NULL, int_type, "i");
+ gcc_jit_block_add_assignment (initial, NULL,
+ i, gcc_jit_context_zero (ctxt, int_type));
+
+ gcc_jit_block_end_with_jump (initial, NULL, loop_test);
+
+ gcc_jit_block_end_with_conditional (
+ loop_test, NULL,
+
+ /* (i < n) */
+ gcc_jit_context_new_comparison (
+ ctxt, NULL,
+ GCC_JIT_COMPARISON_LT,
+ gcc_jit_lvalue_as_rvalue (i),
+ gcc_jit_param_as_rvalue (param_n)),
+
+ loop_body,
+ final);
+
+ /* Build: "result += a[i] * b[i];" */
+ gcc_jit_block_add_assignment_op (
+ loop_body, NULL,
+ result,
+ GCC_JIT_BINARY_OP_PLUS,
+ gcc_jit_context_new_binary_op (
+ ctxt, NULL,
+ GCC_JIT_BINARY_OP_MULT,
+ val_type,
+ gcc_jit_lvalue_as_rvalue (
+ gcc_jit_context_new_array_access (
+ ctxt, NULL,
+ gcc_jit_param_as_rvalue (param_a),
+ gcc_jit_lvalue_as_rvalue (i))),
+ gcc_jit_lvalue_as_rvalue (
+ gcc_jit_context_new_array_access (
+ ctxt, NULL,
+ gcc_jit_param_as_rvalue (param_b),
+ gcc_jit_lvalue_as_rvalue (i)))));
+
+ /* Build: "i++" */
+ gcc_jit_block_add_assignment_op (
+ loop_body, NULL,
+ i,
+ GCC_JIT_BINARY_OP_PLUS,
+ gcc_jit_context_one (ctxt, int_type));
+
+ gcc_jit_block_end_with_jump (loop_body, NULL, loop_test);
+
+ /* Build: "return result;" */
+ gcc_jit_block_end_with_return (
+ final,
+ NULL,
+ gcc_jit_lvalue_as_rvalue (result));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef double (*my_dot_product_fn_type) (int n, double *a, double *b);
+ CHECK_NON_NULL (result);
+
+ my_dot_product_fn_type my_dot_product =
+ (my_dot_product_fn_type)gcc_jit_result_get_code (result,
+ "my_dot_product");
+ CHECK_NON_NULL (my_dot_product);
+ double test_array[] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};
+ double val = my_dot_product (10, test_array, test_array);
+ note ("my_dot_product returned: %f", val);
+ CHECK_VALUE (val, 385.0);
+}
diff --git a/gcc/testsuite/jit.dg/test-switch.c b/gcc/testsuite/jit.dg/test-switch.c
new file mode 100644
index 00000000000..74088c81f29
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-switch.c
@@ -0,0 +1,147 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Quote from here in docs/topics/functions.rst. */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int
+ test_switch (int x)
+ {
+ switch (x)
+ {
+ case 0 ... 5:
+ return 3;
+
+ case 25 ... 27:
+ return 4;
+
+ case -42 ... -17:
+ return 83;
+
+ case 40:
+ return 8;
+
+ default:
+ return 10;
+ }
+ }
+ */
+ gcc_jit_type *t_int =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *return_type = t_int;
+ gcc_jit_param *x =
+ gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
+ gcc_jit_param *params[1] = {x};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "test_switch",
+ 1, params, 0);
+
+ gcc_jit_block *b_initial =
+ gcc_jit_function_new_block (func, "initial");
+
+ gcc_jit_block *b_default =
+ gcc_jit_function_new_block (func, "default");
+ gcc_jit_block *b_case_0_5 =
+ gcc_jit_function_new_block (func, "case_0_5");
+ gcc_jit_block *b_case_25_27 =
+ gcc_jit_function_new_block (func, "case_25_27");
+ gcc_jit_block *b_case_m42_m17 =
+ gcc_jit_function_new_block (func, "case_m42_m17");
+ gcc_jit_block *b_case_40 =
+ gcc_jit_function_new_block (func, "case_40");
+
+ gcc_jit_case *cases[4] = {
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5),
+ b_case_0_5),
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27),
+ b_case_25_27),
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17),
+ b_case_m42_m17),
+ gcc_jit_context_new_case (
+ ctxt,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40),
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40),
+ b_case_40)
+ };
+ gcc_jit_block_end_with_switch (
+ b_initial, NULL,
+ gcc_jit_param_as_rvalue (x),
+ b_default,
+ 4, cases);
+
+ gcc_jit_block_end_with_return (
+ b_case_0_5, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3));
+ gcc_jit_block_end_with_return (
+ b_case_25_27, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4));
+ gcc_jit_block_end_with_return (
+ b_case_m42_m17, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83));
+ gcc_jit_block_end_with_return (
+ b_case_40, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8));
+ gcc_jit_block_end_with_return (
+ b_default, NULL,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10));
+}
+
+/* Quote up to here in docs/topics/functions.rst. */
+
+static int
+c_test_switch (int x)
+{
+ switch (x)
+ {
+ case 0 ... 5:
+ return 3;
+ case 25 ... 27:
+ return 4;
+ case -42 ... -17:
+ return 83;
+ case 40:
+ return 8;
+ default:
+ return 10;
+ }
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef int (*test_switch_type) (int);
+ CHECK_NON_NULL (result);
+ test_switch_type test_switch =
+ (test_switch_type)gcc_jit_result_get_code (result, "test_switch");
+ CHECK_NON_NULL (test_switch);
+
+ int i;
+
+ for (i = -255; i < 255; i++)
+ {
+ int val = test_switch (i);
+ int exp = c_test_switch (i);
+ if (val != exp)
+ fail ("test_switch (%i) returned: %i; expected; %i", i, val, exp);
+ }
+}
diff --git a/gcc/testsuite/jit.dg/test-switch.cc b/gcc/testsuite/jit.dg/test-switch.cc
new file mode 100644
index 00000000000..862f7a8f72b
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-switch.cc
@@ -0,0 +1,118 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit++.h"
+
+#include "harness.h"
+
+/* Quote from here in docs/cp/topics/functions.rst. */
+
+void
+create_code (gcc_jit_context *c_ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int
+ test_switch (int x)
+ {
+ switch (x)
+ {
+ case 0 ... 5:
+ return 3;
+
+ case 25 ... 27:
+ return 4;
+
+ case -42 ... -17:
+ return 83;
+
+ case 40:
+ return 8;
+
+ default:
+ return 10;
+ }
+ }
+ */
+ gccjit::context ctxt (c_ctxt);
+ gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT);
+ gccjit::type return_type = t_int;
+ gccjit::param x = ctxt.new_param (t_int, "x");
+ std::vector <gccjit::param> params;
+ params.push_back (x);
+ gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "test_switch",
+ params, 0);
+
+ gccjit::block b_initial = func.new_block ("initial");
+
+ gccjit::block b_default = func.new_block ("default");
+ gccjit::block b_case_0_5 = func.new_block ("case_0_5");
+ gccjit::block b_case_25_27 = func.new_block ("case_25_27");
+ gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17");
+ gccjit::block b_case_40 = func.new_block ("case_40");
+
+ std::vector <gccjit::case_> cases;
+ cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0),
+ ctxt.new_rvalue (t_int, 5),
+ b_case_0_5));
+ cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25),
+ ctxt.new_rvalue (t_int, 27),
+ b_case_25_27));
+ cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42),
+ ctxt.new_rvalue (t_int, -17),
+ b_case_m42_m17));
+ cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40),
+ ctxt.new_rvalue (t_int, 40),
+ b_case_40));
+ b_initial.end_with_switch (x,
+ b_default,
+ cases);
+
+ b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3));
+ b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4));
+ b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83));
+ b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8));
+ b_default.end_with_return (ctxt.new_rvalue (t_int, 10));
+}
+
+/* Quote up to here in docs/cp/topics/functions.rst. */
+
+static int
+c_test_switch (int x)
+{
+ switch (x)
+ {
+ case 0 ... 5:
+ return 3;
+ case 25 ... 27:
+ return 4;
+ case -42 ... -17:
+ return 83;
+ case 40:
+ return 8;
+ default:
+ return 10;
+ }
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef int (*test_switch_type) (int);
+ CHECK_NON_NULL (result);
+ test_switch_type test_switch =
+ (test_switch_type)gcc_jit_result_get_code (result, "test_switch");
+ CHECK_NON_NULL (test_switch);
+
+ int i;
+
+ for (i = -255; i < 255; i++)
+ {
+ int val = test_switch (i);
+ int exp = c_test_switch (i);
+ if (val != exp)
+ fail ("test_switch (%i) returned: %i; expected; %i", i, val, exp);
+ }
+}
diff --git a/gcc/testsuite/jit.dg/test-validly-unreachable-block.c b/gcc/testsuite/jit.dg/test-validly-unreachable-block.c
new file mode 100644
index 00000000000..2664818992a
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-validly-unreachable-block.c
@@ -0,0 +1,51 @@
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ void
+ test_fn ()
+ {
+ return;
+
+ return;
+ }
+ where the second block is unreachable, but have it
+ survive validation (PR jit/66546).
+ */
+ gcc_jit_context_set_bool_allow_unreachable_blocks (ctxt, 1);
+
+ gcc_jit_type *void_t =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+
+ /* Build the test_fn. */
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_t,
+ "test_fn",
+ 0, NULL,
+ 0);
+ gcc_jit_block *initial =
+ gcc_jit_function_new_block (test_fn, "a");
+ gcc_jit_block *unreachable =
+ gcc_jit_function_new_block (test_fn, "b");
+
+ gcc_jit_block_end_with_void_return (initial, NULL);
+
+ gcc_jit_block_end_with_void_return (unreachable, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the "unreachable blocks" validator was ignored. */
+ CHECK_NON_NULL (result);
+}