// Inferno utils/6c/txt.c
// http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "gc.h"

void
ginit(void)
{
	int i;
	Type *t;

	thechar = '6';
	thestring = "amd64";
	exregoffset = REGEXT;
	exfregoffset = FREGEXT;
	listinit();
	nstring = 0;
	mnstring = 0;
	nrathole = 0;
	pc = 0;
	breakpc = -1;
	continpc = -1;
	cases = C;
	firstp = P;
	lastp = P;
	tfield = types[TINT];

	typeword = typechlvp;
	typecmplx = typesu;

	/* TO DO */
	memmove(typechlpv, typechlp, sizeof(typechlpv));
	typechlpv[TVLONG] = 1;
	typechlpv[TUVLONG] = 1;

	zprog.link = P;
	zprog.as = AGOK;
	zprog.from.type = D_NONE;
	zprog.from.index = D_NONE;
	zprog.from.scale = 0;
	zprog.to = zprog.from;

	lregnode.op = OREGISTER;
	lregnode.class = CEXREG;
	lregnode.reg = REGTMP;
	lregnode.complex = 0;
	lregnode.addable = 11;
	lregnode.type = types[TLONG];

	qregnode = lregnode;
	qregnode.type = types[TVLONG];

	constnode.op = OCONST;
	constnode.class = CXXX;
	constnode.complex = 0;
	constnode.addable = 20;
	constnode.type = types[TLONG];

	vconstnode = constnode;
	vconstnode.type = types[TVLONG];

	fconstnode.op = OCONST;
	fconstnode.class = CXXX;
	fconstnode.complex = 0;
	fconstnode.addable = 20;
	fconstnode.type = types[TDOUBLE];

	nodsafe = new(ONAME, Z, Z);
	nodsafe->sym = slookup(".safe");
	nodsafe->type = types[TINT];
	nodsafe->etype = types[TINT]->etype;
	nodsafe->class = CAUTO;
	complex(nodsafe);

	t = typ(TARRAY, types[TCHAR]);
	symrathole = slookup(".rathole");
	symrathole->class = CGLOBL;
	symrathole->type = t;

	nodrat = new(ONAME, Z, Z);
	nodrat->sym = symrathole;
	nodrat->type = types[TIND];
	nodrat->etype = TVOID;
	nodrat->class = CGLOBL;
	complex(nodrat);
	nodrat->type = t;

	nodret = new(ONAME, Z, Z);
	nodret->sym = slookup(".ret");
	nodret->type = types[TIND];
	nodret->etype = TIND;
	nodret->class = CPARAM;
	nodret = new(OIND, nodret, Z);
	complex(nodret);

	if(0)
		com64init();

	for(i=0; i<nelem(reg); i++) {
		reg[i] = 1;
		if(i >= D_AX && i <= D_R15 && i != D_SP)
			reg[i] = 0;
		if(i >= D_X0 && i <= D_X7)
			reg[i] = 0;
	}
}

void
gclean(void)
{
	int i;
	Sym *s;

	reg[D_SP]--;
	for(i=D_AX; i<=D_R15; i++)
		if(reg[i])
			diag(Z, "reg %R left allocated", i);
	for(i=D_X0; i<=D_X7; i++)
		if(reg[i])
			diag(Z, "reg %R left allocated", i);
	while(mnstring)
		outstring("", 1L);
	symstring->type->width = nstring;
	symrathole->type->width = nrathole;
	for(i=0; i<NHASH; i++)
	for(s = hash[i]; s != S; s = s->link) {
		if(s->type == T)
			continue;
		if(s->type->width == 0)
			continue;
		if(s->class != CGLOBL && s->class != CSTATIC)
			continue;
		if(s->type == types[TENUM])
			continue;
		gpseudo(AGLOBL, s, nodconst(s->type->width));
	}
	nextpc();
	p->as = AEND;
	outcode();
}

void
nextpc(void)
{

	p = alloc(sizeof(*p));
	*p = zprog;
	p->lineno = nearln;
	pc++;
	if(firstp == P) {
		firstp = p;
		lastp = p;
		return;
	}
	lastp->link = p;
	lastp = p;
}

void
gargs(Node *n, Node *tn1, Node *tn2)
{
	int32 regs;
	Node fnxargs[20], *fnxp;

	regs = cursafe;

	fnxp = fnxargs;
	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */

	curarg = 0;
	fnxp = fnxargs;
	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */

	cursafe = regs;
}

int
nareg(void)
{
	int i, n;

	n = 0;
	for(i=D_AX; i<=D_R15; i++)
		if(reg[i] == 0)
			n++;
	return n;
}

