|
|
researchv10 Norman
# include "mfile2.h"
/* a lot of the machine dependent parts of the second pass */
char *
ccbranches[] = {
" jeql L%d\n",
" jneq L%d\n",
" jleq L%d\n",
" jlss L%d\n",
" jgeq L%d\n",
" jgtr L%d\n",
" jlequ L%d\n",
" jlssu L%d\n",
" jgequ L%d\n",
" jgtru L%d\n",
};
cbgen( o, lab, mode )
int o, lab, mode;
{ /* printf conditional and unconditional branches */
if( !o ) printf( " jbr L%d\n", lab );
else if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] );
else printf( ccbranches[o-EQ], lab );
}
zzzcode( p, ppc, q )
NODE *p; char **ppc; OPTAB *q;
{
register c;
switch( c= *++(*ppc) )
{
case 'I':
cbgen( p->bn.lop, p->bn.label, c );
return;
case 'k': /* complement mask for bit instr */
printf("$%ld", ~p->in.right->tn.lval);
return;
case 'c':
/* argument size */
printf( "$%d", p->stn.argsize/SZINT);
return;
case 'U': /* 32 - n, for unsigned right shifts */
printf("$%d", 32 - p->in.right->tn.lval );
return;
case 'T': /* structure length for arguments */
printf("$%d", p->stn.stsize / SZCHAR);
break;
case 'M': /* move address */
staradr( p->in.right );
break;
case 'S': /* structure assignment */
{
register NODE *l, *r;
register size;
if( p->in.op == STASG )
{
l = p->in.left;
r = p->in.right;
}
else if( p->in.op == STARG )
{ /* store an arg */
r = p->in.left;
}
else cerror( "STASG bad" );
size = p->stn.stsize/SZCHAR;
if( size <= 0 || size > 65535 )
cerror("structure size <0=0 or >65535");
switch(size)
{
case 1:
printf(" movb ");
break;
case 2:
printf(" movw ");
break;
case 4:
printf(" movl ");
break;
case 8:
printf(" movq ");
break;
default:
printf(" movc3 $%d,", size);
break;
}
staradr( r );
printf(",");
if( p->in.op == STARG ) printf( "(sp)" );
else staradr( l );
printf("\n");
}
break;
default:
cerror( "illegal zzzcode" );
}
}
staradr( p )
NODE *p;
{
NODE *pp;
pp = talloc();
pp->in.op = STAR;
pp->in.left = p;
upput( pp );
pp->in.op = FREE;
}
conput( p )
register NODE *p;
{
switch( p->in.op )
{
case ICON:
acon( p );
return;
case REG:
printf( "%s", rnames[p->tn.rval] );
return;
default:
cerror( "illegal conput" );
}
}
insput( p )
NODE *p;
{
cerror( "insput" );
}
/* new use for an old routine
* upput now puts out an indirect address ( STAR node )
* equivalent to the old case STAR in adrput
* as upput, we can now get to this routine directly from the
* templates, using the U symbol
*/
int sideff;
upput( p )
NODE *p;
{
register NODE *r, *l, *pp;
register o;
pp = ( STAR == p->in.op ) ? p->in.left : p ;
o = pp->in.op;
if( o==NAME || o==STAR || o==TEMP || o==VAUTO || o==VPARAM )
{
printf( "*" );
adrput(pp);
return;
}
if( o==ICON )
{
acon( pp );
sideff = 0;
return;
}
if( o == PLUS )
{
r = pp->in.right;
l = pp->in.left;
if( l->in.op == REG && r->in.op == ICON )
{
acon( r );
pp = pp->in.left;
}
else
{
/* index mode (shudder) */
/* save the index, rewrite p to point to
/* the rest, call adrput recursively, and
/* then tack on the index */
if( l->in.op == UNARY AND )
{ /* double index */
adrput( l->in.left );
l = r;
}
else
{
p->in.left = r;
adrput( p );
p->in.left = pp; /* back to normal */
}
if( l->in.op == LS ) l = l->in.left;
if( l->in.op != REG ) cerror("illegal address");
printf( "[%s]", rnames[l->tn.rval] );
return;
}
}
else if( o == MINUS )
{
r = pp->in.right;
if( r->tn.op != ICON || r->tn.name ) cerror("illegal address");
r->tn.lval = -r->tn.lval;
acon( r );
r->tn.lval = -r->tn.lval;
pp = pp->in.left;
}
else if( o == ASG MINUS )
{
r = pp->in.right;
if( r->tn.op != ICON ) cerror("illegal address");
r = pp->in.left;
if( r->tn.op != REG ) cerror("illegal address");
/* always do the side effect */
printf( "-(%s)", rnames[r->tn.rval] );
sideff = 1; /* cream it */
return;
}
else if( o == INCR )
{
r = pp->in.right;
if( r->tn.op != ICON ) cerror("illegal address");
r = pp->in.left;
if( r->tn.op != REG ) cerror("illegal address");
if( sideff ) printf( "(%s)+", rnames[r->tn.rval] );
else printf( "(%s)", rnames[r->tn.rval] );
return;
}
if( pp->tn.op != REG ) cerror("illegal address");
printf( "(%s)", rnames[pp->tn.rval] );
return;
}
adrput( p )
register NODE *p;
{
/* output an address, with offsets, from p */
register o;
while( (o=p->in.op) == FLD || o==CONV )
{
p = p->in.left;
o = p->in.op;
}
switch( o )
{
case NAME:
acon( p );
sideff = 0;
return;
case ICON:
/* addressable value of the constant */
printf( "$" );
acon( p );
sideff = 0;
return;
case REG:
printf( "%s", rnames[p->tn.rval] );
sideff = 0;
return;
case STAR:
upput( p );
return;
case TEMP:
sideff = 0;
printf( "%ld(fp)", p->tn.lval - maxboff / SZCHAR );
return;
case VAUTO:
sideff = 0;
printf( "%ld(fp)", p->tn.lval );
return;
case VPARAM:
sideff = 0;
printf( "%ld(ap)", p->tn.lval );
return;
default:
cerror( "illegal address" );
return;
}
}
acon(p)
NODE *p;
{ /* print out a constant */
if( p->tn.name == 0 )
{ /* constant only */
printf( "%ld", p->tn.lval);
}
else if( p->tn.lval == 0 )
{ /* name only */
printf( "%s", p->tn.name );
}
else
{ /* name + offset */
printf( "%s+%ld", p->tn.name, p->tn.lval );
}
}
special()
{
cerror("reached special");
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.