Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140606204028

Diff

Diff from 1.105 to:

Annotations

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

Annotated File View

plunky
1.105
1 /*      $Id: gcc_compat.c,v 1.105 2014/06/06 20:40:28 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" },
plunky
1.105
363         CS(GCC_ATYP_LEAF)       { A_0ARG"leaf" },
ragge
1.55
364
ragge
1.56
365         CS(GCC_ATYP_BOUNDED)    { A_3ARG|A_MANY|A1_NAME"bounded" },
ragge
1.26
366 };
ragge
1.55
367
ragge
1.47
368 #if SZPOINT(CHAR) == SZLONGLONG
369 #define GPT     LONGLONG
370 #else
371 #define GPT     INT
372 #endif
373
374 struct atax mods[] = {
375         { 0NULL },
376         { INT"SI" },
377         { INT"word" },
378         { GPT"pointer" },
379         { CHAR"byte" },
380         { CHAR"QI" },
381         { SHORT"HI" },
382         { LONGLONG"DI" },
383         { FLOAT"SF" },
384         { DOUBLE"DF" },
ragge
1.72
385         { LDOUBLE"XF" },
386         { FCOMPLEX"SC" },
387         { COMPLEX"DC" },
388         { LCOMPLEX"XC" },
ragge
1.90
389         { INT"libgcc_cmp_return" },
390         { INT"libgcc_shift_count" },
ragge
1.99
391         { LONG"unwind_word" },
ragge
1.87
392 #ifdef TARGET_TIMODE
ragge
1.89
393         { 800"TI" },
ragge
1.87
394 #endif
ragge
1.68
395 #ifdef TARGET_MODS
396         TARGET_MODS
397 #endif
ragge
1.47
398 };
399 #define ATSZ    (sizeof(mods)/sizeof(mods[0]))
ragge
1.26
400
401 static int
ragge
1.47
402 amatch(char *sstruct atax *atint mx)
ragge
1.26
403 {
404         int ilen;
405
406         if (s[0] == '_' && s[1] == '_')
407                 s += 2;
408         len = strlen(s);
409         if (len > 2 && s[len-1] == '_' && s[len-2] == '_')
410                 len -= 2;
ragge
1.47
411         for (i = 0i < mxi++) {
412                 char *t = at[i].name;
ragge
1.26
413                 if (t != NULL && strncmp(stlen) == 0 && t[len] == 0)
414                         return i;
415         }
416         return 0;
417 }
418
419 static void
ragge
1.64
420 setaarg(int strunion aarg *aaNODE *p)
ragge
1.26
421 {
422         if (str) {
ragge
1.39
423                 if (((str & (A1_STR|A2_STR|A3_STR)) && p->n_op != STRING) ||
424                     ((str & (A1_NAME|A2_NAME|A3_NAME)) && p->n_op != NAME))
425                         uerror("bad arg to attribute");
ragge
1.69
426                 if (p->n_op == STRING) {
plunky
1.97
427                         aa->sarg = newstring(p->n_namestrlen(p->n_name));
ragge
1.69
428                 } else
429                         aa->sarg = (char *)p->n_sp;
ragge
1.26
430                 nfree(p);
431         } else
gmcgarry
1.36
432                 aa->iarg = (int)icons(eve(p));
ragge
1.26
433 }
434
ragge
1.18
435 /*
ragge
1.23
436  * Parse attributes from an argument list.
ragge
1.20
437  */
ragge
1.77
438 static struct attr *
439 gcc_attribs(NODE *p)
ragge
1.20
440 {
ragge
1.26
441         NODE *q, *r;
ragge
1.77
442         struct attr *ap;
ragge
1.49
443         char *name = NULL, *c;
ragge
1.89
444         int cwattrnarg;
ragge
1.20
445
446         if (p->n_op == NAME) {
447                 name = (char *)p->n_sp;
448         } else if (p->n_op == CALL || p->n_op == UCALL) {
449                 name = (char *)p->n_left->n_sp;
ragge
1.67
450         } else if (p->n_op == ICON && p->n_type == STRTY) {
ragge
1.77
451                 return NULL;
ragge
1.20
452         } else
453                 cerror("bad variable attribute");
454
ragge
1.47
455         if ((attr = amatch(nameataxGCC_ATYP_MAX)) == 0) {
ragge
1.26
456                 werror("unsupported attribute '%s'"name);
ragge
1.77
457                 ap = NULL;
ragge
1.27
458                 goto out;
ragge
1.26
459         }
460         narg = 0;
461         if (p->n_op == CALL)
462                 for (narg = 1q = p->n_rightq->n_op == CMq = q->n_left)
463                         narg++;
464
465         cw = atax[attr].typ;
466         if (!(cw & A_MANY) && ((narg > 3) || ((cw & (1 << narg)) == 0))) {
467                 uerror("wrong attribute arg count");
ragge
1.77
468                 return NULL;
ragge
1.26
469         }
ragge
1.64
470         ap = attr_new(attr3); /* XXX should be narg */
ragge
1.26
471         q = p->n_right;
472
473         switch (narg) {
474         default:
475                 /* XXX */
476                 while (narg-- > 3) {
477                         r = q;
478                         q = q->n_left;
479                         tfree(r->n_right);
480                         nfree(r);
481                 }
482                 /* FALLTHROUGH */
483         case 3:
ragge
1.64
484                 setaarg(cw & (A3_NAME|A3_STR), &ap->aa[2], q->n_right);
ragge
1.26
485                 r = q;
486                 q = q->n_left;
487                 nfree(r);
488                 /* FALLTHROUGH */
489         case 2:
ragge
1.64
490                 setaarg(cw & (A2_NAME|A2_STR), &ap->aa[1], q->n_right);
ragge
1.26
491                 r = q;
492                 q = q->n_left;
493                 nfree(r);
494                 /* FALLTHROUGH */
495         case 1:
ragge
1.64
496                 setaarg(cw & (A1_NAME|A1_STR), &ap->aa[0], q);
ragge
1.26
497                 p->n_op = UCALL;
498                 /* FALLTHROUGH */
499         case 0:
500                 break;
501         }
502
503         /* some attributes must be massaged special */
504         switch (attr) {
ragge
1.103
505         case ATTR_ALIGNED:
ragge
1.26
506                 if (narg == 0)
ragge
1.64
507                         ap->aa[0].iarg = ALMAX;
ragge
1.26
508                 else
ragge
1.64
509                         ap->aa[0].iarg *= SZCHAR;
ragge
1.26
510                 break;
511         case GCC_ATYP_PACKED:
ragge
1.28
512                 if (narg == 0)
ragge
1.64
513                         ap->aa[0].iarg = 1/* bitwise align */
ragge
1.28
514                 else
ragge
1.64
515                         ap->aa[0].iarg *= SZCHAR;
ragge
1.26
516                 break;
ragge
1.43
517
ragge
1.49
518         case GCC_ATYP_VISIBILITY:
ragge
1.64
519                 c = ap->aa[0].sarg;
ragge
1.49
520                 if (strcmp(c"default") && strcmp(c"hidden") &&
521                     strcmp(c"internal") && strcmp(c"protected"))
522                         werror("unknown visibility %s"c);
523                 break;
524
ragge
1.66
525         case GCC_ATYP_TLSMODEL:
526                 c = ap->aa[0].sarg;
527                 if (strcmp(c"global-dynamic") && strcmp(c"local-dynamic") &&
528                     strcmp(c"initial-exec") && strcmp(c"local-exec"))
529                         werror("unknown tls model %s"c);
530                 break;
531
ragge
1.26
532         default:
533                 break;
534         }
535 out:
ragge
1.77
536         return ap;
ragge
1.18
537 }
538
ragge
1.17
539 /*
ragge
1.64
540  * Extract attributes from a node tree and return attribute entries 
541  * based on its contents.
ragge
1.17
542  */
ragge
1.64
543 struct attr *
ragge
1.23
544 gcc_attr_parse(NODE *p)
ragge
1.17
545 {
ragge
1.77
546         struct attr *b, *c;
ragge
1.18
547
ragge
1.65
548         if (p == NIL)
549                 return NULL;
ragge
1.77
550
551         if (p->n_op != CM) {
552                 b = gcc_attribs(p);
553                 tfree(p);
554         } else {
555                 b = gcc_attr_parse(p->n_left);
556                 c = gcc_attr_parse(p->n_right);
557                 nfree(p);
558                 b = b ? attr_add(bc) : c;
559         }
560         return b;
ragge
1.17
561 }
562
ragge
1.23
563 /*
564  * Fixup struct/unions depending on attributes.
565  */
566 void
ragge
1.64
567 gcc_tcattrfix(NODE *p)
ragge
1.20
568 {
ragge
1.23
569         struct symtab *sp;
ragge
1.64
570         struct attr *ap;
ragge
1.80
571         int szcoffcszaloalmxal;
ragge
1.23
572
ragge
1.64
573         if ((ap = attr_find(p->n_apGCC_ATYP_PACKED)) == NULL)
574                 return/* nothing to fix */
ragge
1.20
575
ragge
1.64
576         al = ap->iarg(0);
ragge
1.80
577         mxal = 0;
ragge
1.20
578
ragge
1.64
579         /* Must repack struct */
580         coff = csz = 0;
581         for (sp = strmemb(ap); spsp = sp->snext) {
ragge
1.79
582                 oal = talign(sp->stypesp->sap);
583                 if (oal > al)
584                         oal = al;
ragge
1.80
585                 if (mxal < oal)
586                         mxal = oal;
ragge
1.64
587                 if (sp->sclass & FIELD)
588                         sz = sp->sclass&FLDSIZ;
589                 else
590                         sz = (int)tsize(sp->stypesp->sdfsp->sap);
ragge
1.79
591                 sp->soffset = upoff(szoal, &coff);
ragge
1.64
592                 if (coff > csz)
593                         csz = coff;
594                 if (p->n_type == UNIONTY)
595                         coff = 0;
596         }
ragge
1.81
597         if (mxal < ALCHAR)
598                 mxal = ALCHAR/* for bitfields */
ragge
1.80
599         SETOFF(cszmxal); /* Roundup to whatever */
ragge
1.64
600
ragge
1.78
601         ap = attr_find(p->n_apATTR_STRUCT);
602         ap->amsize = csz;
ragge
1.103
603         ap = attr_find(p->n_apATTR_ALIGNED);
ragge
1.80
604         ap->iarg(0) = mxal;
605
ragge
1.25
606 }
607
ragge
1.71
608 /*
609  * gcc-specific pragmas.
610  */
611 int
612 pragmas_gcc(char *t)
613 {
plunky
1.83
614         char u;
plunky
1.104
615         extern char *pragstore;
ragge
1.71
616
617         if (strcmp((t = pragtok(NULL)), "diagnostic") == 0) {
plunky
1.104
618                 int warnerr;
619
ragge
1.71
620                 if (strcmp((t = pragtok(NULL)), "ignored") == 0)
plunky
1.104
621                         warn = 0err = 0;
ragge
1.71
622                 else if (strcmp(t"warning") == 0)
plunky
1.104
623                         warn = 1err = 0;
ragge
1.71
624                 else if (strcmp(t"error") == 0)
plunky
1.104
625                         warn = 1err = 1;
ragge
1.71
626                 else
627                         return 1;
plunky
1.104
628
ragge
1.71
629                 if (eat('\"') || eat('-'))
630                         return 1;
plunky
1.104
631
ragge
1.71
632                 for (t = pragstore; *t && *t != '\"'t++)
633                         ;
plunky
1.104
634
ragge
1.71
635                 u = *t;
636                 *t = 0;
plunky
1.104
637                 Wset(pragstore + 1warnerr);
ragge
1.71
638                 *t = u;
ragge
1.72
639         } else if (strcmp(t"poison") == 0) {
640                 /* currently ignore */;
641         } else if (strcmp(t"visibility") == 0) {
642                 /* currently ignore */;
plunky
1.84
643         } else if (strcmp(t"system_header") == 0) {
644                 /* currently ignore */;
ragge
1.72
645         } else
646                 werror("gcc pragma unsupported");
ragge
1.71
647         return 0;
648 }
649
ragge
1.87
650 /*
651  * Fixup types when modes given in defid().
652  */
653 void
654 gcc_modefix(NODE *p)
655 {
plunky
1.92
656         struct attr *ap;
657 #ifdef TARGET_TIMODE
658         struct attr *a2;
659 #endif
ragge
1.88
660         struct symtab *sp;
ragge
1.91
661         char *s;
ragge
1.89
662         int iu;
663
664         if ((ap = attr_find(p->n_apGCC_ATYP_MODE)) == NULL)
665                 return;
ragge
1.87
666
ragge
1.98
667         u = ISUNSIGNED(BTYPE(p->n_type));
ragge
1.89
668         if ((i = amatch(ap->aa[0].sargmodsATSZ)) == 0) {
669                 werror("unknown mode arg %s"ap->aa[0].sarg);
670                 return;
671         }
672         i = mods[i].typ;
673         switch (i) {
674 #ifdef TARGET_TIMODE
675         case 800:
676                 if (BTYPE(p->n_type) == STRTY)
677                         break;
ragge
1.91
678                 MODTYPE(p->n_typetisp->stype);
679                 p->n_df = tisp->sdf;
680                 p->n_ap = tisp->sap;
681                 if (ap->iarg(1) == u)
682                         break;
683                 /* must add a new mode struct to avoid overwriting */
684                 a2 = attr_new(GCC_ATYP_MODE3);
685                 a2->sarg(0) = ap->sarg(0);
686                 a2->iarg(1) = u;
687                 p->n_ap = attr_add(p->n_apa2);
ragge
1.89
688                 break;
ragge
1.87
689 #endif
ragge
1.91
690         case 1 ... MAXTYPES:
ragge
1.90
691                 MODTYPE(p->n_typectype(i));
ragge
1.89
692                 if (u)
693                         p->n_type = ENUNSIGN(p->n_type);
694                 break;
ragge
1.91
695
696         case FCOMPLEX:
697         case COMPLEX:
698         case LCOMPLEX:
699                 /* Destination should have been converted to a struct already */
ragge
1.93
700                 if (BTYPE(p->n_type) != STRTY)
ragge
1.91
701                         uerror("gcc_modefix: complex not STRTY");
702                 i -= (FCOMPLEX-FLOAT);
703                 ap = strattr(p->n_ap);
704                 sp = ap->amlist;
705                 if (sp->stype == (unsigned)i)
706                         return/* Already correct type */
707                 /* we must change to another struct */
708                 s = i == FLOAT ? "0f" :
709                     i == DOUBLE ? "0d" :
710                     i == LDOUBLE ? "0l" : 0;
711                 sp = lookup(addname(s), 0);
712                 for (ap = sp->sapap != NULLap = ap->next)
713                         p->n_ap = attr_add(p->n_apattr_dup(ap3));
714                 break;
715
ragge
1.89
716         default:
717                 cerror("gcc_modefix");
718         }
ragge
1.87
719 }
720
721 #ifdef TARGET_TIMODE
ragge
1.94
722
ragge
1.98
723 /*
724  * Return ap if this node is a TI node, else NULL.
725  */
726 struct attr *
727 isti(NODE *p)
728 {
729         struct attr *ap;
730
731         if (p->n_type != STRTY)
732                 return NULL;
733         if ((ap = attr_find(p->n_apGCC_ATYP_MODE)) == NULL)
734                 return NULL;
735         if (strcmp(ap->sarg(0), TISTR))
736                 return NULL;
737         return ap;
738 }
739
ragge
1.94
740 static char *
741 tistack(void)
ragge
1.87
742 {
ragge
1.89
743         struct symtab *sp, *sp2;
ragge
1.87
744         char buf[12];
745         NODE *q;
746         char *n;
747
748         /* allocate space on stack */
749         snprintf(buf12"%d"getlab());
750         n = addname(buf);
751         sp = lookup(n0);
ragge
1.91
752         sp2 = tisp;
ragge
1.89
753         q = block(TYPENILNILsp2->stypesp2->sdfsp2->sap);
ragge
1.87
754         q->n_sp = sp;
755         nidcl2(qAUTO0);
756         nfree(q);
ragge
1.94
757         return n;
758 }
759
760 #define biop(x,y,z) block(x, y, z, INT, 0, 0)
761 /*
762  * Create a ti node from something not a ti node.
763  * This usually means:  allocate space on stack, store val, give stack address.
764  */
765 static NODE *
766 ticast(NODE *pint u)
767 {
768         CONSZ val;
769         NODE *q;
770         char *n;
771         int u2;
772
773         n = tistack();
ragge
1.87
774
775         /* store val */
776         switch (p->n_op) {
777         case ICON:
ragge
1.88
778                 val = 0;
779                 if (u == 0 && p->n_lval < 0)
780                         val = -1;
ragge
1.87
781                 q = eve(biop(DOTbdty(NAMEn), bdty(NAMEloti)));
782                 q = buildtree(ASSIGNqp);
783                 p = biop(DOTbdty(NAMEn), bdty(NAMEhiti));
ragge
1.88
784                 p = eve(biop(ASSIGNpbcon(val)));
ragge
1.87
785                 q = buildtree(COMOPqp);
786                 p = buildtree(COMOPqeve(bdty(NAMEn)));
787                 break;
788
789         default:
ragge
1.94
790                 u2 = ISUNSIGNED(p->n_type);
791                 q = eve(biop(DOTbdty(NAMEn), bdty(NAMEloti)));
792                 q = buildtree(ASSIGNqp);
793                 p = biop(DOTbdty(NAMEn), bdty(NAMEhiti));
794                 if (u2) {
795                         p = eve(biop(ASSIGNpbcon(0)));
796                 } else {
ragge
1.95
797                         q = buildtree(ASSIGNeve(ccopy(p)), q);
798                         p = buildtree(RSEQeve(p), bcon(SZLONG-1));
ragge
1.94
799                 }
800                 q = buildtree(COMOPqp);
801                 p = buildtree(COMOPqeve(bdty(NAMEn)));
802                 break;
ragge
1.87
803         }
804         return p;
805 }
806
807 /*
ragge
1.94
808  * Check if we may have to do a cast to/from TI.
ragge
1.88
809  */
810 NODE *
ragge
1.94
811 gcc_eval_ticast(int opNODE *p1NODE *p2)
ragge
1.88
812 {
813         struct attr *a1, *a2;
ragge
1.91
814         int t;
ragge
1.88
815
ragge
1.98
816         if ((a1 = isti(p1)) == NULL && (a2 = isti(p2)) == NULL)
817                 return NIL;
818
819         if (op == RETURN)
820                 p1 = ccopy(p1);
821         if (a1 == NULL) {
822                 if (a2 == NULL)
823                         cerror("gcc_eval_ticast error");
ragge
1.95
824                 switch (p1->n_type) {
825                 case LDOUBLE:
826                         p2 = doacall(floatuntixfsp,
827                             nametree(floatuntixfsp), p2);
ragge
1.98
828                         tfree(p1);
ragge
1.95
829                         break;
ragge
1.96
830                 case ULONG:
ragge
1.95
831                 case LONG:
832                         p2 = cast(structref(p2DOTloti), p1->n_type0);
ragge
1.98
833                         tfree(p1);
ragge
1.95
834                         break;
ragge
1.98
835                 case VOID:
836                         return NIL;
ragge
1.95
837                 default:
838                         uerror("gcc_eval_ticast: %d"p1->n_type);
839                 }
840                 return p2;
841         }
ragge
1.88
842         /* p2 can be anything, but we must cast it to p1 */
843         t = a1->iarg(1);
844
ragge
1.91
845         if (p2->n_type == STRTY &&
846             (a2 = attr_find(p2->n_apGCC_ATYP_MODE)) &&
847             strcmp(a2->sarg(0), TISTR) == 0) {
ragge
1.88
848                 /* Already TI, just add extra mode bits */
849                 a2 = attr_new(GCC_ATYP_MODE3);
ragge
1.91
850                 a2->sarg(0) = TISTR;
ragge
1.88
851                 a2->iarg(1) = t;
852                 p2->n_ap = attr_add(p2->n_apa2);
ragge
1.94
853         } else  {
854                 p2 = ticast(p2t);
855         }
ragge
1.98
856         tfree(p1);
ragge
1.94
857         return p2;
ragge
1.88
858 }
859
860 /*
861  * Apply a unary op on a TI value.
862  */
863 NODE *
864 gcc_eval_tiuni(int opNODE *p1)
865 {
866         struct attr *a1;
867         NODE *p;
868
ragge
1.98
869         if ((a1 = isti(p1)) == NULL)
ragge
1.89
870                 return NULL;
ragge
1.88
871
872         switch (op) {
873         case UMINUS:
ragge
1.89
874                 p = ticast(bcon(0), 0);
ragge
1.88
875                 p = buildtree(CMpp1);
ragge
1.90
876                 p = doacall(subvti3spnametree(subvti3sp), p);
ragge
1.88
877                 break;
878
879         case UMUL:
880                 p = NULL;
881         default:
882                 uerror("unsupported unary TI mode op %d"op);
883                 p = NULL;
884         }
885         return p;
886 }
887
888 /*
ragge
1.94
889  * Evaluate AND/OR/ER.  p1 and p2 are pointers to ti struct.
890  */
891 static NODE *
892 gcc_andorer(int opNODE *p1NODE *p2)
893 {
894         char *n = tistack();
895         NODE *p, *t1, *t2, *p3;
896
897         t1 = tempnode(0p1->n_typep1->n_dfp1->n_ap);
898         t2 = tempnode(0p2->n_typep2->n_dfp2->n_ap);
899
900         p1 = buildtree(ASSIGNccopy(t1), p1);
901         p2 = buildtree(ASSIGNccopy(t2), p2);
902         p = buildtree(COMOPp1p2);
903
904         p3 = buildtree(ADDROFeve(bdty(NAMEn)), NIL);
905         p1 = buildtree(ASSIGNstructref(ccopy(p3), STREFhiti),
906             buildtree(opstructref(ccopy(t1), STREFhiti),
907             structref(ccopy(t2), STREFhiti)));
908         p = buildtree(COMOPpp1);
909         p1 = buildtree(ASSIGNstructref(ccopy(p3), STREFloti),
910             buildtree(opstructref(t1STREFloti),
911             structref(t2STREFloti)));
912         p = buildtree(COMOPpp1);
913         p = buildtree(COMOPpbuildtree(UMULp3NIL));
914         return p;
915 }
916
917 /*
ragge
1.96
918  * Ensure that a 128-bit assign succeeds.
919  * If left is not TI, make right not TI,
920  * else if left _is_ TI, make right TI,
921  * else do nothing.
922  */
923 static NODE *
924 timodeassign(NODE *p1NODE *p2)
925 {
ragge
1.98
926         struct attr *a1, *a2;
ragge
1.96
927
ragge
1.98
928         a1 = isti(p1);
929         a2 = isti(p2);
930         if (a1 && a2 == NULL) {
ragge
1.96
931                 p2 = ticast(p2a1->iarg(1));
ragge
1.98
932         } else if (a1 == NULL && a2) {
ragge
1.96
933                 if (ISFTY(p1->n_type))
934                         cerror("cannot TI float convert");
935                 p2 = structref(p2DOTloti);
936         }
937         return buildtree(ASSIGNp1p2);
938 }
939
940 /*
ragge
1.87
941  * Evaluate 128-bit operands.
942  */
943 NODE *
944 gcc_eval_timode(int opNODE *p1NODE *p2)
945 {
946         struct attr *a1, *a2;
947         struct symtab *sp;
948         NODE *p;
ragge
1.95
949         int isu = 0gottiisaop;
ragge
1.87
950
951         if (op == CM)
952