// 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 "go.h"
#include "gen.h"

Prog*
gbranch(int op, Node *t)
{
	Prog *p;

	p = prog(op);
	p->addr.type = ABRANCH;
	p->pt = conv2pt(t);
	return p;
}

Prog*
gopcode(int op, int pt, Node *n)
{
	Prog *p;

	p = prog(op);
	p->pt = pt;
	p->addr.node = n;
	if(n == N) {
		p->addr.type = ANONE;
		return p;
	}
	if(n->op == OTYPE) {
		p->pt1 = conv2pt(n);
		p->addr.type = ANONE;
		return p;
	}
	p->addr.type = ANODE;
//	p->param = n->param;
	return p;
}

Prog*
gopcodet(int op, Node *t, Node *n)
{
	return gopcode(op, conv2pt(t), n);
}

void
gaddoffset(Node *n)
{
	Prog *p;

	if(n == N || n->op != ONAME || n->sym == S)
		goto bad;
	p = gopcode(PADDO, PTADDR, n);
	return;

bad:
	fatal("gaddoffset: %N", n);

}

void
gconv(int t1, int t2)
{
	Prog *p;

	p = gopcode(PCONV, t1, N);
	p->pt1 = t2;
}

int
conv2pt(Node *t)
{
	if(t == N)
		return PTxxx;
	switch(t->etype) {
	case TPTR:
		t = t->type;
		if(t == N)
			return PTERROR;
		switch(t->etype) {
		case PTSTRING:
		case PTCHAN:
		case PTMAP:
			return t->etype;
		}
		return TPTR;
	}
	return t->etype;
}

void
patch(Prog *p, Prog *to)
{
	if(p->addr.type != ABRANCH)
		yyerror("patch: not a branch");
	p->addr.branch = to;
}

Prog*
prog(int as)
{
	Prog *p;

	p = pc;
	pc = mal(sizeof(*pc));

	pc->op = PEND;
	pc->addr.type = ANONE;
	pc->loc = p->loc+1;

	p->op = as;
	p->lineno = dynlineno;
	p->link = pc;
	return p;
}

void
proglist(void)
{
	Prog *p;

	print("--- prog list ---\n");
	for(p=firstpc; p!=P; p=p->link)
		print("%P\n", p);
}

char*	ptnames[] =
{
	[PTxxx]		= "",
	[PTINT8]	= "I8",
	[PTUINT8]	= "U8",
	[PTINT16]	= "I16",
	[PTUINT16]	= "U16",
	[PTINT32]	= "I32",
	[PTUINT32]	= "U32",
	[PTINT64]	= "I64",
	[PTUINT64]	= "U64",
	[PTFLOAT32]	= "F32",
	[PTFLOAT64]	= "F64",
	[PTFLOAT80]	= "F80",
	[PTBOOL]	= "B",
	[PTPTR]		= "P",
	[PTADDR]	= "A",
	[PTINTER]	= "I",
	[PTNIL]		= "N",
	[PTSTRUCT]	= "S",
	[PTSTRING]	= "Z",
	[PTCHAN]	= "C",
	[PTMAP]		= "M",
	[PTERROR]	= "?",
};

int
Xconv(Fmt *fp)
{
	char buf[100];
	int pt;

	pt = va_arg(fp->args, int);
	if(pt < 0 || pt >= nelem(ptnames) || ptnames[pt] == nil) {
		snprint(buf, sizeof(buf), "PT(%d)", pt);
		return fmtstrcpy(fp, buf);
	}
	return fmtstrcpy(fp, ptnames[pt]);
}

int
Qconv(Fmt *fp)
{
	char buf[100];
	int pt;

	pt = va_arg(fp->args, int);
	if(pt == PTADDR)
		pt = PTPTR;
	snprint(buf, sizeof(buf), "_T_%X", pt);
	return fmtstrcpy(fp, buf);
}

int
Rconv(Fmt *fp)
{
	char buf[100];
	int pt;

	pt = va_arg(fp->args, int);
	if(pt == PTADDR)
		snprint(buf, sizeof(buf), "_R_%X", pt);
	else
		snprint(buf, sizeof(buf), "_U._R_%X", pt);
	return fmtstrcpy(fp, buf);
}

