// 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 "gg.h"

/*
 * generate:
 *	res = n;
 * simplifies and calls gmove.
 */
void
cgen(Node *n, Node *res)
{
	Node *nl, *nr, *r;
	Node n1, n2, n3, f0, f1;
	int a, w;
	Prog *p1, *p2, *p3;
	Addr addr;

	if(debug['g']) {
		dump("\ncgen-n", n);
		dump("cgen-res", res);
	}
	if(n == N || n->type == T)
		goto ret;

	if(res == N || res->type == T)
		fatal("cgen: res nil");

	// TODO compile complex
	if(n != N && n->type != T && iscomplex[n->type->etype])
		return;
	if(res != N && res->type != T && iscomplex[res->type->etype])
		return;

	while(n->op == OCONVNOP)
		n = n->left;

	if(n->ullman >= UINF) {
		if(n->op == OINDREG)
			fatal("cgen: this is going to misscompile");
		if(res->ullman >= UINF) {
			tempname(&n1, n->type);
			cgen(n, &n1);
			cgen(&n1, res);
			goto ret;
		}
	}

	if(isfat(n->type)) {
		sgen(n, res, n->type->width);
		goto ret;
	}

	// update addressability for string, slice
	// can't do in walk because n->left->addable
	// changes if n->left is an escaping local variable.
	switch(n->op) {
	case OLEN:
		if(isslice(n->left->type) || istype(n->left->type, TSTRING))
			n->addable = n->left->addable;
		break;
	case OCAP:
		if(isslice(n->left->type))
			n->addable = n->left->addable;
		break;
	}

	// if both are addressable, move
	if(n->addable && res->addable) {
		if (is64(n->type) || is64(res->type) || n->op == OREGISTER || res->op == OREGISTER) {
			gmove(n, res);
		} else {
			regalloc(&n1, n->type, N);
			gmove(n, &n1);
			cgen(&n1, res);
			regfree(&n1);
		}
		goto ret;
	}

	// if both are not addressable, use a temporary.
	if(!n->addable && !res->addable) {
		// could use regalloc here sometimes,
		// but have to check for ullman >= UINF.
		tempname(&n1, n->type);
		cgen(n, &n1);
		cgen(&n1, res);
		return;
	}

	// if result is not addressable directly but n is,
	// compute its address and then store via the address.
	if(!res->addable) {
		igen(res, &n1, N);
		cgen(n, &n1);
		regfree(&n1);
		return;
	}

	// if n is sudoaddable generate addr and move
	if (!is64(n->type) && !is64(res->type)) {
		a = optoas(OAS, n->type);
		if(sudoaddable(a, n, &addr, &w)) {
			if (res->op != OREGISTER) {
				regalloc(&n2, res->type, N);
				p1 = gins(a, N, &n2);
				p1->from = addr;
				if(debug['g'])
					print("%P [ignore previous line]\n", p1);
				gmove(&n2, res);
				regfree(&n2);
			} else {
				p1 = gins(a, N, res);
				p1->from = addr;
				if(debug['g'])
					print("%P [ignore previous line]\n", p1);
			}
			sudoclean();
			goto ret;
		}
	}

	// otherwise, the result is addressable but n is not.
	// let's do some computation.

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

	if(nl != N && nl->ullman >= UINF)
	if(nr != N && nr->ullman >= UINF) {
		tempname(&n1, nl->type);
		cgen(nl, &n1);
		n2 = *n;
		n2.left = &n1;
		cgen(&n2, res);
		goto ret;
	}

	// 64-bit ops are hard on 32-bit machine.
	if(is64(n->type) || is64(res->type) || n->left != N && is64(n->left->type)) {
		switch(n->op) {
		// math goes to cgen64.
		case OMINUS:
		case OCOM:
		case OADD:
		case OSUB:
		case OMUL:
		case OLSH:
		case ORSH:
		case OAND:
		case OOR:
		case OXOR:
			cgen64(n, res);
			return;
		}
	}

	if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype])
		goto flt;
	switch(n->op) {
	default:
		dump("cgen", n);
		fatal("cgen: unknown op %N", n);
		break;

	case OREAL:
	case OIMAG:
	case OCMPLX:
		// TODO compile complex
		return;

	// 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(AB, T);
		p2 = pc;
		gmove(nodbool(1), res);
		p3 = gbranch(AB, T);
		patch(p1, pc);
		bgen(n, 1, p2);
		gmove(nodbool(0), res);
		patch(p3, pc);
		goto ret;

	case OPLUS:
		cgen(nl, res);
		goto ret;

	// unary
	case OCOM:
		a = optoas(OXOR, nl->type);
		regalloc(&n1, nl->type, N);
		cgen(nl, &n1);
		nodconst(&n2, nl->type, -1);
		gins(a, &n2, &n1);
		gmove(&n1, res);
		regfree(&n1);
		goto ret;

	case OMINUS:
		nodconst(&n3, nl->type, 0);
		regalloc(&n2, nl->type, res);
		regalloc(&n1, nl->type, N);
		gmove(&n3, &n2);
		cgen(nl, &n1);
		gins(optoas(OSUB, nl->type), &n1, &n2);
		gmove(&n2, res);
		regfree(&n1);
		regfree(&n2);
		goto ret;

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

	// asymmetric binary
	case OSUB:
		a = optoas(n->op, nl->type);
		goto abop;

	case OLSH:
	case ORSH:
		cgen_shift(n->op, nl, nr, res);
		break;

	case OCONV:
		if(eqtype(n->type, nl->type) || noconv(n->type, nl->type)) {
			cgen(nl, res);
			break;
		}
		if(nl->addable && !is64(nl->type)) {
			regalloc(&n1, nl->type, res);
			gmove(nl, &n1);
		} else {
			if(n->type->width > widthptr || is64(nl->type) || isfloat[nl->type->etype])
				tempname(&n1, nl->type);
			else
				regalloc(&n1, nl->type, res);
			cgen(nl, &n1);
		}
		if(n->type->width > widthptr || is64(n->type) || isfloat[n->type->etype])
			tempname(&n2, n->type);
		else
			regalloc(&n2, n->type, N);
		gmove(&n1, &n2);
		gmove(&n2, res);
		if(n1.op == OREGISTER)
			regfree(&n1);
		if(n2.op == OREGISTER)
			regfree(&n2);
		break;

	case ODOT:
	case ODOTPTR:
	case OINDEX:
	case OIND:
	case ONAME:	// PHEAP or PPARAMREF var
		igen(n, &n1, res);
		gmove(&n1, res);
		regfree(&n1);
		break;

	case OLEN:
		if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
			// map has len in the first 32-bit word.
			// a zero pointer means zero length
			regalloc(&n1, types[tptr], res);
			cgen(nl, &n1);

			nodconst(&n2, types[tptr], 0);
			regalloc(&n3, n2.type, N);
			gmove(&n2, &n3);
			gcmp(optoas(OCMP, types[tptr]), &n1, &n3);
			regfree(&n3);
			p1 = gbranch(optoas(OEQ, types[tptr]), T);

			n2 = n1;
			n2.op = OINDREG;
			n2.type = types[TINT32];
			gmove(&n2, &n1);

			patch(p1, pc);

			gmove(&n1, res);
			regfree(&n1);
			break;
		}
		if(istype(nl->type, TSTRING) || isslice(nl->type)) {
			// both slice and string have len one pointer into the struct.
			igen(nl, &n1, res);
			n1.op = OREGISTER;	// was OINDREG
			regalloc(&n2, types[TUINT32], &n1);
			n1.op = OINDREG;
			n1.type = types[TUINT32];
			n1.xoffset = Array_nel;
			gmove(&n1, &n2);
			gmove(&n2, res);
			regfree(&n1);
			regfree(&n2);
			break;
		}
		fatal("cgen: OLEN: unknown type %lT", nl->type);
		break;

	case OCAP:
		if(istype(nl->type, TCHAN)) {
			// chan has cap in the second 32-bit word.
			// a zero pointer means zero length
			regalloc(&n1, types[tptr], res);
			cgen(nl, &n1);

			nodconst(&n2, types[tptr], 0);
			regalloc(&n3, n2.type, N);
			gmove(&n2, &n3);
			gcmp(optoas(OCMP, types[tptr]), &n1, &n3);
			regfree(&n3);
			p1 = gbranch(optoas(OEQ, types[tptr]), T);

			n2 = n1;
			n2.op = OINDREG;
			n2.xoffset = 4;
			n2.type = types[TINT32];
			gmove(&n2, &n1);

			patch(p1, pc);

			gmove(&n1, res);
			regfree(&n1);
			break;
		}
		if(isslice(nl->type)) {
			regalloc(&n1, types[tptr], res);
			agen(nl, &n1);
			n1.op = OINDREG;
			n1.type = types[TUINT32];
			n1.xoffset = Array_cap;
			gmove(&n1, res);
			regfree(&n1);
			break;
		}
		fatal("cgen: OCAP: unknown type %lT", nl->type);
		break;

	case OADDR:
		agen(nl, res);
		break;

	case OCALLMETH:
		cgen_callmeth(n, 0);
		cgen_callret(n, res);
		break;

	case OCALLINTER:
		cgen_callinter(n, res, 0);
		cgen_callret(n, res);
		break;

	case OCALLFUNC:
		cgen_call(n, 0);
		cgen_callret(n, res);
		break;

	case OMOD:
	case ODIV:
		a = optoas(n->op, nl->type);
		goto abop;
	}
	goto ret;

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

