// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go.h"

#undef	EXTERN
#define	EXTERN
#include "gen.h"

static	Node*	curfn;

void
compile(Node *fn)
{
	Plist *pl;

	if(fn->nbody == N)
		return;
	if(nerrors != 0) {
		walk(fn);
		return;
	}

	if(debug['w'])
		dump("--- pre walk ---", fn->nbody);
	walk(fn);
	if(nerrors != 0)
		return;
	if(debug['w'])
		dump("--- post walk ---", fn->nbody);

	curfn = fn;

	continpc = P;
	breakpc = P;

	pc = mal(sizeof(*pc));
	firstpc = pc;
	pc->op = PEND;
	pc->addr.type = ANONE;
	pc->loc = 1;
	inarggen();
	gen(curfn->nbody);

	if(curfn->type->outtuple != 0)
		gopcodet(PPANIC, N, N);

	if(debug['p'])
		proglist();

	pl = mal(sizeof(*pl));
	pl->name = curfn->nname;
	pl->locals = autodcl;
	pl->firstpc = firstpc;

	if(plist == nil)
		plist = pl;
	else
		plast->link = pl;
	plast = pl;

	if(debug['f'])
		frame(0);
}

/*
 * compile statements
 */
void
gen(Node *n)
{
	long lno;
	Prog *scontin, *sbreak;
	Prog *p1, *p2, *p3;
	Sym *s;

	lno = dynlineno;

loop:
	if(n == N)
		goto ret;
	dynlineno = n->lineno;	// for diagnostics

	switch(n->op) {
	default:
		dump("gen: unknown op", n);
		break;

	case OLIST:
		gen(n->left);
		n = n->right;
		goto loop;

	case OPANIC:
	case OPRINT:
		genprint(n->left);
		if(n->op == OPANIC)
			gopcodet(PPANIC, N, N);
		break;

	case OCASE:
	case OFALL:
	case OXCASE:
	case OXFALL:
	case OEMPTY:
		break;

	case OLABEL:
		// before declaration, s->label points at
		// a link list of PXGOTO instructions.
		// after declaration, s->label points
		// at a PGOTO to .+1

		s = n->left->sym;
		p1 = (Prog*)s->label;

		if(p1 != P) {
			if(p1->op == PGOTO) {
				yyerror("label redeclared: %S", s);
				break;
			}
			while(p1 != P) {
				if(p1->op != PGOTOX)
					fatal("bad label pointer: %S", s);
				p2 = p1->addr.branch;
				p1->addr.branch = pc;
				p1->op = PGOTO;
				p1 = p2;
			}
		}

		s->label = pc;
		p1 = gbranch(PGOTO, N);
		patch(p1, pc);
		break;

	case OGOTO:
		s = n->left->sym;
		p1 = (Prog*)s->label;
		if(p1 != P && p1->op == PGOTO) {
			// already declared
			p2 = gbranch(PGOTO, N);
			patch(p2, p1->addr.branch);
			break;
		}

		// not declaraed yet
		p2 = gbranch(PGOTOX, N);
		p2->addr.node = n;	// info for diagnostic if never declared
		patch(p2, p1);
		s->label = p2;
		break;

	case OBREAK:
		if(breakpc == P) {
			yyerror("gen: break is not in a loop");
			break;
		}
		patch(gbranch(PGOTO, N), breakpc);
		break;

	case OCONTINUE:
		if(continpc == P) {
			yyerror("gen: continue is not in a loop");
			break;
		}
		patch(gbranch(PGOTO, N), continpc);
		break;

	case OFOR:
		gen(n->ninit);				// 		init
		p1 = gbranch(PGOTO, N);			// 		goto test
		sbreak = breakpc;
		breakpc = gbranch(PGOTO, N);		// break:	goto done
		scontin = continpc;
		continpc = pc;
		gen(n->nincr);				// contin:	incr
		patch(p1, pc);				// test:
		bgen(n->ntest, 0, breakpc);		//		if(!test) goto break
		gen(n->nbody);				//		body
		patch(gbranch(PGOTO, N), continpc);	//		goto contin
		patch(breakpc, pc);			// done:
		continpc = scontin;
		breakpc = sbreak;
		break;

	case OIF:
		gen(n->ninit);				//		init
		p1 = gbranch(PGOTO, N);			//		goto test
		p2 = gbranch(PGOTO, N);			// p2:		goto else
		patch(p1, pc);				// test:
		bgen(n->ntest, 0, p2);			// 		if(!test) goto p2
		gen(n->nbody);				//		then
		p3 = gbranch(PGOTO, N);			//		goto done
		patch(p2, pc);				// else:
		gen(n->nelse);				//		else
		patch(p3, pc);				// done:
		break;

	case OSWITCH:
		gen(n->ninit);				// 		init
		p1 = gbranch(PGOTO, N);			// 		goto test
		sbreak = breakpc;
		breakpc = gbranch(PGOTO, N);		// break:	goto done
		patch(p1, pc);				// test:
		swgen(n);				//		switch(test) body
		patch(breakpc, pc);			// done:
		breakpc = sbreak;
		break;

	case OASOP:
		cgen_asop(n->left, n->right, n->kaka);
		break;

	case OAS:
		cgen_as(n->left, n->right, n->op, n->kaka);
		break;

	case OCALL:
	case OCALLPTR:
	case OCALLMETH:
	case OCALLINTER:
		cgen_call(n, 1);
		break;

	case ORETURN:
		cgen_ret(n);
		break;
	}

ret:
	dynlineno = lno;
}

