// 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 {
			cx.type = types[TUINT32];
			gmove(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 {
			cx.type = types[TUINT32];
			gmove(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();
}

