From 1d43595d6c3a52e1832355555ce4c2fa38148ad9 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sun, 26 Jan 1986 07:55:34 -0800 Subject: [PATCH] optimize structure assignment based on size and alignment SCCS-vsn: old/pcc/ccom.tahoe/local2.c 1.3 --- usr/src/old/pcc/ccom.tahoe/local2.c | 235 +++++++++++++++++++--------- 1 file changed, 162 insertions(+), 73 deletions(-) diff --git a/usr/src/old/pcc/ccom.tahoe/local2.c b/usr/src/old/pcc/ccom.tahoe/local2.c index 20e5bee4ff..5e1070feaf 100644 --- a/usr/src/old/pcc/ccom.tahoe/local2.c +++ b/usr/src/old/pcc/ccom.tahoe/local2.c @@ -1,5 +1,5 @@ #ifndef lint -static char sccsid[] = "@(#)local2.c 1.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)local2.c 1.3 (Berkeley) %G%"; #endif # include "mfile2" @@ -380,60 +380,176 @@ zzzcode( p, c ) register NODE *p; { } 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"); - /* - * Can't optimize with movw's or movl's here as - * we don't know the alignment properties of - * either source or destination (governed, potentially - * by alignment of enclosing structure/union). - * (PERHAPS WE COULD SIMULATE dclstruct?) - */ - if (size != 1) { - printf("\tmovab\t"); - adrput(l); - printf(",r1\n\tmovab\t"); - adrput(r); - printf(",r0\n\tmovl\t$%d,r2\n\tmovblk\n", size); - rname(2); - } else { +#define MOVB(dst, src, off) { \ + printf("\tmovb\t"); upput(src, off); putchar(','); \ + upput(dst, off); putchar('\n'); \ +} +#define MOVW(dst, src, off) { \ + printf("\tmovw\t"); upput(src, off); putchar(','); \ + upput(dst, off); putchar('\n'); \ +} +#define MOVL(dst, src, off) { \ + printf("\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: + printf("\tmovb\t"); + optimized: + adrput(r); + printf(","); + adrput(l); + printf("\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); + printf("\tmovb\t"); + } else + printf("\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); printf("\tmovb\t"); - adrput(r); - printf(","); - adrput(l); - printf("\n"); + } else { + MOVW(l, r, SZSHORT); + printf("\tmovw\t"); } - if( r->in.op == NAME ) r->in.op = ICON; - else if( r->in.op == OREG ) r->in.op = REG; + } else + printf("\tmovl\t"); + goto optimized; + + case 6: + if (p->stn.stalign != 2) + goto movblk; + MOVW(l, r, 2*SZSHORT); + MOVW(l, r, 1*SZSHORT); + printf("\tmovw\t"); + goto optimized; + + case 8: + if (p->stn.stalign == 4) { + MOVL(l, r, SZLONG); + printf("\tmovl\t"); + goto optimized; + } + /* fall thru...*/ - } + default: + movblk: + /* + * Can we ever get a register conflict with R1 here? + */ + printf("\tmovab\t"); + adrput(l); + printf(",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; +} - default: - cerror( "illegal zzzcode" ); +/* + * 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) { + printf("%s", 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) ); @@ -603,33 +719,6 @@ insput( p ) NODE *p; { 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 */ -- 2.20.1