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