/*
 * compile expression to (unnamed) reg
 */
void
cgen(Node *n)
{
	long lno;
	Node *nl, *nr, *r;
	int a;
	Prog *p1, *p2, *p3;

	if(n == N)
		return;

	lno = dynlineno;
	if(n->op != ONAME)
		dynlineno = n->lineno;	// for diagnostics

	nl = n->left;
	nr = n->right;

	if(nr != N && nr->ullman >= UINF && nl != N && nl->ullman >= UINF) {
		cgen(nr);
		r = tempname(n->type);
		gopcodet(PSTORE, n->type, r);
		nr = r;
	}

	switch(n->op) {
	default:
		yyerror("cgen: unknown op %O", n->op);
		break;

	case ONAME:
	case OLITERAL:
		gopcodet(PLOAD, n->type, n);
		break;

	case ONEW:
		gopcodet(PNEW, n->type, n);
		break;

	// these call bgen to get a bool value
	case OOROR:
	case OANDAND:
	case OEQ:
	case ONE:
	case OLT:
	case OLE:
	case OGE:
	case OGT:
	case ONOT:
		p1 = gbranch(PGOTO, N);
		p2 = gopcodet(PLOAD, n->type, booltrue);
		p3 = gbranch(PGOTO, N);
		patch(p1, pc);
		bgen(n, 1, p2);
		p2 = gopcodet(PLOAD, n->type, boolfalse);
		patch(p3, pc);
		goto ret;

	case OPLUS:
		cgen(nl);
		goto ret;

	// unary
	case OMINUS:
	case OCOM:
		a = optopop(n->op);
		goto uop;

	// symmetric binary
	case OAND:
	case OOR:
	case OXOR:
	case OADD:
	case OMUL:
		a = optopop(n->op);
		goto sbop;

	// asymmetric binary
	case OMOD:
	case OSUB:
	case ODIV:
	case OLSH:
	case ORSH:
	case OCAT:
		a = optopop(n->op);
		goto abop;

	case OCONV:
		if(isbytearray(nl->type)) {
			if(nl->type->etype == TPTR)
				cgen(nl);
			else
				agen(nl);
			gopcode(PCONV, PTNIL, nod(OCONV, n->type, nl->type));
			break;
		}

		cgen(nl);
		gopcode(PCONV, PTNIL, nod(OCONV, n->type, nl->type));
		break;

	case OINDEXPTRSTR:
		nl = n->left;
		nr = n->right;
		if(nl->addable) {
			cgen(nr);
			cgen(nl);
			gopcode(PLOADI, PTADDR, N);
			gopcodet(PINDEXZ, nr->type, N);
			break;
		}
fatal("xxx");
		break;

	case OINDEXSTR:
		nl = n->left;
		nr = n->right;
		if(nl->addable) {
			cgen(nr);
			gopcodet(PINDEXZ, nr->type, nl);
			break;
		}
		cgen(nl);
		r = tempname(nl->type);
		gopcodet(PSTORE, nl->type, r);
		cgen(nr);
		gopcodet(PINDEXZ, nr->type, r);
		break;

	case OSLICESTR:
	case OSLICEPTRSTR:
		nl = n->left;	// name
		nr = n->right;

		r = nr->right;	// index2
		if(!r->addable) {
			cgen(r);
			r = tempname(r->type);
			gopcodet(PSTORE, r->type, r);
		}

		// string into PTADDR
		if(!nl->addable) {
			cgen(nl);
			gconv(PTADDR, nl->type->etype);
		} else
			gopcode(PLOAD, PTADDR, nl);

		if(n->op == OSLICEPTRSTR)
			gopcode(PLOADI, PTADDR, N);

		// offset in int reg
		cgen(nr->left);

		// index 2 addressed
		gopcodet(PSLICE, r->type, r);
		break;

	case OINDEXPTR:
	case OINDEX:
	case ODOT:
	case ODOTPTR:
	case OIND:
		agen(n);
		gopcodet(PLOADI, n->type, N);
		break;

	case OLEN:
		cgen(nl);
		gopcodet(PLEN, nl->type, nl);
		break;

	case ODOTMETH:
	case ODOTINTER:
		cgen(n->left);
		break;

	case OADDR:
		agen(nl);
		gconv(PTPTR, PTADDR);
		break;

	case OCALL:
	case OCALLPTR:
	case OCALLMETH:
	case OCALLINTER:
		cgen_call(n, 0);
		cgen_callret(n, N);
		break;
	}
	goto ret;

sbop:	// symmetric
	if(nl->ullman < nr->ullman) {
		r = nl;
		nl = nr;
		nr = r;
	}

abop:	// asymmetric
	if(nr->addable) {
		cgen(nl);
		gopcodet(a, n->type, nr);
		goto ret;
	}

	cgen(nr);
	r = tempname(n->type);
	gopcodet(PSTORE, n->type, r);
	cgen(nl);
	gopcodet(a, n->type, r);
	goto ret;

uop:	// unary
	cgen(nl);
	gopcodet(a, n->type, N);
	goto ret;

ret:
	dynlineno = lno;
}

