// 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, *l, *r;
	Node lo1, lo2, hi1, hi2;
	Node al, ah, bl, bh, cl, ch; //, s1, s2;
	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;
	}

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

	regalloc(&al, lo1.type, N);
	regalloc(&ah, hi1.type, N);
	// Do op.  Leave result in ah:al.
	switch(n->op) {
	default:
		fatal("cgen64: not implemented: %N\n", n);

	case OADD:
		// TODO: Constants
		regalloc(&bl, types[TPTR32], N);
		regalloc(&bh, types[TPTR32], N);
		gins(AMOVW, &hi1, &ah);
		gins(AMOVW, &lo1, &al);
		gins(AMOVW, &hi2, &bh);
		gins(AMOVW, &lo2, &bl);
		gins(AADD, &bl, &al);
		gins(AADC, &bh, &ah);
		regfree(&bl);
		regfree(&bh);
		break;

	case OSUB:
		// TODO: Constants.
		gins(AMOVW, &lo1, &al);
		gins(AMOVW, &hi1, &ah);
		gins(ASUB, &lo2, &al);
		gins(ASBC, &hi2, &ah);
		break;

	case OMUL:
		// TODO(kaib): this can be done with 4 regs and does not need 6
		regalloc(&bh, types[TPTR32], N);
		regalloc(&bl, types[TPTR32], N);
		regalloc(&ch, types[TPTR32], N);
		regalloc(&cl, types[TPTR32], N);

		// load args into bh:bl and bh:bl.
		gins(AMOVW, &hi1, &bh);
		gins(AMOVW, &lo1, &bl);
		gins(AMOVW, &hi2, &ch);
		gins(AMOVW, &lo2, &cl);

		// bl * cl
		p1 = gins(AMULLU, N, N);
		p1->from.type = D_REG;
		p1->from.reg = bl.val.u.reg;
		p1->reg = cl.val.u.reg;
		p1->to.type = D_REGREG;
		p1->to.reg = al.val.u.reg;
		p1->to.offset = ah.val.u.reg;
//print("%P\n", p1);

		// bl * ch
		p1 = gins(AMULALU, N, N);
		p1->from.type = D_REG;
		p1->from.reg = ah.val.u.reg;
		p1->reg = bl.val.u.reg;
		p1->to.type = D_REGREG;
		p1->to.reg = ch.val.u.reg;
		p1->to.offset = ah.val.u.reg;
//print("%P\n", p1);

		// bh * cl
		p1 = gins(AMULALU, N, N);
		p1->from.type = D_REG;
		p1->from.reg = ah.val.u.reg;
		p1->reg = bh.val.u.reg;
		p1->to.type = D_REGREG;
		p1->to.reg = cl.val.u.reg;
		p1->to.offset = ah.val.u.reg;
//print("%P\n", p1);

		regfree(&bh);
		regfree(&bl);
		regfree(&ch);
		regfree(&cl);

		break;

	case OLSH:
		if(r->op == OLITERAL) {
			v = mpgetfix(r->val.u.xval);
			if(v >= 64) {
				// TODO(kaib): replace with gins(AMOVW, nodintconst(0), &al)
				// here and below (verify it optimizes to EOR)
				gins(AEOR, &al, &al);
				gins(AEOR, &ah, &ah);
				break;
			}
			if(v >= 32) {
				gins(AEOR, &al, &al);
				//	MOVW	lo1<<(v-32), ah
				p1 = gins(AMOVW, &lo1, &ah);
				p1->from.type = D_SHIFT;
				p1->from.offset = SHIFT_LL | (v-32)<<7 | lo1.val.u.reg;
				p1->from.reg = NREG;
				break;
			}

			// general literal left shift

			//	MOVW	lo1<<v, al
			p1 = gins(AMOVW, &lo1, &al);
			p1->from.type = D_SHIFT;
			p1->from.offset = SHIFT_LL | v<<7 | lo1.val.u.reg;
			p1->from.reg = NREG;
			break;

			//	MOVW	hi1<<v, ah
			p1 = gins(AMOVW, &hi1, &ah);
			p1->from.type = D_SHIFT;
			p1->from.offset = SHIFT_LL | v<<7 | hi1.val.u.reg;
			p1->from.reg = NREG;
			break;

			//	OR		lo1>>(32-v), ah
			p1 = gins(AORR, &lo1, &ah);
			p1->from.type = D_SHIFT;
			p1->from.offset = SHIFT_LR | (32-v)<<7 | lo1.val.u.reg;
			p1->from.reg = NREG;
			break;
		}

		fatal("cgen64 OLSH, !OLITERAL not implemented");
		break;


	case ORSH:
		if(r->op == OLITERAL) {
			v = mpgetfix(r->val.u.xval);
			if(v >= 64) {
				if(hi1.type->etype == TINT32) {
					//	MOVW	hi1->31, al
					p1 = gins(AMOVW, &hi1, &al);
					p1->from.type = D_SHIFT;
					p1->from.offset = SHIFT_AR | 31 << 7 | hi1.val.u.reg;
					p1->from.reg = NREG;

					//	MOVW	hi1->31, ah
					p1 = gins(AMOVW, &hi1, &ah);
					p1->from.type = D_SHIFT;
					p1->from.offset = SHIFT_AR | 31 << 7 | hi1.val.u.reg;
					p1->from.reg = NREG;
				} else {
					gins(AEOR, &al, &al);
					gins(AEOR, &ah, &ah);
				}
				break;
			}
			if(v >= 32) {
				if(hi1.type->etype == TINT32) {
					//	MOVW	hi1->(v-32), al
					p1 = gins(AMOVW, &hi1, &al);
					p1->from.type = D_SHIFT;
					p1->from.offset = SHIFT_AR | (v-32)<<7 | hi1.val.u.reg;
					p1->from.reg = NREG;

					//	MOVW	hi1->31, ah
					p1 = gins(AMOVW, &hi1, &ah);
					p1->from.type = D_SHIFT;
					p1->from.offset = SHIFT_AR | 31<<7 | hi1.val.u.reg;
					p1->from.reg = NREG;
				} else {
					//	MOVW	hi1>>(v-32), al
					p1 = gins(AMOVW, &hi1, &al);
					p1->from.type = D_SHIFT;
					p1->from.offset = SHIFT_LR | (v-32)<<7 | hi1.val.u.reg;
					p1->from.reg = NREG;
					gins(AEOR, &ah, &ah);
				}
				break;
			}

			// general literal right shift

			//	MOVW	lo1>>v, al
			p1 = gins(AMOVW, &lo1, &al);
			p1->from.type = D_SHIFT;
			p1->from.offset = SHIFT_LR | v<<7 | lo1.val.u.reg;
			p1->from.reg = NREG;

			//	OR		hi1<<(32-v), al, al
			p1 = gins(AORR, &hi1, &al);
			p1->from.type = D_SHIFT;
			p1->from.offset = SHIFT_LL | (32-v)<<7 | hi1.val.u.reg;
			p1->from.reg = NREG;
			p1->reg = al.val.u.reg;

			if(hi1.type->etype == TINT32) {
				//	MOVW	hi1->v, ah
				p1 = gins(AMOVW, &hi1, &ah);
				p1->from.type = D_SHIFT;
				p1->from.offset = SHIFT_AR | v<<7 | hi1.val.u.reg;
				p1->from.reg = NREG;
			} else {
				//	MOVW	hi1>>v, ah
				p1 = gins(AMOVW, &hi1, &ah);
				p1->from.type = D_SHIFT;
				p1->from.offset = SHIFT_LR | v<<7 | hi1.val.u.reg;
				p1->from.reg = NREG;
			}
			break;
		}
		fatal("cgen64 ORSH, !OLITERAL not implemented");

//		// 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:
		// TODO(kaib): literal optimizations
		// 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(AMOVW, &lo1, &al);
		gins(AMOVW, &hi1, &ah);
		gins(optoas(n->op, lo1.type), &lo2, &al);
		gins(optoas(n->op, lo1.type), &hi2, &ah);
		break;
	}
	if(is64(r->type))
		splitclean();
	splitclean();

	split64(res, &lo1, &hi1);
	gins(AMOVW, &al, &lo1);
	gins(AMOVW, &ah, &hi1);
	splitclean();

//out:
	if(r == &t2)
		tempfree(&t2);
	if(l == &t1)
		tempfree(&t1);
	regfree(&al);
	regfree(&ah);
}

/*
 * 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)
{
	fatal("cmp64 not implemented");
//	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();
}
