// Inferno utils/cc/scon.c
// http://code.google.com/p/inferno-os/source/browse/utils/cc/scon.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 <u.h>
#include "cc.h"

static Node*
acast(Type *t, Node *n)
{
	if(n->type->etype != t->etype || n->op == OBIT) {
		n = new1(OCAST, n, Z);
		if(nocast(n->left->type, t))
			*n = *n->left;
		n->type = t;
	}
	return n;
}


void
evconst(Node *n)
{
	Node *l, *r;
	int et, isf;
	vlong v;
	double d;

	if(n == Z || n->type == T)
		return;

	et = n->type->etype;
	isf = typefd[et];

	l = n->left;
	r = n->right;

	d = 0;
	v = 0;

	switch(n->op) {
	default:
		return;

	case ONEG:
		if(isf)
			d = -l->fconst;
		else
			v = -l->vconst;
		break;

	case OCOM:
		v = ~l->vconst;
		break;

	case OCAST:
		if(et == TVOID)
			return;
		et = l->type->etype;
		if(isf) {
			if(typefd[et])
				d = l->fconst;
			else
				d = l->vconst;
		} else {
			if(typefd[et])
				v = l->fconst;
			else
				v = convvtox(l->vconst, n->type->etype);
		}
		break;

	case OCONST:
		break;

	case OADD:
		if(isf)
			d = l->fconst + r->fconst;
		else {
			v = l->vconst + r->vconst;
		}
		break;

	case OSUB:
		if(isf)
			d = l->fconst - r->fconst;
		else
			v = l->vconst - r->vconst;
		break;

	case OMUL:
		if(isf)
			d = l->fconst * r->fconst;
		else {
			v = l->vconst * r->vconst;
		}
		break;

	case OLMUL:
		v = (uvlong)l->vconst * (uvlong)r->vconst;
		break;


	case ODIV:
		if(vconst(r) == 0) {
			warn(n, "divide by zero");
			return;
		}
		if(isf)
			d = l->fconst / r->fconst;
		else
			v = l->vconst / r->vconst;
		break;

	case OLDIV:
		if(vconst(r) == 0) {
			warn(n, "divide by zero");
			return;
		}
		v = (uvlong)l->vconst / (uvlong)r->vconst;
		break;

	case OMOD:
		if(vconst(r) == 0) {
			warn(n, "modulo by zero");
			return;
		}
		v = l->vconst % r->vconst;
		break;

	case OLMOD:
		if(vconst(r) == 0) {
			warn(n, "modulo by zero");
			return;
		}
		v = (uvlong)l->vconst % (uvlong)r->vconst;
		break;

	case OAND:
		v = l->vconst & r->vconst;
		break;

	case OOR:
		v = l->vconst | r->vconst;
		break;

	case OXOR:
		v = l->vconst ^ r->vconst;
		break;

	case OLSHR:
		if(l->type->width != sizeof(uvlong))
			v = ((uvlong)l->vconst & 0xffffffffULL) >> r->vconst;
		else
			v = (uvlong)l->vconst >> r->vconst;
		break;

	case OASHR:
		v = l->vconst >> r->vconst;
		break;

	case OASHL:
		v = l->vconst << r->vconst;
		break;

	case OLO:
		v = (uvlong)l->vconst < (uvlong)r->vconst;
		break;

	case OLT:
		if(typefd[l->type->etype])
			v = l->fconst < r->fconst;
		else
			v = l->vconst < r->vconst;
		break;

	case OHI:
		v = (uvlong)l->vconst > (uvlong)r->vconst;
		break;

	case OGT:
		if(typefd[l->type->etype])
			v = l->fconst > r->fconst;
		else
			v = l->vconst > r->vconst;
		break;

	case OLS:
		v = (uvlong)l->vconst <= (uvlong)r->vconst;
		break;

	case OLE:
		if(typefd[l->type->etype])
			v = l->fconst <= r->fconst;
		else
			v = l->vconst <= r->vconst;
		break;

	case OHS:
		v = (uvlong)l->vconst >= (uvlong)r->vconst;
		break;

	case OGE:
		if(typefd[l->type->etype])
			v = l->fconst >= r->fconst;
		else
			v = l->vconst >= r->vconst;
		break;

	case OEQ:
		if(typefd[l->type->etype])
			v = l->fconst == r->fconst;
		else
			v = l->vconst == r->vconst;
		break;

	case ONE:
		if(typefd[l->type->etype])
			v = l->fconst != r->fconst;
		else
			v = l->vconst != r->vconst;
		break;

	case ONOT:
		if(typefd[l->type->etype])
			v = !l->fconst;
		else
			v = !l->vconst;
		break;

	case OANDAND:
		if(typefd[l->type->etype])
			v = l->fconst && r->fconst;
		else
			v = l->vconst && r->vconst;
		break;

	case OOROR:
		if(typefd[l->type->etype])
			v = l->fconst || r->fconst;
		else
			v = l->vconst || r->vconst;
		break;
	}
	if(isf) {
		n->fconst = d;
	} else {
		n->vconst = convvtox(v, n->type->etype);
	}
	n->oldop = n->op;
	n->op = OCONST;
}