/*
 * compile the address of a value
 */
void
agen(Node *n)
{
	Node *nl, *nr;
	Node *t, *r;

	if(n == N || n->type == N)
		return;
	switch(n->op) {
	default:
		dump("agen: unknown op", n);
		break;

	case ONAME:
		gopcode(PADDR, PTADDR, n);
		break;

	case OINDEXPTR:
		nl = n->left;
		nr = n->right;
		if(nl->addable) {
			cgen(nr);
			gopcode(PLOAD, PTADDR, nl);
			genindex(n);
			break;
		}
		if(nr->addable) {
			cgen(nl);
			gconv(PTADDR, nl->type->etype);
			cgen(nr);
			genindex(n);
			break;
		}
		cgen(nr);
		r = tempname(n->type);
		gopcodet(PSTORE, n->type, r);
		cgen(nl);
		gconv(PTADDR, nl->type->etype);
		cgen(r);
		genindex(n);
		break;

	case OINDEX:
		nl = n->left;
		nr = n->right;
		if(nl->addable) {
			cgen(nr);
			agen(nl);
			genindex(n);
			break;
		}
		if(nr->addable) {
			agen(nl);
			cgen(nr);
			genindex(n);
			break;
		}
		cgen(nr);
		r = tempname(n->type);
		gopcodet(PSTORE, n->type, r);
		agen(nl);
		cgen(r);
		genindex(n);
		break;

	case OIND:
		nl = n->left;
		if(nl->addable) {
			gopcode(PLOAD, PTADDR, nl);
			break;
		}
		cgen(nl);
		gconv(PTADDR, nl->type->etype);
		break;
		
	case ODOT:
	case ODOTPTR:
		nl = n->left;
		nr = n->right;
		t = nl->type;
		switch(t->etype) {
		default:
			badtype(n->op, n->left->type, n->right->type);
			break;

		case TPTR:
			if(nl->op != ONAME) {
				cgen(nl);
				gconv(PTADDR, nl->type->etype);
			} else
				gopcode(PLOAD, PTADDR, nl);
			gaddoffset(nr);
			break;

		case TSTRUCT:
			agen(nl);
			gaddoffset(nr);
			break;
		}
		break;
	}
}

