aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/i386/iamcu/test_passing_structs.c
diff options
context:
space:
mode:
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.c237
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;
+}