#include	"defs.h"

#if FAMILY == DMR
#	include "dmr.h"
#endif

#if FAMILY==SCJ && OUTPUT==BINARY
#	include "scj.h"
#endif

/*
      INTERDATA-SPECIFIC PRINTING ROUTINES
*/

int maxregvar = 0;
static char textline[50];
int regnum[] = { 14, 13, 12, 11, 10, 9, 8 };


prsave()
{
}



goret(type)
int type;
{
#if  FAMILY == DMR
	p2op(P2RETURN);
#endif

#if FAMILY==SCJ
	p2pass(sprintf(textline, "\tjmp\tcret"));
#endif
}




/*
 * move argument slot arg1 (relative to ap)
 * to slot arg2 (relative to ARGREG)
 */

mvarg(type, arg1, arg2)
int type, arg1, arg2;
{
#if TARGET == PDP11
	mvarg1(P2INT, arg1+4, arg2);
	if (type == TYLONG)
		mvarg1(P2INT, arg1+6, arg2+2);
#endif

#if TARGET == INTERDATA
	if (type == TYSHORT)
		mvarg1(P2SHORT, arg1, arg2);
	else
		mvarg1(P2INT, arg1, arg2);
#endif
}

mvarg1(type, m, n)
int type;
int m, n;
{
#if FAMILY == DMR
	/***
	p2reg(ARGREG, P2SHORT|P2PTR);
	p2op2(P2ICON, P2SHORT);
	p2i(n);
	p2op2(P2PLUS, P2SHORT|P2PTR);
	p2op2(P2INDIRECT, P2SHORT);
	p2reg(AUTOREG, P2SHORT|P2PTR);
	p2op2(P2ICON, P2SHORT);
	p2i(m);
	p2op2(P2PLUS, P2SHORT|P2PTR);
	p2op2(P2INDIRECT, P2SHORT);
	p2op2(P2ASSIGN, P2SHORT);
	 ***/

	putautovar(n, type);
	p2op2(P2INDIRECT, type);
	putautovar(m, type);
	p2op2(P2INDIRECT, type);
	p2op2(P2ASSIGN, type);

	putstmt();
#endif

#if FAMILY == SCJ
	p2pass(sprintf(textline, "\tmov\t%d.(r5),%d.(r4)", m, n));
#endif
}




prlabel(fp, k)
FILEP fp;
int k;
{
	fprintf(fp, "L%d\tequ\t*\n", k);
}

prconi(fp, type, n)
FILEP fp;
int type;
ftnint n;
{
	register short *np;

	np = &n;
	if (type == TYLONG)
		fprintf(fp, "\tdc\tx'%x',x'%x'\n", np[0], np[1]);
	else
		fprintf(fp, "\tdc\tx'%x'\n", np[1]);
}



prcona(fp, a)
FILEP fp;
ftnint a;
{
	fprintf(fp, "L%ld\tequ\t*\n", a);
}



#if HERE!=INTERDATA
BAD NEWS
#endif

prconr(fp, type, x)
FILEP fp;
int type;
double	x;
{
	union	typedefs	{
		int	u_int;
		short	u_short;
		long	u_long;
		float	u_real;
		double	u_dbl;
		long	u_dp[2];
		};
	register union typedefs *c1;

	c1 = &x;
	fprintf(fp, "\t");
	switch (type)  {
		case TYSHORT:
			fprintf(fp, "dc\tx'%x'\n", c1->u_short);
			break;

		case TYLONG:
		case TYREAL:
			fprintf(fp, "dc\ty'%x'\n", c1->u_long);
			break;

		case TYDREAL:
			fprintf(fp, "dc\ty'%x',y'%x'\n", c1->u_dp[0],c1->u_dp[1]);
			break;

		default:
			fatal1("Output of bad type constant\n");
		}
}


/*
 *   force alignment:
 *   pdp11: .even
 *   interdata: align length (if valid)
 */
preven(k)
int k;
{
	switch (k)  {
		case 2:
		case 4:
		case 8:
			fprintf(asmfile, "\talign\t%d\n", k);
			break;

		default:
			break;

		}
}

#if FAMILY == SCJ