/*
 * compile boolean expression
 * true is branch-true or branch-false
 * to is where to branch
 */
void
bgen(Node *n, int true, Prog *to)
{
	long lno;
	int et, a;
	Node *nl, *nr, *r;
	Prog *p1, *p2;

	if(n == N)
		n = booltrue;

	lno = dynlineno;
	if(n->op != ONAME)
		dynlineno = n->lineno;	// for diagnostics

	if(n == N)
		goto ret;
	if(n->type == N) {
		convlit(n, types[TBOOL]);
		if(n->type == N)
			goto ret;
	}

	et = n->type->etype;
	if(et != TBOOL) {
		yyerror("cgen: bad type %T for %O", n->type, n->op);
		patch(gbranch(PERROR, N), to);
		goto ret;
	}
	nl = N;
	nr = N;

	switch(n->op) {
	default:
		cgen(n);
		gopcodet(PTEST, n->type, N);
		a = PBTRUE;
		if(!true)
			a = PBFALSE;
		patch(gbranch(a, n->type), to);
		goto ret;

	case OLITERAL:
		if(!true == !n->val.vval)
			patch(gbranch(PGOTO, N), to);
		goto ret;

	case ONAME:
		gopcodet(PTEST, n->type, n);
		a = PBTRUE;
		if(!true)
			a = PBFALSE;
		patch(gbranch(a, n->type), to);
		goto ret;

	case OANDAND:
		if(!true)
			goto caseor;

	caseand:
		p1 = gbranch(PGOTO, N);
		p2 = gbranch(PGOTO, N);
		patch(p1, pc);
		bgen(n->left, !true, p2);
		bgen(n->right, !true, p2);
		p1 = gbranch(PGOTO, N);
		patch(p1, to);
		patch(p2, pc);
		goto ret;

	case OOROR:
		if(!true)
			goto caseand;

	caseor:
		bgen(n->left, true, to);
		bgen(n->right, true, to);
		goto ret;

	case OEQ:
	case ONE:
	case OLT:
	case OGT:
	case OLE:
	case OGE:
		nr = n->right;
		if(nr == N || nr->type == N)
			goto ret;

	case ONOT:	// unary
		nl = n->left;
		if(nl == N || nl->type == N)
			goto ret;
	}

	switch(n->op) {

	case ONOT:
		bgen(nl, !true, to);
		goto ret;

	case OEQ: a = PBEQ; goto br;
	case ONE: a = PBNE; goto br;
	case OLT: a = PBLT; goto br;
	case OGT: a = PBGT; goto br;
	case OLE: a = PBLE; goto br;
	case OGE: a = PBGE; goto br;
	br:
		if(!true)
			a = brcom(a);

		// make simplest on right
		if(nl->ullman < nr->ullman) {
			a = brrev(a);
			r = nl;
			nl = nr;
			nr = r;
		}

		if(nr->addable) {
			cgen(nl);
			gopcodet(PCMP, nr->type, nr);
			patch(gbranch(a, nr->type), to);
			break;
		}
		cgen(nr);
		r = tempname(nr->type);
		gopcodet(PSTORE, nr->type, r);
		cgen(nl);
		gopcodet(PCMP, nr->type, r);
		patch(gbranch(a, nr->type), to);
		break;
	}
	goto ret;

ret:
	dynlineno = lno;
}

