// 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"

int thechar = '6';
char *thestring = "amd64";

LinkArch	*thelinkarch = &linkamd64;

void
linkarchinit(void)
{
	if(strcmp(getgoarch(), "amd64p32") == 0)
		thelinkarch = &linkamd64p32;
}

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

	dodefine("_64BITREG");
	if(ewidth[TIND] == 8)
		dodefine("_64BIT");
	listinit();
	nstring = 0;
	mnstring = 0;
	nrathole = 0;
	pc = 0;
	breakpc = -1;
	continpc = -1;
	cases = C;
	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;
	}
	if(nacl) {
		reg[D_BP] = 1;
		reg[D_R15] = 1;
	}
}

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

	reg[D_SP]--;
	if(nacl) {
		reg[D_BP]--;
		reg[D_R15]--;
	}
	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)
{
	Plist *pl;

	p = alloc(sizeof(*p));
	*p = zprog;
	p->lineno = nearln;
	p->pc = pc;
	pc++;
	if(lastp == nil) {
		pl = linknewplist(ctxt);
		pl->firstpc = p;
	} else
		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 >= 0 && 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 >= nelem(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, nil);
	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) {
		fatal(n, "regaalloc1 and REGARG<0");
		return;
	}
	nodreg(n, nn, REGARG);
	reg[(uchar)REGARG]++;
	curarg = align(curarg, nn->type, Aarg1, nil);
	curarg = align(curarg, nn->type, Aarg2, nil);
	maxargsafe = maxround(maxargsafe, cursafe+curarg);
}

void
regaalloc(Node *n, Node *nn)
{
	curarg = align(curarg, nn->type, Aarg1, nil);
	*n = *nn;
	n->op = OINDREG;
	n->reg = REGSP;
	n->xoffset = curarg;
	n->complex = 0;
	n->addable = 20;
	curarg = align(curarg, nn->type, Aarg2, nil);
	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, Addr *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 = nil;
		break;

	case OEXREG:
		a->type = D_INDIR + D_TLS;
		a->offset = n->reg - 1;
		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 = nil;
		a->offset = n->xoffset;
		break;

	case ONAME:
		a->etype = n->etype;
		a->type = D_STATIC;
		a->sym = linksym(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->u.dval = n->fconst;
			break;
		}
		a->sym = nil;
		a->type = D_CONST;
		if(typev[n->type->etype] || (n->type->etype == TIND && ewidth[TIND] == 8))
			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;
	if(ewidth[TIND] == 4) {
		if(ft == TIND)
			ft = TUINT;
		if(tt == TIND)
			tt = TUINT;
	}
	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;
		if(ewidth[TIND] == 4)
			a = AMOVL;

	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(	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(	TSHORT,	TSHORT):
	case CASE(	TUSHORT,TSHORT):
	case CASE(	TINT,	TSHORT):
	case CASE(	TUINT,	TSHORT):
	case CASE(	TLONG,	TSHORT):
	case CASE(	TULONG,	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(	TINT,	TINT):
	case CASE(	TUINT,	TINT):
	case CASE(	TLONG,	TINT):
	case CASE(	TULONG,	TINT):

	case CASE(	TINT,	TUINT):
	case CASE(	TUINT,	TUINT):
	case CASE(	TLONG,	TUINT):
	case CASE(	TULONG,	TUINT):
 *****/
		a = AMOVL;
		break;

	case CASE(	TINT,	TIND):
	case CASE(	TINT,	TVLONG):
	case CASE(	TINT,	TUVLONG):
	case CASE(	TLONG,	TIND):
	case CASE(	TLONG,	TVLONG):
	case CASE(	TLONG,	TUVLONG):
		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 = AMOVLQZX;
		if(f->op == OCONST) {
			f->vconst &= (uvlong)0xffffffffU;
			a = AMOVQ;
		}
		break;
	
	case CASE(	TIND,	TCHAR):
	case CASE(	TIND,	TUCHAR):
	case CASE(	TIND,	TSHORT):
	case CASE(	TIND,	TUSHORT):
	case CASE(	TIND,	TINT):
	case CASE(	TIND,	TUINT):
	case CASE(	TIND,	TLONG):
	case CASE(	TIND,	TULONG):
	case CASE(	TVLONG,	TCHAR):
	case CASE(	TVLONG,	TUCHAR):
	case CASE(	TVLONG,	TSHORT):
	case CASE(	TVLONG,	TUSHORT):
	case CASE(	TVLONG,	TINT):
	case CASE(	TVLONG,	TUINT):
	case CASE(	TVLONG,	TLONG):
	case CASE(	TVLONG,	TULONG):
	case CASE(	TUVLONG,	TCHAR):
	case CASE(	TUVLONG,	TUCHAR):
	case CASE(	TUVLONG,	TSHORT):
	case CASE(	TUVLONG,	TUSHORT):
	case CASE(	TUVLONG,	TINT):
	case CASE(	TUVLONG,	TUINT):
	case CASE(	TUVLONG,	TLONG):
	case CASE(	TUVLONG,	TULONG):
		a = AMOVQL;
		if(f->op == OCONST) {
			f->vconst &= (int)0xffffffffU;
			a = AMOVL;
		}
		break;	

	case CASE(	TIND,	TIND):
	case CASE(	TIND,	TVLONG):
	case CASE(	TIND,	TUVLONG):
	case CASE(	TVLONG,	TIND):
	case CASE(	TVLONG,	TVLONG):
	case CASE(	TVLONG,	TUVLONG):
	case CASE(	TUVLONG,	TIND):
	case CASE(	TUVLONG,	TVLONG):
	case CASE(	TUVLONG,	TUVLONG):
		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]++;	// can't 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(et == TIND && ewidth[TIND] == 4)
		et = TUINT;
	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 OROTL:
		a = AROLL;
		if(et == TCHAR || et == TUCHAR)
			a = AROLB;
		if(et == TSHORT || et == TUSHORT)
			a = AROLW;
		if(et == TVLONG || et == TUVLONG || et == TIND)
			a = AROLQ;
		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;
	op->to.u.branch = nil;
	op->pcond = nil;
}

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

	nextpc();
	p->as = a;
	p->from.type = D_EXTERN;
	p->from.sym = linksym(s);

	switch(a) {
	case ATEXT:
		p->from.scale = textflag;
		textflag = 0;
		break;
	case AGLOBL:
		p->from.scale = s->dataflag;
		break;
	}

	if(s->class == CSTATIC)
		p->from.type = D_STATIC;
	naddr(n, &p->to);
	if(a == ADATA || a == AGLOBL)
		pc--;
}

void
gpcdata(int index, int value)
{
	Node n1;
	
	n1 = *nodconst(index);
	gins(APCDATA, &n1, nodconst(value));
}

void
gprefetch(Node *n)
{
	Node n1;
	
	regalloc(&n1, n, Z);
	gmove(n, &n1);
	n1.op = OINDREG;
	gins(APREFETCHNTA, &n1, Z);
	regfree(&n1);
}

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 >= 64)
			return 0;
		o = exregoffset;
		exregoffset += ewidth[TIND];
		return o+1;	// +1 to avoid 0 == failure; naddr's case OEXREG will subtract 1.
	}
	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]*/
};