void
garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
{
	Node nod;

	if(n == Z)
		return;
	if(n->op == OLIST) {
		garg1(n->left, tn1, tn2, f, fnxp);
		garg1(n->right, tn1, tn2, f, fnxp);
		return;
	}
	if(f == 0) {
		if(n->complex >= FNX) {
			regsalloc(*fnxp, n);
			nod = znode;
			nod.op = OAS;
			nod.left = *fnxp;
			nod.right = n;
			nod.type = n->type;
			cgen(&nod, Z);
			(*fnxp)++;
		}
		return;
	}
	if(typesu[n->type->etype]) {
		regaalloc(tn2, n);
		if(n->complex >= FNX) {
			sugen(*fnxp, tn2, n->type->width);
			(*fnxp)++;
		} else
			sugen(n, tn2, n->type->width);
		return;
	}
	if(REGARG && curarg == 0 && typechlpv[n->type->etype]) {
		regaalloc1(tn1, n);
		if(n->complex >= FNX) {
			cgen(*fnxp, tn1);
			(*fnxp)++;
		} else
			cgen(n, tn1);
		return;
	}
	if(vconst(n) == 0) {
		regaalloc(tn2, n);
		gmove(n, tn2);
		return;
	}
	regalloc(tn1, n, Z);
	if(n->complex >= FNX) {
		cgen(*fnxp, tn1);
		(*fnxp)++;
	} else
		cgen(n, tn1);
	regaalloc(tn2, n);
	gmove(tn1, tn2);
	regfree(tn1);
}

Node*
nodgconst(vlong v, Type *t)
{
	if(!typev[t->etype])
		return nodconst((int32)v);
	vconstnode.vconst = v;
	return &vconstnode;
}

Node*
nodconst(int32 v)
{
	constnode.vconst = v;
	return &constnode;
}

Node*
nodfconst(double d)
{
	fconstnode.fconst = d;
	return &fconstnode;
}

int
isreg(Node *n, int r)
{

	if(n->op == OREGISTER)
		if(n->reg == r)
			return 1;
	return 0;
}

int
nodreg(Node *n, Node *nn, int r)
{
	int et;

	*n = qregnode;
	n->reg = r;
	if(nn != Z){
		et = nn->type->etype;
		if(!typefd[et] && nn->type->width <= SZ_LONG && 0)
			n->type = typeu[et]? types[TUINT]: types[TINT];
		else
			n->type = nn->type;
//print("nodreg %s [%s]\n", tnames[et], tnames[n->type->etype]);
		n->lineno = nn->lineno;
	}
	if(reg[r] == 0)
		return 0;
	if(nn != Z) {
		if(nn->op == OREGISTER)
		if(nn->reg == r)
			return 0;
	}
	return 1;
}

void
regret(Node *n, Node *nn)
{
	int r;

	r = REGRET;
	if(typefd[nn->type->etype])
		r = FREGRET;
	nodreg(n, nn, r);
	reg[r]++;
}

void
regalloc(Node *n, Node *tn, Node *o)
{
	int i;

	switch(tn->type->etype) {
	case TCHAR:
	case TUCHAR:
	case TSHORT:
	case TUSHORT:
	case TINT:
	case TUINT:
	case TLONG:
	case TULONG:
	case TVLONG:
	case TUVLONG:
	case TIND:
		if(o != Z && o->op == OREGISTER) {
			i = o->reg;
			if(i >= D_AX && i <= D_R15)
				goto out;
		}
		for(i=D_AX; i<=D_R15; i++)
			if(reg[i] == 0)
				goto out;
		diag(tn, "out of fixed registers");
		goto err;

	case TFLOAT:
	case TDOUBLE:
		if(o != Z && o->op == OREGISTER) {
			i = o->reg;
			if(i >= D_X0 && i <= D_X7)
				goto out;
		}
		for(i=D_X0; i<=D_X7; i++)
			if(reg[i] == 0)
				goto out;
		diag(tn, "out of float registers");
		goto out;
	}
	diag(tn, "unknown type in regalloc: %T", tn->type);
err:
	i = 0;
out:
	if(i)
		reg[i]++;
	nodreg(n, tn, i);
}

void
regialloc(Node *n, Node *tn, Node *o)
{
	Node nod;

	nod = *tn;
	nod.type = types[TIND];
	regalloc(n, &nod, o);
}

void
regfree(Node *n)
{
	int i;

	i = 0;
	if(n->op != OREGISTER && n->op != OINDREG)
		goto err;
	i = n->reg;
	if(i < 0 || i >= sizeof(reg))
		goto err;
	if(reg[i] <= 0)
		goto err;
	reg[i]--;
	return;
err:
	diag(n, "error in regfree: %R", i);
}

void
regsalloc(Node *n, Node *nn)
{
	cursafe = align(cursafe, nn->type, Aaut3);
	maxargsafe = maxround(maxargsafe, cursafe+curarg);
	*n = *nodsafe;
	n->xoffset = -(stkoff + cursafe);
	n->type = nn->type;
	n->etype = nn->type->etype;
	n->lineno = nn->lineno;
}

void
regaalloc1(Node *n, Node *nn)
{
	if(REGARG == 0)
		diag(n, "regaalloc1 and REGARG==0");
	nodreg(n, nn, REGARG);
	reg[REGARG]++;
	curarg = align(curarg, nn->type, Aarg1);
	curarg = align(curarg, nn->type, Aarg2);
	maxargsafe = maxround(maxargsafe, cursafe+curarg);
}

void
regaalloc(Node *n, Node *nn)
{
	curarg = align(curarg, nn->type, Aarg1);
	*n = *nn;
	n->op = OINDREG;
	n->reg = REGSP;
	n->xoffset = curarg;
	n->complex = 0;
	n->addable = 20;
	curarg = align(curarg, nn->type, Aarg2);
	maxargsafe = maxround(maxargsafe, cursafe+curarg);
}

