Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140607070409

Diff

Diff from 1.106 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/gcc_compat.c

Annotated File View

plunky
1.106
1 /*      $Id: gcc_compat.c,v 1.106 2014/06/07 07:04:09 plunky Exp $     */
ragge
1.1
2 /*
3  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Routines to support some of the gcc extensions to C.
31  */
32 #ifdef GCC_COMPAT
33
34 #include "pass1.h"
ragge
1.5
35 #include "cgram.h"
ragge
1.1
36
ragge
1.2
37 #include <string.h>
38
ragge
1.1
39 static struct kw {
40         char *name, *ptr;
41         int rv;
42 kw[] = {
ragge
1.9
43 /*
44  * Do NOT change the order of these entries unless you know 
45  * what you're doing!
46  */
ragge
1.13
47 /* 0 */ { "__asm"NULLC_ASM },
48 /* 1 */ { "__signed"NULL0 },
49 /* 2 */ { "__inline"NULLC_FUNSPEC },
50 /* 3 */ { "__const"NULL0 },
51 /* 4 */ { "__asm__"NULLC_ASM },
52 /* 5 */ { "__inline__"NULLC_FUNSPEC },
53 /* 6 */ { "__thread"NULL0 },
54 /* 7 */ { "__FUNCTION__"NULL0 },
55 /* 8 */ { "__volatile"NULL0 },
56 /* 9 */ { "__volatile__"NULL0 },
57 /* 10 */"__restrict"NULL, -1 },
ragge
1.14
58 /* 11 */"__typeof__"NULLC_TYPEOF },
59 /* 12 */"typeof"NULLC_TYPEOF },
ragge
1.15
60 /* 13 */"__extension__"NULL, -1 },
ragge
1.16
61 /* 14 */"__signed__"NULL0 },
ragge
1.22
62 /* 15 */"__attribute__"NULL0 },
ragge
1.24
63 /* 16 */"__attribute"NULL0 },
ragge
1.32
64 /* 17 */"__real__"NULL0 },
65 /* 18 */"__imag__"NULL0 },
ragge
1.37
66 /* 19 */"__builtin_offsetof"NULLPCC_OFFSETOF },
ragge
1.58
67 /* 20 */"__PRETTY_FUNCTION__"NULL0 },
ragge
1.59
68 /* 21 */"__alignof__"NULLC_ALIGNOF },
ragge
1.61
69 /* 22 */"__typeof"NULLC_TYPEOF },
ragge
1.73
70 /* 23 */"__alignof"NULLC_ALIGNOF },
ragge
1.74
71 /* 24 */"__restrict__"NULL, -1 },
ragge
1.1
72         { NULLNULL0 },
73 };
74
ragge
1.38
75 /* g77 stuff */
76 #if SZFLOAT == SZLONG
77 #define G77_INTEGER LONG
78 #define G77_UINTEGER ULONG
79 #elif SZFLOAT == SZINT
80 #define G77_INTEGER INT
81 #define G77_UINTEGER UNSIGNED
82 #else
83 #error fix g77 stuff
84 #endif
85 #if SZFLOAT*2 == SZLONG
86 #define G77_LONGINT LONG
87 #define G77_ULONGINT ULONG
88 #elif SZFLOAT*2 == SZLONGLONG
89 #define G77_LONGINT LONGLONG
90 #define G77_ULONGINT ULONGLONG
91 #else
92 #error fix g77 long stuff
93 #endif
94
95 static TWORD g77t[] = { G77_INTEGERG77_UINTEGERG77_LONGINTG77_ULONGINT };
96 static char *g77n[] = { "__g77_integer""__g77_uinteger",
97         "__g77_longint""__g77_ulongint" };
98
ragge
1.87
99 #ifdef TARGET_TIMODE
ragge
1.91
100 static char *loti, *hiti, *TISTR;
101 static struct symtab *tisp, *ucmpti2sp, *cmpti2sp, *subvti3sp,
ragge
1.94
102         *addvti3sp, *mulvti3sp, *divti3sp, *udivti3sp, *modti3sp, *umodti3sp,
ragge
1.95
103         *ashldi3sp, *ashrdi3sp, *lshrdi3sp, *floatuntixfsp;
ragge
1.87
104
105 static struct symtab *
106 addftn(char *nTWORD t)
107 {
108         NODE *p = block(TYPE00000);
109         struct symtab *sp;
110
111         sp = lookup(addname(n), 0);
112         p->n_type = INCREF(t) + (FTN-PTR);
113         p->n_sp = sp;
ragge
1.89
114         p->n_df = memset(permalloc(sizeof(union dimfun)), 0,
115             sizeof(union dimfun));
ragge
1.90
116         defid(pEXTERN);
ragge
1.87
117         nfree(p);
118         return sp;
119 }
ragge
1.88
120
121 static struct symtab *
ragge
1.91
122 addstr(char *n)
ragge
1.88
123 {
124         NODE *p = block(NAMENILNILFLOAT00);
125         struct symtab *sp;
126         NODE *q;
127         struct attr *ap;
128         struct rstack *rp;
129         extern struct rstack *rpole;
130
ragge
1.91
131         p->n_type = ctype(ULONGLONG);
ragge
1.88
132         rpole = rp = bstruct(NULLSTNAMENULL);
133         soumemb(ploti0);
134         soumemb(phiti0);
135         q = dclstruct(rp);
136         sp = q->n_sp = lookup(addname(n), 0);
137         defid(qTYPEDEF);
138         ap = attr_new(GCC_ATYP_MODE3);
ragge
1.89
139         ap->sarg(0) = addname("TI");
ragge
1.91
140         ap->iarg(1) = 0;
ragge
1.88
141         sp->sap = attr_add(sp->sapap);
142         nfree(q);
143         nfree(p);
144
145         return sp;
146 }
ragge
1.87
147 #endif
148
ragge
1.1
149 void
plunky
1.85
150 gcc_init(void)
ragge
1.1
151 {
152         struct kw *kwp;
ragge
1.38
153         NODE *p;
154         TWORD t;
ragge
1.87
155         int id_debug;
ragge
1.1
156
ragge
1.87
157         d_debug = ddebug;
158         ddebug = 0;
ragge
1.1
159         for (kwp = kwkwp->namekwp++)
160                 kwp->ptr = addname(kwp->name);
161
ragge
1.38
162         for (i = 0i < 4i++) {
gmcgarry
1.44
163                 struct symtab *sp;
ragge
1.38
164                 t = ctype(g77t[i]);
ragge
1.78
165                 p = block(NAMENILNILtNULL0);
gmcgarry
1.44
166                 sp = lookup(addname(g77n[i]), 0);
ragge
1.38
167                 p->n_sp = sp;
168                 defid(pTYPEDEF);
169                 nfree(p);
170         }
ragge
1.87
171         ddebug = d_debug;
172 #ifdef TARGET_TIMODE
173         {
ragge
1.91
174                 struct attr *ap;
ragge
1.87
175
176                 loti = addname("__loti");
177                 hiti = addname("__hiti");
ragge
1.91
178                 TISTR = addname("TI");
ragge
1.87
179
ragge
1.91
180                 tisp = addstr("0ti");
ragge
1.88
181
182                 cmpti2sp = addftn("__cmpti2"INT);
ragge
1.87
183                 ucmpti2sp = addftn("__ucmpti2"INT);
ragge
1.90
184
185                 addvti3sp = addftn("__addvti3"STRTY);
186                 addvti3sp->sap = tisp->sap;
187                 subvti3sp = addftn("__subvti3"STRTY);
188                 subvti3sp->sap = tisp->sap;
189                 mulvti3sp = addftn("__mulvti3"STRTY);
190                 mulvti3sp->sap = tisp->sap;
191                 divti3sp = addftn("__divti3"STRTY);
192                 divti3sp->sap = tisp->sap;
193                 modti3sp = addftn("__modti3"STRTY);
194                 modti3sp->sap = tisp->sap;
ragge
1.91
195
196                 ap = attr_new(GCC_ATYP_MODE3);
197                 ap->sarg(0) = TISTR;
198                 ap->iarg(1) = 1;
199                 ap = attr_add(tisp->sapap);
200                 udivti3sp = addftn("__udivti3"STRTY);
201                 udivti3sp->sap = ap;
ragge
1.90
202                 umodti3sp = addftn("__umodti3"STRTY);
ragge
1.91
203                 umodti3sp->sap = ap;
ragge
1.100
204                 ashldi3sp = addftn("__ashldi3"ctype(LONGLONG));
ragge
1.94
205                 ashldi3sp->sap = ap;
ragge
1.100
206                 ashrdi3sp = addftn("__ashrdi3"ctype(LONGLONG));
ragge
1.94
207                 ashrdi3sp->sap = ap;
ragge
1.100
208                 lshrdi3sp = addftn("__lshrdi3"ctype(LONGLONG));
ragge
1.94
209                 lshrdi3sp->sap = ap;
ragge
1.95
210
211                 floatuntixfsp = addftn("__floatuntixf"LDOUBLE);
ragge
1.87
212         }
213 #endif
ragge
1.1
214 }
215
ragge
1.11
216 #define TS      "\n#pragma tls\n# %d\n"
217 #define TLLEN   sizeof(TS)+10
ragge
1.1
218 /*
219  * See if a string matches a gcc keyword.
220  */
221 int
ragge
1.5
222 gcc_keyword(char *strNODE **n)
ragge
1.1
223 {
ragge
1.22
224         extern int inattrparlvlparbal;
ragge
1.32
225         YYSTYPE *yyl = (YYSTYPE *)n/* XXX should pass yylval */
ragge
1.11
226         char tlbuf[TLLEN], *tw;
ragge
1.1
227         struct kw *kwp;
228         int i;
229
ragge
1.62
230         /* XXX hack, should pass everything in expressions */
231         if (str == kw[21].ptr)
232                 return kw[21].rv;
233
ragge
1.57
234         if (inattr)
235                 return 0;
236
ragge
1.1
237         for (i = 0kwp = kwkwp->namekwp++, i++)
ragge
1.5
238                 if (str == kwp->ptr)
ragge
1.1
239                         break;
240         if (kwp->name == NULL)
241                 return 0;
242         if (kwp->rv)
243                 return kwp->rv;
244         switch (i) {
ragge
1.16
245         case 1:  /* __signed */
246         case 14/* __signed__ */
ragge
1.78
247                 *n = mkty((TWORD)SIGNED00);
ragge
1.1
248                 return C_TYPE;
ragge
1.4
249         case 3/* __const */
ragge
1.5
250                 *n = block(QUALIFIERNILNILCON00);
ragge
1.75
251                 (*n)->n_qual = CON;
ragge
1.4
252                 return C_QUALIFIER;
ragge
1.11
253         case 6/* __thread */
254                 snprintf(tlbufTLLENTSlineno);
255                 tw = &tlbuf[strlen(tlbuf)];
256                 while (tw > tlbuf)
257                         cunput(*--tw);
258                 return -1;
ragge
1.12
259         case 7/* __FUNCTION__ */
ragge
1.58
260         case 20/* __PRETTY_FUNCTION__ */
ragge
1.12
261                 if (cftnsp == NULL) {
ragge
1.58
262                         uerror("%s outside function"kwp->name);
ragge
1.12
263                         yylval.strp = "";
264                 } else
265                         yylval.strp = cftnsp->sname/* XXX - not C99 */
266                 return C_STRING;
267         case 8/* __volatile */
268         case 9/* __volatile__ */
269                 *n = block(QUALIFIERNILNILVOL00);
ragge
1.75
270                 (*n)->n_qual = VOL;
ragge
1.12
271                 return C_QUALIFIER;
ragge
1.22
272         case 15/* __attribute__ */
ragge
1.24
273         case 16/* __attribute */
ragge
1.22
274                 inattr = 1;
275                 parlvl = parbal;
276                 return C_ATTRIBUTE;
ragge
1.32
277         case 17/* __real__ */
278                 yyl->intval = XREAL;
279                 return C_UNOP;
280         case 18/* __imag__ */
281                 yyl->intval = XIMAG;
282                 return C_UNOP;
ragge
1.1
283         }
284         cerror("gcc_keyword");
285         return 0;
286 }
ragge
1.17
287
ragge
1.23
288 #ifndef TARGET_ATTR
ragge
1.26
289 #define TARGET_ATTR(p, sue)             0
ragge
1.20
290 #endif
ragge
1.19
291 #ifndef ALMAX
292 #define ALMAX (ALLDOUBLE > ALLONGLONG ? ALLDOUBLE : ALLONGLONG)
293 #endif
ragge
1.18
294
ragge
1.26
295 /* allowed number of args */
296 #define A_0ARG  0x01
297 #define A_1ARG  0x02
298 #define A_2ARG  0x04
299 #define A_3ARG  0x08
ragge
1.39
300 /* arg # is a name */
301 #define A1_NAME 0x10
302 #define A2_NAME 0x20
303 #define A3_NAME 0x40
ragge
1.26
304 #define A_MANY  0x80
ragge
1.39
305 /* arg # is "string" */
306 #define A1_STR  0x100
307 #define A2_STR  0x200
308 #define A3_STR  0x400
ragge
1.26
309
ragge
1.55
310 #ifdef __MSC__
311 #define CS(x)
312 #else
313 #define CS(x) [x] =
314 #endif
315
ragge
1.26
316 struct atax {
317         int typ;
318         char *name;
319 atax[GCC_ATYP_MAX] = {
ragge
1.64
320         CS(ATTR_NONE)           { 0NULL },
321         CS(ATTR_COMPLEX)        { 0NULL },
ragge
1.78
322         CS(xxxATTR_BASETYP)     { 0NULL },
ragge
1.64
323         CS(ATTR_QUALTYP)        { 0NULL },
324         CS(ATTR_STRUCT)         { 0NULL },
ragge
1.103
325         CS(ATTR_ALIGNED)        { A_0ARG|A_1ARG"aligned" },
ragge
1.55
326         CS(GCC_ATYP_PACKED)     { A_0ARG|A_1ARG"packed" },
327         CS(GCC_ATYP_SECTION)    { A_1ARG|A1_STR"section" },
328         CS(GCC_ATYP_TRANSP_UNION) { A_0ARG"transparent_union" },
329         CS(GCC_ATYP_UNUSED)     { A_0ARG"unused" },
330         CS(GCC_ATYP_DEPRECATED) { A_0ARG"deprecated" },
331         CS(GCC_ATYP_MAYALIAS)   { A_0ARG"may_alias" },
332         CS(GCC_ATYP_MODE)       { A_1ARG|A1_NAME"mode" },
333         CS(GCC_ATYP_NORETURN)   { A_0ARG"noreturn" },
334         CS(GCC_ATYP_FORMAT)     { A_3ARG|A1_NAME"format" },
335         CS(GCC_ATYP_NONNULL)    { A_MANY"nonnull" },
336         CS(GCC_ATYP_SENTINEL)   { A_0ARG|A_1ARG"sentinel" },
337         CS(GCC_ATYP_WEAK)       { A_0ARG"weak" },
338         CS(GCC_ATYP_FORMATARG)  { A_1ARG"format_arg" },
339         CS(GCC_ATYP_GNU_INLINE) { A_0ARG"gnu_inline" },
340         CS(GCC_ATYP_MALLOC)     { A_0ARG"malloc" },
341         CS(GCC_ATYP_NOTHROW)    { A_0ARG"nothrow" },
342         CS(GCC_ATYP_CONST)      { A_0ARG"const" },
343         CS(GCC_ATYP_PURE)       { A_0ARG"pure" },
344         CS(GCC_ATYP_CONSTRUCTOR) { A_0ARG"constructor" },
345         CS(GCC_ATYP_DESTRUCTOR) { A_0ARG"destructor" },
346         CS(GCC_ATYP_VISIBILITY) { A_1ARG|A1_STR"visibility" },
347         CS(GCC_ATYP_STDCALL)    { A_0ARG"stdcall" },
348         CS(GCC_ATYP_CDECL)      { A_0ARG"cdecl" },
349         CS(GCC_ATYP_WARN_UNUSED_RESULT) { A_0ARG"warn_unused_result" },
350         CS(GCC_ATYP_USED)       { A_0ARG"used" },
351         CS(GCC_ATYP_NO_INSTR_FUN) { A_0ARG"no_instrument_function" },
352         CS(GCC_ATYP_NOINLINE)   { A_0ARG"noinline" },
353         CS(GCC_ATYP_ALIAS)      { A_1ARG|A1_STR"alias" },
354         CS(GCC_ATYP_WEAKREF)    { A_0ARG|A_1ARG|A1_STR"weakref" },
ragge
1.60
355         CS(GCC_ATYP_ALLOCSZ)    { A_1ARG|A_2ARG"alloc_size" },
ragge
1.63
356         CS(GCC_ATYP_ALW_INL)    { A_0ARG"always_inline" },
ragge
1.66
357         CS(GCC_ATYP_TLSMODEL)   { A_1ARG|A1_STR"tls_model" },
ragge
1.70
358         CS(GCC_ATYP_ALIASWEAK)  { A_1ARG|A1_STR"aliasweak" },
plunky
1.82
359         CS(GCC_ATYP_RETURNS_TWICE) { A_0ARG"returns_twice" },
ragge
1.86
360         CS(GCC_ATYP_WARNING)    { A_1ARG|A1_STR"warning" },
ragge
1.99
361         CS(GCC_ATYP_NOCLONE)    { A_0ARG"noclone" },
ragge
1.102
362         CS(GCC_ATYP_REGPARM)    { A_1ARG"regparm" },
ragge
1.55
363
ragge
1.56
364         CS(GCC_ATYP_BOUNDED)    { A_3ARG|A_MANY|A1_NAME"bounded" },
ragge
1.26
365 };
ragge
1.55
366
ragge
1.47
367 #if SZPOINT(CHAR) == SZLONGLONG
368 #define GPT     LONGLONG
369 #else
370 #define GPT     INT
371 #endif
372
373 struct atax mods[] = {
374         { 0NULL },
375         { INT"SI" },
376         { INT"word" },
377         { GPT"pointer" },
378         { CHAR"byte" },
379         { CHAR"QI" },
380         { SHORT"HI" },
381         { LONGLONG"DI" },
382         { FLOAT"SF" },
383         { DOUBLE"DF" },
ragge
1.72
384         { LDOUBLE"XF" },
385         { FCOMPLEX"SC" },
386         { COMPLEX"DC" },
387         { LCOMPLEX"XC" },
ragge
1.90
388         { INT"libgcc_cmp_return" },
389         { INT"libgcc_shift_count" },
ragge
1.99
390         { LONG"unwind_word" },
ragge
1.87
391 #ifdef TARGET_TIMODE
ragge
1.89
392         { 800"TI" },
ragge
1.87
393 #endif
ragge
1.68
394 #ifdef TARGET_MODS
395         TARGET_MODS
396 #endif
ragge
1.47
397 };
398 #define ATSZ    (sizeof(mods)/sizeof(mods[0]))
ragge
1.26
399
400 static int
ragge
1.47
401 amatch(char *sstruct atax *atint mx)
ragge
1.26
402 {
403         int ilen;
404
405         if (s[0] == '_' && s[1] == '_')
406                 s += 2;
407         len = strlen(s);
408         if (len > 2 && s[len-1] == '_' && s[len-2] == '_')
409                 len -= 2;
ragge
1.47
410         for (i = 0i < mxi++) {
411                 char *t = at[i].name;
ragge
1.26
412                 if (t != NULL && strncmp(stlen) == 0 && t[len] == 0)
413                         return i;
414         }
415         return 0;
416 }
417
418 static void
ragge
1.64
419 setaarg(int strunion aarg *aaNODE *p)
ragge
1.26
420 {
421         if (str) {
ragge
1.39
422                 if (((str & (A1_STR|A2_STR|A3_STR)) && p->n_op != STRING) ||
423                     ((str & (A1_NAME|A2_NAME|A3_NAME)) && p->n_op != NAME))
424                         uerror("bad arg to attribute");
ragge
1.69
425                 if (p->n_op == STRING) {
plunky
1.97
426                         aa->sarg = newstring(p->n_namestrlen(p->n_name));
ragge
1.69
427                 } else
428                         aa->sarg = (char *)p->n_sp;
ragge
1.26
429                 nfree(p);
430         } else
gmcgarry
1.36
431                 aa->iarg = (int)icons(eve(p));
ragge
1.26
432 }
433
ragge
1.18
434 /*
ragge
1.23
435  * Parse attributes from an argument list.
ragge
1.20
436  */
ragge
1.77
437 static struct attr *
438 gcc_attribs(NODE *p)
ragge
1.20
439 {
ragge
1.26
440         NODE *q, *r;
ragge
1.77
441         struct attr *ap;
ragge
1.49
442         char *name = NULL, *c;
ragge
1.89
443         int cwattrnarg;
ragge
1.20
444
445         if (p->n_op == NAME) {
446                 name = (char *)p->n_sp;
447         } else if (p->n_op == CALL || p->n_op == UCALL) {
448                 name = (char *)p->n_left->n_sp;
ragge
1.67
449         } else if (p->n_op == ICON && p->n_type == STRTY) {
ragge
1.77
450                 return NULL;
ragge
1.20
451         } else
452                 cerror("bad variable attribute");
453
ragge
1.47
454         if ((attr = amatch(nameataxGCC_ATYP_MAX)) == 0) {
plunky
1.106
455                 warner(Wattributesname);
ragge
1.77
456                 ap = NULL;
ragge
1.27
457                 goto out;
ragge
1.26
458         }
459         narg = 0;
460         if (p->n_op == CALL)
461                 for (narg = 1q = p->n_rightq->n_op == CMq = q->n_left)
462                         narg++;
463
464         cw = atax[attr].typ;
465         if (!(cw & A_MANY) && ((narg > 3) || ((cw & (1 << narg)) == 0))) {
466                 uerror("wrong attribute arg count");
ragge
1.77
467                 return NULL;
ragge
1.26
468         }
ragge
1.64
469         ap = attr_new(attr3); /* XXX should be narg */
ragge
1.26
470         q = p->n_right;
471
472         switch (narg) {
473         default:
474                 /* XXX */
475                 while (narg-- > 3) {
476                         r = q;
477                         q = q->n_left;
478                         tfree(r->n_right);
479                         nfree(r);
480                 }
481                 /* FALLTHROUGH */
482         case 3:
ragge
1.64
483                 setaarg(cw & (A3_NAME|A3_STR), &ap->aa[2], q->n_right);
ragge
1.26
484                 r = q;
485                 q = q->n_left;
486                 nfree(r);
487                 /* FALLTHROUGH */
488         case 2:
ragge
1.64
489                 setaarg(cw & (A2_NAME|A2_STR), &ap->aa[1], q->n_right);
ragge
1.26
490                 r = q;
491                 q = q->n_left;
492                 nfree(r);
493                 /* FALLTHROUGH */
494         case 1:
ragge
1.64
495                 setaarg(cw & (A1_NAME|A1_STR), &ap->aa[0], q);
ragge
1.26
496                 p->n_op = UCALL;
497                 /* FALLTHROUGH */
498         case 0:
499                 break;
500         }
501
502         /* some attributes must be massaged special */
503         switch (attr) {
ragge
1.103
504         case ATTR_ALIGNED:
ragge
1.26
505                 if (narg == 0)
ragge
1.64
506                         ap->aa[0].iarg = ALMAX;
ragge
1.26
507                 else
ragge
1.64
508                         ap->aa[0].iarg *= SZCHAR;
ragge
1.26
509                 break;
510         case GCC_ATYP_PACKED:
ragge
1.28
511                 if (narg == 0)
ragge
1.64
512                         ap->aa[0].iarg = 1/* bitwise align */
ragge
1.28
513                 else
ragge
1.64
514                         ap->aa[0].iarg *= SZCHAR;
ragge
1.26
515                 break;
ragge
1.43
516
ragge
1.49
517         case GCC_ATYP_VISIBILITY:
ragge
1.64
518                 c = ap->aa[0].sarg;
ragge
1.49
519                 if (strcmp(c"default") && strcmp(c"hidden") &&
520                     strcmp(c"internal") && strcmp(c"protected"))
521                         werror("unknown visibility %s"c);
522                 break;
523
ragge
1.66
524         case GCC_ATYP_TLSMODEL:
525                 c = ap->aa[0].sarg;
526                 if (strcmp(c"global-dynamic") && strcmp(c"local-dynamic") &&
527                     strcmp(c"initial-exec") && strcmp(c"local-exec"))
528                         werror("unknown tls model %s"c);
529                 break;
530
ragge
1.26
531         default:
532                 break;
533         }
534 out:
ragge
1.77
535         return ap;
ragge
1.18
536 }
537
ragge
1.17
538 /*
ragge
1.64
539  * Extract attributes from a node tree and return attribute entries 
540  * based on its contents.
ragge
1.17
541  */
ragge
1.64
542 struct attr *
ragge
1.23
543 gcc_attr_parse(NODE *p)
ragge
1.17
544 {
ragge
1.77
545         struct attr *b, *c;
ragge
1.18
546
ragge
1.65
547         if (p == NIL)
548                 return NULL;
ragge
1.77
549
550         if (p->n_op != CM) {
551                 b = gcc_attribs(p);
552                 tfree(p);
553         } else {
554                 b = gcc_attr_parse(p->n_left);
555                 c = gcc_attr_parse(p->n_right);
556                 nfree(p);
557                 b = b ? attr_add(bc) : c;
558         }
559         return b;
ragge
1.17
560 }
561
ragge
1.23
562 /*
563  * Fixup struct/unions depending on attributes.
564  */
565 void
ragge
1.64
566 gcc_tcattrfix(NODE *p)
ragge
1.20
567 {
ragge
1.23
568         struct symtab *sp;
ragge
1.64
569         struct attr *ap;
ragge
1.80
570         int szcoffcszaloalmxal;
ragge
1.23
571
ragge
1.64
572         if ((ap = attr_find(p->n_apGCC_ATYP_PACKED)) == NULL)
573                 return/* nothing to fix */
ragge
1.20
574
ragge
1.64
575         al = ap->iarg(0);
ragge
1.80
576         mxal = 0;
ragge
1.20
577
ragge
1.64
578         /* Must repack struct */
579         coff = csz = 0;
580         for (sp = strmemb(ap); spsp = sp->snext) {
ragge
1.79
581                 oal = talign(sp->stypesp->sap);
582                 if (oal > al)
583                         oal = al;
ragge
1.80
584                 if (mxal < oal)
585                         mxal = oal;
ragge
1.64
586                 if (sp->sclass & FIELD)
587                         sz = sp->sclass&FLDSIZ;
588                 else
589                         sz = (int)tsize(sp->stypesp->sdfsp->sap);
ragge
1.79
590                 sp->soffset = upoff(szoal, &coff);
ragge
1.64
591                 if (coff > csz)
592                         csz = coff;
593                 if (p->n_type == UNIONTY)
594                         coff = 0;
595         }
ragge
1.81
596         if (mxal < ALCHAR)
597                 mxal = ALCHAR/* for bitfields */
ragge
1.80
598         SETOFF(cszmxal); /* Roundup to whatever */
ragge
1.64
599
ragge
1.78
600         ap = attr_find(p->n_apATTR_STRUCT);
601         ap->amsize = csz;
ragge
1.103
602         ap = attr_find(p->n_apATTR_ALIGNED);
ragge
1.80
603         ap->iarg(0) = mxal;
604
ragge
1.25
605 }
606
ragge
1.71
607 /*
608  * gcc-specific pragmas.
609  */
610 int
611 pragmas_gcc(char *t)
612 {
plunky
1.83
613         char u;
plunky
1.104
614         extern char *pragstore;
ragge
1.71
615
616         if (strcmp((t = pragtok(NULL)), "diagnostic") == 0) {
plunky
1.104
617                 int warnerr;
618
ragge
1.71
619                 if (strcmp((t = pragtok(NULL)), "ignored") == 0)
plunky
1.104
620                         warn = 0err = 0;
ragge
1.71
621                 else if (strcmp(t"warning") == 0)
plunky
1.104
622                         warn = 1err = 0;
ragge
1.71
623                 else if (strcmp(t"error") == 0)
plunky
1.104
624                         warn = 1err = 1;
ragge
1.71
625                 else
626                         return 1;
plunky
1.104
627
ragge
1.71
628                 if (eat('\"') || eat('-'))
629                         return 1;
plunky
1.104
630
ragge
1.71
631                 for (t = pragstore; *t && *t != '\"'t++)
632                         ;
plunky
1.104
633
ragge
1.71
634                 u = *t;
635                 *t = 0;
plunky
1.104
636                 Wset(pragstore + 1warnerr);
ragge
1.71
637                 *t = u;
ragge
1.72
638         } else if (strcmp(t"poison") == 0) {
639                 /* currently ignore */;
640         } else if (strcmp(t"visibility") == 0) {
641                 /* currently ignore */;
plunky
1.84
642         } else if (strcmp(t"system_header") == 0) {
643                 /* currently ignore */;
ragge
1.72
644         } else
645                 werror("gcc pragma unsupported");
ragge
1.71
646         return 0;
647 }
648
ragge
1.87
649 /*
650  * Fixup types when modes given in defid().
651  */
652 void
653 gcc_modefix(NODE *p)
654 {
plunky
1.92
655         struct attr *ap;
656 #ifdef TARGET_TIMODE
657         struct attr *a2;
658 #endif
ragge
1.88
659         struct symtab *sp;
ragge
1.91
660         char *s;
ragge
1.89
661         int iu;
662
663         if ((ap = attr_find(p->n_apGCC_ATYP_MODE)) == NULL)
664                 return;
ragge
1.87
665
ragge
1.98
666         u = ISUNSIGNED(BTYPE(p->n_type));
ragge
1.89
667         if ((i = amatch(ap->aa[0].sargmodsATSZ)) == 0) {
668                 werror("unknown mode arg %s"ap->aa[0].sarg);
669                 return;
670         }
671         i = mods[i].typ;
672         switch (i) {
673 #ifdef TARGET_TIMODE
674         case 800:
675                 if (BTYPE(p->n_type) == STRTY)
676                         break;
ragge
1.91
677                 MODTYPE(p->n_typetisp->stype);
678                 p->n_df = tisp->sdf;
679                 p->n_ap = tisp->sap;
680                 if (ap->iarg(1) == u)
681                         break;
682                 /* must add a new mode struct to avoid overwriting */
683                 a2 = attr_new(GCC_ATYP_MODE3);
684                 a2->sarg(0) = ap->sarg(0);
685                 a2->iarg(1) = u;
686                 p->n_ap = attr_add(p->n_apa2);
ragge
1.89
687                 break;
ragge
1.87
688 #endif
ragge
1.91
689         case 1 ... MAXTYPES:
ragge
1.90
690                 MODTYPE(p->n_typectype(i));
ragge
1.89
691                 if (u)
692                         p->n_type = ENUNSIGN(p->n_type);
693                 break;
ragge
1.91
694
695         case FCOMPLEX:
696         case COMPLEX:
697         case LCOMPLEX:
698                 /* Destination should have been converted to a struct already */
ragge
1.93
699                 if (BTYPE(p->n_type) != STRTY)
ragge
1.91
700                         uerror("gcc_modefix: complex not STRTY");
701                 i -= (FCOMPLEX-FLOAT);
702                 ap = strattr(p->n_ap);
703                 sp = ap->amlist;
704                 if (sp->stype == (unsigned)i)
705                         return/* Already correct type */
706                 /* we must change to another struct */
707                 s = i == FLOAT ? "0f" :
708                     i == DOUBLE ? "0d" :
709                     i == LDOUBLE ? "0l" : 0;
710                 sp = lookup(addname(s), 0);
711                 for (ap = sp->sapap != NULLap = ap->next)
712                         p->n_ap = attr_add(p->n_apattr_dup(ap3));
713                 break;
714
ragge
1.89
715         default:
716                 cerror("gcc_modefix");
717         }
ragge
1.87
718 }
719
720 #ifdef TARGET_TIMODE
ragge
1.94
721
ragge
1.98
722 /*
723  * Return ap if this node is a TI node, else NULL.
724  */
725 struct attr *
726 isti(NODE *p)
727 {
728         struct attr *ap;
729
730         if (p->n_type != STRTY)
731                 return NULL;
732         if ((ap = attr_find(p->n_apGCC_ATYP_MODE)) == NULL)
733                 return NULL;
734         if (strcmp(ap->sarg(0), TISTR))
735                 return NULL;
736         return ap;
737 }
738
ragge
1.94
739 static char *
740 tistack(void)
ragge
1.87
741 {
ragge
1.89
742         struct symtab *sp, *sp2;
ragge
1.87
743         char buf[12];
744         NODE *q;
745         char *n;
746
747         /* allocate space on stack */
748         snprintf(buf12"%d"getlab());
749         n = addname(buf);
750         sp = lookup(n0);
ragge
1.91
751         sp2 = tisp;
ragge
1.89
752         q = block(TYPENILNILsp2->stypesp2->sdfsp2->sap);
ragge
1.87
753         q->n_sp = sp;
754         nidcl2(qAUTO0);
755         nfree(q);
ragge
1.94
756         return n;
757 }
758
759 #define biop(x,y,z) block(x, y, z, INT, 0, 0)
760 /*
761  * Create a ti node from something not a ti node.
762  * This usually means:  allocate space on stack, store val, give stack address.
763  */
764 static NODE *
765 ticast(NODE *pint u)
766 {
767         CONSZ val;
768         NODE *q;
769         char *n;
770         int u2;
771
772         n = tistack();
ragge
1.87
773
774         /* store val */
775         switch (p->n_op) {
776         case ICON:
ragge
1.88
777                 val = 0;
778                 if (u == 0 && p->n_lval < 0)
779                         val = -1;
ragge
1.87
780                 q = eve(biop(DOTbdty(NAMEn), bdty(NAMEloti)));
781                 q = buildtree(ASSIGNqp);
782                 p = biop(DOTbdty(NAMEn), bdty(NAMEhiti));
ragge
1.88
783                 p = eve(biop(ASSIGNpbcon(val)));
ragge
1.87
784                 q = buildtree(COMOPqp);
785                 p = buildtree(COMOPqeve(bdty(NAMEn)));
786                 break;
787
788         default:
ragge
1.94
789                 u2 = ISUNSIGNED(p->n_type);
790                 q = eve(biop(DOTbdty(NAMEn), bdty(NAMEloti)));
791                 q = buildtree(ASSIGNqp);
792                 p = biop(DOTbdty(NAMEn), bdty(NAMEhiti));
793                 if (u2) {
794                         p = eve(biop(ASSIGNpbcon(0)));
795                 } else {
ragge
1.95
796                         q = buildtree(ASSIGNeve(ccopy(p)), q);
797                         p = buildtree(RSEQeve(p), bcon(SZLONG-1));
ragge
1.94
798                 }
799                 q = buildtree(COMOPqp);
800                 p = buildtree(COMOPqeve(bdty(NAMEn)));
801                 break;
ragge
1.87
802         }
803         return p;
804 }
805
806 /*
ragge
1.94
807  * Check if we may have to do a cast to/from TI.
ragge
1.88
808  */
809 NODE *
ragge
1.94
810 gcc_eval_ticast(int opNODE *p1NODE *p2)
ragge
1.88
811 {
812         struct attr *a1, *a2;
ragge
1.91
813         int t;
ragge
1.88
814
ragge
1.98
815         if ((a1 = isti(p1)) == NULL && (a2 = isti(p2)) == NULL)
816                 return NIL;
817
818         if (op == RETURN)
819                 p1 = ccopy(p1);
820         if (a1 == NULL) {
821                 if (a2 == NULL)
822                         cerror("gcc_eval_ticast error");
ragge
1.95
823                 switch (p1->n_type) {
824                 case LDOUBLE:
825                         p2 = doacall(floatuntixfsp,
826                             nametree(floatuntixfsp), p2);
ragge
1.98
827                         tfree(p1);
ragge
1.95
828                         break;
ragge
1.96
829                 case ULONG:
ragge
1.95
830                 case LONG:
831                         p2 = cast(structref(p2DOTloti), p1->n_type0);
ragge
1.98
832                         tfree(p1);
ragge
1.95
833                         break;
ragge
1.98
834                 case VOID:
835                         return NIL;
ragge
1.95
836                 default:
837                         uerror("gcc_eval_ticast: %d"p1->n_type);
838                 }
839                 return p2;
840         }
ragge
1.88
841         /* p2 can be anything, but we must cast it to p1 */
842         t = a1->iarg(1);
843
ragge
1.91
844         if (p2->n_type == STRTY &&
845             (a2 = attr_find(p2->n_apGCC_ATYP_MODE)) &&
846             strcmp(a2->sarg(0), TISTR) == 0) {
ragge
1.88
847                 /* Already TI, just add extra mode bits */
848                 a2 = attr_new(GCC_ATYP_MODE3);
ragge
1.91
849                 a2->sarg(0) = TISTR;
ragge
1.88
850                 a2->iarg(1) = t;
851                 p2->n_ap = attr_add(p2->n_apa2);
ragge
1.94
852         } else  {
853                 p2 = ticast(p2t);
854         }
ragge
1.98
855         tfree(p1);
ragge
1.94
856         return p2;
ragge
1.88
857 }
858
859 /*
860  * Apply a unary op on a TI value.
861  */
862 NODE *
863 gcc_eval_tiuni(int opNODE *p1)
864 {
865         struct attr *a1;
866         NODE *p;
867
ragge
1.98
868         if ((a1 = isti(p1)) == NULL)
ragge
1.89
869                 return NULL;
ragge
1.88
870
871         switch (op) {
872         case UMINUS:
ragge
1.89
873                 p = ticast(bcon(0), 0);
ragge
1.88
874                 p = buildtree(CMpp1);
ragge
1.90
875                 p = doacall(subvti3spnametree(subvti3sp), p);
ragge
1.88
876                 break;
877
878         case UMUL:
879                 p = NULL;
880         default:
881                 uerror("unsupported unary TI mode op %d"op);
882                 p = NULL;
883         }
884         return p;
885 }
886
887 /*
ragge
1.94
888  * Evaluate AND/OR/ER.  p1 and p2 are pointers to ti struct.
889  */
890 static NODE *
891 gcc_andorer(int opNODE *p1NODE *p2)
892 {
893         char *n = tistack();
894         NODE *p, *t1, *t2, *p3;
895
896         t1 = tempnode(0p1->n_typep1->n_dfp1->n_ap);
897         t2 = tempnode(0p2->n_typep2->n_dfp2->n_ap);
898
899         p1 = buildtree(ASSIGNccopy(t1), p1);
900         p2 = buildtree(ASSIGNccopy(t2), p2);
901         p = buildtree(COMOPp1p2);
902
903         p3 = buildtree(ADDROFeve(bdty(NAMEn)), NIL);
904         p1 = buildtree(ASSIGNstructref(ccopy(p3), STREFhiti),
905             buildtree(opstructref(ccopy(t1), STREFhiti),
906             structref(ccopy(t2), STREFhiti)));
907         p = buildtree(COMOPpp1);
908         p1 = buildtree(ASSIGNstructref(ccopy(p3), STREFloti),
909             buildtree(opstructref(t1STREFloti),
910             structref(t2STREFloti)));
911         p = buildtree(COMOPpp1);
912         p = buildtree(COMOPpbuildtree(UMULp3NIL));
913         return p;
914 }
915
916 /*
ragge
1.96
917  * Ensure that a 128-bit assign succeeds.
918  * If left is not TI, make right not TI,
919  * else if left _is_ TI, make right TI,
920  * else do nothing.
921  */
922 static NODE *
923 timodeassign(NODE *p1NODE *p2)
924 {
ragge
1.98
925         struct attr *a1, *a2;
ragge
1.96
926
ragge
1.98
927         a1 = isti(p1);
928         a2 = isti(p2);
929         if (a1 && a2 == NULL) {
ragge
1.96
930                 p2 = ticast(p2a1->iarg(1));
ragge
1.98
931         } else if (a1 == NULL && a2) {
ragge
1.96
932                 if (ISFTY(p1->n_type))
933                         cerror("cannot TI float convert");
934                 p2 = structref(p2DOTloti);
935         }
936         return buildtree(ASSIGNp1p2);
937 }
938
939 /*
ragge
1.87
940  * Evaluate 128-bit operands.
941  */
942 NODE *
943 gcc_eval_timode(int opNODE *p1NODE *p2)
944 {
945         struct attr *a1, *a2;
946         struct symtab *sp;
947         NODE *p;
ragge
1.95
948         int isu = 0gottiisaop;
ragge
1.87
949