OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [testsuite/] [gcc.target/] [x86_64/] [abi/] [test_struct_returning.c] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* This tests returning of structures.  */
2
 
3
#include <stdio.h>
4
#include "defines.h"
5
#include "macros.h"
6
#include "args.h"
7
 
8
struct IntegerRegisters iregs;
9
struct FloatRegisters fregs;
10
unsigned int num_iregs, num_fregs;
11
 
12
int current_test;
13
int num_failed = 0;
14
 
15
#undef assert
16
#define assert(test) do { if (!(test)) {fprintf (stderr, "failed in test %d\n", current_test); num_failed++; } } while (0)
17
 
18
#define xmm0f xmm_regs[0]._float
19
#define xmm0d xmm_regs[0]._double
20
#define xmm1f xmm_regs[1]._float
21
#define xmm1d xmm_regs[1]._double
22
 
23
typedef enum {
24
  INT = 0,
25
  SSE_F,
26
  SSE_D,
27
  X87,
28
  MEM,
29
  INT_SSE,
30
  SSE_INT,
31
  SSE_F_V
32
} Type;
33
 
34
/* Structures which should be returned in INTEGER.  */
35
#define D(I,MEMBERS,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = INT; \
36
struct S_ ## I f_ ## I (void) { struct S_ ## I s; memset (&s, 0, sizeof(s)); B; return s; }
37
 
38
D(1,char m1, s.m1=42)
39
D(2,short m1, s.m1=42)
40
D(3,int m1, s.m1=42)
41
D(4,long m1, s.m1=42)
42
D(5,long long m1, s.m1=42)
43
D(6,char m1;short s, s.m1=42)
44
D(7,char m1;int i, s.m1=42)
45
D(8,char m1; long l, s.m1=42)
46
D(9,char m1; long long l, s.m1=42)
47
D(10,char m1[16], s.m1[0]=42)
48
D(11,short m1[8], s.m1[0]=42)
49
D(12,int m1[4], s.m1[0]=42)
50
D(13,long m1[2], s.m1[0]=42)
51
D(14,long long m1[2], s.m1[0]=42)
52
 
53
#undef D
54
 
55
/* Structures which should be returned in SSE.  */
56
#define D(I,MEMBERS,C,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = C; \
57
struct S_ ## I f_ ## I (void) { struct S_ ## I s; memset (&s, 0, sizeof(s)); B; return s; }
58
 
59
D(100,float f,SSE_F, s.f=42)
60
D(101,double d,SSE_D, s.d=42)
61
D(102,float f;float f2,SSE_F, s.f=42)
62
D(103,float f;double d,SSE_F, s.f=42)
63
D(104,double d; float f,SSE_D, s.d=42)
64
D(105,double d; double d2,SSE_D, s.d=42)
65
D(106,float f[2],SSE_F, s.f[0]=42)
66
D(107,float f[3],SSE_F, s.f[0]=42)
67
D(108,float f[4],SSE_F, s.f[0]=42)
68
D(109,double d[2],SSE_D, s.d[0]=42)
69
D(110,float f[2]; double d,SSE_F, s.f[0]=42)
70
D(111,double d;float f[2],SSE_D, s.d=42)
71
 
72
#undef D
73
 
74
/* Structures which should be returned on x87 stack.  */
75
#define D(I,MEMBERS) struct S_ ## I { MEMBERS ; }; Type class_ ## I = X87; \
76
struct S_ ## I f_ ## I (void) { struct S_ ## I s = { 42 }; return s; }
77
 
78
/* The only struct containing a long double, which is returned in
79
   registers at all, is the singleton struct.  All others are too large.
80
   This includes a struct containing complex long double, which is passed
81
   in memory, although a complex long double type itself is returned in
82
   two registers.  */
83
D(200,long double ld)
84
 
85
#undef D
86
 
87
/* Structures which should be returned in INT (low) and SSE (high).  */
88
#define D(I,MEMBERS) struct S_ ## I { MEMBERS ; }; Type class_ ## I = INT_SSE; \
89
struct S_ ## I f_ ## I (void) { struct S_ ## I s = { 42,43 }; return s; }
90
 
91
D(300,char m1; float m2)
92
D(301,char m1; double m2)
93
D(302,short m1; float m2)
94
D(303,short m1; double m2)
95
D(304,int m1; float m2)
96
D(305,int m1; double m2)
97
D(306,long m1; float m2)
98
D(307,long m1; double m2)
99
 
100
#undef D
101
 
102
void check_300 (void)
103
{
104
  XMM_T x;
105
  x._ulong[0] = rax;
106
  switch (current_test) {
107
    case 300: assert ((rax & 0xff) == 42 && x._float[1] == 43); break;
108
    case 301: assert ((rax & 0xff) == 42 && xmm0d[0] == 43); break;
109
    case 302: assert ((rax & 0xffff) == 42 && x._float[1] == 43); break;
110
    case 303: assert ((rax & 0xffff) == 42 && xmm0d[0] == 43); break;
111
    case 304: assert ((rax & 0xffffffff) == 42 && x._float[1] == 43); break;
112
    case 305: assert ((rax & 0xffffffff) == 42 && xmm0d[0] == 43); break;
113
    case 306: assert (rax == 42 && xmm0f[0] == 43); break;
114
    case 307: assert (rax == 42 && xmm0d[0] == 43); break;
115
    default: assert (0); break;
116
  }
117
}
118
 
