#ifndef lint
-static char sccsid[] = "@(#)local2.c 1.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)local2.c 1.5 (Berkeley) %G%";
#endif
-# include "mfile2"
-# include "ctype.h"
+# include "pass2.h"
+# include <ctype.h>
+
+# define putstr(s) fputs((s), stdout)
+
# ifdef FORT
int ftlab1, ftlab2;
# endif
{
case DOUBLE:
- printf("d");
+ putchar('d');
return;
case FLOAT:
- printf("f");
+ putchar('f');
return;
case INT:
case UNSIGNED:
- printf("l");
+ putchar('l');
return;
case SHORT:
case USHORT:
- printf("w");
+ putchar('w');
return;
case CHAR:
case UCHAR:
- printf("b");
+ putchar('b');
return;
default:
if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type");
else {
- printf("l");
+ putchar('l');
return;
}
}
if (r->in.op == ICON)
if(r->in.name[0] == '\0') {
if (r->tn.lval == 0) {
- printf("clr");
+ putstr("clr");
prtype(l);
- printf(" ");
+ putchar('\t');
adrput(l);
return;
}
if (r->tn.lval < 0 && r->tn.lval >= -63) {
- printf("mneg");
+ putstr("mneg");
prtype(l);
r->tn.lval = -r->tn.lval;
goto ops;
}
#ifdef MOVAFASTER
} else {
- printf("movab");
- printf(" ");
+ putstr("movab\t");
acon(r);
- printf(",");
+ putchar(',');
adrput(l);
return;
#endif MOVAFASTER
if (l->in.op == REG) {
if( tlen(l) < tlen(r) ) {
- !ISUNSIGNED(l->in.type)?
- printf("cvt"):
- printf("movz");
+ putstr(!ISUNSIGNED(l->in.type)?
+ "cvt": "movz");
prtype(l);
- printf("l");
+ putchar('l');
goto ops;
} else
l->in.type = INT;
}
if (tlen(l) == tlen(r)) {
- printf("mov");
+ putstr("mov");
prtype(l);
goto ops;
} else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type))
- printf("movz");
+ putstr("movz");
else
- printf("cvt");
+ putstr("cvt");
prtype(r);
prtype(l);
ops:
- printf(" ");
+ putchar('\t');
adrput(r);
- printf(",");
+ putchar(',');
adrput(l);
return;
}
if (xdebug) eprint(p, 0, &val, &val);
r = p->in.right;
if( tlen(r) == sizeof(int) && r->in.type != FLOAT )
- printf("movl");
+ putstr("movl");
else {
- printf(ISUNSIGNED(r->in.type) ? "movz" : "cvt");
+ putstr(ISUNSIGNED(r->in.type) ? "movz" : "cvt");
prtype(r);
- printf("l");
+ putchar('l');
}
return;
}
case 'D': /* INCR and DECR */
zzzcode(p->in.left, 'A');
- printf("\n ");
+ putstr("\n ");
case 'E': /* INCR and DECR, FOREFF */
if (p->in.right->tn.lval == 1)
{
- printf("%s", (p->in.op == INCR ? "inc" : "dec") );
+ putstr(p->in.op == INCR ? "inc" : "dec");
prtype(p->in.left);
- printf(" ");
+ putchar('\t');
adrput(p->in.left);
return;
}
- printf("%s", (p->in.op == INCR ? "add" : "sub") );
+ putstr(p->in.op == INCR ? "add" : "sub");
prtype(p->in.left);
- printf("2 ");
+ putstr("2 ");
adrput(p->in.right);
- printf(",");
+ putchar(',');
adrput(p->in.left);
return;
case 'F': /* masked constant for fields */
- printf("$%d", (p->in.right->tn.lval&((1<<fldsz)-1))<<fldshf);
+ printf(ACONFMT, (p->in.right->tn.lval&((1<<fldsz)-1))<<fldshf);
return;
case 'H': /* opcode for shift */
if(p->in.op == LS || p->in.op == ASG LS)
- printf("shll");
+ putstr("shll");
else if(ISUNSIGNED(p->in.left->in.type))
- printf("shrl");
+ putstr("shrl");
else
- printf("shar");
+ putstr("shar");
return;
case 'L': /* type of left operand */
}
case 'S': /* structure assignment */
- {
- register NODE *l, *r;
- register int size;
+ stasg(p);
+ break;
- if( p->in.op == STASG ){
- l = p->in.left;
- r = p->in.right;
+ default:
+ cerror( "illegal zzzcode" );
+ }
+ }
- }
- else if( p->in.op == STARG ){ /* store an arg into a temporary */
- l = getlr( p, '3' );
- r = p->in.left;
- }
- else cerror( "STASG bad" );
-
- if( r->in.op == ICON ) r->in.op = NAME;
- else if( r->in.op == REG ) r->in.op = OREG;
- else if( r->in.op != OREG ) cerror( "STASG-r" );
-
- size = p->stn.stsize;
-
- 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(" movl ");
- upput(r);
- printf(",");
- upput(l);
- printf("\n movl ");
- break;
- default:
- printf(" movab ");
- adrput(l);
- printf(",r1\n movab ");
- adrput(r);
- printf(",r0\n movl $%d,r2\n movblk\n", size);
- rname(2);
- goto endstasg;
- }
- adrput(r);
- printf(",");
- adrput(l);
- printf("\n");
- endstasg:
- if( r->in.op == NAME ) r->in.op = ICON;
- else if( r->in.op == OREG ) r->in.op = REG;
+#define MOVB(dst, src, off) { \
+ putstr("\tmovb\t"); upput(src, off); putchar(','); \
+ upput(dst, off); putchar('\n'); \
+}
+#define MOVW(dst, src, off) { \
+ putstr("\tmovw\t"); upput(src, off); putchar(','); \
+ upput(dst, off); putchar('\n'); \
+}
+#define MOVL(dst, src, off) { \
+ putstr("\tmovl\t"); upput(src, off); putchar(','); \
+ upput(dst, off); putchar('\n'); \
+}
+/*
+ * Generate code for a structure assignment.
+ */
+stasg(p)
+ register NODE *p;
+{
+ register NODE *l, *r;
+ register int size;
- }
+ switch (p->in.op) {
+ case STASG: /* regular assignment */
+ l = p->in.left;
+ r = p->in.right;
+ break;
+ case STARG: /* place arg on the stack */
+ l = getlr(p, '3');
+ r = p->in.left;
+ break;
+ default:
+ cerror("STASG bad");
+ /*NOTREACHED*/
+ }
+ /*
+ * Pun source for use in code generation.
+ */
+ switch (r->in.op) {
+ case ICON:
+ r->in.op = NAME;
break;
+ case REG:
+ r->in.op = OREG;
+ break;
+ default:
+ cerror( "STASG-r" );
+ /*NOTREACHED*/
+ }
+ size = p->stn.stsize;
+ if (size <= 0 || size > 65535)
+ cerror("structure size out of range");
+ /*
+ * Generate optimized code based on structure size
+ * and alignment properties....
+ */
+ switch (size) {
+
+ case 1:
+ putstr("\tmovb\t");
+ optimized:
+ adrput(r);
+ putchar(',');
+ adrput(l);
+ putchar('\n');
+werror("optimized structure assignment (size %d alignment %d)", size, p->stn.stalign);
+ break;
+
+ case 2:
+ if (p->stn.stalign != 2) {
+ MOVB(l, r, SZCHAR);
+ putstr("\tmovb\t");
+ } else
+ putstr("\tmovw\t");
+ goto optimized;
+
+ case 4:
+ if (p->stn.stalign != 4) {
+ if (p->stn.stalign != 2) {
+ MOVB(l, r, 3*SZCHAR);
+ MOVB(l, r, 2*SZCHAR);
+ MOVB(l, r, 1*SZCHAR);
+ putstr("\tmovb\t");
+ } else {
+ MOVW(l, r, SZSHORT);
+ putstr("\tmovw\t");
+ }
+ } else
+ putstr("\tmovl\t");
+ goto optimized;
+
+ case 6:
+ if (p->stn.stalign != 2)
+ goto movblk;
+ MOVW(l, r, 2*SZSHORT);
+ MOVW(l, r, 1*SZSHORT);
+ putstr("\tmovw\t");
+ goto optimized;
+
+ case 8:
+ if (p->stn.stalign == 4) {
+ MOVL(l, r, SZLONG);
+ putstr("\tmovl\t");
+ goto optimized;
+ }
+ /* fall thru...*/
default:
- cerror( "illegal zzzcode" );
+ movblk:
+ /*
+ * Can we ever get a register conflict with R1 here?
+ */
+ putstr("\tmovab\t");
+ adrput(l);
+ putstr(",r1\n\tmovab\t");
+ adrput(r);
+ printf(",r0\n\tmovl\t$%d,r2\n\tmovblk\n", size);
+ rname(R2);
+ break;
+ }
+ /*
+ * Reverse above pun for reclaim.
+ */
+ if (r->in.op == NAME)
+ r->in.op = ICON;
+ else if (r->in.op == OREG)
+ r->in.op = REG;
+}
+
+/*
+ * Output the address of the second item in the
+ * pair pointed to by p.
+ */
+upput(p, size)
+ register NODE *p;
+{
+ CONSZ save;
+
+ if (p->in.op == FLD)
+ p = p->in.left;
+ switch (p->in.op) {
+
+ case NAME:
+ case OREG:
+ save = p->tn.lval;
+ p->tn.lval += size/SZCHAR;
+ adrput(p);
+ p->tn.lval = save;
+ break;
+
+ case REG:
+ if (size == SZLONG) {
+ putstr(rname(p->tn.rval+1));
+ break;
}
+ /* fall thru... */
+
+ default:
+ cerror("illegal upper address op %s size %d",
+ opst[p->tn.op], size);
+ /*NOTREACHED*/
}
+}
rmove( rt, rs, t ) TWORD t;{
printf( " movl %s,%s\n", rname(rs), rname(rt) );
fregs = 6; /* tbl- 6 free regs on Tahoe (0-5) */
}
+#ifndef szty
szty(t) TWORD t;{ /* size, in registers, needed to hold thing of type t */
return(t==DOUBLE ? 2 : 1 );
}
+#endif
rewfld( p ) NODE *p; {
return(1);
return(0);
}
+#ifndef shltype
shltype( o, p ) register NODE *p; {
return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) );
}
+#endif
flshape( p ) NODE *p; {
register int o = p->in.op;
}
adrcon( val ) CONSZ val; {
- printf( "$" );
- printf( CONFMT, val );
+ printf(ACONFMT, val);
}
conput( p ) register NODE *p; {
return;
case REG:
- printf( "%s", rname(p->tn.rval) );
+ putstr(rname(p->tn.rval));
return;
default:
cerror( "insput" );
}
-upput( p ) register NODE *p; {
- /* output the address of the second long in the
- pair pointed to by p (for DOUBLEs)*/
- CONSZ save;
-
- if( p->in.op == FLD ){
- p = p->in.left;
- }
- switch( p->in.op ){
-
- case NAME:
- case OREG:
- save = p->tn.lval;
- p->tn.lval += SZLONG/SZCHAR;
- adrput(p);
- p->tn.lval = save;
- return;
-
- case REG:
- printf( "%s", rname(p->tn.rval+1) );
- return;
-
- default:
- cerror( "illegal upper address" );
- }
- }
-
adrput( p ) register NODE *p; {
register int r;
/* output an address, with offsets, from p */
case ICON:
/* addressable value of the constant */
- printf( "$" );
+ putchar('$');
acon( p );
return;
case REG:
- printf( "%s", rname(p->tn.rval) );
+ putstr(rname(p->tn.rval));
if(p->in.type == DOUBLE) /* for entry mask */
(void) rname(p->tn.rval+1);
return;
register int flags;
flags = R2UPK3(r);
- if( flags & 1 ) printf("*");
+ if( flags & 1 ) putchar('*');
if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p);
if( R2UPK1(r) != 100) printf( "(%s)", rname(R2UPK1(r)) );
printf( "[%s]", rname(R2UPK2(r)) );
if( r == FP && p->tn.lval > 0 ){ /* in the argument region */
if( p->in.name[0] != '\0' ) werror( "bad arg temp" );
printf( CONFMT, p->tn.lval );
- printf( "(fp)" );
+ putstr( "(fp)" );
return;
}
if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p );
case UNARY MUL:
/* STARNM or STARREG found */
if( tshape(p, STARNM) ) {
- printf( "*" );
+ putchar( '*' );
adrput( p->in.left);
}
return;
if( p->in.name[0] == '\0' ){
printf( CONFMT, p->tn.lval);
- }
- else if( p->tn.lval == 0 ) {
+ return;
+ } else {
#ifndef FLEXNAMES
printf( "%.8s", p->in.name );
#else
- printf( "%s", p->in.name );
+ putstr(p->in.name);
#endif
+ if (p->tn.lval != 0) {
+ putchar('+');
+ printf(CONFMT, p->tn.lval);
}
- else {
-#ifndef FLEXNAMES
- printf( "%.8s+", p->in.name );
-#else
- printf( "%s+", p->in.name );
-#endif
- printf( CONFMT, p->tn.lval );
- }
+ }
}
genscall( p, cookie ) register NODE *p; {
# ifdef ONEPASS
/* do local tree transformations and optimizations */
# define RV(p) p->in.right->tn.lval
+# define nncon(p) ((p)->in.op == ICON && (p)->in.name[0] == 0)
register int o = p->in.op;
register int i;