abop:	// asymmetric binary
	// TODO(kaib): use fewer registers here.
	if(nl->ullman >= nr->ullman) {
		regalloc(&n1, nl->type, res);
		cgen(nl, &n1);
		regalloc(&n2, nr->type, N);
		cgen(nr, &n2);
	} else {
		regalloc(&n2, nr->type, N);
		cgen(nr, &n2);
		regalloc(&n1, nl->type, res);
		cgen(nl, &n1);
	}
	gins(a, &n2, &n1);
	gmove(&n1, res);
	regfree(&n1);
	regfree(&n2);
	goto ret;

flt:	// floating-point.
	regalloc(&f0, nl->type, res);
	if(nr != N)
		goto flt2;

	if(n->op == OMINUS) {
		nr = nodintconst(-1);
		convlit(&nr, n->type);
		n->op = OMUL;
		goto flt2;
	}

	// unary
	cgen(nl, &f0);
	if(n->op != OCONV && n->op != OPLUS)
		gins(optoas(n->op, n->type), &f0, &f0);
	gmove(&f0, res);
	regfree(&f0);
	goto ret;

flt2:	// binary
	if(nl->ullman >= nr->ullman) {
		cgen(nl, &f0);
		regalloc(&f1, n->type, N);
		gmove(&f0, &f1);
		cgen(nr, &f0);
		gins(optoas(n->op, n->type), &f0, &f1);
	} else {
		cgen(nr, &f0);
		regalloc(&f1, n->type, N);
		cgen(nl, &f1);
		gins(optoas(n->op, n->type), &f0, &f1);
	}
	gmove(&f1, res);
	regfree(&f0);
	regfree(&f1);
	goto ret;

