1/* This tests passing of structs. */ 2 3#include "defines.h" 4#include "args.h" 5#include <complex.h> 6 7struct IntegerRegisters iregs; 8struct FloatRegisters fregs; 9unsigned int num_iregs, num_fregs; 10 11struct int_struct 12{ 13 int i; 14}; 15 16struct long_struct 17{ 18 long l; 19}; 20 21struct long2_struct 22{ 23 long l1, l2; 24}; 25 26struct long3_struct 27{ 28 long l1, l2, l3; 29}; 30 31 32/* Check that the struct is passed as the individual members in iregs. */ 33void 34check_struct_passing1 (struct int_struct is ATTRIBUTE_UNUSED) 35{ 36 check_int_arguments; 37} 38 39void 40check_struct_passing2 (struct long_struct ls ATTRIBUTE_UNUSED) 41{ 42 check_int_arguments; 43} 44 45void 46check_struct_passing3 (struct long2_struct ls ATTRIBUTE_UNUSED) 47{ 48 check_int_arguments; 49} 50 51void 52check_struct_passing4 (struct long3_struct ls ATTRIBUTE_UNUSED) 53{ 54 /* Check the passing on the stack by comparing the address of the 55 stack elements to the expected place on the stack. */ 56 assert ((unsigned long)&ls.l1 == rsp+8); 57 assert ((unsigned long)&ls.l2 == rsp+16); 58 assert ((unsigned long)&ls.l3 == rsp+24); 59} 60 61#ifdef CHECK_M64_M128 62struct m128_struct 63{ 64 __m128 x; 65}; 66 67struct m128_2_struct 68{ 69 __m128 x1, x2; 70}; 71 72/* Check that the struct is passed as the individual members in fregs. */ 73void 74check_struct_passing5 (struct m128_struct ms1 ATTRIBUTE_UNUSED, 75 struct m128_struct ms2 ATTRIBUTE_UNUSED, 76 struct m128_struct ms3 ATTRIBUTE_UNUSED, 77 struct m128_struct ms4 ATTRIBUTE_UNUSED, 78 struct m128_struct ms5 ATTRIBUTE_UNUSED, 79 struct m128_struct ms6 ATTRIBUTE_UNUSED, 80 struct m128_struct ms7 ATTRIBUTE_UNUSED, 81 struct m128_struct ms8 ATTRIBUTE_UNUSED) 82{ 83 check_m128_arguments; 84} 85 86void 87check_struct_passing6 (struct m128_2_struct ms ATTRIBUTE_UNUSED) 88{ 89 /* Check the passing on the stack by comparing the address of the 90 stack elements to the expected place on the stack. */ 91 assert ((unsigned long)&ms.x1 == rsp+8); 92 assert ((unsigned long)&ms.x2 == rsp+24); 93} 94#endif 95 96struct flex1_struct 97{ 98 long i; 99 long flex[]; 100}; 101 102struct flex2_struct 103{ 104 long i; 105 long flex[0]; 106}; 107 108void 109check_struct_passing7 (struct flex1_struct is ATTRIBUTE_UNUSED) 110{ 111 check_int_arguments; 112} 113 114void 115check_struct_passing8 (struct flex2_struct is ATTRIBUTE_UNUSED) 116{ 117 check_int_arguments; 118} 119 120struct complex1_struct 121{ 122 int c; 123 __complex__ float x; 124}; 125 126struct complex1a_struct 127{ 128 long l; 129 float f; 130}; 131 132struct complex2_struct 133{ 134 int c; 135 __complex__ float x; 136 float y; 137}; 138 139struct complex2a_struct 140{ 141 long l; 142 double d; 143}; 144 145void 146check_struct_passing9 (struct complex1_struct is ATTRIBUTE_UNUSED) 147{ 148 check_int_arguments; 149 check_float_arguments; 150} 151 152void 153check_struct_passing10 (struct complex2_struct is ATTRIBUTE_UNUSED) 154{ 155 check_int_arguments; 156 check_double_arguments; 157} 158 159static struct flex1_struct f1s = { 60, { } }; 160static struct flex2_struct f2s = { 61, { } }; 161 162int 163main (void) 164{ 165 struct int_struct is = { 48 }; 166 struct long_struct ls = { 49 }; 167#ifdef CHECK_LARGER_STRUCTS 168 struct long2_struct l2s = { 50, 51 }; 169 struct long3_struct l3s = { 52, 53, 54 }; 170#endif 171#ifdef CHECK_M64_M128 172 struct m128_struct m128s[8]; 173 struct m128_2_struct m128_2s = { 174 { 48.394, 39.3, -397.9, 3484.9 }, 175 { -8.394, -93.3, 7.9, 84.94 } 176 }; 177 int i; 178#endif 179 struct complex1_struct c1s = { 4, ( -13.4 + 3.5*I ) }; 180 union 181 { 182 struct complex1_struct c; 183 struct complex1a_struct u; 184 } c1u; 185 struct complex2_struct c2s = { 4, ( -13.4 + 3.5*I ), -34.5 }; 186 union 187 { 188 struct complex2_struct c; 189 struct complex2a_struct u; 190 } c2u; 191 192 clear_struct_registers; 193 iregs.I0 = is.i; 194 num_iregs = 1; 195 clear_int_hardware_registers; 196 WRAP_CALL (check_struct_passing1)(is); 197 198 clear_struct_registers; 199 iregs.I0 = ls.l; 200 num_iregs = 1; 201 clear_int_hardware_registers; 202 WRAP_CALL (check_struct_passing2)(ls); 203 204#ifdef CHECK_LARGER_STRUCTS 205 clear_struct_registers; 206 iregs.I0 = l2s.l1; 207 iregs.I1 = l2s.l2; 208 num_iregs = 2; 209 clear_int_hardware_registers; 210 WRAP_CALL (check_struct_passing3)(l2s); 211 WRAP_CALL (check_struct_passing4)(l3s); 212#endif 213 214#ifdef CHECK_M64_M128 215 clear_struct_registers; 216 for (i = 0; i < 8; i++) 217 { 218 m128s[i].x = (__m128){32+i, 0, i, 0}; 219 (&fregs.xmm0)[i]._m128[0] = m128s[i].x; 220 } 221 num_fregs = 8; 222 clear_float_hardware_registers; 223 WRAP_CALL (check_struct_passing5)(m128s[0], m128s[1], m128s[2], m128s[3], 224 m128s[4], m128s[5], m128s[6], m128s[7]); 225 WRAP_CALL (check_struct_passing6)(m128_2s); 226#endif 227 228 clear_struct_registers; 229 iregs.I0 = f1s.i; 230 num_iregs = 1; 231 clear_int_hardware_registers; 232 WRAP_CALL (check_struct_passing7)(f1s); 233 234 clear_struct_registers; 235 iregs.I0 = f2s.i; 236 num_iregs = 1; 237 clear_int_hardware_registers; 238 WRAP_CALL (check_struct_passing8)(f2s); 239 240 clear_struct_registers; 241 c1u.c = c1s; 242 iregs.I0 = c1u.u.l; 243 num_iregs = 1; 244 fregs.xmm0._float [0] = c1u.u.f; 245 num_fregs = 1; 246 clear_int_hardware_registers; 247 clear_float_hardware_registers; 248 WRAP_CALL (check_struct_passing9)(c1s); 249 250 clear_struct_registers; 251 c2u.c = c2s; 252 iregs.I0 = c2u.u.l; 253 num_iregs = 1; 254 fregs.xmm0._double[0] = c2u.u.d; 255 num_fregs = 1; 256 clear_int_hardware_registers; 257 clear_float_hardware_registers; 258 WRAP_CALL (check_struct_passing10)(c2s); 259 260 return 0; 261} 262