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

/*
 * attempt to generate 64-bit
 *	res = n
 * return 1 on success, 0 if op not handled.
 */
void
cgen64(Node *n, Node *res)
{
	Node t1, t2, ax, dx, cx, ex, fx, *l, *r;
	Node lo1, lo2, hi1, hi2;
	Prog *p1, *p2;
	uint64 v;
	uint32 lv, hv;

	if(res->op != OINDREG && res->op != ONAME) {
		dump("n", n);
		dump("res", res);
		fatal("cgen64 %O of %O", n->op, res->op);
	}
	switch(n->op) {
	default:
		fatal("cgen64 %O", n->op);

	case OMINUS:
		cgen(n->left, res);
		split64(res, &lo1, &hi1);
		gins(ANEGL, N, &lo1);
		gins(AADCL, ncon(0), &hi1);
		gins(ANEGL, N, &hi1);
		splitclean();
		return;

	case OCOM:
		cgen(n->left, res);
		split64(res, &lo1, &hi1);
		gins(ANOTL, N, &lo1);
		gins(ANOTL, N, &hi1);
		splitclean();
		return;

	case OADD:
	case OSUB:
	case OMUL:
	case OLSH:
	case ORSH:
	case OAND:
	case OOR:
	case OXOR:
		// binary operators.
		// common setup below.
		break;
	}

	l = n->left;
	r = n->right;
	if(!l->addable) {
		tempalloc(&t1, l->type);
		cgen(l, &t1);
		l = &t1;
	}
	if(r != N && !r->addable) {
		tempalloc(&t2, r->type);
		cgen(r, &t2);
		r = &t2;
	}

	nodreg(&ax, types[TINT32], D_AX);
	nodreg(&cx, types[TINT32], D_CX);
	nodreg(&dx, types[TINT32], D_DX);

	// Setup for binary operation.
	split64(l, &lo1, &hi1);
	if(is64(r->type))
		split64(r, &lo2, &hi2);

	// Do op.  Leave result in DX:AX.
	switch(n->op) {
	case OADD:
		// TODO: Constants
		gins(AMOVL, &lo1, &ax);
		gins(AMOVL, &hi1, &dx);
		gins(AADDL, &lo2, &ax);
		gins(AADCL, &hi2, &dx);
		break;

	case OSUB:
		// TODO: Constants.
		gins(AMOVL, &lo1, &ax);
		gins(AMOVL, &hi1, &dx);
		gins(ASUBL, &lo2, &ax);
		gins(ASBBL, &hi2, &dx);
		break;

	case OMUL:
		// let's call the next two EX and FX.
		regalloc(&ex, types[TPTR32], N);
		regalloc(&fx, types[TPTR32], N);

		// load args into DX:AX and EX:CX.
		gins(AMOVL, &lo1, &ax);
		gins(AMOVL, &hi1, &dx);
		gins(AMOVL, &lo2, &cx);
		gins(AMOVL, &hi2, &ex);

		// if DX and EX are zero, use 32 x 32 -> 64 unsigned multiply.
		gins(AMOVL, &dx, &fx);
		gins(AORL, &ex, &fx);
		p1 = gbranch(AJNE, T);
		gins(AMULL, &cx, N);	// implicit &ax
		p2 = gbranch(AJMP, T);
		patch(p1, pc);

		// full 64x64 -> 64, from 32x32 -> 64.
		gins(AIMULL, &cx, &dx);
		gins(AMOVL, &ax, &fx);
		gins(AIMULL, &ex, &fx);
		gins(AADDL, &dx, &fx);
		gins(AMOVL, &cx, &dx);
		gins(AMULL, &dx, N);	// implicit &ax
		gins(AADDL, &fx, &dx);
		patch(p2, pc);

		regfree(&ex);
		regfree(&fx);
		break;

	case OLSH:
		if(r->op == OLITERAL) {
			v = mpgetfix(r->val.u.xval);
			if(v >= 64) {
				if(is64(r->type))
					splitclean();
				splitclean();
				split64(res, &lo2, &hi2);
				gins(AMOVL, ncon(0), &lo2);
				gins(AMOVL, ncon(0), &hi2);
				splitclean();
				goto out;
			}
			if(v >= 32) {
				if(is64(r->type))
					splitclean();
				split64(res, &lo2, &hi2);
				gmove(&lo1, &hi2);
				if(v > 32) {
					gins(ASHLL, ncon(v - 32), &hi2);
				}
				gins(AMOVL, ncon(0), &lo2);
				splitclean();
				splitclean();
				goto out;
			}

			// general shift
			gins(AMOVL, &lo1, &ax);
			gins(AMOVL, &hi1, &dx);
			p1 = gins(ASHLL, ncon(v), &dx);
			p1->from.index = D_AX;	// double-width shift
			p1->from.scale = 0;
			gins(ASHLL, ncon(v), &ax);
			break;
		}

		// load value into DX:AX.
		gins(AMOVL, &lo1, &ax);
		gins(AMOVL, &hi1, &dx);

		// load shift value into register.
		// if high bits are set, zero value.
		p1 = P;
		if(is64(r->type)) {
			gins(ACMPL, &hi2, ncon(0));
			p1 = gbranch(AJNE, T);
			gins(AMOVL, &lo2, &cx);
		} else
			gins(AMOVL, r, &cx);

		// if shift count is >=64, zero value
		gins(ACMPL, &cx, ncon(64));
		p2 = gbranch(optoas(OLT, types[TUINT32]), T);
		if(p1 != P)
			patch(p1, pc);
		gins(AXORL, &dx, &dx);
		gins(AXORL, &ax, &ax);
		patch(p2, pc);

		// if shift count is >= 32, zero low.
		gins(ACMPL, &cx, ncon(32));
		p1 = gbranch(optoas(OLT, types[TUINT32]), T);
		gins(AMOVL, &ax, &dx);
		gins(ASHLL, &cx, &dx);	// SHLL only uses bottom 5 bits of count
		gins(AXORL, &ax, &ax);
		p2 = gbranch(AJMP, T);
		patch(p1, pc);

		// general shift
		p1 = gins(ASHLL, &cx, &dx);
		p1->from.index = D_AX;	// double-width shift
		p1->from.scale = 0;
		gins(ASHLL, &cx, &ax);
		patch(p2, pc);
		break;

	case ORSH:
		if(r->op == OLITERAL) {
			v = mpgetfix(r->val.u.xval);
			if(v >= 64) {
				if(is64(r->type))
					splitclean();
				splitclean();
				split64(res, &lo2, &hi2);
				if(hi1.type->etype == TINT32) {
					gmove(&hi1, &lo2);
					gins(ASARL, ncon(31), &lo2);
					gmove(&hi1, &hi2);
					gins(ASARL, ncon(31), &hi2);
				} else {
					gins(AMOVL, ncon(0), &lo2);
					gins(AMOVL, ncon(0), &hi2);
				}
				splitclean();
				goto out;
			}
			if(v >= 32) {
				if(is64(r->type))
					splitclean();
				split64(res, &lo2, &hi2);
				gmove(&hi1, &lo2);
				if(v > 32)
					gins(optoas(ORSH, hi1.type), ncon(v-32), &lo2);
				if(hi1.type->etype == TINT32) {
					gmove(&hi1, &hi2);
					gins(ASARL, ncon(31), &hi2);
				} else
					gins(AMOVL, ncon(0), &hi2);
				splitclean();
				splitclean();
				goto out;
			}

			// general shift
			gins(AMOVL, &lo1, &ax);
			gins(AMOVL, &hi1, &dx);
			p1 = gins(ASHRL, ncon(v), &ax);
			p1->from.index = D_DX;	// double-width shift
			p1->from.scale = 0;
			gins(optoas(ORSH, hi1.type), ncon(v), &dx);
			break;
		}

		// load value into DX:AX.
		gins(AMOVL, &lo1, &ax);
		gins(AMOVL, &hi1, &dx);

		// load shift value into register.
		// if high bits are set, zero value.
		p1 = P;
		if(is64(r->type)) {
			gins(ACMPL, &hi2, ncon(0));
			p1 = gbranch(AJNE, T);
			gins(AMOVL, &lo2, &cx);
		} else
			gins(AMOVL, r, &cx);

		// if shift count is >=64, zero or sign-extend value
		gins(ACMPL, &cx, ncon(64));
		p2 = gbranch(optoas(OLT, types[TUINT32]), T);
		if(p1 != P)
			patch(p1, pc);
		if(hi1.type->etype == TINT32) {
			gins(ASARL, ncon(31), &dx);
			gins(AMOVL, &dx, &ax);
		} else {
			gins(AXORL, &dx, &dx);
			gins(AXORL, &ax, &ax);
		}
		patch(p2, pc);

		// if shift count is >= 32, sign-extend hi.
		gins(ACMPL, &cx, ncon(32));
		p1 = gbranch(optoas(OLT, types[TUINT32]), T);
		gins(AMOVL, &dx, &ax);
		if(hi1.type->etype == TINT32) {
			gins(ASARL, &cx, &ax);	// SARL only uses bottom 5 bits of count
			gins(ASARL, ncon(31), &dx);
		} else {
			gins(ASHRL, &cx, &ax);
			gins(AXORL, &dx, &dx);
		}
		p2 = gbranch(AJMP, T);
		patch(p1, pc);

		// general shift
		p1 = gins(ASHRL, &cx, &ax);
		p1->from.index = D_DX;	// double-width shift
		p1->from.scale = 0;
		gins(optoas(ORSH, hi1.type), &cx, &dx);
		patch(p2, pc);
		break;

	case OXOR:
	case OAND:
	case OOR:
		// make constant the right side (it usually is anyway).
		if(lo1.op == OLITERAL) {
			nswap(&lo1, &lo2);
			nswap(&hi1, &hi2);
		}
		if(lo2.op == OLITERAL) {
			// special cases for constants.
			lv = mpgetfix(lo2.val.u.xval);
			hv = mpgetfix(hi2.val.u.xval);
			splitclean();	// right side
			split64(res, &lo2, &hi2);
			switch(n->op) {
			case OXOR:
				gmove(&lo1, &lo2);
				gmove(&hi1, &hi2);
				switch(lv) {
				case 0:
					break;
				case 0xffffffffu:
					gins(ANOTL, N, &lo2);
					break;
				default:
					gins(AXORL, ncon(lv), &lo2);
					break;
				}
				switch(hv) {
				case 0:
					break;
				case 0xffffffffu:
					gins(ANOTL, N, &hi2);
					break;
				default:
					gins(AXORL, ncon(hv), &hi2);
					break;
				}
				break;

			case OAND:
				switch(lv) {
				case 0:
					gins(AMOVL, ncon(0), &lo2);
					break;
				default:
					gmove(&lo1, &lo2);
					if(lv != 0xffffffffu)
						gins(AANDL, ncon(lv), &lo2);
					break;
				}
				switch(hv) {
				case 0:
					gins(AMOVL, ncon(0), &hi2);
					break;
				default:
					gmove(&hi1, &hi2);
					if(hv != 0xffffffffu)
						gins(AANDL, ncon(hv), &hi2);
					break;
				}
				break;

			case OOR:
				switch(lv) {
				case 0:
					gmove(&lo1, &lo2);
					break;
				case 0xffffffffu:
					gins(AMOVL, ncon(0xffffffffu), &lo2);
					break;
				default:
					gmove(&lo1, &lo2);
					gins(AORL, ncon(lv), &lo2);
					break;
				}
				switch(hv) {
				case 0:
					gmove(&hi1, &hi2);
					break;
				case 0xffffffffu:
					gins(AMOVL, ncon(0xffffffffu), &hi2);
					break;
				default:
					gmove(&hi1, &hi2);
					gins(AORL, ncon(hv), &hi2);
					break;
				}
				break;
			}
			splitclean();
			splitclean();
			goto out;
		}
		gins(AMOVL, &lo1, &ax);
		gins(AMOVL, &hi1, &dx);
		gins(optoas(n->op, lo1.type), &lo2, &ax);
		gins(optoas(n->op, lo1.type), &hi2, &dx);
		break;
	}
	if(is64(r->type))
		splitclean();
	splitclean();

	split64(res, &lo1, &hi1);
	gins(AMOVL, &ax, &lo1);
	gins(AMOVL, &dx, &hi1);
	splitclean();

out:
	if(r == &t2)
		tempfree(&t2);
	if(l == &t1)
		tempfree(&t1);
}