ret:
	;
}

/*
 * generate array index into res.
 * n might be any size; res is 32-bit.
 * returns Prog* to patch to panic call.
 */
Prog*
cgenindex(Node *n, Node *res)
{
	Node tmp, lo, hi, zero, n1, n2;

	if(!is64(n->type)) {
		cgen(n, res);
		return nil;
	}

	tempname(&tmp, types[TINT64]);
	cgen(n, &tmp);
	split64(&tmp, &lo, &hi);
	gmove(&lo, res);
	if(debug['B']) {
		splitclean();
		return nil;
	}
	regalloc(&n1, types[TINT32], N);
	regalloc(&n2, types[TINT32], N);
	nodconst(&zero, types[TINT32], 0);
	gmove(&hi, &n1);
	gmove(&zero, &n2);
	gcmp(ACMP, &n1, &n2);
	regfree(&n2);
	regfree(&n1);
	splitclean();
	return gbranch(ABNE, T);
}

/*
 * generate:
 *	res = &n;
 */
void
agen(Node *n, Node *res)
{
	Node *nl, *nr;
	Node n1, n2, n3, n4, n5, tmp;
	Prog *p1, *p2;
	uint32 w;
	uint64 v;
	int r;

	if(debug['g']) {
		dump("\nagen-res", res);
		dump("agen-r", n);
	}
	if(n == N || n->type == T || res == N || res->type == T)
		fatal("agen");

	while(n->op == OCONVNOP)
		n = n->left;

	if(n->addable) {
		memset(&n1, 0, sizeof n1);
		n1.op = OADDR;
		n1.left = n;
		regalloc(&n2, types[tptr], res);
		gins(AMOVW, &n1, &n2);
		gmove(&n2, res);
		regfree(&n2);
		goto ret;
	}

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

	switch(n->op) {
	default:
		fatal("agen: unknown op %N", n);
		break;

	case OCALLMETH:
	case OCALLFUNC:
		// Release res so that it is available for cgen_call.
		// Pick it up again after the call.
		r = -1;
		if(n->ullman >= UINF) {
			if(res->op == OREGISTER || res->op == OINDREG) {
				r = res->val.u.reg;
				reg[r]--;
			}
		}
		if(n->op == OCALLMETH)
			cgen_callmeth(n, 0);
		else
			cgen_call(n, 0);
		if(r >= 0)
			reg[r]++;
		cgen_aret(n, res);
		break;

	case OCALLINTER:
		cgen_callinter(n, res, 0);
		cgen_aret(n, res);
		break;

	case OINDEX:
		p2 = nil;  // to be patched to panicindex.
		w = n->type->width;
		if(nr->addable) {
			agenr(nl, &n3, res);
			if(!isconst(nr, CTINT)) {
				tempname(&tmp, types[TINT32]);
				p2 = cgenindex(nr, &tmp);
				regalloc(&n1, tmp.type, N);
				gmove(&tmp, &n1);
			}
		} else if(nl->addable) {
			if(!isconst(nr, CTINT)) {
				tempname(&tmp, types[TINT32]);
				p2 = cgenindex(nr, &tmp);
				regalloc(&n1, tmp.type, N);
				gmove(&tmp, &n1);
			}
			regalloc(&n3, types[tptr], res);
			agen(nl, &n3);
		} else {
			tempname(&tmp, types[TINT32]);
			p2 = cgenindex(nr, &tmp);
			nr = &tmp;
			agenr(nl, &n3, res);
			regalloc(&n1, tmp.type, N);
			gins(optoas(OAS, tmp.type), &tmp, &n1);
		}

		// &a is in &n3 (allocated in res)
		// i is in &n1 (if not constant)
		// w is width

		if(w == 0)
			fatal("index is zero width");

		// constant index
		if(isconst(nr, CTINT)) {
			v = mpgetfix(nr->val.u.xval);
			if(isslice(nl->type)) {

				if(!debug['B'] && !n->etype) {
					n1 = n3;
					n1.op = OINDREG;
					n1.type = types[tptr];
					n1.xoffset = Array_nel;
					regalloc(&n4, n1.type, N);
					cgen(&n1, &n4);
					nodconst(&n2, types[TUINT32], v);
					regalloc(&n5, n2.type, N);
					gmove(&n2, &n5);
					gcmp(optoas(OCMP, types[TUINT32]), &n4, &n5);
					regfree(&n4);
					regfree(&n5);
					p1 = gbranch(optoas(OGT, types[TUINT32]), T);
					ginscall(panicindex, 0);
					patch(p1, pc);
				}

				n1 = n3;
				n1.op = OINDREG;
				n1.type = types[tptr];
				n1.xoffset = Array_array;
				gmove(&n1, &n3);
			}

			nodconst(&n2, types[tptr], v*w);
			regalloc(&n4, n2.type, N);
			gmove(&n2, &n4);
			gins(optoas(OADD, types[tptr]), &n4, &n3);
			regfree(&n4);

			gmove(&n3, res);
			regfree(&n3);
			break;
		}

		regalloc(&n2, types[TINT32], &n1);			// i
		gmove(&n1, &n2);
		regfree(&n1);

		if(!debug['B'] && !n->etype) {
			// check bounds
			regalloc(&n4, types[TUINT32], N);
			if(isslice(nl->type)) {
				n1 = n3;
				n1.op = OINDREG;
				n1.type = types[tptr];
				n1.xoffset = Array_nel;
				cgen(&n1, &n4);
			} else {
				nodconst(&n1, types[TUINT32], nl->type->bound);
				gmove(&n1, &n4);
			}
			gcmp(optoas(OCMP, types[TUINT32]), &n2, &n4);
			regfree(&n4);
			p1 = gbranch(optoas(OLT, types[TUINT32]), T);
			if(p2)
				patch(p2, pc);
			ginscall(panicindex, 0);
			patch(p1, pc);
		}

		if(isslice(nl->type)) {
			n1 = n3;
			n1.op = OINDREG;
			n1.type = types[tptr];
			n1.xoffset = Array_array;
			gmove(&n1, &n3);
		}

		if(w == 1 || w == 2 || w == 4 || w == 8) {
			memset(&n4, 0, sizeof n4);
			n4.op = OADDR;
			n4.left = &n2;
			cgen(&n4, &n3);
			if (w == 1)
				gins(AADD, &n2, &n3);
			else if(w == 2)
				gshift(AADD, &n2, SHIFT_LL, 1, &n3);
			else if(w == 4)
				gshift(AADD, &n2, SHIFT_LL, 2, &n3);
			else if(w == 8)
				gshift(AADD, &n2, SHIFT_LL, 3, &n3);	
		} else {
			regalloc(&n4, types[TUINT32], N);
			nodconst(&n1, types[TUINT32], w);
			gmove(&n1, &n4);
			gins(optoas(OMUL, types[TUINT32]), &n4, &n2);
			gins(optoas(OADD, types[tptr]), &n2, &n3);
			regfree(&n4);
			gmove(&n3, res);
		}

		gmove(&n3, res);
		regfree(&n2);
		regfree(&n3);
		break;

	case ONAME:
		// should only get here with names in this func.
		if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
			dump("bad agen", n);
			fatal("agen: bad ONAME funcdepth %d != %d",
				n->funcdepth, funcdepth);
		}

		// should only get here for heap vars or paramref
		if(!(n->class & PHEAP) && n->class != PPARAMREF) {
			dump("bad agen", n);
			fatal("agen: bad ONAME class %#x", n->class);
		}
		cgen(n->heapaddr, res);
		if(n->xoffset != 0) {
			nodconst(&n1, types[TINT32], n->xoffset);
			regalloc(&n2, n1.type, N);
			regalloc(&n3, types[TINT32], N);
			gmove(&n1, &n2);
			gmove(res, &n3);
			gins(optoas(OADD, types[tptr]), &n2, &n3);
			gmove(&n3, res);
			regfree(&n2);
			regfree(&n3);
		}
		break;

	case OIND:
		cgen(nl, res);
		break;

	case ODOT:
		agen(nl, res);
		if(n->xoffset != 0) {
			nodconst(&n1, types[TINT32], n->xoffset);
			regalloc(&n2, n1.type, N);
			regalloc(&n3, types[TINT32], N);
			gmove(&n1, &n2);
			gmove(res, &n3);
			gins(optoas(OADD, types[tptr]), &n2, &n3);
			gmove(&n3, res);
			regfree(&n2);
			regfree(&n3);
		}
		break;

	case ODOTPTR:
		cgen(nl, res);
		if(n->xoffset != 0) {
			// explicit check for nil if struct is large enough
			// that we might derive too big a pointer.
			if(nl->type->type->width >= unmappedzero) {
				regalloc(&n1, types[tptr], N);
				gmove(res, &n1);
				p1 = gins(AMOVW, &n1, &n1);
				p1->from.type = D_OREG;
				p1->from.offset = 0;
				regfree(&n1);
			}
			nodconst(&n1, types[TINT32], n->xoffset);
			regalloc(&n2, n1.type, N);
			regalloc(&n3, types[tptr], N);
			gmove(&n1, &n2);
			gmove(res, &n3);
			gins(optoas(OADD, types[tptr]), &n2, &n3);
			gmove(&n3, res);
			regfree(&n2);
			regfree(&n3);
		}
		break;
	}

