diff options
Diffstat (limited to 'gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c')
-rw-r--r-- | gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c new file mode 100644 index 00000000000..1660a4d430b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c @@ -0,0 +1,237 @@ +/* This tests passing of structs. */ + +#include "defines.h" +#include "args.h" +#include <complex.h> + +struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 }; +struct IntegerRegisters iregs; +unsigned int num_iregs; + +struct int_struct +{ + int i; +}; + +struct long_struct +{ + long l; +}; + +struct longlong2_struct +{ + long long ll1, ll2; +}; + +struct longlong3_struct +{ + long long ll1, ll2, ll3; +}; + +/* Check that the struct is passed as the individual members in iregs. */ +void +check_struct_passing1 (struct int_struct is ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +void +check_struct_passing2 (struct long_struct ls ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +void +check_struct_passing3 (struct longlong2_struct ls ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +void +check_struct_passing4 (struct longlong3_struct ls ATTRIBUTE_UNUSED) +{ + /* Check the passing on the stack by comparing the address of the + stack elements to the expected place on the stack. */ + assert ((unsigned long)&ls.ll1 == esp+4); + assert ((unsigned long)&ls.ll2 == esp+12); + assert ((unsigned long)&ls.ll3 == esp+20); +} + +struct flex1_struct +{ + long i; + long flex[]; +}; + +struct flex2_struct +{ + long i; + long flex[0]; +}; + +void +check_struct_passing7 (struct flex1_struct is ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +void +check_struct_passing8 (struct flex2_struct is ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +struct complex1_struct +{ + __complex__ float x; +}; + +struct complex1a_struct +{ + long l; + union + { + float f; + int i; + } u; +}; + +void +check_struct_passing9 (struct complex1_struct is ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +struct long3_struct +{ + long l1, l2, l3; +}; + +void +check_struct_passing10 (struct long3_struct ls ATTRIBUTE_UNUSED) +{ + /* Check the passing on the stack by comparing the address of the + stack elements to the expected place on the stack. */ + assert ((unsigned long)&ls.l1 == esp+4); + assert ((unsigned long)&ls.l2 == esp+8); + assert ((unsigned long)&ls.l3 == esp+12); +} + +struct char3_struct +{ + char c1, c2, c3; +}; + +void +check_struct_passing11 (struct char3_struct is ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +struct char7_struct +{ + char c1, c2, c3, c4, c5, c6, c7; +}; + +void +check_struct_passing12 (struct char7_struct is ATTRIBUTE_UNUSED) +{ + check_int_arguments; +} + +static struct flex1_struct f1s = { 60, { } }; +static struct flex2_struct f2s = { 61, { } }; + +int +main (void) +{ + struct int_struct is = { 48 }; + struct long_struct ls = { 49 }; +#ifdef CHECK_LARGER_STRUCTS + struct longlong2_struct ll2s = { 50, 51 }; + struct longlong3_struct ll3s = { 52, 53, 54 }; + struct long3_struct l3s = { 60, 61, 62 }; +#endif + struct complex1_struct c1s = { ( -13.4 + 3.5*I ) }; + union + { + struct complex1_struct c; + struct complex1a_struct u; + } c1u; + struct char3_struct c3 = { 0x12, 0x34, 0x56 }; + union + { + struct char3_struct c; + int i; + } c3u; + struct char7_struct c7 = { 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56 }; + union + { + struct char7_struct c; + struct + { + int i0, i1; + } i; + } c7u; + + clear_struct_registers; + iregs.I0 = is.i; + num_iregs = 1; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing1)(is); + + clear_struct_registers; + iregs.I0 = ls.l; + num_iregs = 1; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing2)(ls); + +#ifdef CHECK_LARGER_STRUCTS + clear_struct_registers; + num_iregs = 0; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing3)(ll2s); + WRAP_CALL (check_struct_passing4)(ll3s); + WRAP_CALL (check_struct_passing10)(l3s); +#endif + + clear_struct_registers; + iregs.I0 = f1s.i; + num_iregs = 1; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing7)(f1s); + + clear_struct_registers; + iregs.I0 = f2s.i; + num_iregs = 1; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing8)(f2s); + + clear_struct_registers; + c1u.c = c1s; + iregs.I0 = c1u.u.l; + iregs.I1 = c1u.u.u.i; + num_iregs = 2; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing9)(c1s); + + clear_struct_registers; + c3u.c = c3; + iregs.I0 = c3u.i; + iregbits.I0 = 0xffffff; + num_iregs = 1; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing11)(c3); + + clear_struct_registers; + c7u.c = c7; + iregs.I0 = c7u.i.i0; + iregs.I1 = c7u.i.i1; + iregbits.I0 = 0xffffffff; + iregbits.I1 = 0xffffff; + num_iregs = 2; + clear_int_hardware_registers; + WRAP_CALL (check_struct_passing12)(c7); + + return 0; +} |