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

static	void	subnode(Node *nr, Node *ni, Node *nc);
static	void	minus(Node *nl, Node *res);
	void	complexminus(Node*, Node*);
	void	complexadd(int op, Node*, Node*, Node*);
	void	complexmul(Node*, Node*, Node*);

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

/*
 * generate:
 *	res = n;
 * simplifies and calls gmove.
 */
void
complexmove(Node *f, Node *t)
{
	int ft, tt;
	Node n1, n2, n3, n4;

	if(debug['g']) {
		dump("\ncomplexmove-f", f);
		dump("complexmove-t", t);
	}

	if(!t->addable)
		fatal("complexmove: to not addable");

	ft = simsimtype(f->type);
	tt = simsimtype(t->type);
	switch(CASE(ft,tt)) {

	default:
		fatal("complexmove: unknown conversion: %T -> %T\n",
			f->type, t->type);

	case CASE(TCOMPLEX64,TCOMPLEX64):
	case CASE(TCOMPLEX64,TCOMPLEX128):
	case CASE(TCOMPLEX128,TCOMPLEX64):
	case CASE(TCOMPLEX128,TCOMPLEX128):
		// complex to complex move/convert
		// make from addable
		if(!f->addable) {
			tempname(&n1, f->type);
			complexmove(f, &n1);
			f = &n1;
		}

		subnode(&n1, &n2, f);
		subnode(&n3, &n4, t);

		cgen(&n1, &n3);
		cgen(&n2, &n4);
		break;
	}
}

int
complexop(Node *n, Node *res)
{
	if(n != N && n->type != T)
	if(iscomplex[n->type->etype]) {
		goto maybe;
	}
	if(res != N && res->type != T)
	if(iscomplex[res->type->etype]) {
		goto maybe;
	}

	if(n->op == OREAL || n->op == OIMAG)
		goto yes;

	goto no;

maybe:
	switch(n->op) {
	case OCONV:	// implemented ops
	case OADD:
	case OSUB:
	case OMUL:
	case OMINUS:
	case OCMPLX:
	case OREAL:
	case OIMAG:
		goto yes;

	case ODOT:
	case ODOTPTR:
	case OINDEX:
	case OIND:
	case ONAME:
		goto yes;
	}

no:
//dump("\ncomplex-no", n);
	return 0;
yes:
//dump("\ncomplex-yes", n);
	return 1;
}

void
complexgen(Node *n, Node *res)
{
	Node *nl, *nr;
	Node tnl, tnr;
	Node n1, n2, tmp;
	int tl, tr;

	if(debug['g']) {
		dump("\ncomplexgen-n", n);
		dump("complexgen-res", res);
	}

	// pick off float/complex opcodes
	switch(n->op) {
	case OCMPLX:
		subnode(&n1, &n2, res);
		tempname(&tmp, n1.type);
		cgen(n->left, &tmp);
		cgen(n->right, &n2);
		cgen(&tmp, &n1);
		return;

	case OREAL:
		subnode(&n1, &n2, n->left);
		cgen(&n1, res);
		return;

	case OIMAG:
		subnode(&n1, &n2, n->left);
		cgen(&n2, res);
		return;
	}

	// perform conversion from n to res
	tl = simsimtype(res->type);
	tl = cplxsubtype(tl);
	tr = simsimtype(n->type);
	tr = cplxsubtype(tr);
	if(tl != tr) {
		if(!n->addable) {
			tempname(&n1, n->type);
			complexmove(n, &n1);
			n = &n1;
		}
		complexmove(n, res);
		return;
	}

	if(!res->addable) {
		igen(res, &n1, N);
		cgen(n, &n1);
		regfree(&n1);
		return;
	}
	if(n->addable) {
		complexmove(n, res);
		return;
	}

	switch(n->op) {
	default:
		dump("complexgen: unknown op", n);
		fatal("complexgen: unknown op %O", n->op);

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

	case OCONV:
	case OADD:
	case OSUB:
	case OMUL:
	case OMINUS:
	case OCMPLX:
	case OREAL:
	case OIMAG:
		break;
	}

	nl = n->left;
	if(nl == N)
		return;
	nr = n->right;

	// make both sides addable in ullman order
	if(nr != N) {
		if(nl->ullman > nr->ullman && !nl->addable) {
			tempname(&tnl, nl->type);
			cgen(nl, &tnl);
			nl = &tnl;
		}
		if(!nr->addable) {
			tempname(&tnr, nr->type);
			cgen(nr, &tnr);
			nr = &tnr;
		}
	}
	if(!nl->addable) {
		tempname(&tnl, nl->type);
		cgen(nl, &tnl);
		nl = &tnl;
	}

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

	case OCONV:
		complexmove(nl, res);
		break;

	case OMINUS:
		complexminus(nl, res);
		break;

	case OADD:
	case OSUB:
		complexadd(n->op, nl, nr, res);
		break;

	case OMUL:
		complexmul(nl, nr, res);
		break;
	// ODIV call a runtime function
	}
}