void
swgen(Node *n)
{
	Node *c1, *c2;
	Case *s0, *se, *s;
	Prog *p1, *dflt;
	long lno;
	int any;
	Iter save1, save2;

	lno = dynlineno;

	p1 = gbranch(PGOTO, N);
	s0 = C;
	se = C;

	// walk thru the body placing breaks
	// and labels into the case statements

	any = 0;
	dflt = P;
	c1 = listfirst(&save1, &n->nbody);
	while(c1 != N) {
		dynlineno = c1->lineno;	// for diagnostics
		if(c1->op != OCASE) {
			if(s0 == C)
				yyerror("unreachable statements in a switch");
			gen(c1);

			any = 1;
			if(c1->op == OFALL)
				any = 0;
			c1 = listnext(&save1);
			continue;
		}

		// put in the break between cases
		if(any) {
			patch(gbranch(PGOTO, N), breakpc);
			any = 0;
		}

		// over case expressions
		c2 = listfirst(&save2, &c1->left);
		if(c2 == N)
			dflt = pc;

		while(c2 != N) {

			s = mal(sizeof(*s));
			if(s0 == C)
				s0 = s;
			else
				se->slink = s;
			se = s;

			s->scase = c2;		// case expression
			s->sprog = pc;		// where to go

			c2 = listnext(&save2);
		}

		c1 = listnext(&save1);
	}

	if(any)
		patch(gbranch(PGOTO, N), breakpc);

	patch(p1, pc);
	c1 = tempname(n->ntest->type);
	cgen(n->ntest);
	gopcodet(PSTORE, n->ntest->type, c1);

	for(s=s0; s!=C; s=s->slink) {
		cgen(s->scase);
		gopcodet(PCMP, n->ntest->type, c1);
		patch(gbranch(PBEQ, n->ntest->type), s->sprog);
	}
	if(dflt != P) {
		patch(gbranch(PGOTO, N), dflt);
		goto ret;
	}
	patch(gbranch(PGOTO, N), breakpc);

ret:
	dynlineno = lno;
}

/*
 * does this tree use
 * the pointer register
 */
int
usesptr(Node *n)
{
//	if(n->addable)
//		return 0;
	return 1;
}

void
cgen_as(Node *nl, Node *nr, int op, int kaka)
{
	Node *r;

loop:
	switch(op) {
	default:
		fatal("cgen_as: unknown op %O", op);

	case OAS:
		if(nr == N && nl->op == OLIST) {
			kaka = PAS_SINGLE;
			cgen_as(nl->left, nr, op, kaka);
			nl = nl->right;
			goto loop;
		}
		switch(kaka) {
		default:
			yyerror("cgen_as: unknown param %d %d", kaka, PAS_CALLM);
			break;

		case PAS_CALLM: // function returning multi values
			cgen_call(nr, 0);
			cgen_callret(nr, nl);
			break;

		case PAS_SINGLE: // single return val used in expr
			if(nr == N || isnil(nr)) {
				if(nl->addable) {
					gopcodet(PSTOREZ, nl->type, nl);
					break;
				}
				agen(nl);
				gopcodet(PSTOREZI, nl->type, N);
				break;
			}

			if(nl->addable) {
				cgen(nr);
				genconv(nl, nr);
				gopcodet(PSTORE, nl->type, nl);
				break;
			}

			if(nr->addable && !needconvert(nl->type, nr->type)) {
				agen(nl);
				gopcodet(PSTOREI, nr->type, nr);
				break;
			}
			if(!usesptr(nr)) {
				cgen(nr);
				genconv(nl, nr);
				agen(nl);
				gopcodet(PSTOREI, nr->type, N);
				break;
			}
			agen(nl);
			r = tempname(ptrto(nl->type));
			gopcode(PSTORE, PTADDR, r);
			cgen(nr);
			genconv(nl, nr);
			gopcode(PLOAD, PTADDR, r);
			gopcodet(PSTOREI, nl->type, N);
			break;

		case PAS_STRUCT: // structure assignment
			r = ptrto(nr->type);
			if(!usesptr(nr)) {
				agen(nr);
				agen(nl);
				gopcodet(PLOAD, N, r);
				gopcodet(PERROR, nr->type, N);
				break;
			}
			r = tempname(r);
			agen(nr);
			gopcode(PSTORE, PTADDR, r);

			agen(nl);
			gopcodet(PERROR, nr->type, r);
			break;
		}
		break;
	}
}

