On Tue, Jun 23, 2015 at 11:38 AM, Kirill Yukhin <kirill.yuk...@gmail.com> wrote: > Hello, > This patch introduces tests for new psABI. > > gcc/testsuite/ > * 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. > > New tests pass, when run on for 32b target. > Is it ok for trunk?
I didn't look in all the details, but the patch LGTM. So, OK. Thanks, Uros. > -- > Thanks, K > > 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 0000000..b5b3261 > --- /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 0000000..f8abde4 > --- /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 0000000..b4a4a14 > --- /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 0000000..e715f42 > --- /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 0000000..98fbc66 > --- /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 0000000..7bec211 > --- /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 0000000..ecece94 > --- /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 0000000..f14cf17 > --- /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 0000000..e4b6369 > --- /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 0000000..23efa6e > --- /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 0000000..6582fc6 > --- /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 0000000..3b5027f > --- /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 0000000..93ba5ff > --- /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 0000000..0b1c293 > --- /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 0000000..9e9678d > --- /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 0000000..6bb24cc > --- /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 0000000..046e140 > --- /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 0000000..1660a4d > --- /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 0000000..ff6354c > --- /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 0000000..534fc85 > --- /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 0000000..49a6b1f > --- /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 0000000..124bef1 > --- /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; > +}