void
regind(Node *n, Node *nn)
{

	if(n->op != OREGISTER) {
		diag(n, "regind not OREGISTER");
		return;
	}
	n->op = OINDREG;
	n->type = nn->type;
}

void
naddr(Node *n, Adr *a)
{
	int32 v;

	a->type = D_NONE;
	if(n == Z)
		return;
	switch(n->op) {
	default:
	bad:
		diag(n, "bad in naddr: %O %D", n->op, a);
		break;

	case OREGISTER:
		a->type = n->reg;
		a->sym = S;
		break;


	case OIND:
		naddr(n->left, a);
		if(a->type >= D_AX && a->type <= D_R15)
			a->type += D_INDIR;
		else
		if(a->type == D_CONST)
			a->type = D_NONE+D_INDIR;
		else
		if(a->type == D_ADDR) {
			a->type = a->index;
			a->index = D_NONE;
		} else
			goto bad;
		break;

	case OINDEX:
		a->type = idx.ptr;
		if(n->left->op == OADDR || n->left->op == OCONST)
			naddr(n->left, a);
		if(a->type >= D_AX && a->type <= D_R15)
			a->type += D_INDIR;
		else
		if(a->type == D_CONST)
			a->type = D_NONE+D_INDIR;
		else
		if(a->type == D_ADDR) {
			a->type = a->index;
			a->index = D_NONE;
		} else
			goto bad;
		a->index = idx.reg;
		a->scale = n->scale;
		a->offset += n->xoffset;
		break;

	case OINDREG:
		a->type = n->reg+D_INDIR;
		a->sym = S;
		a->offset = n->xoffset;
		break;

	case ONAME:
		a->etype = n->etype;
		a->type = D_STATIC;
		a->sym = n->sym;
		a->offset = n->xoffset;
		if(n->class == CSTATIC)
			break;
		if(n->class == CEXTERN || n->class == CGLOBL) {
			a->type = D_EXTERN;
			break;
		}
		if(n->class == CAUTO) {
			a->type = D_AUTO;
			break;
		}
		if(n->class == CPARAM) {
			a->type = D_PARAM;
			break;
		}
		goto bad;

	case OCONST:
		if(typefd[n->type->etype]) {
			a->type = D_FCONST;
			a->dval = n->fconst;
			break;
		}
		a->sym = S;
		a->type = D_CONST;
		if(typev[n->type->etype] || n->type->etype == TIND)
			a->offset = n->vconst;
		else
			a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG);
		break;

	case OADDR:
		naddr(n->left, a);
		if(a->type >= D_INDIR) {
			a->type -= D_INDIR;
			break;
		}
		if(a->type == D_EXTERN || a->type == D_STATIC ||
		   a->type == D_AUTO || a->type == D_PARAM)
			if(a->index == D_NONE) {
				a->index = a->type;
				a->type = D_ADDR;
				break;
			}
		goto bad;

	case OADD:
		if(n->right->op == OCONST) {
			v = n->right->vconst;
			naddr(n->left, a);
		} else
		if(n->left->op == OCONST) {
			v = n->left->vconst;
			naddr(n->right, a);
		} else
			goto bad;
		a->offset += v;
		break;

	}
}

void
gcmp(int op, Node *n, vlong val)
{
	Node *cn, nod;

	cn = nodgconst(val, n->type);
	if(!immconst(cn)){
		regalloc(&nod, n, Z);
		gmove(cn, &nod);
		gopcode(op, n->type, n, &nod);
		regfree(&nod);
	}else
		gopcode(op, n->type, n, cn);
}

#define	CASE(a,b)	((a<<8)|(b<<0))

