scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

code.c (10751B)


      1 #include <assert.h>
      2 #include <inttypes.h>
      3 #include <ctype.h>
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <stdarg.h>
      7 
      8 #include <scc/scc.h>
      9 #include "cc1.h"
     10 
     11 static void emitbin(int, void *),
     12             emitcast(int, void *),
     13             emitsym(int, void *),
     14             emitexp(int, void *),
     15             emitsymid(int, void *),
     16             emittext(int, void *),
     17             emitfun(int, void *),
     18             emitdcl(int, void *),
     19             emitinit(int, void *),
     20             emittype(int, void *),
     21             emitbuilt(int, void *);
     22 
     23 char *optxt[] = {
     24 	[OADD] = "+",
     25 	[OSUB] = "-",
     26 	[OMUL] = "*",
     27 	[OINC] = ":i",
     28 	[ODEC] =  ":d",
     29 	[OPTR] = "@",
     30 	[OMOD] = "%",
     31 	[ODIV] = "/",
     32 	[OSHL] = "l",
     33 	[OSHR]  = "r",
     34 	[OLT] = "<",
     35 	[OGT] = ">",
     36 	[OGE] = "]",
     37 	[OLE] =  "[",
     38 	[OEQ] = "=",
     39 	[ONE] = "!",
     40 	[OBAND] = "&",
     41 	[OBXOR]  = "^",
     42 	[OBOR] = "|",
     43 	[OASSIGN] = ":",
     44 	[OA_MUL] = ":*",
     45 	[OA_DIV] = ":/",
     46 	[OA_MOD] = ":%",
     47 	[OA_ADD] = ":+",
     48 	[OA_SUB] = ":-",
     49 	[OA_SHL] = ":l",
     50 	[OA_SHR] = ":r",
     51 	[OA_AND] = ":&",
     52 	[OA_XOR] = ":^",
     53 	[OA_OR] = ":|",
     54 	[OADDR] = "'",
     55 	[OSNEG] = "_",
     56 	[ONEG] = "n",
     57 	[OCPL] = "~",
     58 	[OAND] = "a",
     59 	[OOR] = "o",
     60 	[OASK] = "?",
     61 	[OCOMMA] = ",",
     62 	[OLABEL] = "L%d\n",
     63 	[ODEFAULT] = "\tf\tL%d\n",
     64 	[OBSWITCH] = "\ts",
     65 	[OESWITCH] = "\tt\tL%d\n",
     66 	[OCASE] = "\tv\tL%d",
     67 	[OJUMP] = "\tj\tL%d\n",
     68 	[OBRANCH] = "\ty\tL%d",
     69 	[OEFUN] = "}\n",
     70 	[OELOOP] = "\te\n",
     71 	[OBLOOP] = "\tb\n",
     72 	[ORET] = "\th",
     73 	[OPAR] = "p",
     74 	[OCALL] = "c",
     75 	[OCALLE] = "z",
     76 	[OFIELD] = "."
     77 };
     78 
     79 void (*opcode[])(int, void *) = {
     80 	[OADD] = emitbin,
     81 	[OSUB] = emitbin,
     82 	[OMUL] = emitbin,
     83 	[OINC] = emitbin,
     84 	[ODEC] =  emitbin,
     85 	[OPTR] = emitbin,
     86 	[OMOD] = emitbin,
     87 	[ODIV] = emitbin,
     88 	[OSHL] = emitbin,
     89 	[OSHR]  = emitbin,
     90 	[OLT] = emitbin,
     91 	[OGT] = emitbin,
     92 	[OGE] = emitbin,
     93 	[OLE] =  emitbin,
     94 	[OEQ] = emitbin,
     95 	[ONE] = emitbin,
     96 	[OBAND] = emitbin,
     97 	[OBXOR]  = emitbin,
     98 	[OBOR] = emitbin,
     99 	[OASSIGN] = emitbin,
    100 	[OA_MUL] = emitbin,
    101 	[OA_DIV] = emitbin,
    102 	[OA_MOD] = emitbin,
    103 	[OA_ADD] = emitbin,
    104 	[OA_SUB] = emitbin,
    105 	[OA_SHL] = emitbin,
    106 	[OA_SHR] = emitbin,
    107 	[OA_AND] = emitbin,
    108 	[OA_XOR] = emitbin,
    109 	[OA_OR] = emitbin,
    110 	[OADDR] = emitbin,
    111 	[OSNEG] = emitbin,
    112 	[ONEG] = emitbin,
    113 	[OCPL] = emitbin,
    114 	[OAND] = emitbin,
    115 	[OOR] = emitbin,
    116 	[OCOMMA] = emitbin,
    117 	[OCAST] = emitcast,
    118 	[OSYM] = emitsym,
    119 	[OASK] = emitbin,
    120 	[OCOLON] = emitbin,
    121 	[OFIELD]= emitbin,
    122 	[OEXPR] = emitexp,
    123 	[OLABEL] = emitsymid,
    124 	[ODEFAULT] = emitsymid,
    125 	[OCASE] = emitsymid,
    126 	[OJUMP] = emitsymid,
    127 	[OBRANCH] = emitsymid,
    128 	[OEFUN] = emittext,
    129 	[OELOOP] = emittext,
    130 	[OBLOOP] = emittext,
    131 	[OFUN] = emitfun,
    132 	[ORET] = emittext,
    133 	[ODECL] = emitdcl,
    134 	[OBSWITCH] = emittext,
    135 	[OESWITCH] = emitsymid,
    136 	[OPAR] = emitbin,
    137 	[OCALL] = emitbin,
    138 	[OCALLE] = emitbin,
    139 	[OINIT] = emitinit,
    140 	[OBUILTIN] = emitbuilt,
    141 	[OTYP] = emittype,
    142 };
    143 
    144 static FILE *outfp;
    145 
    146 void
    147 icode(void)
    148 {
    149 	outfp = stdout;
    150 }
    151 
    152 void
    153 freetree(Node *np)
    154 {
    155 	if (!np)
    156 		return;
    157 	freetree(np->left);
    158 	freetree(np->right);
    159 	free(np);
    160 }
    161 
    162 static void
    163 emitnode(Node *np)
    164 {
    165 	if (np)
    166 		(*opcode[np->op])(np->op, np);
    167 }
    168 
    169 Node *
    170 prtree(char *s, Node *np)
    171 {
    172 	FILE *tmp = outfp;
    173 
    174 	outfp = stderr;
    175 	fprintf(outfp, "DBG prtree %s", s);
    176 	emitnode(np);
    177 	putc('\n', outfp);
    178 	outfp = tmp;
    179 
    180 	return np;
    181 }
    182 
    183 void
    184 emit(int op, void *arg)
    185 {
    186 	extern int failure;
    187 
    188 	if (failure || onlycpp || onlyheader)
    189 		return;
    190 	(*opcode[op])(op, arg);
    191 }
    192 
    193 static void
    194 emitvar(Symbol *sym)
    195 {
    196 	int c;
    197 	short flags = sym->flags;
    198 
    199 	if (flags & SLOCAL)
    200 		c = 'T';
    201 	else if (flags & SPRIVATE)
    202 		c =  'Y';
    203 	else if (flags & SGLOBAL)
    204 		c = 'G';
    205 	else if (flags & SREGISTER)
    206 		c = 'R';
    207 	else if (flags & SFIELD)
    208 		c = 'M';
    209 	else if (flags & SEXTERN)
    210 		c = 'X';
    211 	else
    212 		c = 'A';
    213 	fprintf(outfp, "%c%u", c, sym->id);
    214 }
    215 
    216 static void
    217 emitconst(Node *np)
    218 {
    219 	int n;
    220 	unsigned char *fp, *p;
    221 	Symbol *sym = np->sym;
    222 	Type *tp = np->type;
    223 	unsigned long long u;
    224 
    225 	switch (tp->op) {
    226 	case FLOAT:
    227 		if (tp == floattype)
    228 			u = *(uint32_t *) &sym->u.f;
    229 		else if (tp == doubletype)
    230 			u = *(uint64_t *) &sym->u.d;
    231 		else
    232 			abort(); /* TODO: What here?? */
    233 		goto print;
    234 	case PTR:
    235 	case INT:
    236 	case ENUM:
    237 		u = (tp->prop & TSIGNED) ? sym->u.i : sym->u.u;
    238 	print:
    239 		fprintf(outfp,
    240 		        "#%c%llX",
    241 		        tp->letter,
    242 		        u & ones(tp->size));
    243 		break;
    244 	default:
    245 		abort();
    246 	}
    247 }
    248 
    249 static void
    250 emitsym(int op, void *arg)
    251 {
    252 	Node *np = arg;
    253 
    254 	if ((np->sym->flags & SINITLST) == 0) {
    255 		/*
    256 		 * When we have a compound literal we are going
    257 		 * to call to emitnode for every element of it,
    258 		 * and it means that we will have two '\t'
    259 		 * for the first element
    260 		 */
    261 		putc('\t', outfp);
    262 	}
    263 	(np->flags & NCONST) ? emitconst(np) : emitvar(np->sym);
    264 }
    265 
    266 static void
    267 emitletter(Type *tp)
    268 {
    269 	int letter;
    270 
    271 	letter = (tp->prop&TELLIPSIS) ? 'E' : tp->letter;
    272 	putc(letter, outfp);
    273 	switch (tp->op) {
    274 	case ARY:
    275 	case STRUCT:
    276 	case UNION:
    277 		fprintf(outfp, "%u", tp->id);
    278 	}
    279 }
    280 
    281 static void
    282 emittype(int op, void *arg)
    283 {
    284 	long long n;
    285 	Symbol **sp;
    286 	char *tag;
    287 	Type *tp = arg;
    288 
    289 	if (!(tp->prop & TDEFINED))
    290 		return;
    291 
    292 	switch (tp->op) {
    293 	case ARY:
    294 		emitletter(tp);
    295 		putc('\t', outfp);
    296 		emitletter(tp->type);
    297 		fprintf(outfp,
    298 		        "\t#%c%llX\n",
    299 		        sizettype->letter, (long long) tp->n.elem);
    300 		return;
    301 	case UNION:
    302 	case STRUCT:
    303 		emitletter(tp);
    304 		tag = tp->tag->name;
    305 		fprintf(outfp,
    306 		       "\t\"%s\t#%c%lX\t#%c%X\n",
    307 		       (tag) ? tag : "",
    308 		       sizettype->letter,
    309 		       tp->size,
    310 		       sizettype->letter,
    311 		       tp->align);
    312 		n = tp->n.elem;
    313 		for (sp = tp->p.fields; n-- > 0; ++sp)
    314 			emit(ODECL, *sp);
    315 		break;
    316 	case PTR:
    317 	case FTN:
    318 	case ENUM:
    319 		return;
    320 	default:
    321 		abort();
    322 	}
    323 }
    324 
    325 static void
    326 emitrstring(Symbol *sym, Type *tp)
    327 {
    328 	Rune *bp, *lim;
    329 
    330 	bp = sym->u.rs;
    331 	lim = &sym->u.rs[tp->n.elem];
    332 	while (bp < lim) {
    333 		fprintf(outfp,
    334 			"\t#%c%" PRIX32 "\n",
    335 			wchartype->letter, *bp++);
    336 	}
    337 }
    338 
    339 static void
    340 emitstring(Symbol *sym, Type *tp)
    341 {
    342 	char *bp, *s, *lim;
    343 	int n;
    344 
    345 	bp = sym->u.s;
    346 	lim = &sym->u.s[tp->n.elem];
    347 	while (bp < lim) {
    348 		s = bp;
    349 		while (bp < lim && isprint(*bp))
    350 			++bp;
    351 		if ((n = bp - s) > 1)
    352 			fprintf(outfp, "\t#\"%.*s\n", n, s);
    353 		else
    354 			bp = s;
    355 		if (bp == lim)
    356 			break;
    357 		do {
    358 			fprintf(outfp,
    359 			        "\t#%c%X\n",
    360 			        chartype->letter, (*bp++) & 0xFF);
    361 		} while (bp < lim && !isprint(*bp));
    362 	}
    363 }
    364 
    365 Node *
    366 zeronode(Type *tp)
    367 {
    368 	return simplify(convert(constnode(zero), tp, 0));
    369 }
    370 
    371 static void
    372 emitpadding(Type *tp, unsigned long long *addr)
    373 {
    374 	int i, align;
    375 	unsigned long long a, n;
    376 
    377 	align = tp->align - 1;
    378 	a = *addr;
    379 	n = a+align & ~align;
    380 
    381 	for ( ; a != n; ++a)
    382 		emitexp(OEXPR, zeronode(chartype));
    383 	*addr = n;
    384 }
    385 
    386 static void
    387 emitdesig(Node *np, Type *tp, unsigned long long *addr)
    388 {
    389 	Symbol *sym;
    390 	unsigned long long n;
    391 	Node *aux;
    392 	Type *p;
    393 
    394 	emitpadding(tp, addr);
    395 
    396 	if (!np) {
    397 		sym = NULL;
    398 	} else {
    399 		if (!np->sym)
    400 			goto emit_expression;
    401 		sym = np->sym;
    402 		if (sym->flags & SSTRING) {
    403 			emitstring(sym, tp);
    404 			*addr += tp->n.elem;
    405 			return;
    406 		}
    407 		if (sym->flags & SRSTRING) {
    408 			emitrstring(sym, tp);
    409 			*addr += tp->n.elem * wchartype->size;
    410 			return;
    411 		}
    412 		
    413 		if ((sym->flags & SINITLST) == 0)
    414 			goto emit_expression;
    415 	}
    416 
    417 	switch (tp->op) {
    418 	case PTR:
    419 	case INT:
    420 	case ENUM:
    421 		aux = sym ? *sym->u.init : zeronode(tp);
    422 		*addr += aux->type->size;
    423 		emitexp(OEXPR, aux);
    424 		break;
    425 	case UNION:
    426 		aux = (sym) ? sym->u.init[0] : NULL;
    427 		p = (aux) ? aux->type : tp->p.fields[0]->type;
    428 		emitdesig(aux, p, addr);
    429 		emitpadding(tp, addr);
    430 		break;
    431 	case STRUCT:
    432 	case ARY:
    433 		for (n = 0; n < tp->n.elem; ++n) {
    434 			aux = (sym) ? sym->u.init[n] : NULL;
    435 			p = (tp->op == ARY) ? tp->type : tp->p.fields[n]->type;
    436 			emitdesig(aux, p, addr);
    437 		}
    438 		emitpadding(tp, addr);
    439 		break;
    440 	default:
    441 		abort();
    442 	}
    443 
    444 	if (sym) {
    445 		free(sym->u.init);
    446 		sym->u.init = NULL;
    447 	}
    448 	freetree(np);
    449 	return;
    450 
    451 emit_expression:
    452 	emitexp(OEXPR, np);
    453 	*addr += tp->size;
    454 }
    455 
    456 static void
    457 emitinit(int op, void *arg)
    458 {
    459 	Node *np = arg;
    460 	unsigned long long addr = 0;
    461 
    462 	fputs("\t(\n", outfp);
    463 	emitdesig(np, np->type, &addr);
    464 	fputs(")\n", outfp);
    465 }
    466 
    467 static void
    468 emitdcl(int op, void *arg)
    469 {
    470 	Symbol *sym = arg;
    471 
    472 	if (sym->flags & SEMITTED)
    473 		return;
    474 	emitvar(sym);
    475 	putc('\t', outfp);
    476 	if (sym->type->op == FTN) {
    477 		emitletter(sym->type->type);
    478 		putc('\t', outfp);
    479 	}
    480 	emitletter(sym->type);
    481 	fprintf(outfp, "\t\"%s", (sym->name) ? sym->name : "");
    482 	if (sym->flags & SFIELD)
    483 		fprintf(outfp, "\t#%c%llX", sizettype->letter, sym->u.i);
    484 	sym->flags |= SEMITTED;
    485 	if ((sym->flags & SHASINIT) == 0)
    486 		putc('\n', outfp);
    487 }
    488 
    489 static void
    490 emitcast(int op, void *arg)
    491 {
    492 	Node *np = arg, *lp = np->left;
    493 
    494 	emitnode(lp);
    495 	if (np->type != voidtype)
    496 		fprintf(outfp, "\tg%c", np->type->letter);
    497 }
    498 
    499 static void
    500 emitbin(int op, void *arg)
    501 {
    502 	Node *np = arg;
    503 	char *s;
    504 
    505 	emitnode(np->left);
    506 	emitnode(np->right);
    507 
    508 	/* do not print in OCOLON case */
    509 	if ((s = optxt[op]) != NULL)  {
    510 		fprintf(outfp, "\t%s", s);
    511 		emitletter(np->type);
    512 	}
    513 }
    514 
    515 static void
    516 emitbuilt(int op, void *arg)
    517 {
    518 	Node *np = arg;
    519 
    520 	emitnode(np->left);
    521 	emitnode(np->right);
    522 	fprintf(outfp, "\t\"%s\tm", np->sym->name);
    523 	emitletter(np->type);
    524 }
    525 
    526 
    527 static void
    528 emitexp(int op, void *arg)
    529 {
    530 	Node *np = arg;
    531 
    532 	emitnode(np);
    533 	putc('\n', outfp);
    534 	freetree(np);
    535 }
    536 
    537 static void
    538 emitfun(int op, void *arg)
    539 {
    540 	Symbol *sym = arg, **sp;
    541 
    542 	emitdcl(op, arg);
    543 	fputs("{\n", outfp);
    544 
    545 	for (sp = sym->u.pars; sp && *sp; ++sp)
    546 		emit(ODECL, *sp);
    547 	fputs("\\\n", outfp);
    548 }
    549 
    550 static void
    551 emittext(int op, void *arg)
    552 {
    553 	fputs(optxt[op], outfp);
    554 }
    555 
    556 static void
    557 emitsymid(int op, void *arg)
    558 {
    559 	Symbol *sym = arg;
    560 	fprintf(outfp, optxt[op], sym->id);
    561 }
    562 
    563 Node *
    564 node(int op, Type *tp, Node *lp, Node *rp)
    565 {
    566 	Node *np;
    567 
    568 	np = xmalloc(sizeof(*np));
    569 	np->op = op;
    570 	np->type = tp;
    571 	np->sym = NULL;
    572 	np->flags = 0;
    573 	np->left = lp;
    574 	np->right = rp;
    575 
    576 	if (lp)
    577 		np->flags |= lp->flags & NEFFECT;
    578 	if (rp)
    579 		np->flags |= rp->flags & NEFFECT;
    580 	return np;
    581 }
    582 
    583 Node *
    584 varnode(Symbol *sym)
    585 {
    586 	Node *np;
    587 	Type *tp = sym->type;
    588 
    589 	np = node(OSYM, sym->type, NULL, NULL);
    590 	np->type = sym->type;
    591 	np->flags = (tp->op != FTN && tp->op != ARY) ? NLVAL : 0;
    592 	np->sym = sym;
    593 	return np;
    594 }
    595 
    596 Node *
    597 constnode(Symbol *sym)
    598 {
    599 	Node *np;
    600 
    601 	np = node(OSYM, sym->type, NULL, NULL);
    602 	np->flags = NCONST;
    603 	np->sym = sym;
    604 	return np;
    605 }
    606 
    607 Node *
    608 sizeofnode(Type *tp)
    609 {
    610 	Symbol *sym;
    611 
    612 	sym = newsym(NS_IDEN, NULL);
    613 	sym->type = sizettype;
    614 	sym->flags |= SCONSTANT;
    615 	sym->u.u = tp->size;
    616 	DBG("EXPR sizeof %llu", sym->u.u);
    617 	return constnode(sym);
    618 }
    619 
    620 Node *
    621 offsetnode(Symbol *field, Type *tp)
    622 {
    623 	Symbol *sym;
    624 
    625 	assert(field->flags & SFIELD);
    626 	sym = newsym(NS_IDEN, NULL);
    627 	sym->type = tp;
    628 	sym->flags |= SCONSTANT;
    629 	sym->u.u = field->u.u;
    630 
    631 	return constnode(sym);
    632 }
    633 
    634 Node *
    635 addrnode(unsigned long long u)
    636 {
    637 	Symbol *sym;
    638 
    639 	sym = newsym(NS_IDEN, NULL);
    640 	sym->type = pvoidtype;
    641 	sym->flags |= SCONSTANT;
    642 	sym->u.u = u;
    643 
    644 	return constnode(sym);
    645 }