ret:
	;
}

/*
 * generate:
 *	newreg = &n;
 *	res = newreg
 *
 * on exit, a has been changed to be *newreg.
 * caller must regfree(a).
 */
void
igen(Node *n, Node *a, Node *res)
{
	regalloc(a, types[tptr], res);
	agen(n, a);
	a->op = OINDREG;
	a->type = n->type;
}

/*
 * generate:
 *	newreg = &n;
 *
 * caller must regfree(a).
 */
void
agenr(Node *n, Node *a, Node *res)
{
	Node n1;

	tempname(&n1, types[tptr]);
	agen(n, &n1);
	regalloc(a, types[tptr], res);
	gmove(&n1, a);
}

/*
 * generate:
 *	if(n == true) goto to;
 */
void
bgen(Node *n, int true, Prog *to)
{
	int et, a;
	Node *nl, *nr, *r;
	Node n1, n2, n3, n4, tmp;
	Prog *p1, *p2;

	if(debug['g']) {
		dump("\nbgen", n);
	}

	if(n == N)
		n = nodbool(1);

	if(n->ninit != nil)
		genlist(n->ninit);

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

	// TODO compile complex
	if(nl != N && nl->type != T && iscomplex[nl->type->etype])
		return;
	if(nr != N && nr->type != T && iscomplex[nr->type->etype])
		return;

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

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

	switch(n->op) {
	default:
	def:
		regalloc(&n1, n->type, N);
		cgen(n, &n1);
		nodconst(&n2, n->type, 0);
		regalloc(&n3, n->type, N);
		gmove(&n2, &n3);
		gcmp(optoas(OCMP, n->type), &n1, &n3);
		a = ABNE;
		if(!true)
			a = ABEQ;
		patch(gbranch(a, n->type), to);
		regfree(&n1);
		regfree(&n3);
		goto ret;

	case OLITERAL:
		// need to ask if it is bool?
		if(!true == !n->val.u.bval)
			patch(gbranch(AB, T), to);
		goto ret;

	case ONAME:
		if(n->addable == 0)
			goto def;
		nodconst(&n1, n->type, 0);
		regalloc(&n2, n->type, N);
		regalloc(&n3, n->type, N);
		gmove(&n1, &n2);
		cgen(n, &n3);
		gcmp(optoas(OCMP, n->type), &n2, &n3);
		a = ABNE;
		if(!true)
			a = ABEQ;
		patch(gbranch(a, n->type), to);
		regfree(&n2);
		regfree(&n3);
		goto ret;

	case OANDAND:
		if(!true)
			goto caseor;

	caseand:
		p1 = gbranch(AB, T);
		p2 = gbranch(AB, T);
		patch(p1, pc);
		bgen(n->left, !true, p2);
		bgen(n->right, !true, p2);
		p1 = gbranch(AB, T);
		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 == T)
			goto ret;

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

	switch(n->op) {

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

	case OEQ:
	case ONE:
	case OLT:
	case OGT:
	case OLE:
	case OGE:
		a = n->op;
		if(!true) {
			if(isfloat[nl->type->etype]) {
				// brcom is not valid on floats when NaN is involved.
				p1 = gbranch(AB, T);
				p2 = gbranch(AB, T);
				patch(p1, pc);
				bgen(n, 1, p2);
				patch(gbranch(AB, T), to);
				patch(p2, pc);
				goto ret;
			}				
			a = brcom(a);
		}

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

		if(isslice(nl->type)) {
			// only valid to cmp darray to literal nil
			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
				yyerror("illegal array comparison");
				break;
			}
			a = optoas(a, types[tptr]);
			regalloc(&n1, types[tptr], N);
			regalloc(&n3, types[tptr], N);
			regalloc(&n4, types[tptr], N);
			agen(nl, &n1);
			n2 = n1;
			n2.op = OINDREG;
			n2.xoffset = Array_array;
			gmove(&n2, &n4);
			nodconst(&tmp, types[tptr], 0);
			gmove(&tmp, &n3);
			gcmp(optoas(OCMP, types[tptr]), &n4, &n3);
			patch(gbranch(a, types[tptr]), to);
			regfree(&n4);
			regfree(&n3);
			regfree(&n1);
			break;
		}

		if(isinter(nl->type)) {
			// front end shold only leave cmp to literal nil
			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
				yyerror("illegal interface comparison");
				break;
			}
			a = optoas(a, types[tptr]);
			regalloc(&n1, types[tptr], N);
			regalloc(&n3, types[tptr], N);
			regalloc(&n4, types[tptr], N);
			agen(nl, &n1);
			n2 = n1;
			n2.op = OINDREG;
			n2.xoffset = 0;
			gmove(&n2, &n4);
			nodconst(&tmp, types[tptr], 0);
			gmove(&tmp, &n3);
			gcmp(optoas(OCMP, types[tptr]), &n4, &n3);
			patch(gbranch(a, types[tptr]), to);
			regfree(&n1);
			regfree(&n3);
			regfree(&n4);
			break;
		}

		if(is64(nr->type)) {
			if(!nl->addable) {
				tempname(&n1, nl->type);
				cgen(nl, &n1);
				nl = &n1;
			}
			if(!nr->addable) {
				tempname(&n2, nr->type);
				cgen(nr, &n2);
				nr = &n2;
			}
			cmp64(nl, nr, a, to);
			break;
		}

		a = optoas(a, nr->type);

		if(nr->ullman >= UINF) {
			regalloc(&n1, nr->type, N);
			cgen(nr, &n1);

			tempname(&tmp, nr->type);
			gmove(&n1, &tmp);
			regfree(&n1);

			regalloc(&n1, nl->type, N);
			cgen(nl, &n1);

			regalloc(&n2, nr->type, N);
			cgen(&tmp, &n2);

			gcmp(optoas(OCMP, nr->type), &n1, &n2);
			patch(gbranch(a, nr->type), to);

			regfree(&n1);
			regfree(&n2);
			break;
		}

		regalloc(&n1, nl->type, N);
		cgen(nl, &n1);

		regalloc(&n2, nr->type, N);
		cgen(nr, &n2);

		gcmp(optoas(OCMP, nr->type), &n1, &n2);
		if(isfloat[nl->type->etype]) {
			p1 = gbranch(ABVS, nr->type);
			patch(gbranch(a, nr->type), to);
			if(n->op == ONE)
				patch(p1, to);
			else
				patch(p1, pc);
		} else {
			patch(gbranch(a, nr->type), to);
		}

		regfree(&n1);
		regfree(&n2);
		break;
	}
	goto ret;