void
gmove(Node *f, Node *t)
{
	int ft, tt, t64, a;
	Node nod, nod1, nod2, nod3;
	Prog *p1, *p2;

	ft = f->type->etype;
	tt = t->type->etype;
	t64 = tt == TVLONG || tt == TUVLONG || tt == TIND;
	if(debug['M'])
		print("gop: %O %O[%s],%O[%s]\n", OAS,
			f->op, tnames[ft], t->op, tnames[tt]);
	if(typefd[ft] && f->op == OCONST) {
		/* TO DO: pick up special constants, possibly preloaded */
		if(f->fconst == 0.0){
			regalloc(&nod, t, t);
			gins(AXORPD, &nod, &nod);
			gmove(&nod, t);
			regfree(&nod);
			return;
		}
	}
/*
 * load
 */
	if(ft == TVLONG || ft == TUVLONG)
	if(f->op == OCONST)
	if(f->vconst > 0x7fffffffLL || f->vconst < -0x7fffffffLL)
	if(t->op != OREGISTER) {
		regalloc(&nod, f, Z);
		gmove(f, &nod);
		gmove(&nod, t);
		regfree(&nod);
		return;
	}

	if(f->op == ONAME || f->op == OINDREG ||
	   f->op == OIND || f->op == OINDEX)
	switch(ft) {
	case TCHAR:
		a = AMOVBLSX;
		if(t64)
			a = AMOVBQSX;
		goto ld;
	case TUCHAR:
		a = AMOVBLZX;
		if(t64)
			a = AMOVBQZX;
		goto ld;
	case TSHORT:
		a = AMOVWLSX;
		if(t64)
			a = AMOVWQSX;
		goto ld;
	case TUSHORT:
		a = AMOVWLZX;
		if(t64)
			a = AMOVWQZX;
		goto ld;
	case TINT:
	case TLONG:
		if(typefd[tt]) {
			regalloc(&nod, t, t);
			if(tt == TDOUBLE)
				a = ACVTSL2SD;
			else
				a = ACVTSL2SS;
			gins(a, f, &nod);
			gmove(&nod, t);
			regfree(&nod);
			return;
		}
		a = AMOVL;
		if(t64)
			a = AMOVLQSX;
		goto ld;
	case TUINT:
	case TULONG:
		a = AMOVL;
		if(t64)
			a = AMOVLQZX;	/* could probably use plain MOVL */
		goto ld;
	case TVLONG:
		if(typefd[tt]) {
			regalloc(&nod, t, t);
			if(tt == TDOUBLE)
				a = ACVTSQ2SD;
			else
				a = ACVTSQ2SS;
			gins(a, f, &nod);
			gmove(&nod, t);
			regfree(&nod);
			return;
		}
	case TUVLONG:
		a = AMOVQ;
		goto ld;
	case TIND:
		a = AMOVQ;

	ld:
		regalloc(&nod, f, t);
		nod.type = t64? types[TVLONG]: types[TINT];
		gins(a, f, &nod);
		gmove(&nod, t);
		regfree(&nod);
		return;

	case TFLOAT:
		a = AMOVSS;
		goto fld;
	case TDOUBLE:
		a = AMOVSD;
	fld:
		regalloc(&nod, f, t);
		if(tt != TDOUBLE && tt != TFLOAT){	/* TO DO: why is this here */
			prtree(f, "odd tree");
			nod.type = t64? types[TVLONG]: types[TINT];
		}
		gins(a, f, &nod);
		gmove(&nod, t);
		regfree(&nod);
		return;
	}

/*
 * store
 */
	if(t->op == ONAME || t->op == OINDREG ||
	   t->op == OIND || t->op == OINDEX)
	switch(tt) {
	case TCHAR:
	case TUCHAR:
		a = AMOVB;	goto st;
	case TSHORT:
	case TUSHORT:
		a = AMOVW;	goto st;
	case TINT:
	case TUINT:
	case TLONG:
	case TULONG:
		a = AMOVL;	goto st;
	case TVLONG:
	case TUVLONG:
	case TIND:
		a = AMOVQ;	goto st;

	st:
		if(f->op == OCONST) {
			gins(a, f, t);
			return;
		}
	fst:
		regalloc(&nod, t, f);
		gmove(f, &nod);
		gins(a, &nod, t);
		regfree(&nod);
		return;

	case TFLOAT:
		a = AMOVSS;
		goto fst;
	case TDOUBLE:
		a = AMOVSD;
		goto fst;
	}

/*
 * convert
 */
	switch(CASE(ft,tt)) {
	default:
/*
 * integer to integer
 ********
		a = AGOK;	break;

	case CASE(	TCHAR,	TCHAR):
	case CASE(	TUCHAR,	TCHAR):
	case CASE(	TSHORT,	TCHAR):
	case CASE(	TUSHORT,TCHAR):
	case CASE(	TINT,	TCHAR):
	case CASE(	TUINT,	TCHAR):
	case CASE(	TLONG,	TCHAR):
	case CASE(	TULONG,	TCHAR):
	case CASE(	TIND,	TCHAR):

	case CASE(	TCHAR,	TUCHAR):
	case CASE(	TUCHAR,	TUCHAR):
	case CASE(	TSHORT,	TUCHAR):
	case CASE(	TUSHORT,TUCHAR):
	case CASE(	TINT,	TUCHAR):
	case CASE(	TUINT,	TUCHAR):
	case CASE(	TLONG,	TUCHAR):
	case CASE(	TULONG,	TUCHAR):
	case CASE(	TIND,	TUCHAR):

	case CASE(	TSHORT,	TSHORT):
	case CASE(	TUSHORT,TSHORT):
	case CASE(	TINT,	TSHORT):
	case CASE(	TUINT,	TSHORT):
	case CASE(	TLONG,	TSHORT):
	case CASE(	TULONG,	TSHORT):
	case CASE(	TIND,	TSHORT):

	case CASE(	TSHORT,	TUSHORT):
	case CASE(	TUSHORT,TUSHORT):
	case CASE(	TINT,	TUSHORT):
	case CASE(	TUINT,	TUSHORT):
	case CASE(	TLONG,	TUSHORT):
	case CASE(	TULONG,	TUSHORT):
	case CASE(	TIND,	TUSHORT):

	case CASE(	TINT,	TINT):
	case CASE(	TUINT,	TINT):
	case CASE(	TLONG,	TINT):
	case CASE(	TULONG,	TINT):
	case CASE(	TIND,	TINT):

	case CASE(	TINT,	TUINT):
	case CASE(	TUINT,	TUINT):
	case CASE(	TLONG,	TUINT):
	case CASE(	TULONG,	TUINT):
	case CASE(	TIND,	TUINT):

	case CASE(	TUINT,	TIND):
	case CASE(	TVLONG,	TUINT):
	case CASE(	TVLONG,	TULONG):
	case CASE(	TUVLONG, TUINT):
	case CASE(	TUVLONG, TULONG):
 *****/
		a = AMOVL;
		break;

	case CASE(	TVLONG,	TCHAR):
	case	CASE(	TVLONG,	TSHORT):
	case CASE(	TVLONG,	TINT):
	case CASE(	TVLONG,	TLONG):
	case CASE(	TUVLONG, TCHAR):
	case	CASE(	TUVLONG, TSHORT):
	case CASE(	TUVLONG, TINT):
	case CASE(	TUVLONG, TLONG):
	case CASE(	TINT,	TVLONG):
	case CASE(	TINT,	TUVLONG):
	case CASE(	TLONG,	TVLONG):
	case CASE(	TINT,	TIND):
	case CASE(	TLONG,	TIND):
		a = AMOVLQSX;
		if(f->op == OCONST) {
			f->vconst &= (uvlong)0xffffffffU;
			if(f->vconst & 0x80000000)
				f->vconst |= (vlong)0xffffffff << 32;
			a = AMOVQ;
		}
		break;

	case CASE(	TUINT,	TIND):
	case CASE(	TUINT,	TVLONG):
	case CASE(	TUINT,	TUVLONG):
	case CASE(	TULONG,	TVLONG):
	case CASE(	TULONG,	TUVLONG):
	case CASE(	TULONG,	TIND):
		a = AMOVL;	/* same effect as AMOVLQZX */
		if(f->op == OCONST) {
			f->vconst &= (uvlong)0xffffffffU;
			a = AMOVQ;
		}
		break;

	case CASE(	TIND,	TVLONG):
	case CASE(	TVLONG,	TVLONG):
	case CASE(	TUVLONG,	TVLONG):
	case CASE(	TVLONG,	TUVLONG):
	case CASE(	TUVLONG,	TUVLONG):
	case CASE(	TIND,	TUVLONG):
	case CASE(	TVLONG,	TIND):
	case CASE(	TUVLONG,	TIND):
	case CASE(	TIND,	TIND):
		a = AMOVQ;
		break;

	case CASE(	TSHORT,	TINT):
	case CASE(	TSHORT,	TUINT):
	case CASE(	TSHORT,	TLONG):
	case CASE(	TSHORT,	TULONG):
		a = AMOVWLSX;
		if(f->op == OCONST) {
			f->vconst &= 0xffff;
			if(f->vconst & 0x8000)
				f->vconst |= 0xffff0000;
			a = AMOVL;
		}
		break;

	case CASE(	TSHORT,	TVLONG):
	case CASE(	TSHORT,	TUVLONG):
	case CASE(	TSHORT,	TIND):
		a = AMOVWQSX;
		if(f->op == OCONST) {
			f->vconst &= 0xffff;
			if(f->vconst & 0x8000){
				f->vconst |= 0xffff0000;
				f->vconst |= (vlong)~0 << 32;
			}
			a = AMOVL;
		}
		break;

	case CASE(	TUSHORT,TINT):
	case CASE(	TUSHORT,TUINT):
	case CASE(	TUSHORT,TLONG):
	case CASE(	TUSHORT,TULONG):
		a = AMOVWLZX;
		if(f->op == OCONST) {
			f->vconst &= 0xffff;
			a = AMOVL;
		}
		break;

	case CASE(	TUSHORT,TVLONG):
	case CASE(	TUSHORT,TUVLONG):
	case CASE(	TUSHORT,TIND):
		a = AMOVWQZX;
		if(f->op == OCONST) {
			f->vconst &= 0xffff;
			a = AMOVL;	/* MOVL also zero-extends to 64 bits */
		}
		break;

	case CASE(	TCHAR,	TSHORT):
	case CASE(	TCHAR,	TUSHORT):
	case CASE(	TCHAR,	TINT):
	case CASE(	TCHAR,	TUINT):
	case CASE(	TCHAR,	TLONG):
	case CASE(	TCHAR,	TULONG):
		a = AMOVBLSX;
		if(f->op == OCONST) {
			f->vconst &= 0xff;
			if(f->vconst & 0x80)
				f->vconst |= 0xffffff00;
			a = AMOVL;
		}
		break;

	case CASE(	TCHAR,	TVLONG):
	case CASE(	TCHAR,	TUVLONG):
	case CASE(	TCHAR,	TIND):
		a = AMOVBQSX;
		if(f->op == OCONST) {
			f->vconst &= 0xff;
			if(f->vconst & 0x80){
				f->vconst |= 0xffffff00;
				f->vconst |= (vlong)~0 << 32;
			}
			a = AMOVQ;
		}
		break;

	case CASE(	TUCHAR,	TSHORT):
	case CASE(	TUCHAR,	TUSHORT):
	case CASE(	TUCHAR,	TINT):
	case CASE(	TUCHAR,	TUINT):
	case CASE(	TUCHAR,	TLONG):
	case CASE(	TUCHAR,	TULONG):
		a = AMOVBLZX;
		if(f->op == OCONST) {
			f->vconst &= 0xff;
			a = AMOVL;
		}
		break;

	case CASE(	TUCHAR,	TVLONG):
	case CASE(	TUCHAR,	TUVLONG):
	case CASE(	TUCHAR,	TIND):
		a = AMOVBQZX;
		if(f->op == OCONST) {
			f->vconst &= 0xff;
			a = AMOVL;	/* zero-extends to 64-bits */
		}
		break;

/*
 * float to fix
 */
	case CASE(	TFLOAT,	TCHAR):
	case CASE(	TFLOAT,	TUCHAR):
	case CASE(	TFLOAT,	TSHORT):
	case CASE(	TFLOAT,	TUSHORT):
	case CASE(	TFLOAT,	TINT):
	case CASE(	TFLOAT,	TUINT):
	case CASE(	TFLOAT,	TLONG):
	case CASE(	TFLOAT,	TULONG):
	case CASE(	TFLOAT,	TVLONG):
	case CASE(	TFLOAT,	TUVLONG):
	case CASE(	TFLOAT,	TIND):

	case CASE(	TDOUBLE,TCHAR):
	case CASE(	TDOUBLE,TUCHAR):
	case CASE(	TDOUBLE,TSHORT):
	case CASE(	TDOUBLE,TUSHORT):
	case CASE(	TDOUBLE,TINT):
	case CASE(	TDOUBLE,TUINT):
	case CASE(	TDOUBLE,TLONG):
	case CASE(	TDOUBLE,TULONG):
	case CASE(	TDOUBLE,TVLONG):
	case CASE(	TDOUBLE,TUVLONG):
	case CASE(	TDOUBLE,TIND):
		regalloc(&nod, t, Z);
		if(ewidth[tt] == SZ_VLONG || typeu[tt] && ewidth[tt] == SZ_INT){
			if(ft == TFLOAT)
				a = ACVTTSS2SQ;
			else
				a = ACVTTSD2SQ;
		}else{
			if(ft == TFLOAT)
				a = ACVTTSS2SL;
			else
				a = ACVTTSD2SL;
		}
		gins(a, f, &nod);
		gmove(&nod, t);
		regfree(&nod);
		return;

/*
 * uvlong to float
 */
	case CASE(	TUVLONG,	TDOUBLE):
	case CASE(	TUVLONG,	TFLOAT):
		a = ACVTSQ2SS;
		if(tt == TDOUBLE)
			a = ACVTSQ2SD;
		regalloc(&nod, f, f);
		gmove(f, &nod);
		regalloc(&nod1, t, t);
		gins(ACMPQ, &nod, nodconst(0));
		gins(AJLT, Z, Z);
		p1 = p;
		gins(a, &nod, &nod1);
		gins(AJMP, Z, Z);
		p2 = p;
		patch(p1, pc);
		regalloc(&nod2, f, Z);
		regalloc(&nod3, f, Z);
		gmove(&nod, &nod2);
		gins(ASHRQ, nodconst(1), &nod2);
		gmove(&nod, &nod3);
		gins(AANDL, nodconst(1), &nod3);
		gins(AORQ, &nod3, &nod2);
		gins(a, &nod2, &nod1);
		gins(tt == TDOUBLE? AADDSD: AADDSS, &nod1, &nod1);
		regfree(&nod2);
		regfree(&nod3);
		patch(p2, pc);
		regfree(&nod);
		regfree(&nod1);
		return;

	case CASE(	TULONG,	TDOUBLE):
	case CASE(	TUINT,	TDOUBLE):
	case CASE(	TULONG,	TFLOAT):
	case CASE(	TUINT,	TFLOAT):
		a = ACVTSQ2SS;
		if(tt == TDOUBLE)
			a = ACVTSQ2SD;
		regalloc(&nod, f, f);
		gins(AMOVLQZX, f, &nod);
		regalloc(&nod1, t, t);
		gins(a, &nod, &nod1);
		gmove(&nod1, t);
		regfree(&nod);
		regfree(&nod1);
		return;

/*
 * fix to float
 */
	case CASE(	TCHAR,	TFLOAT):
	case CASE(	TUCHAR,	TFLOAT):
	case CASE(	TSHORT,	TFLOAT):
	case CASE(	TUSHORT,TFLOAT):
	case CASE(	TINT,	TFLOAT):
	case CASE(	TLONG,	TFLOAT):
	case	CASE(	TVLONG,	TFLOAT):
	case CASE(	TIND,	TFLOAT):

	case CASE(	TCHAR,	TDOUBLE):
	case CASE(	TUCHAR,	TDOUBLE):
	case CASE(	TSHORT,	TDOUBLE):
	case CASE(	TUSHORT,TDOUBLE):
	case CASE(	TINT,	TDOUBLE):
	case CASE(	TLONG,	TDOUBLE):
	case CASE(	TVLONG,	TDOUBLE):
	case CASE(	TIND,	TDOUBLE):
		regalloc(&nod, t, t);
		if(ewidth[ft] == SZ_VLONG){
			if(tt == TFLOAT)
				a = ACVTSQ2SS;
			else
				a = ACVTSQ2SD;
		}else{
			if(tt == TFLOAT)
				a = ACVTSL2SS;
			else
				a = ACVTSL2SD;
		}
		gins(a, f, &nod);
		gmove(&nod, t);
		regfree(&nod);
		return;

/*
 * float to float
 */
	case CASE(	TFLOAT,	TFLOAT):
		a = AMOVSS;
		break;
	case CASE(	TDOUBLE,TFLOAT):
		a = ACVTSD2SS;
		break;
	case CASE(	TFLOAT,	TDOUBLE):
		a = ACVTSS2SD;
		break;
	case CASE(	TDOUBLE,TDOUBLE):
		a = AMOVSD;
		break;
	}
	if(a == AMOVQ || a == AMOVSD || a == AMOVSS || a == AMOVL && ewidth[ft] == ewidth[tt])	/* TO DO: check AMOVL */
	if(samaddr(f, t))
		return;
	gins(a, f, t);
}