/*
 * generate comparison of nl, nr, both 64-bit.
 * nl is memory; nr is constant or memory.
 */
void
cmp64(Node *nl, Node *nr, int op, Prog *to)
{
	Node lo1, hi1, lo2, hi2, rr;
	Prog *br;
	Type *t;

	split64(nl, &lo1, &hi1);
	split64(nr, &lo2, &hi2);

	// compare most significant word;
	// if they differ, we're done.
	t = hi1.type;
	if(nl->op == OLITERAL || nr->op == OLITERAL)
		gins(ACMPL, &hi1, &hi2);
	else {
		regalloc(&rr, types[TINT32], N);
		gins(AMOVL, &hi1, &rr);
		gins(ACMPL, &rr, &hi2);
		regfree(&rr);
	}
	br = P;
	switch(op) {
	default:
		fatal("cmp64 %O %T", op, t);
	case OEQ:
		// cmp hi
		// jne L
		// cmp lo
		// jeq to
		// L:
		br = gbranch(AJNE, T);
		break;
	case ONE:
		// cmp hi
		// jne to
		// cmp lo
		// jne to
		patch(gbranch(AJNE, T), to);
		break;
	case OGE:
	case OGT:
		// cmp hi
		// jgt to
		// jlt L
		// cmp lo
		// jge to (or jgt to)
		// L:
		patch(gbranch(optoas(OGT, t), T), to);
		br = gbranch(optoas(OLT, t), T);
		break;
	case OLE:
	case OLT:
		// cmp hi
		// jlt to
		// jgt L
		// cmp lo
		// jle to (or jlt to)
		// L:
		patch(gbranch(optoas(OLT, t), T), to);
		br = gbranch(optoas(OGT, t), T);
		break;
	}

	// compare least significant word
	t = lo1.type;
	if(nl->op == OLITERAL || nr->op == OLITERAL)
		gins(ACMPL, &lo1, &lo2);
	else {
		regalloc(&rr, types[TINT32], N);
		gins(AMOVL, &lo1, &rr);
		gins(ACMPL, &rr, &lo2);
		regfree(&rr);
	}

	// jump again
	patch(gbranch(optoas(op, t), T), to);

	// point first branch down here if appropriate
	if(br != P)
		patch(br, pc);

	splitclean();
	splitclean();
}