ret:
	;
}

/*
 * n is on stack, either local variable
 * or return value from function call.
 * return n's offset from SP.
 */
int32
stkof(Node *n)
{
	Type *t;
	Iter flist;
	int32 off;

	switch(n->op) {
	case OINDREG:
		return n->xoffset;

	case ODOT:
		t = n->left->type;
		if(isptr[t->etype])
			break;
		off = stkof(n->left);
		if(off == -1000 || off == 1000)
			return off;
		return off + n->xoffset;

	case OINDEX:
		t = n->left->type;
		if(!isfixedarray(t))
			break;
		off = stkof(n->left);
		if(off == -1000 || off == 1000)
			return off;
		if(isconst(n->right, CTINT))
			return off + t->type->width * mpgetfix(n->right->val.u.xval);
		return 1000;
		
	case OCALLMETH:
	case OCALLINTER:
	case OCALLFUNC:
		t = n->left->type;
		if(isptr[t->etype])
			t = t->type;

		t = structfirst(&flist, getoutarg(t));
		if(t != T)
			return t->width + 4;	// correct for LR
		break;
	}

	// botch - probably failing to recognize address
	// arithmetic on the above. eg INDEX and DOT
	return -1000;
}

/*
 * block copy:
 *	memmove(&res, &n, w);
 * NB: character copy assumed little endian architecture
 */