void
doindex(Node *n)
{
	Node nod, nod1;
	int32 v;

if(debug['Y'])
prtree(n, "index");

if(n->left->complex >= FNX)
print("botch in doindex\n");

	regalloc(&nod, &qregnode, Z);
	v = constnode.vconst;
	cgen(n->right, &nod);
	idx.ptr = D_NONE;
	if(n->left->op == OCONST)
		idx.ptr = D_CONST;
	else if(n->left->op == OREGISTER)
		idx.ptr = n->left->reg;
	else if(n->left->op != OADDR) {
		reg[D_BP]++;	// cant be used as a base
		regalloc(&nod1, &qregnode, Z);
		cgen(n->left, &nod1);
		idx.ptr = nod1.reg;
		regfree(&nod1);
		reg[D_BP]--;
	}
	idx.reg = nod.reg;
	regfree(&nod);
	constnode.vconst = v;
}

void
gins(int a, Node *f, Node *t)
{

	if(f != Z && f->op == OINDEX)
		doindex(f);
	if(t != Z && t->op == OINDEX)
		doindex(t);
	nextpc();
	p->as = a;
	if(f != Z)
		naddr(f, &p->from);
	if(t != Z)
		naddr(t, &p->to);
	if(debug['g'])
		print("%P\n", p);
}