void
cgen_asop(Node *nl, Node *nr, int op)
{
	Node *r;
	int a;

	a = optopop(op);
	if(nr->addable) {
		if(nl->addable) {
			gopcodet(PLOAD, nl->type, nl);
			gopcodet(a, nr->type, nr);
			gopcodet(PSTORE, nl->type, nl);
			return;
		}

		agen(nl);
		gopcodet(PLOADI, nl->type, N);
		gopcodet(a, nr->type, nr);
		gopcodet(PSTOREI, nl->type, N);
		return;
	}

	r = tempname(nr->type);
	cgen(nr);
	gopcodet(PSTORE, nr->type, r);

	agen(nl);
	gopcodet(PLOADI, nl->type, N);
	gopcodet(a, nr->type, r);
	gopcodet(PSTOREI, nl->type, N);
}

void
inarggen(void)
{
	Iter save;
	Node *arg, *t;
	int i;

	t = curfn->type;

	arg = structfirst(&save, getthis(t));
	if(arg != N) {
		fnparam(t, 0, 0);
		gopcodet(PSTORE, arg->type, arg->nname);
	}

	i = 0;
	arg = structfirst(&save, getinarg(t));
	while(arg != N) {
		fnparam(t, 2, i);
		gopcodet(PLOADI, arg->type, arg->nname);

		arg = structnext(&save);
		i++;
	}
}

void
cgen_ret(Node *n)
{
	Node *arg, *a, *f;
	Iter save;

	arg = listfirst(&save, &n->left);	// expr list
	a = getoutargx(curfn->type);
	f = a->type;
	for(;;) {
		if(arg == N)
			break;
		if(f->etype != TFIELD)
			fatal("cgen_ret: not field");
		if(arg->addable && !needconvert(f->type, arg->type)) {
			gopcode(PLOAD, PTADDR, a->nname);
			gopcode(PADDO, PTADDR, f->nname);
			gopcodet(PSTOREI, arg->type, arg);
		} else {
			cgen(arg);
			genconv(f, arg);
			gopcode(PLOAD, PTADDR, a->nname);
			gopcode(PADDO, PTADDR, f->nname);
			gopcodet(PSTOREI, f->type, N);
		}
		arg = listnext(&save);
		f = f->down;
	}
	gopcodet(PRETURN, N, N);
}