void
acom(Node *n)
{
	Type *t;
	Node *l, *r;
	int i;

	switch(n->op)
	{

	case ONAME:
	case OCONST:
	case OSTRING:
	case OINDREG:
	case OREGISTER:
		return;

	case ONEG:
		l = n->left;
		if(addo(n) && addo(l))
			break;
		acom(l);
		return;

	case OADD:
	case OSUB:
	case OMUL:
		l = n->left;
		r = n->right;
		if(addo(n)) {
			if(addo(r))
				break;
			if(addo(l))
				break;
		}
		acom(l);
		acom(r);
		return;

	default:
		l = n->left;
		r = n->right;
		if(l != Z)
			acom(l);
		if(r != Z)
			acom(r);
		return;
	}

	/* bust terms out */
	t = n->type;
	term[0].mult = 0;
	term[0].node = Z;
	nterm = 1;
	acom1(1, n);
	if(debug['m'])
	for(i=0; i<nterm; i++) {
		print("%d %3lld ", i, term[i].mult);
		prtree1(term[i].node, 1, 0);
	}
	if(nterm < NTERM)
		acom2(n, t);
	n->type = t;
}

int
acomcmp1(const void *a1, const void *a2)
{
	vlong c1, c2;
	Term *t1, *t2;

	t1 = (Term*)a1;
	t2 = (Term*)a2;
	c1 = t1->mult;
	if(c1 < 0)
		c1 = -c1;
	c2 = t2->mult;
	if(c2 < 0)
		c2 = -c2;
	if(c1 > c2)
		return 1;
	if(c1 < c2)
		return -1;
	c1 = 1;
	if(t1->mult < 0)
		c1 = 0;
	c2 = 1;
	if(t2->mult < 0)
		c2 = 0;
	if(c2 -= c1)
		return c2;
	if(t2 > t1)
		return 1;
	return -1;
}

int
acomcmp2(const void *a1, const void *a2)
{
	vlong c1, c2;
	Term *t1, *t2;

	t1 = (Term*)a1;
	t2 = (Term*)a2;
	c1 = t1->mult;
	c2 = t2->mult;
	if(c1 > c2)
		return 1;
	if(c1 < c2)
		return -1;
	if(t2 > t1)
		return 1;
	return -1;
}