void
sgen(Node *n, Node *res, int32 w)
{
	Node dst, src, tmp, nend;
	int32 c, q, odst, osrc;
	Prog *p, *ploop;

	if(debug['g']) {
		print("\nsgen w=%d\n", w);
		dump("r", n);
		dump("res", res);
	}
	if(w == 0)
		return;
	if(n->ullman >= UINF && res->ullman >= UINF) {
		fatal("sgen UINF");
	}

	if(w < 0)
		fatal("sgen copy %d", w);

	// offset on the stack
	osrc = stkof(n);
	odst = stkof(res);

	if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) {
		// osrc and odst both on stack, and at least one is in
		// an unknown position.  Could generate code to test
		// for forward/backward copy, but instead just copy
		// to a temporary location first.
		tempname(&tmp, n->type);
		sgen(n, &tmp, w);
		sgen(&tmp, res, w);
		return;
	}

	if(osrc % 4 != 0 || odst %4 != 0)
		fatal("sgen: non word(4) aligned offset src %d or dst %d", osrc, odst);

	regalloc(&dst, types[tptr], res);

	if(n->ullman >= res->ullman) {
		agen(n, &dst);	// temporarily use dst
		regalloc(&src, types[tptr], N);
		gins(AMOVW, &dst, &src);
		agen(res, &dst);
	} else {
		agen(res, &dst);
		regalloc(&src, types[tptr], N);
		agen(n, &src);
	}

	regalloc(&tmp, types[TUINT32], N);

	c = w % 4;	// bytes
	q = w / 4;	// quads

	// if we are copying forward on the stack and
	// the src and dst overlap, then reverse direction
	if(osrc < odst && odst < osrc+w) {
		if(c != 0)
			fatal("sgen: reverse character copy not implemented");
		if(q >= 4) {
			regalloc(&nend, types[TUINT32], N);
			// set up end marker to 4 bytes before source
			p = gins(AMOVW, &src, &nend);
			p->from.type = D_CONST;
			p->from.offset = -4;

			// move src and dest to the end of block
			p = gins(AMOVW, &src, &src);
			p->from.type = D_CONST;
			p->from.offset = (q-1)*4;

			p = gins(AMOVW, &dst, &dst);
			p->from.type = D_CONST;
			p->from.offset = (q-1)*4;

			p = gins(AMOVW, &src, &tmp);
			p->from.type = D_OREG;
			p->from.offset = -4;
			p->scond |= C_PBIT;
			ploop = p;

			p = gins(AMOVW, &tmp, &dst);
			p->to.type = D_OREG;
			p->to.offset = -4;
			p->scond |= C_PBIT;

			p = gins(ACMP, &src, N);
			raddr(&nend, p);

			patch(gbranch(ABNE, T), ploop);

 			regfree(&nend);
		} else {
			// move src and dest to the end of block
			p = gins(AMOVW, &src, &src);
			p->from.type = D_CONST;
			p->from.offset = (q-1)*4;

			p = gins(AMOVW, &dst, &dst);
			p->from.type = D_CONST;
			p->from.offset = (q-1)*4;

			while(q > 0) {
				p = gins(AMOVW, &src, &tmp);
				p->from.type = D_OREG;
				p->from.offset = -4;
 				p->scond |= C_PBIT;

				p = gins(AMOVW, &tmp, &dst);
				p->to.type = D_OREG;
				p->to.offset = -4;
 				p->scond |= C_PBIT;

				q--;
			}
		}
	} else {
		// normal direction
		if(q >= 4) {
			regalloc(&nend, types[TUINT32], N);
			p = gins(AMOVW, &src, &nend);
			p->from.type = D_CONST;
			p->from.offset = q*4;

			p = gins(AMOVW, &src, &tmp);
			p->from.type = D_OREG;
			p->from.offset = 4;
			p->scond |= C_PBIT;
			ploop = p;

			p = gins(AMOVW, &tmp, &dst);
			p->to.type = D_OREG;
			p->to.offset = 4;
			p->scond |= C_PBIT;

			p = gins(ACMP, &src, N);
			raddr(&nend, p);

			patch(gbranch(ABNE, T), ploop);

 			regfree(&nend);
		} else
		while(q > 0) {
			p = gins(AMOVW, &src, &tmp);
			p->from.type = D_OREG;
			p->from.offset = 4;
 			p->scond |= C_PBIT;

			p = gins(AMOVW, &tmp, &dst);
			p->to.type = D_OREG;
			p->to.offset = 4;
 			p->scond |= C_PBIT;

			q--;
		}

		if (c != 0) {
			//	MOVW	(src), tmp
			p = gins(AMOVW, &src, &tmp);
			p->from.type = D_OREG;

			//	MOVW	tmp<<((4-c)*8),src
			gshift(AMOVW, &tmp, SHIFT_LL, ((4-c)*8), &src);

			//	MOVW	src>>((4-c)*8),src
			gshift(AMOVW, &src, SHIFT_LR, ((4-c)*8), &src);

			//	MOVW	(dst), tmp
			p = gins(AMOVW, &dst, &tmp);
			p->from.type = D_OREG;

			//	MOVW	tmp>>(c*8),tmp
			gshift(AMOVW, &tmp, SHIFT_LR, (c*8), &tmp);

			//	MOVW	tmp<<(c*8),tmp
			gshift(AMOVW, &tmp, SHIFT_LL, c*8, &tmp);

			//	ORR		src, tmp
			gins(AORR, &src, &tmp);

			//	MOVW	tmp, (dst)
			p = gins(AMOVW, &tmp, &dst);
			p->to.type = D_OREG;
		}
	}
 	regfree(&dst);
	regfree(&src);
	regfree(&tmp);
}