/*
s%[ 	]*%%g
s%(\/\*.*)*%%g
s%,%\n%g
s%\n+%\n%g
s%(=0)*%%g
s%^P(.+)%	[P\1]		= "\1",%g
s%^	........*\]		=%&~%g
s%	=~%=%g
*/

static char*
pnames[] =
{
	[PXXX]		= "XXX",
	[PERROR]	= "ERROR",
	[PPANIC]	= "PANIC",
	[PPRINT]	= "PRINT",
	[PGOTO]		= "GOTO",
	[PGOTOX]	= "GOTOX",
	[PCMP]		= "CMP",
	[PNEW]		= "NEW",
	[PLEN]		= "LEN",
	[PTEST]		= "TEST",
	[PCALL1]	= "CALL1",
	[PCALL2]	= "CALL2",
	[PCALLI2]	= "CALLI2",
	[PCALLM2]	= "CALLM2",
	[PCALLF2]	= "CALLF2",
	[PCALL3]	= "CALL3",
	[PRETURN]	= "RETURN",
	[PBEQ]		= "BEQ",
	[PBNE]		= "BNE",
	[PBLT]		= "BLT",
	[PBLE]		= "BLE",
	[PBGE]		= "BGE",
	[PBGT]		= "BGT",
	[PBTRUE]	= "BTRUE",
	[PBFALSE]	= "BFALSE",
	[PLOAD]		= "LOAD",
	[PLOADI]	= "LOADI",
	[PSTORE]	= "STORE",
	[PSTOREI]	= "STOREI",
	[PSTOREZ]	= "STOREZ",
	[PCONV]		= "CONV",
	[PADDR]		= "ADDR",
	[PADDO]		= "ADDO",
	[PINDEX]	= "INDEX",
	[PINDEXZ]	= "INDEXZ",
	[PCAT]		= "CAT",
	[PADD]		= "ADD",
	[PSUB]		= "SUB",
	[PSLICE]	= "SLICE",
	[PMUL]		= "MUL",
	[PDIV]		= "DIV",
	[PLSH]		= "LSH",
	[PRSH]		= "RSH",
	[PMOD]		= "MOD",
	[PMINUS]	= "MINUS",
	[PCOM]		= "COM",
	[PAND]		= "AND",
	[POR]		= "OR",
	[PXOR]		= "XOR",
	[PEND]		= "END",
};

int
Aconv(Fmt *fp)
{
	char buf[100], buf1[100];
	Prog *p;
	int o;

	p = va_arg(fp->args, Prog*);
	if(p == P) {
		snprint(buf, sizeof(buf), "<P>");
		goto ret;
	}

	o = p->op;
	if(o < 0 || o >= nelem(pnames) || pnames[o] == nil)
		snprint(buf, sizeof(buf), "(A%d)", o);
	else
		snprint(buf, sizeof(buf), "%s", pnames[o]);

	o = p->pt;
	if(o != PTxxx) {
		snprint(buf1, sizeof(buf1), "-%X", o);
		strncat(buf, buf1, sizeof(buf));
	}

	o = p->pt1;
	if(o != PTxxx) {
		snprint(buf1, sizeof(buf1), "-%X", o);
		strncat(buf, buf1, sizeof(buf));
	}

ret:
	return fmtstrcpy(fp, buf);
}

int
Pconv(Fmt *fp)
{
	char buf[500], buf1[500];
	Prog *p;

	p = va_arg(fp->args, Prog*);
	snprint(buf1, sizeof(buf1), "%4ld %4ld %-9A", p->loc, p->lineno, p);

	switch(p->addr.type) {
	default:
		snprint(buf, sizeof(buf), "?%d", p->addr.type);
		break;

	case ANONE:
		goto out;

	case ANODE:
		snprint(buf, sizeof(buf), "%N", p->addr.node);
		break;

	case ABRANCH:
		if(p->addr.branch == P) {
			snprint(buf, sizeof(buf), "<nil>");
			break;
		}
		snprint(buf, sizeof(buf), "%ld", p->addr.branch->loc);
		break;
	}

	strncat(buf1, " ", sizeof(buf1));
	strncat(buf1, buf, sizeof(buf1));

out:
	return fmtstrcpy(fp, buf1);
}