void
complexbool(int op, Node *nl, Node *nr, int true, Prog *to)
{
	Node tnl, tnr;
	Node n1, n2, n3, n4;
	Node na, nb, nc;

	// make both sides addable in ullman order
	if(nr != N) {
		if(nl->ullman > nr->ullman && !nl->addable) {
			tempname(&tnl, nl->type);
			cgen(nl, &tnl);
			nl = &tnl;
		}
		if(!nr->addable) {
			tempname(&tnr, nr->type);
			cgen(nr, &tnr);
			nr = &tnr;
		}
	}
	if(!nl->addable) {
		tempname(&tnl, nl->type);
		cgen(nl, &tnl);
		nl = &tnl;
	}

	// build tree
	// real(l) == real(r) && imag(l) == imag(r)

	subnode(&n1, &n2, nl);
	subnode(&n3, &n4, nr);

	memset(&na, 0, sizeof(na));
	na.op = OANDAND;
	na.left = &nb;
	na.right = &nc;
	na.type = types[TBOOL];

	memset(&nb, 0, sizeof(na));
	nb.op = OEQ;
	nb.left = &n1;
	nb.right = &n3;
	nb.type = types[TBOOL];

	memset(&nc, 0, sizeof(na));
	nc.op = OEQ;
	nc.left = &n2;
	nc.right = &n4;
	nc.type = types[TBOOL];

	if(op == ONE)
		true = !true;

	bgen(&na, true, to);
}

void
nodfconst(Node *n, Type *t, Mpflt* fval)
{
	memset(n, 0, sizeof(*n));
	n->op = OLITERAL;
	n->addable = 1;
	ullmancalc(n);
	n->val.u.fval = fval;
	n->val.ctype = CTFLT;
	n->type = t;

	if(!isfloat[t->etype])
		fatal("nodfconst: bad type %T", t);
}

// break addable nc-complex into nr-real and ni-imaginary
static void
subnode(Node *nr, Node *ni, Node *nc)
{
	int tc;
	Type *t;

	if(!nc->addable)
		fatal("subnode not addable");

	tc = simsimtype(nc->type);
	tc = cplxsubtype(tc);
	t = types[tc];

	if(nc->op == OLITERAL) {
		nodfconst(nr, t, &nc->val.u.cval->real);
		nodfconst(ni, t, &nc->val.u.cval->imag);
		return;
	}

	*nr = *nc;
	nr->type = t;

	*ni = *nc;
	ni->type = t;
	ni->xoffset += t->width;
}

// generate code res = -nl
static void
minus(Node *nl, Node *res)
{
	Node ra;

	memset(&ra, 0, sizeof(ra));
	ra.op = OMINUS;
	ra.left = nl;
	ra.type = nl->type;
	cgen(&ra, res);
}

// build and execute tree
//	real(res) = -real(nl)
//	imag(res) = -imag(nl)
void
complexminus(Node *nl, Node *res)
{
	Node n1, n2, n5, n6;

	subnode(&n1, &n2, nl);
	subnode(&n5, &n6, res);

	minus(&n1, &n5);
	minus(&n2, &n6);
}


// build and execute tree
//	real(res) = real(nl) op real(nr)
//	imag(res) = imag(nl) op imag(nr)
void
complexadd(int op, Node *nl, Node *nr, Node *res)
{
	Node n1, n2, n3, n4, n5, n6;
	Node ra;

	subnode(&n1, &n2, nl);
	subnode(&n3, &n4, nr);
	subnode(&n5, &n6, res);

	memset(&ra, 0, sizeof(ra));
	ra.op = op;
	ra.left = &n1;
	ra.right = &n3;
	ra.type = n1.type;
	cgen(&ra, &n5);

	memset(&ra, 0, sizeof(ra));
	ra.op = op;
	ra.left = &n2;
	ra.right = &n4;
	ra.type = n2.type;
	cgen(&ra, &n6);
}

// build and execute tree
//	tmp       = real(nl)*real(nr) - imag(nl)*imag(nr)
//	imag(res) = real(nl)*imag(nr) + imag(nl)*real(nr)
//	real(res) = tmp
void
complexmul(Node *nl, Node *nr, Node *res)
{
	Node n1, n2, n3, n4, n5, n6;
	Node rm1, rm2, ra, tmp;

	subnode(&n1, &n2, nl);
	subnode(&n3, &n4, nr);
	subnode(&n5, &n6, res);
	tempname(&tmp, n5.type);

	// real part -> tmp
	memset(&rm1, 0, sizeof(ra));
	rm1.op = OMUL;
	rm1.left = &n1;
	rm1.right = &n3;
	rm1.type = n1.type;

	memset(&rm2, 0, sizeof(ra));
	rm2.op = OMUL;
	rm2.left = &n2;
	rm2.right = &n4;
	rm2.type = n2.type;

	memset(&ra, 0, sizeof(ra));
	ra.op = OSUB;
	ra.left = &rm1;
	ra.right = &rm2;
	ra.type = rm1.type;
	cgen(&ra, &tmp);

	// imag part
	memset(&rm1, 0, sizeof(ra));
	rm1.op = OMUL;
	rm1.left = &n1;
	rm1.right = &n4;
	rm1.type = n1.type;

	memset(&rm2, 0, sizeof(ra));
	rm2.op = OMUL;
	rm2.left = &n2;
	rm2.right = &n3;
	rm2.type = n2.type;

	memset(&ra, 0, sizeof(ra));
	ra.op = OADD;
	ra.left = &rm1;
	ra.right = &rm2;
	ra.type = rm1.type;
	cgen(&ra, &n6);

	// tmp ->real part
	cgen(&tmp, &n5);
}
