/* This tests passing of structs. */ #include "defines.h" #include "args.h" #include struct IntegerRegisters iregs; struct FloatRegisters fregs; unsigned int num_iregs, num_fregs; struct int_struct { int i; }; struct long_struct { long l; }; struct long2_struct { long l1, l2; }; struct long3_struct { long l1, l2, l3; }; /* 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 long2_struct ls ATTRIBUTE_UNUSED) { check_int_arguments; } void check_struct_passing4 (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 == rsp+8); assert ((unsigned long)&ls.l2 == rsp+16); assert ((unsigned long)&ls.l3 == rsp+24); } #ifdef CHECK_M64_M128 struct m128_struct { __m128 x; }; struct m128_2_struct { __m128 x1, x2; }; /* Check that the struct is passed as the individual members in fregs. */ void check_struct_passing5 (struct m128_struct ms1 ATTRIBUTE_UNUSED, struct m128_struct ms2 ATTRIBUTE_UNUSED, struct m128_struct ms3 ATTRIBUTE_UNUSED, struct m128_struct ms4 ATTRIBUTE_UNUSED, struct m128_struct ms5 ATTRIBUTE_UNUSED, struct m128_struct ms6 ATTRIBUTE_UNUSED, struct m128_struct ms7 ATTRIBUTE_UNUSED, struct m128_struct ms8 ATTRIBUTE_UNUSED) { check_m128_arguments; } void check_struct_passing6 (struct m128_2_struct ms 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)&ms.x1 == rsp+8); assert ((unsigned long)&ms.x2 == rsp+24); } #endif 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 { int c; __complex__ float x; }; struct complex1a_struct { long l; float f; }; struct complex2_struct { int c; __complex__ float x; float y; }; struct complex2a_struct { long l; double d; }; void check_struct_passing9 (struct complex1_struct is ATTRIBUTE_UNUSED) { check_int_arguments; check_float_arguments; } void check_struct_passing10 (struct complex2_struct is ATTRIBUTE_UNUSED) { check_int_arguments; check_double_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 long2_struct l2s = { 50, 51 }; struct long3_struct l3s = { 52, 53, 54 }; #endif #ifdef CHECK_M64_M128 struct m128_struct m128s[8]; struct m128_2_struct m128_2s = { { 48.394, 39.3, -397.9, 3484.9 }, { -8.394, -93.3, 7.9, 84.94 } }; int i; #endif struct complex1_struct c1s = { 4, ( -13.4 + 3.5*I ) }; union { struct complex1_struct c; struct complex1a_struct u; } c1u; struct complex2_struct c2s = { 4, ( -13.4 + 3.5*I ), -34.5 }; union { struct complex2_struct c; struct complex2a_struct u; } c2u; 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; iregs.I0 = l2s.l1; iregs.I1 = l2s.l2; num_iregs = 2; clear_int_hardware_registers; WRAP_CALL (check_struct_passing3)(l2s); WRAP_CALL (check_struct_passing4)(l3s); #endif #ifdef CHECK_M64_M128 clear_struct_registers; for (i = 0; i < 8; i++) { m128s[i].x = (__m128){32+i, 0, i, 0}; (&fregs.xmm0)[i]._m128[0] = m128s[i].x; } num_fregs = 8; clear_float_hardware_registers; WRAP_CALL (check_struct_passing5)(m128s[0], m128s[1], m128s[2], m128s[3], m128s[4], m128s[5], m128s[6], m128s[7]); WRAP_CALL (check_struct_passing6)(m128_2s); #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; num_iregs = 1; fregs.xmm0._float [0] = c1u.u.f; num_fregs = 1; clear_int_hardware_registers; clear_float_hardware_registers; WRAP_CALL (check_struct_passing9)(c1s); clear_struct_registers; c2u.c = c2s; iregs.I0 = c2u.u.l; num_iregs = 1; fregs.xmm0._double[0] = c2u.u.d; num_fregs = 1; clear_int_hardware_registers; clear_float_hardware_registers; WRAP_CALL (check_struct_passing10)(c2s); return 0; }