void
gopcode(int o, Type *ty, Node *f, Node *t)
{
	int a, et;

	et = TLONG;
	if(ty != T)
		et = ty->etype;
	if(debug['M']) {
		if(f != Z && f->type != T)
			print("gop: %O %O[%s],", o, f->op, tnames[et]);
		else
			print("gop: %O Z,", o);
		if(t != Z && t->type != T)
			print("%O[%s]\n", t->op, tnames[t->type->etype]);
		else
			print("Z\n");
	}
	a = AGOK;
	switch(o) {
	case OCOM:
		a = ANOTL;
		if(et == TCHAR || et == TUCHAR)
			a = ANOTB;
		if(et == TSHORT || et == TUSHORT)
			a = ANOTW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = ANOTQ;
		break;

	case ONEG:
		a = ANEGL;
		if(et == TCHAR || et == TUCHAR)
			a = ANEGB;
		if(et == TSHORT || et == TUSHORT)
			a = ANEGW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = ANEGQ;
		break;

	case OADDR:
		a = ALEAQ;
		break;

	case OASADD:
	case OADD:
		a = AADDL;
		if(et == TCHAR || et == TUCHAR)
			a = AADDB;
		if(et == TSHORT || et == TUSHORT)
			a = AADDW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = AADDQ;
		if(et == TFLOAT)
			a = AADDSS;
		if(et == TDOUBLE)
			a = AADDSD;
		break;

	case OASSUB:
	case OSUB:
		a = ASUBL;
		if(et == TCHAR || et == TUCHAR)
			a = ASUBB;
		if(et == TSHORT || et == TUSHORT)
			a = ASUBW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = ASUBQ;
		if(et == TFLOAT)
			a = ASUBSS;
		if(et == TDOUBLE)
			a = ASUBSD;
		break;

	case OASOR:
	case OOR:
		a = AORL;
		if(et == TCHAR || et == TUCHAR)
			a = AORB;
		if(et == TSHORT || et == TUSHORT)
			a = AORW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = AORQ;
		break;

	case OASAND:
	case OAND:
		a = AANDL;
		if(et == TCHAR || et == TUCHAR)
			a = AANDB;
		if(et == TSHORT || et == TUSHORT)
			a = AANDW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = AANDQ;
		break;

	case OASXOR:
	case OXOR:
		a = AXORL;
		if(et == TCHAR || et == TUCHAR)
			a = AXORB;
		if(et == TSHORT || et == TUSHORT)
			a = AXORW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = AXORQ;
		break;

	case OASLSHR:
	case OLSHR:
		a = ASHRL;
		if(et == TCHAR || et == TUCHAR)
			a = ASHRB;
		if(et == TSHORT || et == TUSHORT)
			a = ASHRW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = ASHRQ;
		break;

	case OASASHR:
	case OASHR:
		a = ASARL;
		if(et == TCHAR || et == TUCHAR)
			a = ASARB;
		if(et == TSHORT || et == TUSHORT)
			a = ASARW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = ASARQ;
		break;

	case OASASHL:
	case OASHL:
		a = ASALL;
		if(et == TCHAR || et == TUCHAR)
			a = ASALB;
		if(et == TSHORT || et == TUSHORT)
			a = ASALW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = ASALQ;
		break;

	case OFUNC:
		a = ACALL;
		break;

	case OASMUL:
	case OMUL:
		if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
			t = Z;
		a = AIMULL;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = AIMULQ;
		if(et == TFLOAT)
			a = AMULSS;
		if(et == TDOUBLE)
			a = AMULSD;
		break;

	case OASMOD:
	case OMOD:
	case OASDIV:
	case ODIV:
		a = AIDIVL;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = AIDIVQ;
		if(et == TFLOAT)
			a = ADIVSS;
		if(et == TDOUBLE)
			a = ADIVSD;
		break;

	case OASLMUL:
	case OLMUL:
		a = AMULL;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = AMULQ;
		break;

	case OASLMOD:
	case OLMOD:
	case OASLDIV:
	case OLDIV:
		a = ADIVL;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = ADIVQ;
		break;

	case OEQ:
	case ONE:
	case OLT:
	case OLE:
	case OGE:
	case OGT:
	case OLO:
	case OLS:
	case OHS:
	case OHI:
		a = ACMPL;
		if(et == TCHAR || et == TUCHAR)
			a = ACMPB;
		if(et == TSHORT || et == TUSHORT)
			a = ACMPW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = ACMPQ;
		if(et == TFLOAT)
			a = AUCOMISS;
		if(et == TDOUBLE)
			a = AUCOMISD;
		gins(a, f, t);
		switch(o) {
		case OEQ:	a = AJEQ; break;
		case ONE:	a = AJNE; break;
		case OLT:	a = AJLT; break;
		case OLE:	a = AJLE; break;
		case OGE:	a = AJGE; break;
		case OGT:	a = AJGT; break;
		case OLO:	a = AJCS; break;
		case OLS:	a = AJLS; break;
		case OHS:	a = AJCC; break;
		case OHI:	a = AJHI; break;
		}
		gins(a, Z, Z);
		return;
	}
	if(a == AGOK)
		diag(Z, "bad in gopcode %O", o);
	gins(a, f, t);
}