prcmgoto(p, nlab, skiplabel, labarray)
expptr p;
int nlab, skiplabel, labarray;
{
int regno;

putforce(p->vtype, p);

if(p->vtype == TYLONG)
	{
	regno = 1;
	p2pass(sprintf(textline, "\ttst\tr0"));
	p2pass(sprintf(textline, "\tbne\tL%d", skiplabel));
	}
else
	regno = 0;

p2pass(sprintf(textline, "\tcmp\tr%d,$%d.", regno, nlab));
p2pass(sprintf(textline, "\tbhi\tL%d", skiplabel));
p2pass(sprintf(textline, "\tasl\tr%d", regno));
p2pass(sprintf(textline, "\tjmp\t*L%d(r%d)", labarray, regno));
}


prarif(p, neg,zer,pos)
expptr p;
int neg, zer, pos;
{
register int ptype;

putforce( ptype = p->vtype, p);
if( ISINT(ptype) )
	{
	p2pass(sprintf(textline, "\ttst\tr0"));
	p2pass(sprintf(textline, "\tjlt\tL%d", neg));
	p2pass(sprintf(textline, "\tjgt\tL%d", pos));
	if(ptype != TYSHORT)
		{
		p2pass(sprintf(textline, "\ttst\tr1"));
		p2pass(sprintf(textline, "\tjeq\tL%d", zer));
		}
	p2pass(sprintf(textline, "\tjbr\tL%d", pos));
	}
else
	{
	p2pass(sprintf(textline, "\ttstf\tr0"));
	p2pass(sprintf(textline, "\tcfcc"));
	p2pass(sprintf(textline, "\tjeq\tL%d", zer));
	p2pass(sprintf(textline, "\tjlt\tL%d", neg));
	p2pass(sprintf(textline, "\tjmp\tL%d", pos));
	}
}

#endif




char *memname(stg, mem)
int stg, mem;
{
static char s[20];

switch(stg)
	{
	case STGCOMMON:
	case STGEXT:
		sprintf(s, "%s", varstr(XL, extsymtab[mem].extname) );
		break;

	case STGBSS:
	case STGINIT:
		sprintf(s, "v.%d", mem);
		break;

	case STGCONST:
		sprintf(s, "L%d", mem);
		break;

	case STGEQUIV:
		sprintf(s, "q.%d", mem);
		break;

	default:
		fatal1("memname: invalid vstg %d", stg);
	}
return(s);
}


prlocvar(s, len)
char *s;
ftnint len;
{
fprintf(asmfile, "%s", s);
prskip(asmfile, len);
}



prext(name, leng, init)
char *name;
ftnint leng;
int init;
{
	if(leng==0 || init)  {
		fprintf(asmfile, "\textrn\t%s\n", name);
		}
	else  {
		fprintf(asmfile, "%s\tcomn\n\tds\t%ld\n\tends\n", name, leng);
		}
}



prendproc()
{
}



prtail()
{
#if FAMILY == SCJ
	p2pass(sprintf(textline, "\t.globl\tcsv,cret"));
#else
	/* end-of-int. code files */
	p2op(P2EOF);
#endif
}



