qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

parse.c (25375B)


      1 #include "all.h"
      2 #include <ctype.h>
      3 #include <stdarg.h>
      4 
      5 enum {
      6 	Ksb = 4, /* matches Oarg/Opar/Jret */
      7 	Kub,
      8 	Ksh,
      9 	Kuh,
     10 	Kc,
     11 	K0,
     12 
     13 	Ke = -2, /* erroneous mode */
     14 	Km = Kl, /* memory pointer */
     15 };
     16 
     17 Op optab[NOp] = {
     18 #define O(op, t, cf) [O##op]={#op, t, cf},
     19 	#include "ops.h"
     20 };
     21 
     22 typedef enum {
     23 	PXXX,
     24 	PLbl,
     25 	PPhi,
     26 	PIns,
     27 	PEnd,
     28 } PState;
     29 
     30 enum Token {
     31 	Txxx = 0,
     32 
     33 	/* aliases */
     34 	Tloadw = NPubOp,
     35 	Tloadl,
     36 	Tloads,
     37 	Tloadd,
     38 	Talloc1,
     39 	Talloc2,
     40 
     41 	Tblit,
     42 	Tcall,
     43 	Tenv,
     44 	Tphi,
     45 	Tjmp,
     46 	Tjnz,
     47 	Tret,
     48 	Thlt,
     49 	Texport,
     50 	Tthread,
     51 	Tfunc,
     52 	Ttype,
     53 	Tdata,
     54 	Tcommon,
     55 	Tsection,
     56 	Talign,
     57 	Tdbgfile,
     58 	Tl,
     59 	Tw,
     60 	Tsh,
     61 	Tuh,
     62 	Th,
     63 	Tsb,
     64 	Tub,
     65 	Tb,
     66 	Td,
     67 	Ts,
     68 	Tz,
     69 
     70 	Tint,
     71 	Tflts,
     72 	Tfltd,
     73 	Ttmp,
     74 	Tlbl,
     75 	Tglo,
     76 	Ttyp,
     77 	Tstr,
     78 
     79 	Tplus,
     80 	Teq,
     81 	Tcomma,
     82 	Tlparen,
     83 	Trparen,
     84 	Tlbrace,
     85 	Trbrace,
     86 	Tnl,
     87 	Tdots,
     88 	Teof,
     89 
     90 	Ntok
     91 };
     92 
     93 static char *kwmap[Ntok] = {
     94 	[Tloadw] = "loadw",
     95 	[Tloadl] = "loadl",
     96 	[Tloads] = "loads",
     97 	[Tloadd] = "loadd",
     98 	[Talloc1] = "alloc1",
     99 	[Talloc2] = "alloc2",
    100 	[Tblit] = "blit",
    101 	[Tcall] = "call",
    102 	[Tenv] = "env",
    103 	[Tphi] = "phi",
    104 	[Tjmp] = "jmp",
    105 	[Tjnz] = "jnz",
    106 	[Tret] = "ret",
    107 	[Thlt] = "hlt",
    108 	[Texport] = "export",
    109 	[Tthread] = "thread",
    110 	[Tfunc] = "function",
    111 	[Ttype] = "type",
    112 	[Tdata] = "data",
    113 	[Tcommon] = "common",
    114 	[Tsection] = "section",
    115 	[Talign] = "align",
    116 	[Tdbgfile] = "dbgfile",
    117 	[Tsb] = "sb",
    118 	[Tub] = "ub",
    119 	[Tsh] = "sh",
    120 	[Tuh] = "uh",
    121 	[Tb] = "b",
    122 	[Th] = "h",
    123 	[Tw] = "w",
    124 	[Tl] = "l",
    125 	[Ts] = "s",
    126 	[Td] = "d",
    127 	[Tz] = "z",
    128 	[Tdots] = "...",
    129 };
    130 
    131 enum {
    132 	NPred = 63,
    133 
    134 	TMask = 16383, /* for temps hash */
    135 	BMask = 8191, /* for blocks hash */
    136 
    137 	K = 11183273, /* found using tools/lexh.c */
    138 	M = 23,
    139 };
    140 
    141 static uchar lexh[1 << (32-M)];
    142 static FILE *inf;
    143 static char *inpath;
    144 static int thead;
    145 static struct {
    146 	char chr;
    147 	double fltd;
    148 	float flts;
    149 	int64_t num;
    150 	char *str;
    151 } tokval;
    152 static int lnum;
    153 
    154 static Fn *curf;
    155 static int tmph[TMask+1];
    156 static Phi **plink;
    157 static Blk *curb;
    158 static Blk **blink;
    159 static Blk *blkh[BMask+1];
    160 static int nblk;
    161 static int rcls;
    162 static uint ntyp;
    163 
    164 void
    165 err(char *s, ...)
    166 {
    167 	va_list ap;
    168 
    169 	va_start(ap, s);
    170 	fprintf(stderr, "qbe:%s:%d: ", inpath, lnum);
    171 	vfprintf(stderr, s, ap);
    172 	fprintf(stderr, "\n");
    173 	va_end(ap);
    174 	exit(1);
    175 }
    176 
    177 static void
    178 lexinit()
    179 {
    180 	static int done;
    181 	int i;
    182 	long h;
    183 
    184 	if (done)
    185 		return;
    186 	for (i=0; i<NPubOp; ++i)
    187 		if (optab[i].name)
    188 			kwmap[i] = optab[i].name;
    189 	assert(Ntok <= UCHAR_MAX);
    190 	for (i=0; i<Ntok; ++i)
    191 		if (kwmap[i]) {
    192 			h = hash(kwmap[i])*K >> M;
    193 			assert(lexh[h] == Txxx);
    194 			lexh[h] = i;
    195 		}
    196 	done = 1;
    197 }
    198 
    199 static int64_t
    200 getint()
    201 {
    202 	uint64_t n;
    203 	int c, m;
    204 
    205 	n = 0;
    206 	c = fgetc(inf);
    207 	m = (c == '-');
    208 	if (m || c == '+')
    209 		c = fgetc(inf);
    210 	do {
    211 		n = 10*n + (c - '0');
    212 		c = fgetc(inf);
    213 	} while ('0' <= c && c <= '9');
    214 	ungetc(c, inf);
    215 	if (m)
    216 		n = 1 + ~n;
    217 	return *(int64_t *)&n;
    218 }
    219 
    220 static int
    221 lex()
    222 {
    223 	static char tok[NString];
    224 	int c, i, esc;
    225 	int t;
    226 
    227 	do
    228 		c = fgetc(inf);
    229 	while (isblank(c));
    230 	t = Txxx;
    231 	tokval.chr = c;
    232 	switch (c) {
    233 	case EOF:
    234 		return Teof;
    235 	case ',':
    236 		return Tcomma;
    237 	case '(':
    238 		return Tlparen;
    239 	case ')':
    240 		return Trparen;
    241 	case '{':
    242 		return Tlbrace;
    243 	case '}':
    244 		return Trbrace;
    245 	case '=':
    246 		return Teq;
    247 	case '+':
    248 		return Tplus;
    249 	case 's':
    250 		if (fscanf(inf, "_%f", &tokval.flts) != 1)
    251 			break;
    252 		return Tflts;
    253 	case 'd':
    254 		if (fscanf(inf, "_%lf", &tokval.fltd) != 1)
    255 			break;
    256 		return Tfltd;
    257 	case '%':
    258 		t = Ttmp;
    259 		c = fgetc(inf);
    260 		goto Alpha;
    261 	case '@':
    262 		t = Tlbl;
    263 		c = fgetc(inf);
    264 		goto Alpha;
    265 	case '$':
    266 		t = Tglo;
    267 		if ((c = fgetc(inf)) == '"')
    268 			goto Quoted;
    269 		goto Alpha;
    270 	case ':':
    271 		t = Ttyp;
    272 		c = fgetc(inf);
    273 		goto Alpha;
    274 	case '#':
    275 		while ((c=fgetc(inf)) != '\n' && c != EOF)
    276 			;
    277 		/* fall through */
    278 	case '\n':
    279 		lnum++;
    280 		return Tnl;
    281 	}
    282 	if (isdigit(c) || c == '-' || c == '+') {
    283 		ungetc(c, inf);
    284 		tokval.num = getint();
    285 		return Tint;
    286 	}
    287 	if (c == '"') {
    288 		t = Tstr;
    289 	Quoted:
    290 		tokval.str = vnew(2, 1, PFn);
    291 		tokval.str[0] = c;
    292 		esc = 0;
    293 		for (i=1;; i++) {
    294 			c = fgetc(inf);
    295 			if (c == EOF)
    296 				err("unterminated string");
    297 			vgrow(&tokval.str, i+2);
    298 			tokval.str[i] = c;
    299 			if (c == '"' && !esc) {
    300 				tokval.str[i+1] = 0;
    301 				return t;
    302 			}
    303 			esc = (c == '\\' && !esc);
    304 		}
    305 	}
    306 Alpha:
    307 	if (!isalpha(c) && c != '.' && c != '_')
    308 		err("invalid character %c (%d)", c, c);
    309 	i = 0;
    310 	do {
    311 		if (i >= NString-1)
    312 			err("identifier too long");
    313 		tok[i++] = c;
    314 		c = fgetc(inf);
    315 	} while (isalpha(c) || c == '$' || c == '.' || c == '_' || isdigit(c));
    316 	tok[i] = 0;
    317 	ungetc(c, inf);
    318 	tokval.str = tok;
    319 	if (t != Txxx) {
    320 		return t;
    321 	}
    322 	t = lexh[hash(tok)*K >> M];
    323 	if (t == Txxx || strcmp(kwmap[t], tok) != 0) {
    324 		err("unknown keyword %s", tok);
    325 		return Txxx;
    326 	}
    327 	return t;
    328 }
    329 
    330 static int
    331 peek()
    332 {
    333 	if (thead == Txxx)
    334 		thead = lex();
    335 	return thead;
    336 }
    337 
    338 static int
    339 next()
    340 {
    341 	int t;
    342 
    343 	t = peek();
    344 	thead = Txxx;
    345 	return t;
    346 }
    347 
    348 static int
    349 nextnl()
    350 {
    351 	int t;
    352 
    353 	while ((t = next()) == Tnl)
    354 		;
    355 	return t;
    356 }
    357 
    358 static void
    359 expect(int t)
    360 {
    361 	static char *ttoa[] = {
    362 		[Tlbl] = "label",
    363 		[Tcomma] = ",",
    364 		[Teq] = "=",
    365 		[Tnl] = "newline",
    366 		[Tlparen] = "(",
    367 		[Trparen] = ")",
    368 		[Tlbrace] = "{",
    369 		[Trbrace] = "}",
    370 		[Teof] = 0,
    371 	};
    372 	char buf[128], *s1, *s2;
    373 	int t1;
    374 
    375 	t1 = next();
    376 	if (t == t1)
    377 		return;
    378 	s1 = ttoa[t] ? ttoa[t] : "??";
    379 	s2 = ttoa[t1] ? ttoa[t1] : "??";
    380 	sprintf(buf, "%s expected, got %s instead", s1, s2);
    381 	err(buf);
    382 }
    383 
    384 static Ref
    385 tmpref(char *v)
    386 {
    387 	int t, *h;
    388 
    389 	h = &tmph[hash(v) & TMask];
    390 	t = *h;
    391 	if (t) {
    392 		if (strcmp(curf->tmp[t].name, v) == 0)
    393 			return TMP(t);
    394 		for (t=curf->ntmp-1; t>=Tmp0; t--)
    395 			if (strcmp(curf->tmp[t].name, v) == 0)
    396 				return TMP(t);
    397 	}
    398 	t = curf->ntmp;
    399 	*h = t;
    400 	newtmp(0, Kx, curf);
    401 	strcpy(curf->tmp[t].name, v);
    402 	return TMP(t);
    403 }
    404 
    405 static Ref
    406 parseref()
    407 {
    408 	Con c;
    409 
    410 	memset(&c, 0, sizeof c);
    411 	switch (next()) {
    412 	default:
    413 		return R;
    414 	case Ttmp:
    415 		return tmpref(tokval.str);
    416 	case Tint:
    417 		c.type = CBits;
    418 		c.bits.i = tokval.num;
    419 		break;
    420 	case Tflts:
    421 		c.type = CBits;
    422 		c.bits.s = tokval.flts;
    423 		c.flt = 1;
    424 		break;
    425 	case Tfltd:
    426 		c.type = CBits;
    427 		c.bits.d = tokval.fltd;
    428 		c.flt = 2;
    429 		break;
    430 	case Tthread:
    431 		c.sym.type = SThr;
    432 		expect(Tglo);
    433 		/* fall through */
    434 	case Tglo:
    435 		c.type = CAddr;
    436 		c.sym.id = intern(tokval.str);
    437 		break;
    438 	}
    439 	return newcon(&c, curf);
    440 }
    441 
    442 static int
    443 findtyp(int i)
    444 {
    445 	while (--i >= 0)
    446 		if (strcmp(tokval.str, typ[i].name) == 0)
    447 			return i;
    448 	err("undefined type :%s", tokval.str);
    449 }
    450 
    451 static int
    452 parsecls(int *tyn)
    453 {
    454 	switch (next()) {
    455 	default:
    456 		err("invalid class specifier");
    457 	case Ttyp:
    458 		*tyn = findtyp(ntyp);
    459 		return Kc;
    460 	case Tsb:
    461 		return Ksb;
    462 	case Tub:
    463 		return Kub;
    464 	case Tsh:
    465 		return Ksh;
    466 	case Tuh:
    467 		return Kuh;
    468 	case Tw:
    469 		return Kw;
    470 	case Tl:
    471 		return Kl;
    472 	case Ts:
    473 		return Ks;
    474 	case Td:
    475 		return Kd;
    476 	}
    477 }
    478 
    479 static int
    480 parserefl(int arg)
    481 {
    482 	int k, ty, env, hasenv, vararg;
    483 	Ref r;
    484 
    485 	hasenv = 0;
    486 	vararg = 0;
    487 	expect(Tlparen);
    488 	while (peek() != Trparen) {
    489 		if (curi - insb >= NIns)
    490 			err("too many instructions");
    491 		if (!arg && vararg)
    492 			err("no parameters allowed after '...'");
    493 		switch (peek()) {
    494 		case Tdots:
    495 			if (vararg)
    496 				err("only one '...' allowed");
    497 			vararg = 1;
    498 			if (arg) {
    499 				*curi = (Ins){.op = Oargv};
    500 				curi++;
    501 			}
    502 			next();
    503 			goto Next;
    504 		case Tenv:
    505 			if (hasenv)
    506 				err("only one environment allowed");
    507 			hasenv = 1;
    508 			env = 1;
    509 			next();
    510 			k = Kl;
    511 			break;
    512 		default:
    513 			env = 0;
    514 			k = parsecls(&ty);
    515 			break;
    516 		}
    517 		r = parseref();
    518 		if (req(r, R))
    519 			err("invalid argument");
    520 		if (!arg && rtype(r) != RTmp)
    521 			err("invalid function parameter");
    522 		if (env)
    523 			if (arg)
    524 				*curi = (Ins){Oarge, k, R, {r}};
    525 			else
    526 				*curi = (Ins){Opare, k, r, {R}};
    527 		else if (k == Kc)
    528 			if (arg)
    529 				*curi = (Ins){Oargc, Kl, R, {TYPE(ty), r}};
    530 			else
    531 				*curi = (Ins){Oparc, Kl, r, {TYPE(ty)}};
    532 		else if (k >= Ksb)
    533 			if (arg)
    534 				*curi = (Ins){Oargsb+(k-Ksb), Kw, R, {r}};
    535 			else
    536 				*curi = (Ins){Oparsb+(k-Ksb), Kw, r, {R}};
    537 		else
    538 			if (arg)
    539 				*curi = (Ins){Oarg, k, R, {r}};
    540 			else
    541 				*curi = (Ins){Opar, k, r, {R}};
    542 		curi++;
    543 	Next:
    544 		if (peek() == Trparen)
    545 			break;
    546 		expect(Tcomma);
    547 	}
    548 	expect(Trparen);
    549 	return vararg;
    550 }
    551 
    552 static Blk *
    553 findblk(char *name)
    554 {
    555 	Blk *b;
    556 	uint32_t h;
    557 
    558 	h = hash(name) & BMask;
    559 	for (b=blkh[h]; b; b=b->dlink)
    560 		if (strcmp(b->name, name) == 0)
    561 			return b;
    562 	b = newblk();
    563 	b->id = nblk++;
    564 	strcpy(b->name, name);
    565 	b->dlink = blkh[h];
    566 	blkh[h] = b;
    567 	return b;
    568 }
    569 
    570 static void
    571 closeblk()
    572 {
    573 	curb->nins = curi - insb;
    574 	idup(&curb->ins, insb, curb->nins);
    575 	blink = &curb->link;
    576 	curi = insb;
    577 }
    578 
    579 static PState
    580 parseline(PState ps)
    581 {
    582 	Ref arg[NPred] = {R};
    583 	Blk *blk[NPred];
    584 	Phi *phi;
    585 	Ref r;
    586 	Blk *b;
    587 	Con *c;
    588 	int t, op, i, k, ty;
    589 
    590 	t = nextnl();
    591 	if (ps == PLbl && t != Tlbl && t != Trbrace)
    592 		err("label or } expected");
    593 	switch (t) {
    594 	case Ttmp:
    595 		r = tmpref(tokval.str);
    596 		expect(Teq);
    597 		k = parsecls(&ty);
    598 		op = next();
    599 		break;
    600 	default:
    601 		if (isstore(t)) {
    602 		case Tblit:
    603 		case Tcall:
    604 		case Ovastart:
    605 			/* operations without result */
    606 			r = R;
    607 			k = Kw;
    608 			op = t;
    609 			break;
    610 		}
    611 		err("label, instruction or jump expected");
    612 	case Trbrace:
    613 		return PEnd;
    614 	case Tlbl:
    615 		b = findblk(tokval.str);
    616 		if (curb && curb->jmp.type == Jxxx) {
    617 			closeblk();
    618 			curb->jmp.type = Jjmp;
    619 			curb->s1 = b;
    620 		}
    621 		if (b->jmp.type != Jxxx)
    622 			err("multiple definitions of block @%s", b->name);
    623 		*blink = b;
    624 		curb = b;
    625 		plink = &curb->phi;
    626 		expect(Tnl);
    627 		return PPhi;
    628 	case Tret:
    629 		curb->jmp.type = Jretw + rcls;
    630 		if (peek() == Tnl)
    631 			curb->jmp.type = Jret0;
    632 		else if (rcls != K0) {
    633 			r = parseref();
    634 			if (req(r, R))
    635 				err("invalid return value");
    636 			curb->jmp.arg = r;
    637 		}
    638 		goto Close;
    639 	case Tjmp:
    640 		curb->jmp.type = Jjmp;
    641 		goto Jump;
    642 	case Tjnz:
    643 		curb->jmp.type = Jjnz;
    644 		r = parseref();
    645 		if (req(r, R))
    646 			err("invalid argument for jnz jump");
    647 		curb->jmp.arg = r;
    648 		expect(Tcomma);
    649 	Jump:
    650 		expect(Tlbl);
    651 		curb->s1 = findblk(tokval.str);
    652 		if (curb->jmp.type != Jjmp) {
    653 			expect(Tcomma);
    654 			expect(Tlbl);
    655 			curb->s2 = findblk(tokval.str);
    656 		}
    657 		if (curb->s1 == curf->start || curb->s2 == curf->start)
    658 			err("invalid jump to the start block");
    659 		goto Close;
    660 	case Thlt:
    661 		curb->jmp.type = Jhlt;
    662 	Close:
    663 		expect(Tnl);
    664 		closeblk();
    665 		return PLbl;
    666 	case Odbgloc:
    667 		op = t;
    668 		k = Kw;
    669 		r = R;
    670 		expect(Tint);
    671 		arg[0] = INT(tokval.num);
    672 		if (arg[0].val != tokval.num)
    673 			err("line number too big");
    674 		goto Ins;
    675 	}
    676 	if (op == Tcall) {
    677 		arg[0] = parseref();
    678 		parserefl(1);
    679 		op = Ocall;
    680 		expect(Tnl);
    681 		if (k == Kc) {
    682 			k = Kl;
    683 			arg[1] = TYPE(ty);
    684 		}
    685 		if (k >= Ksb)
    686 			k = Kw;
    687 		goto Ins;
    688 	}
    689 	if (op == Tloadw)
    690 		op = Oloadsw;
    691 	if (op >= Tloadl && op <= Tloadd)
    692 		op = Oload;
    693 	if (op == Talloc1 || op == Talloc2)
    694 		op = Oalloc;
    695 	if (op == Ovastart && !curf->vararg)
    696 		err("cannot use vastart in non-variadic function");
    697 	if (k >= Ksb)
    698 		err("size class must be w, l, s, or d");
    699 	i = 0;
    700 	if (peek() != Tnl)
    701 		for (;;) {
    702 			if (i == NPred)
    703 				err("too many arguments");
    704 			if (op == Tphi) {
    705 				expect(Tlbl);
    706 				blk[i] = findblk(tokval.str);
    707 			}
    708 			arg[i] = parseref();
    709 			if (req(arg[i], R))
    710 				err("invalid instruction argument");
    711 			i++;
    712 			t = peek();
    713 			if (t == Tnl)
    714 				break;
    715 			if (t != Tcomma)
    716 				err(", or end of line expected");
    717 			next();
    718 		}
    719 	next();
    720 	switch (op) {
    721 	case Tphi:
    722 		if (ps != PPhi || curb == curf->start)
    723 			err("unexpected phi instruction");
    724 		phi = alloc(sizeof *phi);
    725 		phi->to = r;
    726 		phi->cls = k;
    727 		phi->arg = vnew(i, sizeof arg[0], PFn);
    728 		memcpy(phi->arg, arg, i * sizeof arg[0]);
    729 		phi->blk = vnew(i, sizeof blk[0], PFn);
    730 		memcpy(phi->blk, blk, i * sizeof blk[0]);
    731 		phi->narg = i;
    732 		*plink = phi;
    733 		plink = &phi->link;
    734 		return PPhi;
    735 	case Tblit:
    736 		if (curi - insb >= NIns-1)
    737 			err("too many instructions");
    738 		memset(curi, 0, 2 * sizeof(Ins));
    739 		curi->op = Oblit0;
    740 		curi->arg[0] = arg[0];
    741 		curi->arg[1] = arg[1];
    742 		curi++;
    743 		if (rtype(arg[2]) != RCon)
    744 			err("blit size must be constant");
    745 		c = &curf->con[arg[2].val];
    746 		r = INT(c->bits.i);
    747 		if (c->type != CBits
    748 		|| rsval(r) < 0
    749 		|| rsval(r) != c->bits.i)
    750 			err("invalid blit size");
    751 		curi->op = Oblit1;
    752 		curi->arg[0] = r;
    753 		curi++;
    754 		return PIns;
    755 	default:
    756 		if (op >= NPubOp)
    757 			err("invalid instruction");
    758 	Ins:
    759 		if (curi - insb >= NIns)
    760 			err("too many instructions");
    761 		curi->op = op;
    762 		curi->cls = k;
    763 		curi->to = r;
    764 		curi->arg[0] = arg[0];
    765 		curi->arg[1] = arg[1];
    766 		curi++;
    767 		return PIns;
    768 	}
    769 }
    770 
    771 static int
    772 usecheck(Ref r, int k, Fn *fn)
    773 {
    774 	return rtype(r) != RTmp || fn->tmp[r.val].cls == k
    775 		|| (fn->tmp[r.val].cls == Kl && k == Kw);
    776 }
    777 
    778 static void
    779 typecheck(Fn *fn)
    780 {
    781 	Blk *b;
    782 	Phi *p;
    783 	Ins *i;
    784 	uint n;
    785 	int k;
    786 	Tmp *t;
    787 	Ref r;
    788 	BSet pb[1], ppb[1];
    789 
    790 	fillpreds(fn);
    791 	bsinit(pb, fn->nblk);
    792 	bsinit(ppb, fn->nblk);
    793 	for (b=fn->start; b; b=b->link) {
    794 		for (p=b->phi; p; p=p->link)
    795 			fn->tmp[p->to.val].cls = p->cls;
    796 		for (i=b->ins; i<&b->ins[b->nins]; i++)
    797 			if (rtype(i->to) == RTmp) {
    798 				t = &fn->tmp[i->to.val];
    799 				if (clsmerge(&t->cls, i->cls))
    800 					err("temporary %%%s is assigned with"
    801 						" multiple types", t->name);
    802 			}
    803 	}
    804 	for (b=fn->start; b; b=b->link) {
    805 		bszero(pb);
    806 		for (n=0; n<b->npred; n++)
    807 			bsset(pb, b->pred[n]->id);
    808 		for (p=b->phi; p; p=p->link) {
    809 			bszero(ppb);
    810 			t = &fn->tmp[p->to.val];
    811 			for (n=0; n<p->narg; n++) {
    812 				k = t->cls;
    813 				if (bshas(ppb, p->blk[n]->id))
    814 					err("multiple entries for @%s in phi %%%s",
    815 						p->blk[n]->name, t->name);
    816 				if (!usecheck(p->arg[n], k, fn))
    817 					err("invalid type for operand %%%s in phi %%%s",
    818 						fn->tmp[p->arg[n].val].name, t->name);
    819 				bsset(ppb, p->blk[n]->id);
    820 			}
    821 			if (!bsequal(pb, ppb))
    822 				err("predecessors not matched in phi %%%s", t->name);
    823 		}
    824 		for (i=b->ins; i<&b->ins[b->nins]; i++)
    825 			for (n=0; n<2; n++) {
    826 				k = optab[i->op].argcls[n][i->cls];
    827 				r = i->arg[n];
    828 				t = &fn->tmp[r.val];
    829 				if (k == Ke)
    830 					err("invalid instruction type in %s",
    831 						optab[i->op].name);
    832 				if (rtype(r) == RType)
    833 					continue;
    834 				if (rtype(r) != -1 && k == Kx)
    835 					err("no %s operand expected in %s",
    836 						n == 1 ? "second" : "first",
    837 						optab[i->op].name);
    838 				if (rtype(r) == -1 && k != Kx)
    839 					err("missing %s operand in %s",
    840 						n == 1 ? "second" : "first",
    841 						optab[i->op].name);
    842 				if (!usecheck(r, k, fn))
    843 					err("invalid type for %s operand %%%s in %s",
    844 						n == 1 ? "second" : "first",
    845 						t->name, optab[i->op].name);
    846 			}
    847 		r = b->jmp.arg;
    848 		if (isret(b->jmp.type)) {
    849 			if (b->jmp.type == Jretc)
    850 				k = Kl;
    851 			else if (b->jmp.type >= Jretsb)
    852 				k = Kw;
    853 			else
    854 				k = b->jmp.type - Jretw;
    855 			if (!usecheck(r, k, fn))
    856 				goto JErr;
    857 		}
    858 		if (b->jmp.type == Jjnz && !usecheck(r, Kw, fn))
    859 		JErr:
    860 			err("invalid type for jump argument %%%s in block @%s",
    861 				fn->tmp[r.val].name, b->name);
    862 		if (b->s1 && b->s1->jmp.type == Jxxx)
    863 			err("block @%s is used undefined", b->s1->name);
    864 		if (b->s2 && b->s2->jmp.type == Jxxx)
    865 			err("block @%s is used undefined", b->s2->name);
    866 	}
    867 }
    868 
    869 static Fn *
    870 parsefn(Lnk *lnk)
    871 {
    872 	Blk *b;
    873 	int i;
    874 	PState ps;
    875 
    876 	curb = 0;
    877 	nblk = 0;
    878 	curi = insb;
    879 	curf = alloc(sizeof *curf);
    880 	curf->ntmp = 0;
    881 	curf->ncon = 2;
    882 	curf->tmp = vnew(curf->ntmp, sizeof curf->tmp[0], PFn);
    883 	curf->con = vnew(curf->ncon, sizeof curf->con[0], PFn);
    884 	for (i=0; i<Tmp0; ++i)
    885 		if (T.fpr0 <= i && i < T.fpr0 + T.nfpr)
    886 			newtmp(0, Kd, curf);
    887 		else
    888 			newtmp(0, Kl, curf);
    889 	curf->con[0].type = CBits;
    890 	curf->con[0].bits.i = 0xdeaddead;  /* UNDEF */
    891 	curf->con[1].type = CBits;
    892 	curf->lnk = *lnk;
    893 	blink = &curf->start;
    894 	curf->retty = Kx;
    895 	if (peek() != Tglo)
    896 		rcls = parsecls(&curf->retty);
    897 	else
    898 		rcls = K0;
    899 	if (next() != Tglo)
    900 		err("function name expected");
    901 	strncpy(curf->name, tokval.str, NString-1);
    902 	curf->vararg = parserefl(0);
    903 	if (nextnl() != Tlbrace)
    904 		err("function body must start with {");
    905 	ps = PLbl;
    906 	do
    907 		ps = parseline(ps);
    908 	while (ps != PEnd);
    909 	if (!curb)
    910 		err("empty function");
    911 	if (curb->jmp.type == Jxxx)
    912 		err("last block misses jump");
    913 	curf->mem = vnew(0, sizeof curf->mem[0], PFn);
    914 	curf->nmem = 0;
    915 	curf->nblk = nblk;
    916 	curf->rpo = 0;
    917 	for (b=0; b; b=b->link)
    918 		b->dlink = 0; /* was trashed by findblk() */
    919 	for (i=0; i<BMask+1; ++i)
    920 		blkh[i] = 0;
    921 	memset(tmph, 0, sizeof tmph);
    922 	typecheck(curf);
    923 	return curf;
    924 }
    925 
    926 static void
    927 parsefields(Field *fld, Typ *ty, int t)
    928 {
    929 	Typ *ty1;
    930 	int n, c, a, al, type;
    931 	uint64_t sz, s;
    932 
    933 	n = 0;
    934 	sz = 0;
    935 	al = ty->align;
    936 	while (t != Trbrace) {
    937 		ty1 = 0;
    938 		switch (t) {
    939 		default: err("invalid type member specifier");
    940 		case Td: type = Fd; s = 8; a = 3; break;
    941 		case Tl: type = Fl; s = 8; a = 3; break;
    942 		case Ts: type = Fs; s = 4; a = 2; break;
    943 		case Tw: type = Fw; s = 4; a = 2; break;
    944 		case Th: type = Fh; s = 2; a = 1; break;
    945 		case Tb: type = Fb; s = 1; a = 0; break;
    946 		case Ttyp:
    947 			type = FTyp;
    948 			ty1 = &typ[findtyp(ntyp-1)];
    949 			s = ty1->size;
    950 			a = ty1->align;
    951 			break;
    952 		}
    953 		if (a > al)
    954 			al = a;
    955 		a = (1 << a) - 1;
    956 		a = ((sz + a) & ~a) - sz;
    957 		if (a) {
    958 			if (n < NField) {
    959 				/* padding */
    960 				fld[n].type = FPad;
    961 				fld[n].len = a;
    962 				n++;
    963 			}
    964 		}
    965 		t = nextnl();
    966 		if (t == Tint) {
    967 			c = tokval.num;
    968 			t = nextnl();
    969 		} else
    970 			c = 1;
    971 		sz += a + c*s;
    972 		if (type == FTyp)
    973 			s = ty1 - typ;
    974 		for (; c>0 && n<NField; c--, n++) {
    975 			fld[n].type = type;
    976 			fld[n].len = s;
    977 		}
    978 		if (t != Tcomma)
    979 			break;
    980 		t = nextnl();
    981 	}
    982 	if (t != Trbrace)
    983 		err(", or } expected");
    984 	fld[n].type = FEnd;
    985 	a = 1 << al;
    986 	if (sz < ty->size)
    987 		sz = ty->size;
    988 	ty->size = (sz + a - 1) & -a;
    989 	ty->align = al;
    990 }
    991 
    992 static void
    993 parsetyp()
    994 {
    995 	Typ *ty;
    996 	int t, al;
    997 	uint n;
    998 
    999 	/* be careful if extending the syntax
   1000 	 * to handle nested types, any pointer
   1001 	 * held to typ[] might be invalidated!
   1002 	 */
   1003 	vgrow(&typ, ntyp+1);
   1004 	ty = &typ[ntyp++];
   1005 	ty->isdark = 0;
   1006 	ty->isunion = 0;
   1007 	ty->align = -1;
   1008 	ty->size = 0;
   1009 	if (nextnl() != Ttyp ||  nextnl() != Teq)
   1010 		err("type name and then = expected");
   1011 	strcpy(ty->name, tokval.str);
   1012 	t = nextnl();
   1013 	if (t == Talign) {
   1014 		if (nextnl() != Tint)
   1015 			err("alignment expected");
   1016 		for (al=0; tokval.num /= 2; al++)
   1017 			;
   1018 		ty->align = al;
   1019 		t = nextnl();
   1020 	}
   1021 	if (t != Tlbrace)
   1022 		err("type body must start with {");
   1023 	t = nextnl();
   1024 	if (t == Tint) {
   1025 		ty->isdark = 1;
   1026 		ty->size = tokval.num;
   1027 		if (ty->align == -1)
   1028 			err("dark types need alignment");
   1029 		if (nextnl() != Trbrace)
   1030 			err("} expected");
   1031 		return;
   1032 	}
   1033 	n = 0;
   1034 	ty->fields = vnew(1, sizeof ty->fields[0], PHeap);
   1035 	if (t == Tlbrace) {
   1036 		ty->isunion = 1;
   1037 		do {
   1038 			if (t != Tlbrace)
   1039 				err("invalid union member");
   1040 			vgrow(&ty->fields, n+1);
   1041 			parsefields(ty->fields[n++], ty, nextnl());
   1042 			t = nextnl();
   1043 		} while (t != Trbrace);
   1044 	} else
   1045 		parsefields(ty->fields[n++], ty, t);
   1046 	ty->nunion = n;
   1047 }
   1048 
   1049 static void
   1050 parsedatref(Dat *d)
   1051 {
   1052 	int t;
   1053 
   1054 	d->isref = 1;
   1055 	d->u.ref.name = tokval.str;
   1056 	d->u.ref.off = 0;
   1057 	t = peek();
   1058 	if (t == Tplus) {
   1059 		next();
   1060 		if (next() != Tint)
   1061 			err("invalid token after offset in ref");
   1062 		d->u.ref.off = tokval.num;
   1063 	}
   1064 }
   1065 
   1066 static void
   1067 parsedatstr(Dat *d)
   1068 {
   1069 	d->isstr = 1;
   1070 	d->u.str = tokval.str;
   1071 }
   1072 
   1073 static void
   1074 parsedat(void cb(Dat *), Lnk *lnk)
   1075 {
   1076 	char name[NString] = {0};
   1077 	int t, n;
   1078 	Dat d;
   1079 
   1080 	if (nextnl() != Tglo || nextnl() != Teq)
   1081 		err("data name, then = expected");
   1082 	strncpy(name, tokval.str, NString-1);
   1083 	t = nextnl();
   1084 	lnk->align = 8;
   1085 	if (t == Talign) {
   1086 		if (nextnl() != Tint)
   1087 			err("alignment expected");
   1088 		lnk->align = tokval.num;
   1089 		t = nextnl();
   1090 	}
   1091 	d.type = DStart;
   1092 	d.name = name;
   1093 	d.lnk = lnk;
   1094 	cb(&d);
   1095 
   1096 	if (t != Tlbrace)
   1097 		err("expected data contents in { .. }");
   1098 	for (n = 0;; n++) {
   1099 		if (lnk->common && n > 0)
   1100 			err("common can be used only with one z");
   1101 		switch (nextnl()) {
   1102 		default: err("invalid size specifier %c in data", tokval.chr);
   1103 		case Trbrace: goto Done;
   1104 		case Tl: d.type = DL; break;
   1105 		case Tw: d.type = DW; break;
   1106 		case Th: d.type = DH; break;
   1107 		case Tb: d.type = DB; break;
   1108 		case Ts: d.type = DW; break;
   1109 		case Td: d.type = DL; break;
   1110 		case Tz: d.type = DZ; break;
   1111 		}
   1112 		if (lnk->common && d.type != DZ)
   1113 			err("common can be used only with z");
   1114 		t = nextnl();
   1115 		do {
   1116 			d.isstr = 0;
   1117 			d.isref = 0;
   1118 			memset(&d.u, 0, sizeof d.u);
   1119 			if (t == Tflts)
   1120 				d.u.flts = tokval.flts;
   1121 			else if (t == Tfltd)
   1122 				d.u.fltd = tokval.fltd;
   1123 			else if (t == Tint)
   1124 				d.u.num = tokval.num;
   1125 			else if (t == Tglo)
   1126 				parsedatref(&d);
   1127 			else if (t == Tstr)
   1128 				parsedatstr(&d);
   1129 			else
   1130 				err("constant literal expected");
   1131 			cb(&d);
   1132 			t = nextnl();
   1133 		} while (t == Tint || t == Tflts || t == Tfltd || t == Tstr || t == Tglo);
   1134 		if (t == Trbrace)
   1135 			break;
   1136 		if (t != Tcomma)
   1137 			err(", or } expected");
   1138 	}
   1139 Done:
   1140 	d.type = DEnd;
   1141 	cb(&d);
   1142 }
   1143 
   1144 static int
   1145 parselnk(Lnk *lnk)
   1146 {
   1147 	int t, haslnk;
   1148 
   1149 	for (haslnk=0;; haslnk=1)
   1150 		switch ((t=nextnl())) {
   1151 		case Texport:
   1152 			lnk->export = 1;
   1153 			break;
   1154 		case Tthread:
   1155 			lnk->thread = 1;
   1156 			break;
   1157 		case Tcommon:
   1158 			lnk->common = 1;
   1159 			break;
   1160 		case Tsection:
   1161 			if (lnk->sec)
   1162 				err("only one section allowed");
   1163 			if (next() != Tstr)
   1164 				err("section \"name\" expected");
   1165 			lnk->sec = tokval.str;
   1166 			if (peek() == Tstr) {
   1167 				next();
   1168 				lnk->secf = tokval.str;
   1169 			}
   1170 			break;
   1171 		default:
   1172 			if (t == Tfunc && lnk->thread)
   1173 				err("only data may have thread linkage");
   1174 			if (haslnk && t != Tdata && t != Tfunc)
   1175 				err("only data and function have linkage");
   1176 			if (lnk->common && lnk->sec)
   1177 				err("common symbols cannot have section declarations");
   1178 			if (lnk->common && t != Tdata)
   1179 				err("common symbols only can be used for data");
   1180 			return t;
   1181 		}
   1182 }
   1183 
   1184 void
   1185 parse(FILE *f, char *path, void dbgfile(char *), void data(Dat *), void func(Fn *))
   1186 {
   1187 	Lnk lnk;
   1188 	uint n;
   1189 
   1190 	lexinit();
   1191 	inf = f;
   1192 	inpath = path;
   1193 	lnum = 1;
   1194 	thead = Txxx;
   1195 	ntyp = 0;
   1196 	typ = vnew(0, sizeof typ[0], PHeap);
   1197 	for (;;) {
   1198 		lnk = (Lnk){0};
   1199 		switch (parselnk(&lnk)) {
   1200 		default:
   1201 			err("top-level definition expected");
   1202 		case Tdbgfile:
   1203 			expect(Tstr);
   1204 			dbgfile(tokval.str);
   1205 			break;
   1206 		case Tfunc:
   1207 			func(parsefn(&lnk));
   1208 			break;
   1209 		case Tdata:
   1210 			parsedat(data, &lnk);
   1211 			break;
   1212 		case Ttype:
   1213 			parsetyp();
   1214 			break;
   1215 		case Teof:
   1216 			for (n=0; n<ntyp; n++)
   1217 				if (typ[n].nunion)
   1218 					vfree(typ[n].fields);
   1219 			vfree(typ);
   1220 			return;
   1221 		}
   1222 	}
   1223 }
   1224 
   1225 static void
   1226 printcon(Con *c, FILE *f)
   1227 {
   1228 	switch (c->type) {
   1229 	case CUndef:
   1230 		break;
   1231 	case CAddr:
   1232 		if (c->sym.type == SThr)
   1233 			fprintf(f, "thread ");
   1234 		fprintf(f, "$%s", str(c->sym.id));
   1235 		if (c->bits.i)
   1236 			fprintf(f, "%+"PRIi64, c->bits.i);
   1237 		break;
   1238 	case CBits:
   1239 		if (c->flt == 1)
   1240 			fprintf(f, "s_%f", c->bits.s);
   1241 		else if (c->flt == 2)
   1242 			fprintf(f, "d_%lf", c->bits.d);
   1243 		else
   1244 			fprintf(f, "%"PRIi64, c->bits.i);
   1245 		break;
   1246 	}
   1247 }
   1248 
   1249 void
   1250 printref(Ref r, Fn *fn, FILE *f)
   1251 {
   1252 	int i;
   1253 	Mem *m;
   1254 
   1255 	switch (rtype(r)) {
   1256 	case RTmp:
   1257 		if (r.val < Tmp0)
   1258 			fprintf(f, "R%d", r.val);
   1259 		else
   1260 			fprintf(f, "%%%s", fn->tmp[r.val].name);
   1261 		break;
   1262 	case RCon:
   1263 		if (req(r, UNDEF))
   1264 			fprintf(f, "UNDEF");
   1265 		else
   1266 			printcon(&fn->con[r.val], f);
   1267 		break;
   1268 	case RSlot:
   1269 		fprintf(f, "S%d", rsval(r));
   1270 		break;
   1271 	case RCall:
   1272 		fprintf(f, "%04x", r.val);
   1273 		break;
   1274 	case RType:
   1275 		fprintf(f, ":%s", typ[r.val].name);
   1276 		break;
   1277 	case RMem:
   1278 		i = 0;
   1279 		m = &fn->mem[r.val];
   1280 		fputc('[', f);
   1281 		if (m->offset.type != CUndef) {
   1282 			printcon(&m->offset, f);
   1283 			i = 1;
   1284 		}
   1285 		if (!req(m->base, R)) {
   1286 			if (i)
   1287 				fprintf(f, " + ");
   1288 			printref(m->base, fn, f);
   1289 			i = 1;
   1290 		}
   1291 		if (!req(m->index, R)) {
   1292 			if (i)
   1293 				fprintf(f, " + ");
   1294 			fprintf(f, "%d * ", m->scale);
   1295 			printref(m->index, fn, f);
   1296 		}
   1297 		fputc(']', f);
   1298 		break;
   1299 	case RInt:
   1300 		fprintf(f, "%d", rsval(r));
   1301 		break;
   1302 	}
   1303 }
   1304 
   1305 void
   1306 printfn(Fn *fn, FILE *f)
   1307 {
   1308 	static char ktoc[] = "wlsd";
   1309 	static char *jtoa[NJmp] = {
   1310 	#define X(j) [J##j] = #j,
   1311 		JMPS(X)
   1312 	#undef X
   1313 	};
   1314 	Blk *b;
   1315 	Phi *p;
   1316 	Ins *i;
   1317 	uint n;
   1318 
   1319 	fprintf(f, "function $%s() {\n", fn->name);
   1320 	for (b=fn->start; b; b=b->link) {
   1321 		fprintf(f, "@%s\n", b->name);
   1322 		for (p=b->phi; p; p=p->link) {
   1323 			fprintf(f, "\t");
   1324 			printref(p->to, fn, f);
   1325 			fprintf(f, " =%c phi ", ktoc[p->cls]);
   1326 			assert(p->narg);
   1327 			for (n=0;; n++) {
   1328 				fprintf(f, "@%s ", p->blk[n]->name);
   1329 				printref(p->arg[n], fn, f);
   1330 				if (n == p->narg-1) {
   1331 					fprintf(f, "\n");
   1332 					break;
   1333 				} else
   1334 					fprintf(f, ", ");
   1335 			}
   1336 		}
   1337 		for (i=b->ins; i<&b->ins[b->nins]; i++) {
   1338 			fprintf(f, "\t");
   1339 			if (!req(i->to, R)) {
   1340 				printref(i->to, fn, f);
   1341 				fprintf(f, " =%c ", ktoc[i->cls]);
   1342 			}
   1343 			assert(optab[i->op].name);
   1344 			fprintf(f, "%s", optab[i->op].name);
   1345 			if (req(i->to, R))
   1346 				switch (i->op) {
   1347 				case Oarg:
   1348 				case Oswap:
   1349 				case Oxcmp:
   1350 				case Oacmp:
   1351 				case Oacmn:
   1352 				case Oafcmp:
   1353 				case Oxtest:
   1354 				case Oxdiv:
   1355 				case Oxidiv:
   1356 					fputc(ktoc[i->cls], f);
   1357 				}
   1358 			if (!req(i->arg[0], R)) {
   1359 				fprintf(f, " ");
   1360 				printref(i->arg[0], fn, f);
   1361 			}
   1362 			if (!req(i->arg[1], R)) {
   1363 				fprintf(f, ", ");
   1364 				printref(i->arg[1], fn, f);
   1365 			}
   1366 			fprintf(f, "\n");
   1367 		}
   1368 		switch (b->jmp.type) {
   1369 		case Jret0:
   1370 		case Jretsb:
   1371 		case Jretub:
   1372 		case Jretsh:
   1373 		case Jretuh:
   1374 		case Jretw:
   1375 		case Jretl:
   1376 		case Jrets:
   1377 		case Jretd:
   1378 		case Jretc:
   1379 			fprintf(f, "\t%s", jtoa[b->jmp.type]);
   1380 			if (b->jmp.type != Jret0 || !req(b->jmp.arg, R)) {
   1381 				fprintf(f, " ");
   1382 				printref(b->jmp.arg, fn, f);
   1383 			}
   1384 			if (b->jmp.type == Jretc)
   1385 				fprintf(f, ", :%s", typ[fn->retty].name);
   1386 			fprintf(f, "\n");
   1387 			break;
   1388 		case Jhlt:
   1389 			fprintf(f, "\thlt\n");
   1390 			break;
   1391 		case Jjmp:
   1392 			if (b->s1 != b->link)
   1393 				fprintf(f, "\tjmp @%s\n", b->s1->name);
   1394 			break;
   1395 		default:
   1396 			fprintf(f, "\t%s ", jtoa[b->jmp.type]);
   1397 			if (b->jmp.type == Jjnz) {
   1398 				printref(b->jmp.arg, fn, f);
   1399 				fprintf(f, ", ");
   1400 			}
   1401 			assert(b->s1 && b->s2);
   1402 			fprintf(f, "@%s, @%s\n", b->s1->name, b->s2->name);
   1403 			break;
   1404 		}
   1405 	}
   1406 	fprintf(f, "}\n");
   1407 }