119
/* Structures which should be returned in SSE (low) and INT (high).  */
120
#define D(I,MEMBERS,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = SSE_INT; \
121
struct S_ ## I f_ ## I (void) { struct S_ ## I s; memset (&s, 0, sizeof(s));  B; return s; }
122
 
123
D(400,float f[2];char c, s.f[0]=42; s.c=43)
124
D(401,double d;char c, s.d=42; s.c=43)
125
 
126
#undef D
127
 
128
void check_400 (void)
129
{
130
  switch (current_test) {
131
    case 400: assert (xmm0f[0] == 42 && (rax & 0xff) == 43); break;
132
    case 401: assert (xmm0d[0] == 42 && (rax & 0xff) == 43); break;
133
    default: assert (0); break;
134
  }
135
}
136
 
137
/* Structures which should be returned in MEM.  */
138
void *struct_addr;
139
#define D(I,MEMBERS) struct S_ ## I { MEMBERS ; }; Type class_ ## I = MEM; \
140
struct S_ ## I f_ ## I (void) { union {unsigned char c; struct S_ ## I s;} u; memset (&u.s, 0, sizeof(u.s)); u.c = 42; return u.s; }
141
 
142
/* Too large.  */
143
D(500,char m1[17])
144
D(501,short m1[9])
145
D(502,int m1[5])
146
D(503,long m1[3])
147
D(504,short m1[8];char c)
148
D(505,char m1[1];int i[4])
149
D(506,float m1[5])
150
D(507,double m1[3])
151
D(508,char m1[1];float f[4])
152
D(509,char m1[1];double d[2])
153
D(510,__complex long double m1[1])
154
 
155
/* Too large due to padding.  */
156
D(520,char m1[1];int i;char c2; int i2; char c3)
157
 
158
/* Unnaturally aligned members.  */
159
D(530,short m1[1];int i PACKED)
160
 
161
#undef D
162
 
163
 
164
/* Special tests.  */
165
#define D(I,MEMBERS,C,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = C; \
166
struct S_ ## I f_ ## I (void) { struct S_ ## I s; B; return s; }
167
D(600,float f[4], SSE_F_V, s.f[0] = s.f[1] = s.f[2] = s.f[3] = 42)
168
#undef D
169
 
170
void clear_all (void)
171
{
172
  clear_int_registers;
173
  clear_float_registers;
174
  clear_x87_registers;
175
}
176
 
177
void check_all (Type class, unsigned long size)
178
{
179
  switch (class) {
180
    case INT: if (size < 8) rax &= ~0UL >> (64-8*size); assert (rax == 42); break;
181
    case SSE_F: assert (xmm0f[0] == 42); break;
182
    case SSE_D: assert (xmm0d[0] == 42); break;
183
    case SSE_F_V: assert (xmm0f[0] == 42 && xmm0f[1]==42 && xmm1f[0] == 42 && xmm1f[1] == 42); break;
184
    case X87: assert (x87_regs[0]._ldouble == 42); break;
185
    case INT_SSE: check_300(); break;
186
    case SSE_INT: check_400(); break;
187
    /* Ideally we would like to check that rax == struct_addr.
188
       Unfortunately the address of the target struct escapes (for setting
189
       struct_addr), so the return struct is a temporary one whose address
190
       is given to the f_* functions, otherwise a conforming program
191
       could notice the struct changing already before the function returns.
192
       This temporary struct could be anywhere.  For GCC it will be on
193
       stack, but noone is forbidding that it could be a static variable
194
       if there's no threading or proper locking.  Nobody in his right mind
195
       will not use the stack for that.  */
196
    case MEM: assert (*(unsigned char*)struct_addr == 42 && rdi == rax); break;
197
  }
198
}
199
 
200
#define D(I) { struct S_ ## I s; current_test = I; struct_addr = (void*)&s; \
201
  clear_all(); \
202
  s = WRAP_RET(f_ ## I) (); \
203
  check_all(class_ ## I, sizeof(s)); \
204
}
205
 
206
int
207
main (void)
208
{
209
  D(1) D(2) D(3) D(4) D(5) D(6) D(7) D(8) D(9) D(10) D(11) D(12) D(13) D(14)
210
 
211
  D(100) D(101) D(102) D(103) D(104) D(105) D(106) D(107) D(108) D(109) D(110)
212
  D(111)
213
 
214
  D(200)
215
 
216
  D(300) D(301) D(302) D(303) D(304) D(305) D(306) D(307)
217
 
218
  D(400) D(401)
219
 
220
  D(500) D(501) D(502) D(503) D(504) D(505) D(506) D(507) D(508) D(509)
221
  D(520)
222
  D(530)
223
 
224
  D(600)
225
  if (num_failed)
226
    abort ();
227
 
228
  return 0;
229
}
230
#undef D

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.