int
samaddr(Node *f, Node *t)
{
	return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg;
}

void
gbranch(int o)
{
	int a;

	a = AGOK;
	switch(o) {
	case ORETURN:
		a = ARET;
		break;
	case OGOTO:
		a = AJMP;
		break;
	}
	nextpc();
	if(a == AGOK) {
		diag(Z, "bad in gbranch %O",  o);
		nextpc();
	}
	p->as = a;
}

void
patch(Prog *op, int32 pc)
{

	op->to.offset = pc;
	op->to.type = D_BRANCH;
}

void
gpseudo(int a, Sym *s, Node *n)
{

	nextpc();
	p->as = a;
	p->from.type = D_EXTERN;
	p->from.sym = s;
	p->from.scale = textflag;
	textflag = 0;
	
	if(s->class == CSTATIC)
		p->from.type = D_STATIC;
	naddr(n, &p->to);
	if(a == ADATA || a == AGLOBL)
		pc--;
}

int
sconst(Node *n)
{
	int32 v;

	if(n->op == OCONST && !typefd[n->type->etype]) {
		v = n->vconst;
		if(v >= -32766L && v < 32766L)
			return 1;
	}
	return 0;
}

int32
exreg(Type *t)
{
	int32 o;

	if(typechlpv[t->etype]) {
		if(exregoffset <= REGEXT-4)
			return 0;
		o = exregoffset;
		exregoffset--;
		return o;
	}
	return 0;
}