static char*
typedefs[] =
{
	"int",		"int32",
	"uint",		"uint32",
	"rune",		"uint32",
	"short",	"int16",
	"ushort",	"uint16",
	"long",		"int32",
	"ulong",	"uint32",
	"vlong",	"int64",
	"uvlong",	"uint64",
	"float",	"float32",
	"double",	"float64",

};

void
belexinit(int lextype)
{
	int i;
	Sym *s0, *s1;

	for(i=0; i<nelem(typedefs); i+=2) {
		s1 = lookup(typedefs[i+1]);
		if(s1->lexical != lextype)
			yyerror("need %s to define %s",
				typedefs[i+1], typedefs[i+0]);
		s0 = lookup(typedefs[i+0]);
		s0->lexical = s1->lexical;
		s0->otype = s1->otype;
	}

	fmtinstall('A', Aconv);		// asm opcodes
	fmtinstall('P', Pconv);		// asm instruction
	fmtinstall('R', Rconv);		// interpreted register
	fmtinstall('Q', Qconv);		// interpreted etype
	fmtinstall('X', Xconv);		// interpreted etype

	fmtinstall('D', Dconv);		// addressed operand
	fmtinstall('C', Cconv);		// C type
}

vlong
convvtox(vlong v, int et)
{
	/* botch - do truncation conversion when energetic */
	return v;
}

/*
 * return !(op)
 * eg == <=> !=
 */
int
brcom(int a)
{
	switch(a) {
	case PBEQ:	return PBNE;
	case PBNE:	return PBEQ;
	case PBLT:	return PBGE;
	case PBGT:	return PBLE;
	case PBLE:	return PBGT;
	case PBGE:	return PBLT;
	case PBTRUE:	return PBFALSE;
	case PBFALSE:	return PBTRUE;
	}
	fatal("brcom: no com for %A\n", a);
	return PERROR;
}

/*
 * return reverse(op)
 * eg a op b <=> b r(op) a
 */
int
brrev(int a)
{
	switch(a) {
	case PBEQ:	return PBEQ;
	case PBNE:	return PBNE;
	case PBLT:	return PBGT;
	case PBGT:	return PBLT;
	case PBLE:	return PBGE;
	case PBGE:	return PBLE;
	}
	fatal("brcom: no rev for %A\n", a);
	return PERROR;
}

/*
 * codegen the address of the ith
 * element in the jth argument.
 */
void
fnparam(Node *t, int j, int i)
{
	Node *a, *f;

	switch(j) {
	default:
		fatal("fnparam: bad j");
	case 0:
		a = getthisx(t);
		break;
	case 1:
		a = getoutargx(t);
		break;
	case 2:
		a = getinargx(t);
		break;
	}

	f = a->type;
	while(i > 0) {
		f = f->down;
		i--;
	}
	if(f->etype != TFIELD)
		fatal("fnparam: not field");

	gopcode(PLOAD, PTADDR, a->nname);
	gopcode(PADDO, PTADDR, f->nname);
}

Sig*
lsort(Sig *l, int(*f)(Sig*, Sig*))
{
	Sig *l1, *l2, *le;

	if(l == 0 || l->link == 0)
		return l;

	l1 = l;
	l2 = l;
	for(;;) {
		l2 = l2->link;
		if(l2 == 0)
			break;
		l2 = l2->link;
		if(l2 == 0)
			break;
		l1 = l1->link;
	}

	l2 = l1->link;
	l1->link = 0;
	l1 = lsort(l, f);
	l2 = lsort(l2, f);

	/* set up lead element */
	if((*f)(l1, l2) < 0) {
		l = l1;
		l1 = l1->link;
	} else {
		l = l2;
		l2 = l2->link;
	}
	le = l;

	for(;;) {
		if(l1 == 0) {
			while(l2) {
				le->link = l2;
				le = l2;
				l2 = l2->link;
			}
			le->link = 0;
			break;
		}
		if(l2 == 0) {
			while(l1) {
				le->link = l1;
				le = l1;
				l1 = l1->link;
			}
			break;
		}
		if((*f)(l1, l2) < 0) {
			le->link = l1;
			le = l1;
			l1 = l1->link;
		} else {
			le->link = l2;
			le = l2;
			l2 = l2->link;
		}
	}
	le->link = 0;
	return l;
}
