scc

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

cgen.c (13906B)


      1 #include <assert.h>
      2 #include <stdlib.h>
      3 
      4 #include <scc/cstd.h>
      5 #include <scc/scc.h>
      6 
      7 #include "arch.h"
      8 #include "../../cc2.h"
      9 
     10 #define I1BYTES 0
     11 #define I2BYTES 1
     12 #define I4BYTES 2
     13 #define I8BYTES 3
     14 
     15 static unsigned char opasmw[][2] = {
     16 	[OADD] = {ASADDW, ASADDW},
     17 	[OSUB] = {ASSUBW, ASSUBW},
     18 	[OMUL] = {ASMULW, ASMULW},
     19 	[OMOD] = {ASMODW, ASUMODW},
     20 	[ODIV] = {ASDIVW, ASUDIVW},
     21 	[OSHL] = {ASSHLW, ASSHLW},
     22 	[OSHR] = {ASSHRW, ASUSHRW},
     23 	[OLT] = {ASLTW, ASULTW},
     24 	[OGT] = {ASGTW, ASUGTW},
     25 	[OLE] = {ASLEW, ASULEW},
     26 	[OGE] = {ASGEW, ASUGEW},
     27 	[OEQ] = {ASEQW, ASEQW},
     28 	[ONE] = {ASNEW, ASNEW},
     29 	[OBAND] = {ASBANDW, ASBANDW},
     30 	[OBOR] = {ASBORW, ASBORW},
     31 	[OBXOR] = {ASBXORW, ASBXORW},
     32 };
     33 
     34 static unsigned char opasml[][2] = {
     35 	[OADD] = {ASADDL, ASADDL},
     36 	[OSUB] = {ASSUBL, ASSUBL},
     37 	[OMUL] = {ASMULL, ASMULL},
     38 	[OMOD] = {ASMODL, ASUMODL},
     39 	[ODIV] = {ASDIVL, ASUDIVL},
     40 	[OSHL] = {ASSHLL, ASSHLL},
     41 	[OSHR] = {ASSHRL, ASUSHRL},
     42 	[OLT] = {ASLTL, ASULTL},
     43 	[OGT] = {ASGTL, ASUGTL},
     44 	[OLE] = {ASLEL, ASULEL},
     45 	[OGE] = {ASGEL, ASUGEL},
     46 	[OEQ] = {ASEQL, ASEQL},
     47 	[ONE] = {ASNEL, ASNEL},
     48 	[OBAND] = {ASBANDL, ASBANDL},
     49 	[OBOR] = {ASBORL, ASBORL},
     50 	[OBXOR] = {ASBXORL, ASBXORL},
     51 };
     52 
     53 static unsigned char opasms[][2] = {
     54 	[OADD] = {ASADDS, ASADDS},
     55 	[OSUB] = {ASSUBS, ASSUBS},
     56 	[OMUL] = {ASMULS, ASMULS},
     57 	[ODIV] = {ASDIVS, ASDIVS},
     58 	[OLT] = {ASLTS, ASLTS},
     59 	[OGT] = {ASGTS, ASGTS},
     60 	[OLE] = {ASLES, ASLES},
     61 	[OGE] = {ASGES, ASGES},
     62 	[OEQ] = {ASEQS, ASEQS},
     63 	[ONE] = {ASNES, ASNES},
     64 };
     65 
     66 static unsigned char opasmd[][2] = {
     67 	[OADD] = {ASADDD, ASADDD},
     68 	[OSUB] = {ASSUBD, ASSUBD},
     69 	[OMUL] = {ASMULD, ASMULD},
     70 	[ODIV] = {ASDIVD, ASDIVD},
     71 	[OLT] = {ASLTD, ASLTD},
     72 	[OGT] = {ASGTD, ASGTD},
     73 	[OLE] = {ASLED, ASLED},
     74 	[OGE] = {ASGED, ASGED},
     75 	[OEQ] = {ASEQD, ASEQD},
     76 	[ONE] = {ASNED, ASNED},
     77 };
     78 
     79 static unsigned char (*opbin[][2])[2] = {
     80 	{opasmw, opasml},
     81 	{opasms, opasmd},
     82 };
     83 
     84 static unsigned char i2i_conv[4][4][2] = {
     85 	[I1BYTES] = {
     86 		[I4BYTES] = {ASEXTBW, ASUEXTBW},
     87 		[I8BYTES] = {ASEXTBL, ASUEXTBL},
     88 	},
     89 	[I2BYTES] = {
     90 		[I4BYTES] = {ASEXTHW, ASUEXTHW},
     91 		[I8BYTES] = {ASEXTHL, ASUEXTHL},
     92 	},
     93 	[I4BYTES] = {
     94 		[I8BYTES] = {ASEXTWL, ASUEXTWL},
     95 	}
     96 };
     97 
     98 static unsigned char f2i_conv[4][4][2] = {
     99 	[I4BYTES] = {
    100 		[I4BYTES] = {ASSTOW, ASSTOUW},
    101 		[I8BYTES] = {ASSTOL, ASDTOUL},
    102 	},
    103 	[I8BYTES] = {
    104 		[I4BYTES] = {ASDTOW, ASDTOUW},
    105 		[I8BYTES] = {ASDTOL, ASDTOUL},
    106 	}
    107 };
    108 
    109 static unsigned char i2f_conv[4][4][2] = {
    110 	[I4BYTES] = {
    111 		[I4BYTES] = {ASSWTOS, ASUWTOS},
    112 		[I8BYTES] = {ASSWTOD, ASUWTOD},
    113 	},
    114 	[I8BYTES] = {
    115 		[I4BYTES] = {ASSLTOS, ASULTOS},
    116 		[I8BYTES] = {ASSLTOD, ASULTOD},
    117 	}
    118 };
    119 
    120 extern Type int32type, uint32type, ptrtype;
    121 
    122 /*
    123  * This is strongly influenced by
    124  * http://plan9.bell-labs.com/sys/doc/compiler.ps (/sys/doc/compiler.ps)
    125  * calculate addresability as follows
    126  *     AUTO => 11          value+fp
    127  *     REG => 11           reg
    128  *     STATIC => 11        (value)
    129  *     CONST => 11         $value
    130  * These values of addressability are not used in the code generation.
    131  * They are only used to calculate the Sethi-Ullman numbers. Since
    132  * QBE is AMD64 targered we could do a better job there, and try to
    133  * detect some of the complex addressing modes of these processors.
    134  */
    135 static Node *
    136 complex(Node *np)
    137 {
    138 	Node *lp = np->left, *rp = np->right;
    139 
    140 	if (np->address > 10)
    141 		return np;
    142 	if (lp)
    143 		np->complex = lp->complex;
    144 	if (rp) {
    145 		int d = np->complex - rp->complex;
    146 
    147 		if (d == 0)
    148 			++np->complex;
    149 		else if (d < 0)
    150 			np->complex = rp->complex;
    151 	}
    152 	if (np->complex == 0)
    153 		++np->complex;
    154 
    155 	return np;
    156 }
    157 
    158 Node *
    159 sethi(Node *np)
    160 {
    161 	Node *lp, *rp;
    162 
    163 	if (!np)
    164 		return np;
    165 
    166 	np->complex = 0;
    167 	np->address = 0;
    168 	lp = np->left;
    169 	rp = np->right;
    170 
    171 	switch (np->op) {
    172 	case OAUTO:
    173 	case OREG:
    174 	case OMEM:
    175 	case OCONST:
    176 		np->address = 11;
    177 		break;
    178 	case OASSIG:
    179 		assert(lp->op != OCAST);
    180 		goto binary;
    181 	case OCPL:
    182 		assert(np->type.flags & INTF);
    183 		np->op = OBXOR;
    184 		rp = constnode(NULL, ~(TUINT) 0, &np->type);
    185 		goto binary;
    186 	case OSNEG:
    187 		np->op = OSUB;
    188 		rp = lp;
    189 		lp = constnode(NULL, 0, &np->type);
    190 		if ((np->type.flags & INTF) == 0)
    191 			lp->u.f = 0.0;
    192 	default:
    193 	binary:
    194 		lp = sethi(lp);
    195 		rp = sethi(rp);
    196 		break;
    197 	}
    198 	np->left = lp;
    199 	np->right = rp;
    200 
    201 	return complex(np);
    202 }
    203 
    204 static int
    205 bytes2idx(int nbytes)
    206 {
    207 	if (nbytes== 1)
    208 		return I1BYTES;
    209 	else if (nbytes == 2)
    210 		return I2BYTES;
    211 	else if (nbytes == 4)
    212 		return I4BYTES;
    213 	else if (nbytes == 8)
    214 		return I8BYTES;
    215 	else
    216 		abort();
    217 }
    218 
    219 static Node *
    220 load(Type *tp, Node *np)
    221 {
    222 	int op;
    223 	Node *new;
    224 	int flags = tp->flags;
    225 
    226 	if (flags & (AGGRF|FUNF|ARRF|PTRF))
    227 		return np;
    228 
    229 	switch (tp->size) {
    230 	case 1:
    231 		op = ASLDSB;
    232 		break;
    233 	case 2:
    234 		op = ASLDSH;
    235 		break;
    236 	case 4:
    237 		op = (flags & FLOATF) ? ASLDS : ASLDSW;
    238 		break;
    239 	case 8:
    240 		op = (flags & FLOATF) ? ASLDD : ASLDL;
    241 		break;
    242 	default:
    243 		abort();
    244 	}
    245 	/*
    246 	 * unsigned version of operations are always +1 the
    247 	 * signed version
    248 	 */
    249 	if ((flags & (INTF|SIGNF)) == INTF && tp->size < 8)
    250 		++op;
    251 
    252 	new = tmpnode(tp);
    253 	code(op, new, np, NULL);
    254 
    255 	return new;
    256 }
    257 
    258 static Node *rhs(Node *np);
    259 
    260 static Node *
    261 cast(Type *td, Node *np)
    262 {
    263 	Type *ts;
    264 	Node *tmp;
    265 	int op, d_isint, s_isint, sidx, didx, sign;
    266 
    267 	ts = &np->type;
    268 	d_isint = (td->flags & INTF) != 0;
    269 	s_isint = (ts->flags & INTF) != 0;
    270 
    271 	sidx = bytes2idx(ts->size);
    272 	didx = bytes2idx(td->size);
    273 
    274 	sign = (ts->flags & SIGNF) == 0;
    275 
    276 	if (d_isint && s_isint) {
    277 		/* conversion from int to int */
    278 		if (didx < I4BYTES)
    279 			didx = bytes2idx(4);
    280 
    281 		if (didx <= sidx) {
    282 			np->type = *td;
    283 			return np;
    284 		}
    285 
    286 		op = i2i_conv[sidx][didx][sign];
    287 	} else if (d_isint) {
    288 		/* conversion from float to int */
    289 		if (didx < I4BYTES)
    290 			didx = bytes2idx(4);
    291 
    292 		op = f2i_conv[sidx][didx][sign];
    293 	} else if (s_isint) {
    294 		/* conversion from int to float */
    295 		if (sidx == I1BYTES || sidx == I2BYTES) {
    296 			ts = (ts->flags&SIGNF) ? &int32type : &uint32type;
    297 			np = cast(ts, np);
    298 		}
    299 		op = i2f_conv[sidx][didx][sign];
    300 	} else {
    301 		/* conversion from float to float */
    302 		op = (didx == I4BYTES) ? ASEXTS : ASTRUNCD;
    303 	}
    304 
    305 	assert(op != 0);
    306 	tmp = tmpnode(td);
    307 	code(op, tmp, np, NULL);
    308 
    309 	return tmp;
    310 }
    311 
    312 static Node *
    313 call(Node *np, Node *fun)
    314 {
    315 	int n, op;
    316 	Type *tp;
    317 	Node **q, *tmp, *p, *pars[NR_FUNPARAM];
    318 
    319 	for (n = 0, p = np->right; p; p = p->right)
    320 		pars[n++] = rhs(p->left);
    321 
    322 	tp = &np->type;
    323 	tmp = tmpnode(tp);
    324 	code(ASCALL, tmp, fun, NULL);
    325 
    326 	for (q = pars; q < &pars[n]; ++q) {
    327 		op = (q == &pars[n-1]) ? ASPARE : ASPAR;
    328 		code(op, NULL, *q, tmpnode(&(*q)->type));
    329 	}
    330 	code((np->op == OCALL) ? ASCALLE : ASCALLEX, NULL, NULL, NULL);
    331 
    332 	return tmp;
    333 }
    334 
    335 static Node *
    336 copy(Type *tp, Node *to, Node *from)
    337 {
    338 	int op;
    339 
    340 	switch (tp->size) {
    341 	case 0:
    342 		return from;
    343 	case 1:
    344 		op = ASCOPYB;
    345 		break;
    346 	case 2:
    347 		op = ASCOPYH;
    348 		break;
    349 	case 4:
    350 		op = (tp->flags & FLOATF) ? ASCOPYS : ASCOPYW;
    351 		break;
    352 	case 8:
    353 		op = (tp->flags & FLOATF) ? ASCOPYD : ASCOPYL;
    354 		break;
    355 	default:
    356 		abort();
    357 	}
    358 	code(op, to, from, NULL);
    359 	return from;
    360 }
    361 
    362 static Node *
    363 field(Node *np, int islhs)
    364 {
    365 	Node *tmp, *addr;
    366 	TUINT offset = np->right->u.sym->u.off;
    367 
    368 	addr = rhs(np->left);
    369 	tmp = node(OADD);
    370 	tmp->type = ptrtype;
    371 	tmp->left = addr;
    372 	tmp->right = constnode(NULL, offset, &ptrtype);
    373 	addr = rhs(tmp);
    374 
    375 	if (!islhs)
    376 		addr = load(&np->type, addr);
    377 	return addr;
    378 }
    379 
    380 static Node *
    381 lhs(Node *np)
    382 {
    383 	switch (np->op) {
    384 	case OREG:
    385 	case OMEM:
    386 	case OAUTO:
    387 		return np;
    388 	case OPTR:
    389 		return rhs(np->left);
    390 	case OFIELD:
    391 		return field(np, 1);
    392 	default:
    393 		abort();
    394 	}
    395 }
    396 
    397 static void
    398 bool(Node *np, Symbol *true, Symbol *false)
    399 {
    400 	Node *l = np->left, *r = np->right;
    401 	Node ret, ifyes, ifno;
    402 	Symbol *label;
    403 
    404 	switch (np->op) {
    405 	case ONEG:
    406 		bool(l, false, true);
    407 		break;
    408 	case OAND:
    409 		label = newlabel();
    410 		bool(l, label, false);
    411 		setlabel(label);
    412 		bool(r, true, false);
    413 		break;
    414 	case OOR:
    415 		label = newlabel();
    416 		bool(l, true, label);
    417 		setlabel(label);
    418 		bool(r, true, false);
    419 		break;
    420 	default:
    421 		label2node(&ifyes, true);
    422 		label2node(&ifno, false);
    423 		code(ASBRANCH, rhs(np), &ifyes, &ifno);
    424 		break;
    425 	}
    426 }
    427 
    428 static Node *
    429 ternary(Node *np)
    430 {
    431 	Node ifyes, ifno, phi, *colon, *tmp;
    432 
    433 	tmp = tmpnode(&np->type);
    434 	label2node(&ifyes, NULL);
    435 	label2node(&ifno, NULL);
    436 	label2node(&phi, NULL);
    437 
    438 	colon = np->right;
    439 	code(ASBRANCH, rhs(np->left), &ifyes, &ifno);
    440 
    441 	setlabel(ifyes.u.sym);
    442 	copy(&tmp->type, tmp, rhs(colon->left));
    443 	code(ASJMP, NULL, &phi, NULL);
    444 
    445 	setlabel(ifno.u.sym);
    446 	copy(&tmp->type, tmp, rhs(colon->right));
    447 	setlabel(phi.u.sym);
    448 
    449 	return tmp;
    450 }
    451 
    452 static Node *
    453 function(void)
    454 {
    455 	Node aux;
    456 	Symbol *p;
    457 
    458 	/* allocate stack space for parameters */
    459 	for (p = locals; p; p = p->next) {
    460 		if ((p->type.flags & PARF) == 0)
    461 			continue;
    462 		if ((p->type.flags & AGGRF) != 0)
    463 			continue;
    464 		code(ASALLOC, label2node(&aux, p), NULL, NULL);
    465 	}
    466 
    467 	/* allocate stack space for local variables) */
    468 	for (p = locals; p; p = p->next) {
    469 		if ((p->type.flags & PARF) != 0)
    470 			continue;
    471 		if (p->kind != SAUTO || p->id == TMPSYM)
    472 			continue;
    473 		code(ASALLOC, label2node(&aux, p), NULL, NULL);
    474 	}
    475 
    476 	/* store formal parameters in parameters */
    477 	for (p = locals; p; p = p->next) {
    478 		if ((p->type.flags & PARF) == 0)
    479 			continue;
    480 		if ((p->type.flags & AGGRF) != 0)
    481 			continue;
    482 		if ((p->type.flags & (ARRF|AGGRF)) == 0)
    483 			code(ASFORM, label2node(&aux, p), NULL, NULL);
    484 	}
    485 	return NULL;
    486 }
    487 
    488 static void
    489 swtch_if(Node *idx)
    490 {
    491 	Node aux1, aux2, *np;
    492 	Symbol *deflabel = NULL;
    493 
    494 	for (;;) {
    495 		np = delstmt();
    496 		setlabel(np->label);
    497 
    498 		switch (np->op) {
    499 		case OESWITCH:
    500 			if (!deflabel)
    501 				deflabel = np->u.sym;
    502 			aux1.op = OJMP;
    503 			aux1.label = NULL;
    504 			aux1.u.sym = deflabel;
    505 			cgen(&aux1);
    506 			return;
    507 		case OCASE:
    508 			aux1 = *np;
    509 			aux1.op = OBRANCH;
    510 			aux1.label = NULL;
    511 			aux1.left = &aux2;
    512 
    513 			aux2.op = OEQ;
    514 			aux2.type = idx->type;
    515 			aux2.left = np->left;
    516 			aux2.right = idx;
    517 
    518 			cgen(&aux1);
    519 			break;
    520 		case ODEFAULT:
    521 			deflabel = np->u.sym;
    522 			break;
    523 		default:
    524 			abort();
    525 		}
    526 	}
    527 }
    528 
    529 static int
    530 assignop(Type *tp)
    531 {
    532 	int flags = tp->flags;
    533 
    534 	if (flags & (AGGRF|FUNF|ARRF))
    535 		return ASSTM;
    536 
    537 	switch (tp->size) {
    538 	case 1:
    539 		return ASSTB;
    540 	case 2:
    541 		return ASSTH;
    542 	case 4:
    543 		return (tp->flags & FLOATF) ? ASSTS : ASSTW;
    544 	case 8:
    545 		return (tp->flags & FLOATF) ? ASSTD : ASSTL;
    546 	default:
    547 		abort();
    548 	}
    549 }
    550 
    551 static void
    552 rhs_rhs(Node **lp, Node **rp)
    553 {
    554 	Node *l = *lp, *r = *rp;
    555 
    556 	if (l->complex >= r->complex) {
    557 		l = rhs(l);
    558 		r = rhs(r);
    559 	} else {
    560 		r = rhs(r);
    561 		l = rhs(l);
    562 	}
    563 
    564 	*lp = l, *rp = r;
    565 }
    566 
    567 static void
    568 lhs_rhs(Node **lp, Node **rp)
    569 {
    570 	Node *l = *lp, *r = *rp;
    571 
    572 	if (l->complex >= r->complex) {
    573 		l = lhs(l);
    574 		r = rhs(r);
    575 	} else {
    576 		r = rhs(r);
    577 		l = lhs(l);
    578 	}
    579 
    580 	*lp = l, *rp = r;
    581 }
    582 
    583 static Node *
    584 assign(Node *np)
    585 {
    586 	Node *ret, aux;
    587 	Node *l = np->left, *r = np->right;
    588 	int op;
    589 
    590 	switch (np->u.subop) {
    591 		break;
    592 	case OINC:
    593 		op = OADD;
    594 		goto post_oper;
    595 	case ODEC:
    596 		op = OSUB;
    597 	post_oper:
    598 		lhs_rhs(&l, &r);
    599 		ret = load(&l->type, l);
    600 		aux.op = op;
    601 		aux.left = ret;
    602 		aux.right = r;
    603 		aux.type = np->type;
    604 		r = rhs(sethi(&aux));
    605 		break;
    606 	default:
    607 		/* assign abbreviation */
    608 		assert(l->type.size == r->type.size);
    609 		if (r->type.size < 4) {
    610 			lhs_rhs(&l, &r);
    611 			aux.op = np->u.subop;
    612 			aux.left = load(&r->type, l);
    613 			aux.right = r;
    614 			aux.type = int32type;
    615 			aux.address = np->address;
    616 			ret = r = sethi(rhs(&aux));
    617 			break;
    618 		}
    619 
    620 		aux.op = np->u.subop;
    621 		aux.left = l;
    622 		aux.right = r;
    623 		aux.type = np->type;
    624 		aux.address = np->address;
    625 		r = sethi(&aux);
    626 	case 0:
    627 		lhs_rhs(&l, &r);
    628 		ret = r;
    629 		break;
    630 	}
    631 
    632 	code(assignop(&np->type), l, r, NULL);
    633 	return ret;
    634 }
    635 
    636 static Node *
    637 rhs(Node *np)
    638 {
    639 	Node *tmp, aux1, aux2;
    640 	Node *phi, *l = np->left, *r = np->right;
    641 	Type *tp;
    642 	int sign, size, isfloat, op;
    643 	Symbol *true, *false;
    644 
    645 	tp = &np->type;
    646 
    647 	switch (np->op) {
    648 	case OBFUN:
    649 		return function();
    650 	case ONOP:
    651 	case OBLOOP:
    652 	case OELOOP:
    653 	case OEFUN:
    654 		return NULL;
    655 	case OTMP:
    656 	case OCONST:
    657 		return np;
    658 	case OMEM:
    659 	case OREG:
    660 	case OAUTO:
    661 		return load(tp, np);
    662 	case ONEG:
    663 	case OAND:
    664 	case OOR:
    665 		true = newlabel();
    666 		false = newlabel();
    667 		phi = label2node(&aux1, NULL);
    668 		tmp = tmpnode(&int32type);
    669 
    670 		bool(np, true, false);
    671 
    672 		setlabel(true);
    673 		code(ASCOPYW, tmp, constnode(&aux2, 1, &int32type), NULL);
    674 		code(ASJMP, NULL, phi, NULL);
    675 
    676 		setlabel(false);
    677 		code(ASCOPYW, tmp, constnode(&aux2, 0, &int32type), NULL);
    678 
    679 		setlabel(phi->u.sym);
    680 		return tmp;
    681 	case OMOD:
    682 	case OSHL:
    683 	case OBAND:
    684 	case OBOR:
    685 	case OBXOR:
    686 	case OSHR:
    687 		assert(tp->flags & INTF);
    688 	case ODIV:
    689 	case OLT:
    690 	case OGT:
    691 	case OLE:
    692 	case OGE:
    693 	case OADD:
    694 	case OSUB:
    695 	case OMUL:
    696 	case OEQ:
    697 	case ONE:
    698 		assert(tp->size == 4 || tp->size == 8);
    699 
    700 		sign = (tp->flags & SIGNF) == 0;
    701 		size = tp->size == 8;
    702 		isfloat = (tp->flags & FLOATF) != 0;
    703 		op = opbin[isfloat][size][np->op][sign];
    704 		rhs_rhs(&l, &r);
    705 		tmp = tmpnode(tp);
    706 		code(op, tmp, l, r);
    707 		return tmp;
    708 	case OCALL:
    709 	case OCALLE:
    710 		if (l->op == OPTR)
    711 			l = rhs(l);
    712 		return call(np, l);
    713 	case OCAST:
    714 		return cast(tp, rhs(l));
    715 	case OASSIG:
    716 		return assign(np);
    717 	case OASK:
    718 		return ternary(np);
    719 	case OCOMMA:
    720 		rhs(l);
    721 		return rhs(r);
    722 	case OPTR:
    723 		return load(tp, rhs(l));
    724 	case OADDR:
    725 		l = lhs(l);
    726 		l->type = *tp;
    727 		l->type.flags |= PTRF;
    728 		return l;
    729 	case OFIELD:
    730 		return field(np, 0);
    731 	case OBUILTIN:
    732 		switch (np->u.subop) {
    733 		case BVA_START:
    734 			l = rhs(l);
    735 			code(ASVSTAR, NULL, l, NULL);
    736 		case BVA_END:
    737 			return NULL;
    738 		case BVA_ARG:
    739 			l = rhs(l);
    740 			tmp = tmpnode(tp);
    741 			code(ASVARG, tmp, l, NULL);
    742 			return tmp;
    743 		default:
    744 			abort();
    745 		}
    746 	default:
    747 		abort();
    748 	}
    749 	abort();
    750 }
    751 
    752 Node *
    753 cgen(Node *np)
    754 {
    755 	Node aux, *p, *next;
    756 
    757 	setlabel(np->label);
    758 	switch (np->op) {
    759 	case OJMP:
    760 		label2node(&aux, np->u.sym);
    761 		code(ASJMP, NULL, &aux, NULL);
    762 		break;
    763 	case OBRANCH:
    764 		next = np->next;
    765 		if (!next->label)
    766 			next->label = newlabel();
    767 		bool(np->left, np->u.sym, next->label);
    768 		break;
    769 	case ORET:
    770 		p = (np->left) ? rhs(np->left) : NULL;
    771 		code(ASRET, NULL, p, NULL);
    772 		break;
    773 	case OBSWITCH:
    774 		p = rhs(np->left);
    775 		swtch_if(p);
    776 		break;
    777 	default:
    778 		rhs(np);
    779 		break;
    780 	}
    781 	return NULL;
    782 }