diff options
Diffstat (limited to 'gcc/testsuite')
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); +} |