void
cgen_call(Node *n, int toss)
{
	Node *t, *at, *ae, *sn;
	Iter save;
	int i;

	/*
	 * open a block
	 */
	gopcodet(PCALL1, N, n->left);

	/*
	 * prepare the input args
	 */
	t = n->left->type;
	if(t->etype == TPTR)
		t = t->type;

	at = *getinarg(t);			// parameter struct
	sn = at->nname;				// in arg structure name

	at = at->type;				// parameter fields
	ae = listfirst(&save, &n->right);	// expr list

	for(i=0; i<t->intuple; i++) {
		if(ae == N)
			fatal("cgen_call: tupleness");

		if(ae->addable && !needconvert(at->type, ae->type)) {
			gopcode(PADDR, PTADDR, sn);
			gopcode(PADDO, PTADDR, at->nname);
			gopcodet(PSTOREI, at->type, ae);
		} else {
			cgen(ae);
			genconv(at, ae);
			gopcode(PADDR, PTADDR, sn);
			gopcode(PADDO, PTADDR, at->nname);
			gopcodet(PSTOREI, at->type, N);
		}
		ae = listnext(&save);
		at = at->down;
	}

	/*
	 * call the function
	 */
	switch(n->op) {
	default:
		fatal("cgen_call: %O", n->op);

	case OCALL:
		gopcodet(PCALL2, N, n->left);
		break;

	case OCALLPTR:
		cgen(n->left);
		gopcodet(PCALLI2, N, n->left);
		break;

	case OCALLMETH:
		cgen(n->left);
		gopcodet(PCALLM2, N, n->left);
		break;

	case OCALLINTER:
		cgen(n->left);
		gopcodet(PCALLF2, N, n->left);
		break;
	}

	/*
	 * toss the output args
	 */
	if(toss) {
		gopcodet(PCALL3, N, n->left);
		return;
	}
}

void
cgen_callret(Node *n, Node *mas)
{
	Node *t, *at, *ae, *sn;
	Iter save;
	int i;

	t = n->left->type;
	if(t->etype == TPTR)
		t = t->type;

	at = *getoutarg(t);			// parameter struct
	sn = at->nname;				// out arg structure name
	at = at->type;				// parameter fields

	// call w single return val to a register
	if(mas == N) {
		gopcode(PADDR, PTADDR, sn);
		gopcode(PADDO, PTADDR, at->nname);
		gopcodet(PLOADI, at->type, N);
		gopcodet(PCALL3, N, N);
		return;
	}

	// call w multiple values to lval list
	ae = listfirst(&save, &mas);	// expr list
	for(i=0; i<t->outtuple; i++) {
		if(ae == N)
			fatal("cgen_callret: output arguments do not match");

		if(ae->addable) {
			gopcode(PADDR, PTADDR, sn);
			gopcode(PADDO, PTADDR, at->nname);
			gopcodet(PLOADI, at->type, ae);
		} else {
			agen(ae);
			gopcode(PADDR, PTADDR, sn);
			gopcode(PADDO, PTADDR, at->nname);
			gopcodet(PLOADI, at->type, N);
		}

		ae = listnext(&save);
		at = at->down;
	}

	gopcodet(PCALL3, N, N);
}

void
genprint(Node *n)
{
	Node *arg;
	Iter save;

	arg = listfirst(&save, &n);
	while(arg != N) {
		cgen(arg);
		gopcodet(PPRINT, arg->type, N);
		arg = listnext(&save);
	}
}

int
needconvert(Node *tl, Node *tr)
{
	if(isinter(tl)) {
		if(isptrto(tr, TSTRUCT))
			return 1;
		if(isinter(tr))
			return 1;
		return 0;
	}
	if(isptrto(tl, TSTRUCT))
		if(isinter(tr))
			return 1;
	return 0;
}

void
genconv(Node *l, Node *r)
{
	Node *tl, *tr;

	tl = l->type;
	tr = r->type;
	if(needconvert(tl, tr))
		gopcode(PCONV, PTNIL, nod(OCONV, tl, tr));
}

void
genindex(Node *n)
{
	gopcode(PINDEX, n->right->type->etype, n);
}

int
optopop(int op)
{
	int a;

	switch(op) {
	default:
		fatal("optopop: unknown op %O\n", op);

	case OMINUS:	a = PMINUS;	break;
	case OCOM:	a = PCOM;	break;
	case OAND:	a = PAND;	break;
	case OOR:	a = POR;	break;
	case OXOR:	a = PXOR;	break;
	case OADD:	a = PADD;	break;
	case OMUL:	a = PMUL;	break;
	case OMOD:	a = PMOD;	break;
	case OSUB:	a = PSUB;	break;
	case ODIV:	a = PDIV;	break;
	case OLSH:	a = PLSH;	break;
	case ORSH:	a = PRSH;	break;
	case OCAT:	a = PCAT;	break;
	}
	return a;
}