schar	ewidth[NTYPE] =
{
	-1,		/*[TXXX]*/	
	SZ_CHAR,	/*[TCHAR]*/	
	SZ_CHAR,	/*[TUCHAR]*/
	SZ_SHORT,	/*[TSHORT]*/
	SZ_SHORT,	/*[TUSHORT]*/
	SZ_INT,		/*[TINT]*/
	SZ_INT,		/*[TUINT]*/
	SZ_LONG,	/*[TLONG]*/
	SZ_LONG,	/*[TULONG]*/
	SZ_VLONG,	/*[TVLONG]*/
	SZ_VLONG,	/*[TUVLONG]*/
	SZ_FLOAT,	/*[TFLOAT]*/
	SZ_DOUBLE,	/*[TDOUBLE]*/
	SZ_IND,		/*[TIND]*/
	0,		/*[TFUNC]*/
	-1,		/*[TARRAY]*/
	0,		/*[TVOID]*/
	-1,		/*[TSTRUCT]*/
	-1,		/*[TUNION]*/
	SZ_INT,		/*[TENUM]*/
};
int32	ncast[NTYPE] =
{
	0,				/*[TXXX]*/
	BCHAR|BUCHAR,			/*[TCHAR]*/
	BCHAR|BUCHAR,			/*[TUCHAR]*/	
	BSHORT|BUSHORT,			/*[TSHORT]*/
	BSHORT|BUSHORT,			/*[TUSHORT]*/
	BINT|BUINT|BLONG|BULONG,	/*[TINT]*/		
	BINT|BUINT|BLONG|BULONG,	/*[TUINT]*/
	BINT|BUINT|BLONG|BULONG,	/*[TLONG]*/
	BINT|BUINT|BLONG|BULONG,	/*[TULONG]*/
	BVLONG|BUVLONG|BIND,			/*[TVLONG]*/
	BVLONG|BUVLONG|BIND,			/*[TUVLONG]*/
	BFLOAT,				/*[TFLOAT]*/
	BDOUBLE,			/*[TDOUBLE]*/
	BVLONG|BUVLONG|BIND,		/*[TIND]*/
	0,				/*[TFUNC]*/
	0,				/*[TARRAY]*/
	0,				/*[TVOID]*/
	BSTRUCT,			/*[TSTRUCT]*/
	BUNION,				/*[TUNION]*/
	0,				/*[TENUM]*/
};