void
acom2(Node *n, Type *t)
{
	Node *l, *r;
	Term trm[NTERM];
	int et, nt, i, j;
	vlong c1, c2;

	/*
	 * copy into automatic
	 */
	c2 = 0;
	nt = nterm;
	for(i=0; i<nt; i++)
		trm[i] = term[i];
	/*
	 * recur on subtrees
	 */
	j = 0;
	for(i=1; i<nt; i++) {
		c1 = trm[i].mult;
		if(c1 == 0)
			continue;
		l = trm[i].node;
		if(l != Z) {
			j = 1;
			acom(l);
		}
	}
	c1 = trm[0].mult;
	if(j == 0) {
		n->oldop = n->op;
		n->op = OCONST;
		n->vconst = c1;
		return;
	}
	et = t->etype;

	/*
	 * prepare constant term,
	 * combine it with an addressing term
	 */
	if(c1 != 0) {
		l = new1(OCONST, Z, Z);
		l->type = t;
		l->vconst = c1;
		trm[0].mult = 1;
		for(i=1; i<nt; i++) {
			if(trm[i].mult != 1)
				continue;
			r = trm[i].node;
			if(r->op != OADDR)
				continue;
			r->type = t;
			l = new1(OADD, r, l);
			l->type = t;
			trm[i].mult = 0;
			break;
		}
		trm[0].node = l;
	}
	/*
	 * look for factorable terms
	 * c1*i + c1*c2*j -> c1*(i + c2*j)
	 */
	qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp1);
	for(i=nt-1; i>=0; i--) {
		c1 = trm[i].mult;
		if(c1 < 0)
			c1 = -c1;
		if(c1 <= 1)
			continue;
		for(j=i+1; j<nt; j++) {
			c2 = trm[j].mult;
			if(c2 < 0)
				c2 = -c2;
			if(c2 <= 1)
				continue;
			if(c2 % c1)
				continue;
			r = trm[j].node;
			if(r->type->etype != et)
				r = acast(t, r);
			c2 = trm[j].mult/trm[i].mult;
			if(c2 != 1 && c2 != -1) {
				r = new1(OMUL, r, new(OCONST, Z, Z));
				r->type = t;
				r->right->type = t;
				r->right->vconst = c2;
			}
			l = trm[i].node;
			if(l->type->etype != et)
				l = acast(t, l);
			r = new1(OADD, l, r);
			r->type = t;
			if(c2 == -1)
				r->op = OSUB;
			trm[i].node = r;
			trm[j].mult = 0;
		}
	}
	if(debug['m']) {
		print("\n");
		for(i=0; i<nt; i++) {
			print("%d %3lld ", i, trm[i].mult);
			prtree1(trm[i].node, 1, 0);
		}
	}

	/*
	 * put it all back together
	 */
	qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp2);
	l = Z;
	for(i=nt-1; i>=0; i--) {
		c1 = trm[i].mult;
		if(c1 == 0)
			continue;
		r = trm[i].node;
		if(r->type->etype != et || r->op == OBIT)
			r = acast(t, r);
		if(c1 != 1 && c1 != -1) {
			r = new1(OMUL, r, new(OCONST, Z, Z));
			r->type = t;
			r->right->type = t;
			if(c1 < 0) {
				r->right->vconst = -c1;
				c1 = -1;
			} else {
				r->right->vconst = c1;
				c1 = 1;
			}
		}
		if(l == Z) {
			l = r;
			c2 = c1;
			continue;
		}
		if(c1 < 0)
			if(c2 < 0)
				l = new1(OADD, l, r);
			else
				l = new1(OSUB, l, r);
		else
			if(c2 < 0) {
				l = new1(OSUB, r, l);
				c2 = 1;
			} else
				l = new1(OADD, l, r);
		l->type = t;
	}
	if(c2 < 0) {
		r = new1(OCONST, 0, 0);
		r->vconst = 0;
		r->type = t;
		l = new1(OSUB, r, l);
		l->type = t;
	}
	*n = *l;
}

void
acom1(vlong v, Node *n)
{
	Node *l, *r;

	if(v == 0 || nterm >= NTERM)
		return;
	if(!addo(n)) {
		if(n->op == OCONST)
		if(!typefd[n->type->etype]) {
			term[0].mult += v*n->vconst;
			return;
		}
		term[nterm].mult = v;
		term[nterm].node = n;
		nterm++;
		return;
	}
	switch(n->op) {

	case OCAST:
		acom1(v, n->left);
		break;

	case ONEG:
		acom1(-v, n->left);
		break;

	case OADD:
		acom1(v, n->left);
		acom1(v, n->right);
		break;

	case OSUB:
		acom1(v, n->left);
		acom1(-v, n->right);
		break;

	case OMUL:
		l = n->left;
		r = n->right;
		if(l->op == OCONST)
		if(!typefd[n->type->etype]) {
			acom1(v*l->vconst, r);
			break;
		}
		if(r->op == OCONST)
		if(!typefd[n->type->etype]) {
			acom1(v*r->vconst, l);
			break;
		}
		break;

	default:
		diag(n, "not addo");
	}
}

int
addo(Node *n)
{

	if(n != Z)
	if(!typefd[n->type->etype])
	if(!typev[n->type->etype] || ewidth[TVLONG] == ewidth[TIND])
	switch(n->op) {

	case OCAST:
		if(nilcast(n->left->type, n->type))
			return 1;
		break;

	case ONEG:
	case OADD:
	case OSUB:
		return 1;

	case OMUL:
		if(n->left->op == OCONST)
			return 1;
		if(n->right->op == OCONST)
			return 1;
	}
	return 0;
}
