xref: /netbsd-src/external/bsd/pcc/dist/pcc/cc/ccom/gcc_compat.c (revision 41b9722a1abf231082724f766574d77aa46a5bdd)
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