prolog(ep, argvec)
struct entrypoint *ep;
struct addrblock *argvec;
{
int i, argslot, proflab;
register chainp p;
register struct nameblock *q;
register struct dimblock *dp;
struct constblock *mkaddcon();

if(procclass == CLMAIN)
	prentry("MAIN__");

if(ep->entryname)
	prentry( varstr(XL, ep->entryname->extname) );

if(procclass == CLBLOCK)
	return;

if(profileflag)
	proflab = newlabel();
#if FAMILY == SCJ
	if(profileflag)
		{
		fprintf(asmfile, "L%d:\t. = .+2\n", proflab);
		p2pass(sprintf(textline, "\tmov\t$L%d,r0", proflab));
		p2pass(sprintf(textline, "\tjsr\tpc,mcount"));
		}
	p2pass(sprintf(textline, "\tjsr\tr5,csv"));
	p2pass(sprintf(textline, "\tsub\t$.F%d,sp", procno));
#else
	if(profileflag)
		p2op2(P2PROFILE, proflab);
	p2op(P2SAVE);
/***/	autoleng = (autoleng + sizeof (short)) & ~03;
	p2op2(P2SETSTK, ((int) autoleng));
#endif

if(argvec == NULL)
	addreg(argloc = 4);
else
	{
	addreg( argloc = argvec->memoffset->const.ci );
	if(proctype == TYCHAR)
		{
		mvarg(TYADDR, 0, chslot);
		mvarg(TYLENG, SZADDR, chlgslot);
		argslot = SZADDR + SZLENG;
		}
	else if( ISCOMPLEX(proctype) )
		{
		mvarg(TYADDR, 0, cxslot);
		argslot = SZADDR;
		}
	else
		argslot = 0;

	for(p = ep->arglist ; p ; p =p->nextp)
		{
		q = p->datap;
		mvarg(TYADDR, argslot, q->vardesc.varno);
		argslot += SZADDR;
		}
	for(p = ep->arglist ; p ; p = p->nextp)
		{
		q = p->datap;
		if(q->vtype==TYCHAR || q->vclass==CLPROC)
			{
			if( q->vleng && ! ISCONST(q->vleng) )
				mvarg(TYLENG, argslot, q->vleng->memno);
			argslot += SZLENG;
			}
		}
	}

for(p = ep->arglist ; p ; p = p->nextp)
	if(dp = ( (struct nameblock *) (p->datap) ) ->vdim)
		{
		for(i = 0 ; i < dp->ndim ; ++i)
			if(dp->dims[i].dimexpr)
				puteq( fixtype(cpexpr(dp->dims[i].dimsize)),
					fixtype(cpexpr(dp->dims[i].dimexpr)));
		if(dp->basexpr)
			puteq( 	cpexpr(fixtype(dp->baseoffset)),
				cpexpr(fixtype(dp->basexpr)));
		}

if(typeaddr)
	puteq( cpexpr(typeaddr), mkaddcon(ep->typelabel) );
putgoto(ep->entrylabel);
}



prentry(s)
char *s;
{
#if FAMILY == SCJ
	p2pass(sprintf(textline, "_%s", s));
#else
	p2op(P2RLABEL);
	/*** putc('_', textfile); ***/
	p2str(s);
#endif
}




addreg(k)
int k;
{
#if FAMILY == SCJ
	p2pass(sprintf(textline, "\tmov\tr5,r4"));
	p2pass(sprintf(textline, "\tadd\t$%d.,r4", k));
#else
/***
	p2reg(ARGREG, P2SHORT);
	p2reg(AUTOREG, P2SHORT);
	p2op2(P2ICON, P2SHORT);
	p2i(k);
	p2op2(P2PLUS, P2SHORT);
	p2op2(P2ASSIGN, P2SHORT);
	putstmt();
***/
#endif
}


prhead(fp)
FILEP fp;
{
#if FAMILY==SCJ
#	if OUTPUT == BINARY
		p2triple(P2LBRACKET, ARGREG-1-highregvar, procno);
		p2word( (long) (BITSPERCHAR*autoleng) );
		p2flush();
#	else
		fprintf(fp, "[%02d\t%06ld\t%02d\t\n", procno,
			BITSPERCHAR*autoleng, ARGREG-1-highregvar);
#	endif
#endif
}

prdbginfo()
{
register char *s;
char *t, buff[50];
register struct nameblock *p;
struct hashentry *hp;

if(s = entries->entryname->extname)
	s = varstr(XL, s);
else if(procclass == CLMAIN)
	s = "MAIN__";
else
	return;

if(procclass != CLBLOCK)
	fprintf(asmfile, "~~%s\tequ\t*\n", s, s);

for(hp = hashtab ; hp<lasthash ; ++hp)
    if(p = hp->varp)
	{
	s = NULL;
	if(p->vstg == STGARG)
		s = sprintf(buff, "%d", p->vardesc.varno+argloc);
	else if(p->vclass == CLVAR)
		switch(p->vstg)
			{
			case STGBSS:
			case STGINIT:
			case STGEQUIV:
				t = memname(p->vstg, p->vardesc.varno);
				if(p->voffset)
					s = sprintf(buff, "%s+%d", t, p->voffset);
				else
					s = sprintf(buff, "%s", t);
				break;

			case STGAUTO:
				s = sprintf(buff, "%d", p->voffset);
				break;

			default:
				break;
			}
	if(s)
		fprintf(asmfile, "~%s\tequ\t%s\n", varstr(VL,p->varname), s);
	}

fprintf(asmfile, "~~\tequ\t0\n");
}
