Subject: pcc update Index: lib/pcc 2.11BSD Description: There is really only 1 file needed to be installed in this directory for 'lint' to be compiled. This did however seem as good a time as any to update 'pcc' so that it would at least pass thru the current C compiler without errors. The old 'pcc' hasn't been useable for quite some time and this update does not do nearly enough to correct that. For one thing the ability to build the compiler 2 pass instead of 1 pass has been lost. By the time the tables are increased to where moderately large programs can be compiled (the kernel for example) the compiler is too large to even initialize itself. The following patch is intended to bring the 'pcc' directory more in line with the 4.3BSD version with regard to filenames (macdefs becomes macdefs.h, and so on). Also some of the less machine dependent (switch/case hashtables for example) were adopted. The FLEXNAME ifdef's have been added so that when/if the assembler,linker and the like become updated then long variable names might be possible. The actual code generation has been pretty much left alone (structure copying was altered to follow the Vax method, it's possible something has been broken) and it might be possible for someone to reconstruct the 2 pass version, at which point a C compiler which supports "unsigned long" would become a reality (I have the runtime routines for this written and tested). Repeat-By: Inspection of the sources. Fix: There is a script provided (/tmp/s) which can be used to make the initial changes in the 'pcc' directory, or the commands can be done manually using the script as a guide. The 'stab.c' file included is a collection of stub routines because symbolic debugging information is not supported by the assembler/linker. The entry points were included for compatibility reasons (didn't have to modify the rest of the sources to remove the references). Perhaps the debugging information could be added later. 'pcc' will successfully compile and link (it is overlaid of course). It will not, in its present state, run because the data space is too large. If the 2 pass capability were ever reinvented (or found) then the compiler would possibly require minimal debugging to be useable once again. ----------------------------------------------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # /tmp/s # /tmp/stab.c # /tmp/c # This archive created: Sat Aug 17 17:55:44 1991 export PATH; PATH=/bin:/usr/bin:$PATH if test -f '/tmp/s' then echo shar: "will not over-write existing file '/tmp/s'" else sed 's/^X//' << \SHAR_EOF > '/tmp/s' X#! /bin/sh -v Xcd /usr/src/lib/pcc Xrm INDEX :rofix fort.h.vax Xcp /tmp/stab.c . Xmv macdefs macdefs.h Xmv mac2defs mac2defs.h Xcd .. Xzcat PORT/pcc.tar.Z | tar xvf - pcc/localdefs.h pcc/DEBUGS pcc/INFO Xcd pcc SHAR_EOF chmod +x '/tmp/s' fi if test -f '/tmp/stab.c' then echo shar: "will not over-write existing file '/tmp/stab.c'" else sed 's/^X//' << \SHAR_EOF > '/tmp/stab.c' X#include "pass1.h" X/* X * No op the stab stuff for now X*/ X Xpsline() X { X return(0); X } X X/* ARGSUSED */ Xpstab(p,n) X struct symtab *p; X int n; X { X return(0); X } X X/* ARGSUSED */ Xoutstab(p) X struct symtab *p; X { X return(0); X } X X/* ARGSUSED */ Xfixarg(p) X struct symtab *p; X { X return(0); X } X X/* ARGSUSED */ Xoutstruct(p) X struct symtab *p; X { X return(0); X } X X/* ARGSUSED */ Xpfstab(cp) X char *cp; X { X return(0); X } X X/* ARGSUSED */ Xplcstab(level) X int level; X { X return(0); X } X X/* ARGSUSED */ Xprcstab(level) X int level; X { X return(0); X } SHAR_EOF fi if test -f '/tmp/c' then echo shar: "will not over-write existing file '/tmp/c'" else sed 's/^X//' << \SHAR_EOF > '/tmp/c' X*** Makefile.old Mon Jul 24 18:42:27 1989 X--- Makefile Sun Aug 4 12:57:03 1991 X*************** X*** 1,80 **** X! INSTALL=${DESTDIR}/usr/lib/ccom X! M=/usr/src/lib/mip X! CFLAGS=-O X! head: ccom ; X X! all: ccom X X! cp: ccom X! cp ccom ${DESTDIR}/usr/lib/ccom X! rm *.o cgram.c ccom X X! cmp: ccom X! cmp ccom ${DESTDIR}/usr/lib/ccom X! rm *.o cgram.c X X! ccom: cgram.o xdefs.o scan.o pftn.o trees.o optim.o code.o local.o reader.o local2.o order.o match.o allo.o comm1.o table.o X! cc $(CFLAGS) -s -o ccom -i cgram.o xdefs.o scan.o pftn.o trees.o optim.o code.o local.o reader.o local2.o order.o match.o allo.o comm1.o table.o X! trees.o: $M/manifest macdefs $M/mfile1 $M/trees.c X! cc -c $(CFLAGS) -I$M -I. $M/trees.c X! optim.o: $M/manifest macdefs $M/mfile1 $M/optim.c X! cc -c $(CFLAGS) -I$M -I. $M/optim.c X! pftn.o: $M/manifest macdefs $M/mfile1 $M/pftn.c X! cc -c $(CFLAGS) -I$M -I. $M/pftn.c X! code.o: $M/manifest macdefs $M/mfile1 X! cc -c $(CFLAGS) -I$M -I. code.c X! local.o: $M/manifest macdefs $M/mfile1 X! cc -c $(CFLAGS) -I$M -I. local.c X! scan.o: $M/manifest macdefs $M/mfile1 $M/scan.c X! cc -c $(CFLAGS) -I$M -I. $M/scan.c X! xdefs.o: $M/manifest $M/mfile1 macdefs $M/xdefs.c X! cc -c $(CFLAGS) -I$M -I. $M/xdefs.c X! cgram.o: $M/manifest $M/mfile1 macdefs cgram.c X! cc -c $(CFLAGS) -I$M -I. cgram.c X! cgram.c: $M/cgram.y X! yacc $M/cgram.y X mv y.tab.c cgram.c X! comm1.o: $M/manifest $M/mfile1 $M/common macdefs $M/comm1.c X! cc -c $(CFLAGS) -I. -I$M $M/comm1.c X! table.o: $M/manifest $M/mfile2 mac2defs macdefs table.c X! cc -c $(CFLAGS) -I$M -I. table.c X! reader.o: $M/manifest $M/mfile2 mac2defs macdefs $M/reader.c X! cc -c $(CFLAGS) -I$M -I. $M/reader.c X! local2.o: $M/manifest $M/mfile2 mac2defs macdefs X! cc -c $(CFLAGS) -I$M -I. local2.c X! order.o: $M/manifest $M/mfile2 mac2defs macdefs X! cc -c $(CFLAGS) -I$M -I. order.c X! match.o: $M/manifest $M/mfile2 mac2defs macdefs $M/match.c X! cc -c $(CFLAGS) -I$M -I. $M/match.c X! allo.o: $M/manifest $M/mfile2 mac2defs macdefs $M/allo.c X! cc -c $(CFLAGS) -I$M -I. $M/allo.c X! shrink: X! rm *.o ccom X! lintall: X! lint -hpv -I. -I$M cgram.c xdefs.c $M/scan.c $M/pftn.c $M/trees.c $M/optim.c code.c local.c $M/reader.c local2.c order.c $M/match.c $M/allo.c $M/comm1.c table.c X! fort: ccom fort.o freader.o fallo.o fmatch.o ftable.o forder.o flocal2.o fcomm2.o X! cc -i $(CFLAGS) fort.o freader.o fallo.o fmatch.o ftable.o forder.o flocal2.o fcomm2.o X! mv a.out fort X! fort.o: fort.h $M/fort.c X! cc -c $(CFLAGS) -I$M -I. $M/fort.c X! freader.o: reader.o X! cc -c $(CFLAGS) -I$M -I. $M/freader.c X! fallo.o: allo.o X! cc -c $(CFLAGS) -I$M -I. $M/fallo.c X! fmatch.o: match.o X! cc -c $(CFLAGS) -I$M -I. $M/fmatch.c X! ftable.o: table.o X! cc -c $(CFLAGS) -I$M -I. $M/ftable.c X! forder.o: order.o X! cc -c $(CFLAGS) -I$M -I. $M/forder.c X! flocal2.o: local2.o X! cc -c $(CFLAGS) -I$M -I. $M/flocal2.c X! fcomm2.o: $M/common X! cc -c $(CFLAGS) -I$M -I. $M/fcomm2.c X! fort.o freader.o fallo.o fmatch.o ftable.o forder.o flocal2.o fcomm2.o: $M/mfile2 $M/manifest macdefs mac2defs X! install: X! cp ccom $(INSTALL) X! cp macdefs mac2defs local.c code.c local2.c order.c table.c ${DESTDIR}/usr/src/cmd/pcc X X clean: X! rm -f *.o X--- 1,104 ---- X! # X! # Makefile 1.13 86/03/11 X! # X! # Makefile for PCC X! # X! # FIXSTRUCT no trickery (just output structure) X! # X! # Some symbols are specific to certain compilers: X! # ONEPASS compile pass 1 and pass 2 together X! # SPRECC do single precision in single not double X! # FORT get f77-style pass 2 X! # X! CONFIG= -DONEPASS "-DFIXSTRUCT=outstruct" X! O = -O X! CFLAGS = $(O) -I. -I$(M) $(CONFIG) X! COPTS = $(CFLAGS) X! LDFLAGS = -i X X! RM= /bin/rm -f X! LN= /bin/ln -s X X! P1INCS= $M/pass1.h macdefs.h $M/manifest.h pcclocal.h $M/config.h $M/ndu.h \ X! /usr/include/stdio.h X! P1ONEP= $(P1INCS) $M/onepass.h X! P2INCS= $M/pass2.h macdefs.h mac2defs.h $M/manifest.h pcclocal.h $M/config.h \ X! $M/ndu.h /usr/include/stdio.h X! P2ONEP= $(P2INCS) $M/onepass.h X X! M=../mip X! TESTDIR = . X X! all: ccom X! X! # X! # 'ccom' is a one-pass C compiler. X! # X! ccom: cgram.o xdefs.o scan.o pftn.o trees.o optim.o code.o local.o \ X! reader.o local2.o order.o match.o allo.o comm1.o table.o stab.o X! $(CC) $(LDFLAGS) xdefs.o scan.o pftn.o trees.o \ X! optim.o code.o local.o reader.o order.o match.o \ X! allo.o -Z comm1.o cgram.o -Z local2.o -Y table.o stab.o \ X! -o $(TESTDIR)/ccom X! X! trees.o: $(P1ONEP) $M/trees.c X! $(CC) -c $(COPTS) $M/trees.c X! optim.o: $(P1ONEP) $M/optim.c X! $(CC) -c $(COPTS) $M/optim.c X! pftn.o: $(P1ONEP) $M/pftn.c X! $(CC) -c $(COPTS) $M/pftn.c X! code.o: $(P1ONEP) code.c X! $(CC) -c $(COPTS) code.c X! local.o: $(P1ONEP) local.c X! $(CC) -c $(COPTS) local.c X! scan.o: $(P1ONEP) $M/scan.c X! $(CC) -c $(COPTS) $M/scan.c X! xdefs.o: $(P1ONEP) $M/xdefs.c X! $(CC) -c $(COPTS) $M/xdefs.c X! cgram.o: $(P1ONEP) cgram.c X! $(CC) -c $(COPTS) cgram.c X! cgram.c: $M/cgram.y pcctokens X! cat pcctokens $M/cgram.y > gram.in X! $(YACC) gram.in X mv y.tab.c cgram.c X! comm1.o: $(P1ONEP) $M/common.c X! $(LN) $M/common.c comm1.c X! $(CC) -c $(COPTS) -DPASS1COMMON comm1.c X! $(RM) comm1.c X! table.o: $(P2ONEP) table.c X! $(CC) -c $(COPTS) table.c X! reader.o: $(P2ONEP) $M/reader.c X! $(CC) -c $(COPTS) $M/reader.c X! local2.o: $(P2ONEP) local2.c X! $(CC) -c $(COPTS) local2.c X! order.o: $(P2ONEP) order.c X! $(CC) -c $(COPTS) order.c X! match.o: $(P2ONEP) $M/match.c X! $(CC) -c $(COPTS) $M/match.c X! allo.o: $(P2ONEP) $M/allo.c X! $(CC) -c $(COPTS) $M/allo.c X! stab.o: $(P2ONEP) stab.c X! $(CC) -c $(COPTS) stab.c X X+ install: all X+ install -s ${TESTDIR}/ccom ${DESTDIR}/lib/ccom X+ X+ GREP= egrep X+ X+ pcclocal.h: localdefs.h /usr/include/pcc.h X+ $(RM) pcclocal.h X+ cat /usr/include/pcc.h localdefs.h | $(GREP) '^#[ ]*(define[ ][ ]*PCC(F|T|TM|OM)?_|ifdef|ifndef|endif)' | sed -e 's/PCC[A-Z]*_//' > pcclocal.h X+ X+ pcctokens: localdefs.h /usr/include/pcc.h X+ $(RM) pcctokens X+ cat /usr/include/pcc.h localdefs.h | $(GREP) '^#[ ]*define[ ][ ]*PCC_' | sed -e 's/^#[ ]*define[ ][ ]*PCC_/%term /' > pcctokens X+ X+ shrink: X+ $(RM) *.o ccom X clean: X! $(RM) *.o ccom cgram.c pcctokens pcclocal.h gram.in X! lintall: X! lint -hax -I. -I$M -DONEPASS -DPASS1COMMON cgram.c $M/xdefs.c \ X! $M/scan.c $M/pftn.c $M/trees.c $M/optim.c code.c \ X! local.c $M/reader.c local2.c order.c $M/match.c $M/allo.c \ X! $M/common.c table.c stab.c X*** code.c.old Fri Jul 10 17:36:06 1981 X--- code.c Mon Jul 29 09:00:56 1991 X*************** X*** 1,23 **** X! # include X! # include X X! # include "mfile1" X X! int proflag; X! int strftn = 0; /* is the current function one which returns a value */ X! FILE *tmpfile; X! FILE *outfile = stdout; X X branch( n ){ X /* output a branch to label n */ X /* exception is an ordinary function branching to retlab: then, return */ X if( n == retlab && !strftn ){ X! printf( " jmp cret\n" ); X } X else printf( " jbr L%d\n", n ); X } X X! int lastloc = PROG; X X defalign(n) { X /* cause the alignment to become a multiple of n */ X--- 1,27 ---- X! # include "pass1.h" X! # include X! # include X! # include X X! int proflg = 0; /* are we generating profiling code? */ X! int strftn = 0; /* is the current function one which returns a value */ X! int gdebug; X! int fdefflag; /* are we within a function definition ? */ X! char NULLNAME[8]; X! int labelno; X X! # define putstr(s) fputs((s), stdout) X X branch( n ){ X /* output a branch to label n */ X /* exception is an ordinary function branching to retlab: then, return */ X if( n == retlab && !strftn ){ X! putstr( " jmp cret\n" ); X } X else printf( " jbr L%d\n", n ); X } X X! int lastloc = { -1 }; X X defalign(n) { X /* cause the alignment to become a multiple of n */ X*************** X*** 35,54 **** X switch( l ){ X X case PROG: X! outfile = stdout; X! printf( " .text\n" ); X break; X X case DATA: X case ADATA: X! outfile = stdout; X! if( temp != DATA && temp != ADATA ) X! printf( " .data\n" ); X break; X X case STRNG: X case ISTRNG: X- outfile = tmpfile; X break; X X case STAB: X--- 39,55 ---- X switch( l ){ X X case PROG: X! putstr( " .text\n" ); X! psline(); X break; X X case DATA: X case ADATA: X! putstr( " .data\n" ); X break; X X case STRNG: X case ISTRNG: X break; X X case STAB: X*************** X*** 64,70 **** X X deflab( n ){ X /* output something to define the current position as label n */ X! fprintf( outfile, "L%d:\n", n ); X } X X int crslab = 10; X--- 65,71 ---- X X deflab( n ){ X /* output something to define the current position as label n */ X! printf( "L%d:\n", n ); X } X X int crslab = 10; X*************** X*** 77,106 **** X efcode(){ X /* code for the end of a function */ X X! if( strftn ){ /* copy output (in r0) to caller */ X register struct symtab *p; X! register int stlab; X! register int count; X! int size; X X p = &stab[curftn]; X X deflab( retlab ); X X! stlab = getlab(); X! printf( " mov $L%d,r1\n", stlab ); X! size = tsize( DECREF(p->stype), p->dimoff, p->sizoff ) / SZCHAR; X! count = size/2; X! while( count-- ) { X! printf( " mov (r0)+,(r1)+\n" ); X! } X! printf( " mov $L%d,r0\n", stlab ); X! printf( " .bss\nL%d: .=.+%d.\n .text\n", stlab, size ); X /* turn off strftn flag, so return sequence will be generated */ X strftn = 0; X } X branch( retlab ); X p2bend(); X } X X bfcode( a, n ) int a[]; { X--- 78,129 ---- X efcode(){ X /* code for the end of a function */ X X! if( strftn ){ /* copy output (in R0) to caller */ X! register NODE *l, *r; X register struct symtab *p; X! register TWORD t; X! int i; X X p = &stab[curftn]; X+ t = p->stype; X+ t = DECREF(t); X X deflab( retlab ); X X! i = getlab(); /* label for return area */ X! #ifndef LCOMM X! putstr(" .bss\n" ); X! printf("L%d: .=.+%d.\n", i, tsize(t, p->dimoff, p->sizoff)/SZCHAR ); X! putstr(" .text\n" ); X! #else X! { int sz = tsize(t, p->dimoff, p->sizoff) / SZCHAR; X! if (sz % sizeof (int)) X! sz += sizeof (int) - (sz % sizeof (int)); X! printf(" .lcomm L%d,%d\n", i, sz); X! } X! #endif X! psline(); X! printf(" mov $L%d,r1\n", i); X! X! reached = 1; X! l = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff ); X! l->tn.rval = 1; /* R1 */ X! l->tn.lval = 0; /* no offset */ X! r = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff ); X! r->tn.rval = 0; /* R0 */ X! r->tn.lval = 0; X! l = buildtree( UNARY MUL, l, NIL ); X! r = buildtree( UNARY MUL, r, NIL ); X! l = buildtree( ASSIGN, l, r ); X! l->in.op = FREE; X! ecomp( l->in.left ); X! printf( " mov $L%d,r0\n", i ); X /* turn off strftn flag, so return sequence will be generated */ X strftn = 0; X } X branch( retlab ); X p2bend(); X+ fdefflag = 0; X } X X bfcode( a, n ) int a[]; { X*************** X*** 109,115 **** X register i; X register temp; X register struct symtab *p; X! int off; X X locctr( PROG ); X p = &stab[curftn]; X--- 132,138 ---- X register i; X register temp; X register struct symtab *p; X! OFFSZ off; X X locctr( PROG ); X p = &stab[curftn]; X*************** X*** 119,134 **** X strftn = (temp==STRTY) || (temp==UNIONTY); X X retlab = getlab(); X- if( proflag ){ X- int plab; X- plab = getlab(); X- printf( " mov $L%d,r0\n", plab ); X- printf( " jsr pc,mcount\n" ); X- printf( " .bss\nL%d: .=.+2\n .text\n", plab ); X- } X X /* routine prolog */ X X printf( " jsr r5,csv\n" ); X /* adjust stack for autos */ X printf( " sub $.F%d,sp\n", ftnno ); X--- 142,157 ---- X strftn = (temp==STRTY) || (temp==UNIONTY); X X retlab = getlab(); X X /* routine prolog */ X X+ if( proflg ){ /* profile code */ X+ i = getlab(); X+ printf( " mov $L%d,r0\n", i ); X+ printf( " jsr pc,mcount\n" ); X+ printf( " .bss\nL%d: .=.+2\n .text\n", i ); X+ } X+ X printf( " jsr r5,csv\n" ); X /* adjust stack for autos */ X printf( " sub $.F%d,sp\n", ftnno ); X*************** X*** 142,157 **** X p->sclass = PARAM; /* forget that it is a register */ X p->offset = NOOFFSET; X oalloc( p, &off ); X! printf( " mov %d.(r5),r%d\n", p->offset/SZCHAR, temp ); X p->offset = temp; /* remember register number */ X p->sclass = REGISTER; /* remember that it is a register */ X } X else { X if( oalloc( p, &off ) ) cerror( "bad argument" ); X } X X } X } X X bccode(){ /* called just before the first executable statment */ X /* by now, the automatics and register variables are allocated */ X--- 165,195 ---- X p->sclass = PARAM; /* forget that it is a register */ X p->offset = NOOFFSET; X oalloc( p, &off ); X! printf( " mov %d.(r5),r%d\n", p->offset/SZCHAR, temp); X p->offset = temp; /* remember register number */ X p->sclass = REGISTER; /* remember that it is a register */ X } X+ else if( p->stype == STRTY || p->stype == UNIONTY ) { X+ p->offset = NOOFFSET; X+ if( oalloc( p, &off ) ) cerror( "bad argument" ); X+ SETOFF( off, ALSTACK ); X+ } X else { X if( oalloc( p, &off ) ) cerror( "bad argument" ); X } X X } X+ if (gdebug) { X+ #ifdef STABDOT X+ pstabdot(N_SLINE, lineno); X+ #else X+ pstab(NULLNAME, N_SLINE); X+ printf("0,%d,LL%d\n", lineno, labelno); X+ printf("LL%d:\n", labelno++); X+ #endif X } X+ fdefflag = 1; X+ } X X bccode(){ /* called just before the first executable statment */ X /* by now, the automatics and register variables are allocated */ X*************** X*** 183,207 **** X if( p->sclass == EXTDEF ){ X printf( " .globl %s\n", exname( p->sname ) ); X } X! if( p->sclass == STATIC && p->slevel>1 ) deflab( p->offset ); X else printf( "%s:\n", exname( p->sname ) ); X X } X X bycode( t, i ){ X /* put byte i+1 in a string */ X X i &= 07; X if( t < 0 ){ /* end of the string */ X! if( i != 0 ) fprintf( outfile, "\n" ); X } X X else { /* stash byte t into string */ X! if( i == 0 ) fprintf( outfile, " .byte " ); X! else fprintf( outfile, "," ); X! fprintf( outfile, "%o", t ); X! if( i == 07 ) fprintf( outfile, "\n" ); X } X } X X zecode( n ){ X--- 221,288 ---- X if( p->sclass == EXTDEF ){ X printf( " .globl %s\n", exname( p->sname ) ); X } X! if( p->sclass == STATIC && p->slevel>1 ) deflab( (int)p->offset ); X else printf( "%s:\n", exname( p->sname ) ); X X } X X bycode( t, i ){ X+ #ifdef ASSTRINGS X+ static int lastoctal = 0; X+ #endif X+ X /* put byte i+1 in a string */ X X+ #ifdef ASSTRINGS X+ X+ i &= 077; X+ if ( t < 0 ){ X+ if ( i != 0 ) putstr( "\"\n" ); X+ } else { X+ if ( i == 0 ) putstr("\t.ascii\t\""); X+ if ( t == '\\' || t == '"'){ X+ lastoctal = 0; X+ printf("\\%c", t); X+ } X+ /* X+ * We escape the colon in strings so that X+ * c2 will, in its infinite wisdom, interpret X+ * the characters preceding the colon as a label. X+ * If we didn't escape the colon, c2 would X+ * throw away any trailing blanks or tabs after X+ * the colon, but reconstruct a assembly X+ * language semantically correct program. X+ * C2 hasn't been taught about strings. X+ */ X+ else if ( t == ':' || t < 040 || t >= 0177 ){ X+ lastoctal++; X+ printf("\\%o",t); X+ } X+ else if ( lastoctal && '0' <= t && t <= '9' ){ X+ lastoctal = 0; X+ printf("\"\n\t.ascii\t\"%c", t ); X+ } X+ else X+ { X+ lastoctal = 0; X+ putchar(t); X+ } X+ if ( i == 077 ) putstr("\"\n"); X+ } X+ #else X+ X i &= 07; X if( t < 0 ){ /* end of the string */ X! if( i != 0 ) putchar( '\n' ); X } X X else { /* stash byte t into string */ X! if( i == 0 ) putstr( " .byte " ); X! else putchar( ',' ); X! printf( "0x%x", t ); X! if( i == 07 ) putchar( '\n' ); X } X+ #endif X } X X zecode( n ){ X*************** X*** 232,274 **** X X where(c){ /* print location of error */ X /* c is either 'u', 'c', or 'w' */ X fprintf( stderr, "%s, line %d: ", ftitle, lineno ); X } X X- char *tmpname = "/tmp/pcXXXXXX"; X- X main( argc, argv ) char *argv[]; { X! int dexit(); X! register int c; X! register int i; X! int r; X! X! for( i=1; i0 && range <= 3*n && n>=4 ){ /* implement a direct switch */ X X+ swlab = getlab(); X dlab = p->slab >= 0 ? p->slab : getlab(); X X if( p[1].sval ){ X*************** X*** 300,306 **** X printf( " jhi L%d\n", dlab ); X X printf( " asl r0\n" ); X! printf( " jmp *L%d(r0)\n", swlab = getlab() ); X X /* output table */ X X--- 358,364 ---- X printf( " jhi L%d\n", dlab ); X X printf( " asl r0\n" ); X! printf( " jmp *L%d(r0)\n", swlab ); X X /* output table */ X X*************** X*** 321,326 **** X--- 379,398 ---- X X } X X+ if( n>8 ) { /* heap switch */ X+ X+ heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab(); X+ makeheap(p, n, 1); /* build heap */ X+ X+ walkheap(1, n); /* produce code */ X+ X+ if( p->slab >= 0 ) X+ branch( dlab ); X+ else X+ printf("L%d:\n", dlab); X+ return; X+ } X+ X /* debugging code */ X X /* out for the moment X*************** X*** 332,338 **** X for( i=1; i<=n; ++i ){ X /* already in r0 */ X X! printf( " cmp r0,$" ); X printf( CONFMT, p[i].sval ); X printf( ".\n jeq L%d\n", p[i].slab ); X } X--- 404,410 ---- X for( i=1; i<=n; ++i ){ X /* already in r0 */ X X! putstr( " cmp r0,$" ); X printf( CONFMT, p[i].sval ); X printf( ".\n jeq L%d\n", p[i].slab ); X } X*************** X*** 339,341 **** X--- 411,457 ---- X X if( p->slab>=0 ) branch( p->slab ); X } X+ X+ makeheap(p, m, n) X+ register struct sw *p; X+ { X+ register int q; X+ X+ q = select(m); X+ heapsw[n] = p[q]; X+ if( q>1 ) makeheap(p, q-1, 2*n); X+ if( q m ) break; X+ l = ((k = i/2 - 1) + 1)/2; X+ return( l + (m-k < l ? m-k : l)); X+ } X+ X+ walkheap(start, limit) X+ { X+ int label; X+ X+ X+ if( start > limit ) return; X+ printf(" cmp r0,$%d.\n", heapsw[start].sval); X+ printf(" jeq L%d\n", heapsw[start].slab); X+ if( (2*start) > limit ) { X+ printf(" jbr L%d\n", heapsw[0].slab); X+ return; X+ } X+ if( (2*start+1) <= limit ) { X+ label = getlab(); X+ printf(" jgt L%d\n", label); X+ } else X+ printf(" jgt L%d\n", heapsw[0].slab); X+ walkheap( 2*start, limit); X+ if( (2*start+1) <= limit ) { X+ printf("L%d:\n", label); X+ walkheap( 2*start+1, limit); X+ } X+ } X*** local.c.old Fri Jul 10 17:36:07 1981 X--- local.c Tue Jul 30 15:46:22 1991 X*************** X*** 1,4 **** X! # include "mfile1" X X X /* this file contains code which is dependent on the target machine */ X--- 1,4 ---- X! # include "pass1.h" X X X /* this file contains code which is dependent on the target machine */ X*************** X*** 8,16 **** X /* cast node p to type t */ X X p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p ); X! p->left->op = FREE; X! p->op = FREE; X! return( p->right ); X } X X NODE * X--- 8,16 ---- X /* cast node p to type t */ X X p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p ); X! p->in.left->in.op = FREE; X! p->in.op = FREE; X! return( p->in.right ); X } X X NODE * X*************** X*** 33,45 **** X register o; X register m, ml; X X! switch( o = p->op ){ X X case NAME: X! if( p->rval < 0 ) { /* already processed; ignore... */ X return(p); X } X! q = &stab[p->rval]; X switch( q->sclass ){ X X case AUTO: X--- 33,45 ---- X register o; X register m, ml; X X! switch( o = p->in.op ){ X X case NAME: X! if( p->tn.rval < 0 ) { /* already processed; ignore... */ X return(p); X } X! q = &stab[p->tn.rval]; X switch( q->sclass ){ X X case AUTO: X*************** X*** 46,53 **** X case PARAM: X /* fake up a structure reference */ X r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 ); X! r->lval = 0; X! r->rval = (q->sclass==AUTO?STKREG:ARGREG); X p = stref( block( STREF, r, p, 0, 0, 0 ) ); X break; X X--- 46,53 ---- X case PARAM: X /* fake up a structure reference */ X r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 ); X! r->tn.lval = 0; X! r->tn.rval = (q->sclass==AUTO?STKREG:ARGREG); X p = stref( block( STREF, r, p, 0, 0, 0 ) ); X break; X X*************** X*** 55,68 **** X case LABEL: X case STATIC: X if( q->slevel == 0 ) break; X! p->lval = 0; X! p->rval = -q->offset; X break; X X case REGISTER: X! p->op = REG; X! p->lval = 0; X! p->rval = q->offset; X break; X X } X--- 55,68 ---- X case LABEL: X case STATIC: X if( q->slevel == 0 ) break; X! p->tn.lval = 0; X! p->tn.rval = -q->offset; X break; X X case REGISTER: X! p->in.op = REG; X! p->tn.lval = 0; X! p->tn.rval = q->offset; X break; X X } X*************** X*** 71,120 **** X case LE: X case GT: X case GE: X! if( ISPTR( p->left->type ) || ISPTR( p->right->type ) ){ X! p->op += (ULT-LT); X } X break; X X case PCONV: X /* do pointer conversions for char and longs */ X! ml = p->left->type; X! if( ( ml==CHAR || ml==UCHAR || ml==LONG || ml==ULONG ) && p->left->op != ICON ) break; X X /* pointers all have the same representation; the type is inherited */ X! p->left->type = p->type; X! p->left->cdim = p->cdim; X! p->left->csiz = p->csiz; X! p->op = FREE; X! return( p->left ); X X case SCONV: X! m = (p->type == FLOAT || p->type == DOUBLE ); X! ml = (p->left->type == FLOAT || p->left->type == DOUBLE ); X! if( m != ml ) break; X X /* now, look for conversions downwards */ X X! m = p->type; X! ml = p->left->type; X! if( p->left->op == ICON ){ /* simulate the conversion here */ X CONSZ val; X! val = p->left->lval; X switch( m ){ X case CHAR: X! p->left->lval = (char) val; X break; X case UCHAR: X! p->left->lval = val & 0XFF; X break; X case UNSIGNED: X! p->left->lval = val & 0XFFFFL; X break; X case INT: X! p->left->lval = (int)val; X break; X } X! p->left->type = m; X } X else { X /* meaningful ones are conversion of int to char, int to short, X--- 71,138 ---- X case LE: X case GT: X case GE: X! if(ISPTR(p->in.left->in.type) || ISPTR(p->in.right->in.type)){ X! p->in.op += (ULT-LT); X } X break; X X case PCONV: X /* do pointer conversions for char and longs */ X! ml = p->in.left->in.type; X! if( ( ml==CHAR || ml==UCHAR || ml==LONG || ml==ULONG ) && p->in.left->in.op != ICON ) break; X X /* pointers all have the same representation; the type is inherited */ X! p->in.left->in.type = p->in.type; X! p->in.left->fn.cdim = p->fn.cdim; X! p->in.left->fn.csiz = p->fn.csiz; X! p->in.op = FREE; X! return( p->in.left ); X X case SCONV: X! m = (p->in.type == FLOAT || p->in.type == DOUBLE ); X! ml = (p->in.left->in.type == FLOAT || p->in.left->in.type == DOUBLE ); X! o = p->in.left->in.op; X! if( (o == FCON || o == DCON) && ml && !m ) { X! /* float type to int type */ X! r = block( ICON, (NODE *)NULL, (NODE *)NULL, LONG, 0, 0 ); X! if( o == FCON ) X! r->tn.lval = (long) p->in.left->fpn.fval; X! else X! r->tn.lval = (long) p->in.left->dpn.dval; X! r->tn.rval = NONAME; X! p->in.left->in.op = FREE; X! p->in.left = r; X! } X! else X! #ifdef SPRECC X! if ( ml || m ) X! #else X! if ( ml != m ) X! #endif X! break; X X /* now, look for conversions downwards */ X X! m = p->in.type; X! ml = p->in.left->in.type; X! if( p->in.left->in.op == ICON ){ /* simulate the conversion here */ X CONSZ val; X! val = p->in.left->tn.lval; X switch( m ){ X case CHAR: X! p->in.left->tn.lval = (char) val; X break; X case UCHAR: X! p->in.left->tn.lval = val & 0XFF; X break; X case UNSIGNED: X! p->in.left->tn.lval = val & 0XFFFFL; X break; X case INT: X! p->in.left->tn.lval = (int)val; X break; X } X! p->in.left->in.type = m; X } X else { X /* meaningful ones are conversion of int to char, int to short, X*************** X*** 131,149 **** X } X X /* clobber conversion */ X! p->op = FREE; X! return( p->left ); /* conversion gets clobbered */ X X case ASSIGN: X /* get rid of SCONV for assignments X from LONG -> CHAR|INT */ X! if( p->right->op == SCONV ) { X! m = p->right->type; X! ml = p->right->left->type; X if( ( m==LONG || m==ULONG ) && X ml!=FLOAT && ml!=DOUBLE ) { X! p->right->op = FREE; X! p->right = p->right->left; X } X } X break; X--- 149,167 ---- X } X X /* clobber conversion */ X! p->in.op = FREE; X! return( p->in.left ); /* conversion gets clobbered */ X X case ASSIGN: X /* get rid of SCONV for assignments X from LONG -> CHAR|INT */ X! if( p->in.right->in.op == SCONV ) { X! m = p->in.right->in.type; X! ml = p->in.right->in.left->in.type; X if( ( m==LONG || m==ULONG ) && X ml!=FLOAT && ml!=DOUBLE ) { X! p->in.right->in.op = FREE; X! p->in.right = p->in.right->in.left; X } X } X break; X*************** X*** 150,158 **** X X case PVCONV: X case PMCONV: X! if( p->right->op != ICON ) cerror( "bad conversion", 0); X! p->op = FREE; X! return( buildtree( o==PMCONV?MUL:DIV, p->left, p->right ) ); X X case PLUS: X case MINUS: X--- 168,176 ---- X X case PVCONV: X case PMCONV: X! if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0); X! p->in.op = FREE; X! return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) ); X X case PLUS: X case MINUS: X*************** X*** 159,172 **** X case LS: X case MUL: X /* optimize address calculations with long indexes */ X! if( ISPTR( p->type ) || ISARY( p->type ) ) { X! if( p->left->type==LONG || p->left->type==ULONG ) X! p->left = cast( p->left, INT ); X! if( p->right->type==LONG || p->right->type==ULONG ) X! p->right = cast( p->right, INT ); X } X break; X X } X X return(p); X--- 177,204 ---- X case LS: X case MUL: X /* optimize address calculations with long indexes */ X! if( ISPTR( p->in.type ) || ISARY( p->in.type ) ) { X! if( p->in.left->in.type==LONG || p->in.left->in.type==ULONG ) X! p->in.left = cast( p->in.left, INT ); X! if( p->in.right->in.type==LONG || p->in.right->in.type==ULONG ) X! p->in.right = cast( p->in.right, INT ); X } X break; X X+ case FLD: X+ /* make sure that the second pass does not make the X+ descendant of a FLD operator into a doubly indexed OREG */ X+ X+ if( p->in.left->in.op == UNARY MUL X+ && (r=p->in.left->in.left)->in.op == PCONV) X+ if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS ) X+ if( ISPTR(r->in.type) ) { X+ if( ISUNSIGNED(p->in.left->in.type) ) X+ p->in.left->in.type = UCHAR; X+ else X+ p->in.left->in.type = CHAR; X+ } X+ break; X } X X return(p); X*************** X*** 182,188 **** X X cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */ X X! if( t==INT || t==UNSIGNED || ISPTR(t) ) return(1); X return(0); X } X X--- 214,230 ---- X X cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */ X X! #ifdef TRUST_REG_CHAR_AND_REG_SHORT X! if( t==INT || t==UNSIGNED /* tbl */ X! || t==CHAR || t==UCHAR || t==SHORT /* tbl */ X! || t==USHORT || ISPTR(t)) return(1); /* tbl */ X! #else X! if( t==INT || t==UNSIGNED /* wnj */ X! #ifdef SPRECC X! || t==FLOAT X! #endif X! || ISPTR(t)) return (1); /* wnj */ X! #endif X return(0); X } X X*************** X*** 199,205 **** X /* in general they are necessary for offcon, but not on H'well */ X X p = bcon(0); X! p->lval = off/SZCHAR; X return(p); X X } X--- 241,247 ---- X /* in general they are necessary for offcon, but not on H'well */ X X p = bcon(0); X! p->tn.lval = off/SZCHAR; X return(p); X X } X*************** X*** 216,222 **** X /* we also assume sz < SZINT */ X X if((sz+inwd) > SZINT) cerror("incode: field > int"); X! word |= p->lval< SZINT) cerror("incode: field > int"); X! word |= ((unsigned)(p->tn.lval<<(16-sz))) >> (16-sz-inwd); X inwd += sz; X inoff += sz; X if(inoff%SZINT == 0) { X*************** X*** 241,248 **** X } X X cinit( p, sz ) NODE *p; { X! /* arrange for the initialization of p into a space of X! size sz */ X /* the proper alignment has been opbtained */ X /* inoff is updated to have the proper final value */ X ecode( p ); X--- 283,314 ---- X } X X cinit( p, sz ) NODE *p; { X! NODE *l; X! X! /* X! * as a favor (?) to people who want to write X! * int i = 9600/134.5; X! * we will, under the proper circumstances, do X! * a coersion here. X! */ X! switch (p->in.type) { X! case INT: X! case UNSIGNED: X! l = p->in.left; X! if (l->in.op != SCONV || X! (l->in.left->tn.op != DCON && l->in.left->tn.op != FCON)) X! break; X! l->in.op = FREE; X! l = l->in.left; X! l->tn.lval = l->tn.op == DCON ? (long)(l->dpn.dval) : X! (long)(l->fpn.fval); X! l->tn.rval = NONAME; X! l->tn.op = ICON; X! l->tn.type = INT; X! p->in.left = l; X! break; X! } X! /* arrange for the initialization of p into a space of size sz */ X /* the proper alignment has been opbtained */ X /* inoff is updated to have the proper final value */ X ecode( p ); X*************** X*** 261,288 **** X } X } X X- X char * X exname( p ) char *p; { X /* make a name look like an external name in the local machine */ X X static char text[NCHNAM+1]; X X register i; X X text[0] = '_'; X! for( i=1; *p&&isname ) ); X--- 378,384 ---- X X commdec( id ){ /* make a common declaration for id, if reasonable */ X register struct symtab *q; X! OFFSZ off, tsize(); X X q = &stab[id]; X printf( " .comm %s,", exname( q->sname ) ); X*************** X*** 319,329 **** X return(0); X } X X- X isitfloat( s ) char *s; { X double atof(); X! dcon = atof(s); X! return( FCON ); X } X X ecode( p ) NODE *p; { X--- 395,414 ---- X return(0); X } X X isitfloat( s ) char *s; { X+ union cvt { X+ double d; X+ int n[4]; X+ } cvt; X double atof(); X! X! /* avoid floating point exception for double -> float conversions */ X! dcon = cvt.d = atof(s); X! if( cvt.n[1] == 0 ){ X! fcon = dcon; X! return( FCON ); X! } X! return( DCON ); X } X X ecode( p ) NODE *p; { X*************** X*** 335,337 **** X--- 420,443 ---- X p2compile( p ); X } X X+ #ifndef ONEPASS X+ tlen(p) NODE *p; X+ { X+ switch(p->in.type) { X+ case CHAR: X+ case UCHAR: X+ return(1); X+ X+ case LONG: X+ case ULONG: X+ case FLOAT: X+ return(4); X+ X+ case DOUBLE: X+ return(8); X+ X+ default: X+ return(2); X+ } X+ } X+ #endif X*** local2.c.old Fri Jun 18 12:59:54 1982 X--- local2.c Sat Aug 3 13:44:45 1991 X*************** X*** 1,9 **** X! # include "mfile2" X /* a lot of the machine dependent parts of the second pass */ X X # define BITMASK(n) ((1L<= AUTOINIT ) spoff -= AUTOINIT; X spoff /= SZCHAR; X SETOFF(spoff,2); X! printf( " .F%d = %Ld.\n", ftnno, spoff ); X if( fltused ) { X fltused = 0; X printf( " .globl fltused\n" ); X--- 21,27 ---- X if( spoff >= AUTOINIT ) spoff -= AUTOINIT; X spoff /= SZCHAR; X SETOFF(spoff,2); X! printf( " .F%d = %ld.\n", ftnno, spoff ); X if( fltused ) { X fltused = 0; X printf( " .globl fltused\n" ); X*************** X*** 75,80 **** X--- 78,102 ---- X SBREG, SBREG, X }; X X+ tlen(p) NODE *p; X+ { X+ switch(p->in.type) { X+ case CHAR: X+ case UCHAR: X+ return(1); X+ X+ case LONG: X+ case ULONG: X+ case FLOAT: X+ return(4); X+ X+ case DOUBLE: X+ return(8); X+ X+ default: X+ return(2); X+ } X+ } X NODE *brnode; X int brcase; X X*************** X*** 85,106 **** X switch( c ){ X X case 'B': /* output b if type is byte */ X! if( p->type == CHAR || p->type == UCHAR ) printf( "b" ); X return; X X case 'N': /* logical ops, turned into 0-1 */ X /* use register given by register 1 */ X cbgen( 0, m=getlab(), 'I' ); X! deflab( p->label ); X! printf( " clr %s\n", rnames[getlr( p, '1' )->rval] ); X! if( p->type == LONG || p->type == ULONG ) X! printf( " clr %s\n", rnames[getlr( p, '1' )->rval + 1] ); X deflab( m ); X return; X X case 'I': X case 'F': X! cbgen( p->op, p->label, c ); X return; X X case 'A': X--- 107,128 ---- X switch( c ){ X X case 'B': /* output b if type is byte */ X! if( p->in.type == CHAR || p->in.type == UCHAR ) printf( "b" ); X return; X X case 'N': /* logical ops, turned into 0-1 */ X /* use register given by register 1 */ X cbgen( 0, m=getlab(), 'I' ); X! deflab( p->bn.label ); X! printf( " clr %s\n", rnames[getlr( p, '1' )->tn.rval] ); X! if( p->in.type == LONG || p->in.type == ULONG ) X! printf( " clr %s\n", rnames[getlr(p, '1')->tn.rval + 1] ); X deflab( m ); X return; X X case 'I': X case 'F': X! cbgen( p->in.op, p->bn.label, c ); X return; X X case 'A': X*************** X*** 117,128 **** X register r, l; X TWORD t; X X! if( p->op == ASG LS ) return; X! if( p->op != ASG RS ) cerror( "ZH bad" ); X! if( p->left->op != REG ) cerror( "SH left bad" ); X X! r = p->left->rval; X! t = p->left->type; X l = (t==LONG || t == ULONG ); X X if( t != UNSIGNED && t != UCHAR && t != ULONG ) return; /* signed is ok */ X--- 139,150 ---- X register r, l; X TWORD t; X X! if( p->in.op == ASG LS ) return; X! if( p->in.op != ASG RS ) cerror( "ZH bad" ); X! if( p->in.left->in.op != REG ) cerror( "SH left bad" ); X X! r = p->in.left->tn.rval; X! t = p->in.left->in.type; X l = (t==LONG || t == ULONG ); X X if( t != UNSIGNED && t != UCHAR && t != ULONG ) return; /* signed is ok */ X*************** X*** 136,144 **** X /* in the case where the value is known (rhs a constant), X the mask is just computed and put out... */ X X! if( p->right->op == ICON ){ X int s; X! s = p->right->lval; X if( l ){ X if( s >= 16 ){ X printf( " clr r%d\n", r ); X--- 158,166 ---- X /* in the case where the value is known (rhs a constant), X the mask is just computed and put out... */ X X! if( p->in.right->in.op == ICON ){ X int s; X! s = p->in.right->tn.lval; X if( l ){ X if( s >= 16 ){ X printf( " clr r%d\n", r ); X*************** X*** 158,164 **** X X /* general case */ X X! if( istnode( p->right ) ) q = p->right; X else q = getlr( p, '1' ); /* where -shift is stored */ X X /* first, we store the shifted value on the stack */ X--- 180,186 ---- X X /* general case */ X X! if( istnode( p->in.right ) ) q = p->in.right; X else q = getlr( p, '1' ); /* where -shift is stored */ X X /* first, we store the shifted value on the stack */ X*************** X*** 192,200 **** X /* sign extend or not -- register is one less than the X left descendent */ X X! m = p->left->rval - 1; X X! if( ISUNSIGNED(p->type) ){ X printf( " clr r%d\n", m ); X } X else { X--- 214,222 ---- X /* sign extend or not -- register is one less than the X left descendent */ X X! m = p->in.left->tn.rval - 1; X X! if( ISUNSIGNED(p->in.type) ){ X printf( " clr r%d\n", m ); X } X else { X*************** X*** 216,238 **** X X case '~': X /* complimented CR */ X! p->right->lval = ~p->right->lval; X conput( getlr( p, 'R' ) ); X! p->right->lval = ~p->right->lval; X return; X X case 'M': X /* negated CR */ X! p->right->lval = -p->right->lval; X conput( getlr( p, 'R' ) ); X! p->right->lval = -p->right->lval; X return; X X case 'L': /* INIT for long constants */ X { X unsigned hi, lo; X! lo = p->left->lval & BITMASK(SZINT); X! hi = ( p->left->lval >> SZINT ) & BITMASK(SZINT); X printf( " %o; %o\n", hi, lo ); X return; X } X--- 238,260 ---- X X case '~': X /* complimented CR */ X! p->in.right->tn.lval = ~p->in.right->tn.lval; X conput( getlr( p, 'R' ) ); X! p->in.right->tn.lval = ~p->in.right->tn.lval; X return; X X case 'M': X /* negated CR */ X! p->in.right->tn.lval = -p->in.right->tn.lval; X conput( getlr( p, 'R' ) ); X! p->in.right->tn.lval = -p->in.right->tn.lval; X return; X X case 'L': /* INIT for long constants */ X { X unsigned hi, lo; X! lo = p->in.left->tn.lval & BITMASK(SZINT); X! hi = ( p->in.left->tn.lval >> SZINT ) & BITMASK(SZINT); X printf( " %o; %o\n", hi, lo ); X return; X } X*************** X*** 242,259 **** X LONG|ULONG -> CHAR|UCHAR|INT|UNSIGNED X increment offset to second word */ X X! m = p->type; X! p = p->left; X! switch( p->op ){ X case NAME: X case OREG: X! p->lval += SZINT/SZCHAR; X return; X case REG: X! rfree( p->rval, p->type ); X! p->rval += 1; X! p->type = m; X! rbusy( p->rval, p->type ); X return; X default: X cerror( "Illegal ZT type conversion" ); X--- 264,281 ---- X LONG|ULONG -> CHAR|UCHAR|INT|UNSIGNED X increment offset to second word */ X X! m = p->in.type; X! p = p->in.left; X! switch( p->in.op ){ X case NAME: X case OREG: X! p->tn.lval += SZINT/SZCHAR; X return; X case REG: X! rfree( p->tn.rval, p->in.type ); X! p->tn.rval += 1; X! p->in.type = m; X! rbusy( p->tn.rval, p->in.type ); X return; X default: X cerror( "Illegal ZT type conversion" ); X*************** X*** 263,270 **** X X case 'U': X /* same as AL for exp under U* */ X! if( p->left->op == UNARY MUL ) { X! adrput( getlr( p->left, 'L' ) ); X return; X } X cerror( "Illegal ZU" ); X--- 285,292 ---- X X case 'U': X /* same as AL for exp under U* */ X! if( p->in.left->in.op == UNARY MUL ) { X! adrput( getlr( p->in.left, 'L' ) ); X return; X } X cerror( "Illegal ZU" ); X*************** X*** 271,278 **** X /* NO RETURN */ X X case 'W': /* structure size */ X! if( p->op == STASG ) X! printf( "%d", p->stsize); X else cerror( "Not a structure" ); X return; X X--- 293,300 ---- X /* NO RETURN */ X X case 'W': /* structure size */ X! if( p->in.op == STASG ) X! printf( "%d", p->stn.stsize); X else cerror( "Not a structure" ); X return; X X*************** X*** 281,310 **** X register NODE *l, *r; X register size, count; X X! if( p->op == STASG ){ X! l = p->left; X! r = p->right; X } X! else if( p->op == STARG ){ /* store an arg onto the stack */ X! r = p->left; X } X else cerror( "STASG bad" ); X X! if( r->op == ICON ) r->op = NAME; X! else if( r->op == REG ) r->op = OREG; X! else if( r->op != OREG ) cerror( "STASG-r" ); X X! size = p->stsize; X count = size / 2; X X! r->lval += size; X! if( p->op == STASG ) l->lval += size; X X while( count-- ){ /* simple load/store loop */ X! r->lval -= 2; X expand( r, FOREFF, " mov AR," ); X! if( p->op == STASG ){ X! l->lval -= 2; X expand( l, FOREFF, "AR\n" ); X } X else { X--- 303,332 ---- X register NODE *l, *r; X register size, count; X X! if( p->in.op == STASG ){ X! l = p->in.left; X! r = p->in.right; X } X! else if( p->in.op == STARG ){ /* store an arg onto the stack */ X! r = p->in.left; X } X else cerror( "STASG bad" ); X X! if( r->in.op == ICON ) r->in.op = NAME; X! else if( r->in.op == REG ) r->in.op = OREG; X! else if( r->in.op != OREG ) cerror( "STASG-r" ); X X! size = p->stn.stsize; X count = size / 2; X X! r->tn.lval += size; X! if( p->in.op == STASG ) l->tn.lval += size; X X while( count-- ){ /* simple load/store loop */ X! r->tn.lval -= 2; X expand( r, FOREFF, " mov AR," ); X! if( p->in.op == STASG ){ X! l->tn.lval -= 2; X expand( l, FOREFF, "AR\n" ); X } X else { X*************** X*** 313,320 **** X X } X X! if( r->op == NAME ) r->op = ICON; X! else if( r->op == OREG ) r->op = REG; X X } X break; X--- 335,342 ---- X X } X X! if( r->in.op == NAME ) r->in.op = ICON; X! else if( r->in.op == OREG ) r->in.op = REG; X X } X break; X*************** X*** 371,394 **** X } X X callreg(p) NODE *p; { X! return( (p->type==DOUBLE||p->type==FLOAT) ? FR0 : R0 ); X } X X! shltype( o, p ) NODE *p; { X! if( o == NAME|| o==REG || o == ICON || o == OREG ) return( 1 ); X! return( o==UNARY MUL && shumul(p->left) ); X } X X flshape( p ) register NODE *p; { X! register o = p->op; X if( o==NAME || o==REG || o==ICON || o==OREG ) return( 1 ); X! return( o==UNARY MUL && shumul(p->left)==STARNM ); X } X X shtemp( p ) register NODE *p; { X! if( p->op == UNARY MUL ) p = p->left; X! if( p->op == REG || p->op == OREG ) return( !istreg( p->rval ) ); X! return( p->op == NAME || p->op == ICON ); X } X X spsz( t, v ) TWORD t; CONSZ v; { X--- 393,418 ---- X } X X callreg(p) NODE *p; { X! return( (p->in.type==DOUBLE||p->in.type==FLOAT) ? FR0 : R0 ); X } X X! canaddr( p ) NODE *p; { X! register int o = p->in.op; X! X! if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1); X! return(0); X } X X flshape( p ) register NODE *p; { X! register o = p->in.op; X if( o==NAME || o==REG || o==ICON || o==OREG ) return( 1 ); X! return( o==UNARY MUL && shumul(p->in.left)==STARNM ); X } X X shtemp( p ) register NODE *p; { X! if( p->in.op == UNARY MUL ) p = p->in.left; X! if( p->in.op == REG || p->in.op == OREG ) return( !istreg( p->tn.rval ) ); X! return( p->in.op == NAME || p->in.op == ICON ); X } X X spsz( t, v ) TWORD t; CONSZ v; { X*************** X*** 423,435 **** X shumul( p ) register NODE *p; { X register o; X X! o = p->op; X if( o == NAME || o == OREG || o == ICON ) return( STARNM ); X X if( ( o == INCR || o == ASG MINUS ) && X! ( p->left->op == REG && p->right->op == ICON ) && X! p->right->name[0] == '\0' && X! spsz( p->left->type, p->right->lval ) ) X return( STARREG ); X X return( 0 ); X--- 447,459 ---- X shumul( p ) register NODE *p; { X register o; X X! o = p->in.op; X if( o == NAME || o == OREG || o == ICON ) return( STARNM ); X X if( ( o == INCR || o == ASG MINUS ) && X! ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) && X! p->in.right->in.name[0] == '\0' && X! spsz( p->in.left->in.type, p->in.right->tn.lval ) ) X return( STARREG ); X X return( 0 ); X*************** X*** 440,446 **** X } X X conput( p ) register NODE *p; { X! switch( p->op ){ X X case ICON: X acon( p ); X--- 464,470 ---- X } X X conput( p ) register NODE *p; { X! switch( p->in.op ){ X X case ICON: X acon( p ); X*************** X*** 447,453 **** X return; X X case REG: X! printf( "%s", rnames[p->rval] ); X return; X X default: X--- 471,477 ---- X return; X X case REG: X! putstr( rnames[p->tn.rval] ); X return; X X default: X*************** X*** 464,499 **** X pair pointed to by p (for LONGs)*/ X CONSZ save; X X! if( p->op == FLD ){ X! p = p->left; X } X X! save = p->lval; X! switch( p->op ){ X X case NAME: X! p->lval += SZINT/SZCHAR; X acon( p ); X break; X X case ICON: X /* addressable value of the constant */ X! p->lval &= BITMASK(SZINT); X! printf( "$" ); X acon( p ); X break; X X case REG: X! printf( "%s", rnames[p->rval+1] ); X break; X X case OREG: X! p->lval += SZINT/SZCHAR; X! if( p->rval == R5 ){ /* in the argument region */ X! if( p->name[0] != '\0' ) werror( "bad arg temp" ); X } X! if( p->lval != 0 || p->name[0] != '\0' ) acon( p ); X! printf( "(%s)", rnames[p->rval] ); X break; X X default: X--- 488,523 ---- X pair pointed to by p (for LONGs)*/ X CONSZ save; X X! if( p->in.op == FLD ){ X! p = p->in.left; X } X X! save = p->tn.lval; X! switch( p->in.op ){ X X case NAME: X! p->tn.lval += SZINT/SZCHAR; X acon( p ); X break; X X case ICON: X /* addressable value of the constant */ X! p->tn.lval &= BITMASK(SZINT); X! putstr( "$" ); X acon( p ); X break; X X case REG: X! putstr( rnames[p->tn.rval+1] ); X break; X X case OREG: X! p->tn.lval += SZINT/SZCHAR; X! if( p->tn.rval == R5 ){ /* in the argument region */ X! if( p->in.name[0] != '\0' ) werror( "bad arg temp" ); X } X! if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon( p ); X! printf( "(%s)", rnames[p->tn.rval] ); X break; X X default: X*************** X*** 501,507 **** X break; X X } X! p->lval = save; X X } X X--- 525,531 ---- X break; X X } X! p->tn.lval = save; X X } X X*************** X*** 508,517 **** X adrput( p ) register NODE *p; { X /* output an address, with offsets, from p */ X X! if( p->op == FLD ){ X! p = p->left; X } X! switch( p->op ){ X X case NAME: X acon( p ); X--- 532,541 ---- X adrput( p ) register NODE *p; { X /* output an address, with offsets, from p */ X X! if( p->in.op == FLD ){ X! p = p->in.left; X } X! switch( p->in.op ){ X X case NAME: X acon( p ); X*************** X*** 519,532 **** X X case ICON: X /* addressable value of the constant */ X! if( szty( p->type ) == 2 ) { X /* print the high order value */ X CONSZ save; X! save = p->lval; X! p->lval = ( p->lval >> SZINT ) & BITMASK(SZINT); X! printf( "$" ); X acon( p ); X! p->lval = save; X return; X } X printf( "$" ); X--- 543,556 ---- X X case ICON: X /* addressable value of the constant */ X! if( szty( p->in.type ) == 2 ) { X /* print the high order value */ X CONSZ save; X! save = p->tn.lval; X! p->tn.lval = ( p->tn.lval >> SZINT ) & BITMASK(SZINT); X! putstr( "$" ); X acon( p ); X! p->tn.lval = save; X return; X } X printf( "$" ); X*************** X*** 534,558 **** X return; X X case REG: X! printf( "%s", rnames[p->rval] ); X return; X X case OREG: X! if( p->rval == R5 ){ /* in the argument region */ X! if( p->name[0] != '\0' ) werror( "bad arg temp" ); X! printf( CONFMT, p->lval ); X! printf( ".(r5)" ); X return; X } X! if( p->lval != 0 || p->name[0] != '\0' ) acon( p ); X! printf( "(%s)", rnames[p->rval] ); X return; X X case UNARY MUL: X /* STARNM or STARREG found */ X if( tshape(p, STARNM) ) { X! printf( "*" ); X! adrput( p->left); X } X else { /* STARREG - really auto inc or dec */ X /* turn into OREG so replacement node will X--- 558,582 ---- X return; X X case REG: X! putstr( rnames[p->tn.rval] ); X return; X X case OREG: X! if( p->tn.rval == R5 ){ /* in the argument region */ X! if( p->in.name[0] != '\0' ) werror( "bad arg temp" ); X! printf( CONFMT, p->tn.lval ); X! putstr( ".(r5)" ); X return; X } X! if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon( p ); X! printf( "(%s)", rnames[p->tn.rval] ); X return; X X case UNARY MUL: X /* STARNM or STARREG found */ X if( tshape(p, STARNM) ) { X! putstr( "*" ); X! adrput( p->in.left); X } X else { /* STARREG - really auto inc or dec */ X /* turn into OREG so replacement node will X*************** X*** 560,580 **** X register i; X register NODE *q, *l; X X! l = p->left; X! q = l->left; X! p->op = OREG; X! p->rall = q->rall; X! p->lval = q->lval; X! p->rval = q->rval; X! for( i=0; iname[i] = q->name[i]; X! if( l->op == INCR ) { X adrput( p ); X! printf( "+" ); X! p->lval -= l->right->lval; X } X! else { /* l->op == ASG MINUS */ X! printf( "-" ); X adrput( p ); X } X tfree( l ); X--- 584,608 ---- X register i; X register NODE *q, *l; X X! l = p->in.left; X! q = l->in.left; X! p->in.op = OREG; X! p->in.rall = q->in.rall; X! p->tn.lval = q->tn.lval; X! p->tn.rval = q->tn.rval; X! #ifndef FLEXNAMES X! for(i=0; iin.name[i] = q->in.name[i]; X! #else X! p->in.name = q->in.name; X! #endif X! if( l->in.op == INCR ) { X adrput( p ); X! putstr( "+" ); X! p->tn.lval -= l->in.right->tn.lval; X } X! else { /* l->in.op == ASG MINUS */ X! putstr( "-" ); X adrput( p ); X } X tfree( l ); X*************** X*** 591,606 **** X X acon( p ) register NODE *p; { /* print out a constant */ X X! if( p->name[0] == '\0' ){ /* constant only */ X! printf( CONFMT, p->lval); X printf( "." ); X } X! else if( p->lval == 0 ) { /* name only */ X! printf( "%.8s", p->name ); X } X else { /* name + offset */ X! printf( "%.8s+", p->name ); X! printf( CONFMT, p->lval ); X printf( "." ); X } X } X--- 619,642 ---- X X acon( p ) register NODE *p; { /* print out a constant */ X X! if( p->in.name[0] == '\0' ){ /* constant only */ X! printf( CONFMT, p->tn.lval); X printf( "." ); X } X! else if( p->tn.lval == 0 ) { /* name only */ X! #ifndef FLEXNAMES X! printf( "%.8s", p->in.name ); X! #else X! putstr( p->in.name ); X! #endif X } X else { /* name + offset */ X! #ifndef FLEXNAMES X! printf( "%.8s+", p->in.name ); X! #else X! putstr( p->in.name ); X! #endif X! printf( CONFMT, p->tn.lval ); X printf( "." ); X } X } X*************** X*** 615,632 **** X register temp; X register m; X X! if( p->right ) temp = argsize( p->right ); X else temp = 0; X X! if( p->right ){ /* generate args */ X! genargs( p->right ); X } X X! if( !shltype( p->left->op, p->left ) ) { X! order( p->left, INAREG|SOREG ); X } X X! p->op = UNARY CALL; X m = match( p, INTAREG|INTBREG ); X popargs( temp ); X return(m != MDONE); X--- 651,668 ---- X register temp; X register m; X X! if( p->in.right ) temp = argsize( p->in.right ); X else temp = 0; X X! if( p->in.right ){ /* generate args */ X! genargs( p->in.right ); X } X X! if( !shltype( p->in.left->in.op, p->in.left ) ) { X! order( p->in.left, INAREG|SOREG ); X } X X! p->in.op = UNARY CALL; X m = match( p, INTAREG|INTBREG ); X popargs( temp ); X return(m != MDONE); X*************** X*** 694,700 **** X }; X X /* logical relations when compared in reverse order (cmp R,L) */ X! #ifdef FORT X short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT }; X #else X extern short revrel[]; X--- 730,736 ---- X }; X X /* logical relations when compared in reverse order (cmp R,L) */ X! #ifndef ONEPASS X short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT }; X #else X extern short revrel[]; X*************** X*** 739,745 **** X /* we have failed to match p with cookie; try another */ X if( cookie == FORREW ) return( 0 ); /* hopeless! */ X if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); X! if( !(cookie&INTEMP) && asgop(p->op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); X return( FORREW ); X } X X--- 775,781 ---- X /* we have failed to match p with cookie; try another */ X if( cookie == FORREW ) return( 0 ); /* hopeless! */ X if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); X! if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); X return( FORREW ); X } X X*************** X*** 775,782 **** X register o; X register TWORD t; X X! o = p->op; X! t = p->type; X if( t!=LONG && t!=ULONG ) return; X X for( f=opfunc; f->fop; f++ ) { X--- 811,818 ---- X register o; X register TWORD t; X X! o = p->in.op; X! t = p->in.type; X if( t!=LONG && t!=ULONG ) return; X X for( f=opfunc; f->fop; f++ ) { X*************** X*** 788,825 **** X /* WARNING - this won't work for long in a REG */ X convert: X if( asgop( o ) ) { X! switch( p->left->op ) { X X case UNARY MUL: /* convert to address */ X! p->left->op = FREE; X! p->left = p->left->left; X break; X X case NAME: /* convert to ICON pointer */ X! p->left->op = ICON; X! p->left->type = INCREF( p->left->type ); X break; X X case OREG: /* convert OREG to address */ X! p->left->op = REG; X! p->left->type = INCREF( p->left->type ); X! if( p->left->lval != 0 ) { X q = talloc(); X! q->op = PLUS; X! q->rall = NOPREF; X! q->type = p->left->type; X! q->left = p->left; X! q->right = talloc(); X X! q->right->op = ICON; X! q->right->rall = NOPREF; X! q->right->type = INT; X! q->right->name[0] = '\0'; X! q->right->lval = p->left->lval; X! q->right->rval = 0; X X! p->left->lval = 0; X! p->left = q; X } X break; X X--- 824,865 ---- X /* WARNING - this won't work for long in a REG */ X convert: X if( asgop( o ) ) { X! switch( p->in.left->in.op ) { X X case UNARY MUL: /* convert to address */ X! p->in.left->in.op = FREE; X! p->in.left = p->in.left->in.left; X break; X X case NAME: /* convert to ICON pointer */ X! p->in.left->in.op = ICON; X! p->in.left->in.type = INCREF( p->in.left->in.type ); X break; X X case OREG: /* convert OREG to address */ X! p->in.left->in.op = REG; X! p->in.left->in.type = INCREF( p->in.left->in.type ); X! if( p->in.left->tn.lval != 0 ) { X q = talloc(); X! q->in.op = PLUS; X! q->in.rall = NOPREF; X! q->in.type = p->in.left->in.type; X! q->in.left = p->in.left; X! q->in.right = talloc(); X X! q->in.right->in.op = ICON; X! q->in.right->in.rall = NOPREF; X! q->in.right->in.type = INT; X! #ifdef FLEXNAMES X! q->in.right->in.name = ""; X! #else X! q->in.right->in.name[0] = '\0'; X! #endif X! q->in.right->tn.lval = p->in.left->tn.lval; X! q->in.right->tn.rval = 0; X X! p->in.left->tn.lval = 0; X! p->in.left = q; X } X break; X X*************** X*** 832,853 **** X X /* build comma op for args to function */ X q = talloc(); X! q->op = CM; X! q->rall = NOPREF; X! q->type = INT; X! q->left = p->left; X! q->right = p->right; X! p->op = CALL; X! p->right = q; X X /* put function name in left node of call */ X! p->left = q = talloc(); X! q->op = ICON; X! q->rall = NOPREF; X! q->type = INCREF( FTN + p->type ); X! strcpy( q->name, f->func ); X! q->lval = 0; X! q->rval = 0; X X return; X X--- 872,897 ---- X X /* build comma op for args to function */ X q = talloc(); X! q->in.op = CM; X! q->in.rall = NOPREF; X! q->in.type = INT; X! q->in.left = p->in.left; X! q->in.right = p->in.right; X! p->in.op = CALL; X! p->in.right = q; X X /* put function name in left node of call */ X! p->in.left = q = talloc(); X! q->in.op = ICON; X! q->in.rall = NOPREF; X! q->in.type = INCREF( FTN + p->in.type ); X! #ifndef FLEXNAMES X! strcpy( q->in.name, f->func ); X! #else X! q->in.name = f->func; X! #endif X! q->tn.lval = 0; X! q->tn.rval = 0; X X return; X X*************** X*** 858,889 **** X X register NODE *r; X X! switch( p->op ) { X X case AND: X /* commute L and R to eliminate compliments and constants */ X! if( p->left->op==ICON || p->left->op==COMPL ) { X! r = p->left; X! p->left = p->right; X! p->right = r; X } X case ASG AND: X /* change meaning of AND to ~R&L - bic on pdp11 */ X! r = p->right; X! if( r->op==ICON ) { /* compliment constant */ X! r->lval = ~r->lval; X } X! else if( r->op==COMPL ) { /* ~~A => A */ X! r->op = FREE; X! p->right = r->left; X } X else { /* insert complement node */ X! p->right = talloc(); X! p->right->op = COMPL; X! p->right->rall = NOPREF; X! p->right->type = r->type; X! p->right->left = r; X! p->right->right = NULL; X } X break; X X--- 902,933 ---- X X register NODE *r; X X! switch( p->in.op ) { X X case AND: X /* commute L and R to eliminate compliments and constants */ X! if( p->in.left->in.op==ICON || p->in.left->in.op==COMPL ) { X! r = p->in.left; X! p->in.left = p->in.right; X! p->in.right = r; X } X case ASG AND: X /* change meaning of AND to ~R&L - bic on pdp11 */ X! r = p->in.right; X! if( r->in.op==ICON ) { /* compliment constant */ X! r->tn.lval = ~r->tn.lval; X } X! else if( r->in.op==COMPL ) { /* ~~A => A */ X! r->in.op = FREE; X! p->in.right = r->in.left; X } X else { /* insert complement node */ X! p->in.right = talloc(); X! p->in.right->in.op = COMPL; X! p->in.right->in.rall = NOPREF; X! p->in.right->in.type = r->in.type; X! p->in.right->in.left = r; X! p->in.right->in.right = NULL; X } X break; X X*************** X*** 890,913 **** X } X } X X- myreader(p) register NODE *p; { X- walkf( p, hardops ); /* convert ops to function calls */ X- canon( p ); /* expands r-vals for fileds */ X- walkf( p, optim2 ); X- toff = 0; /* stack offset swindle */ X- } X- X special( p, shape ) register NODE *p; { X /* special shape matching routine */ X X switch( shape ) { X X! case SCCON: X! if( p->op == ICON && p->name[0]=='\0' && p->lval>= -128 && p->lval <=127 ) return( 1 ); X break; X X! case SICON: X! if( p->op == ICON && p->name[0]=='\0' && p->lval>= 0 && p->lval <=32767 ) return( 1 ); X break; X X default: X--- 934,950 ---- X } X } X X special( p, shape ) register NODE *p; { X /* special shape matching routine */ X X switch( shape ) { X X! case SSCON: X! if( p->in.op == ICON && p->in.name[0]=='\0' && p->tn.lval>= -128 && p->tn.lval <=127 ) return( 1 ); X break; X X! case SCCON: X! if( p->in.op == ICON && p->in.name[0]=='\0' && p->tn.lval>= 0 && p->tn.lval <=32767 ) return( 1 ); X break; X X default: X*************** X*** 918,925 **** X--- 955,982 ---- X return( 0 ); X } X X+ NODE * addroreg(l) NODE *l; X+ /* OREG was built in clocal() X+ * for an auto or formal parameter X+ * now its address is being taken X+ * local code must unwind it X+ * back to PLUS/MINUS REG ICON X+ * according to local conventions X+ */ X+ { X+ cerror("address of OREG taken"); X+ /*NOTREACHED*/ X+ } X+ X # ifndef ONEPASS X main( argc, argv ) char *argv[]; { X return( mainp2( argc, argv ) ); X } X # endif X+ X+ myreader(p) register NODE *p; { X+ walkf( p, hardops ); /* convert ops to function calls */ X+ canon( p ); /* expands r-vals for fileds */ X+ walkf( p, optim2 ); X+ toff = 0; /* stack offset swindle */ X+ } X*** mac2defs.h.old Fri Jul 10 17:36:09 1981 X--- mac2defs.h Sat Aug 3 11:21:19 1991 X*************** X*** 1,51 **** X! /* PDP11 Registers */ X X! /* scratch registers */ X! # define R0 0 X! # define R1 1 X X! /* register variables */ X! # define R2 2 X! # define R3 3 X! # define R4 4 X X! /* special purpose */ X! # define R5 5 /* frame pointer */ X! # define SP 6 /* stack pointer */ X! # define PC 7 /* program counter */ X X! /* floating registers */ X X! # define FR0 8 X! # define FR1 9 X! # define FR2 10 X! # define FR3 11 X! # define FR4 12 X! # define FR5 13 X X! # define SAVEREGION 8 /* number of bytes for save area */ X X! # define BYTEOFF(x) ((x)&01) X! # define wdal(k) (BYTEOFF(k)==0) X! # define BITOOR(x) ((x)>>3) /* bit offset to oreg offset */ X X! # define REGSZ 14 X X! # define TMPREG R5 X X X! # define STOARG(p) /* just evaluate the arguments, and be done with it... */ X! # define STOFARG(p) X! # define STOSTARG(p) X! # define genfcall(a,b) gencall(a,b) X! X! X! /* shape for constants between -128 and 127 */ X! # define SCCON (SPECIAL+100) X! /* shape for constants between 0 and 32767 */ X! # define SICON (SPECIAL+101) X! X! # define MYREADER(p) myreader(p) X! extern int fltused; X! /* calls can be nested on the PDP-11 */ X! # define NESTCALLS X--- 1,62 ---- X! /* X! * PDP11 Registers X! */ X X! /* X! * Scratch registers X! */ X! #define R0 0 X! #define R1 1 X X! /* X! * Register variables X! */ X! #define R2 2 X! #define R3 3 X! #define R4 4 X X! /* X! * Special purpose registers X! */ X! #define R5 5 /* frame pointer */ X! #define SP 6 /* stack pointer */ X! #define PC 7 /* program counter */ X X! /* floating registers */ X X! #define FR0 8 X! #define FR1 9 X! #define FR2 10 X! #define FR3 11 X! #define FR4 12 X! #define FR5 13 X X! #define REGSZ 14 X! #define TMPREG R5 X X! extern int fregs; X! extern int maxargs; X X! #define BYTEOFF(x) ((x)&01) X! #define wdal(k) (BYTEOFF(k)==0) /* word align */ X! #define BITOOR(x) ((x)>>3) /* bit offset to oreg offset */ X X! /* X! * Some macros used in store(): X! * just evaluate the arguments, and be done with it... X! */ X! #define STOARG(p) X! #define STOFARG(p) X! #define STOSTARG(p) X! #define genfcall(a,b) gencall(a,b) X X+ /* X+ * Some short routines that get called an awful lot are actually macros. X+ */ X+ #define shltype(o, p) \ X+ ((o) == REG || (o) == NAME || (o) == ICON || \ X+ (o) == OREG || ((o) == UNARY MUL && shumul((p)->in.left))) X+ #define ncopy(q, p) ((q)->in = (p)->in) X X! #define MYREADER(p) myreader(p) X! int optim2(); X*** macdefs.h.old Fri Jul 10 17:36:09 1981 X--- macdefs.h Sun Aug 4 17:07:51 1991 X*************** X*** 1,67 **** X! # define makecc(val,i) lastcon = i ? (val<<8)|lastcon : val X X! # define ARGINIT 32 X! # define AUTOINIT 48 X! # define SZCHAR 8 X! # define SZINT 16 X! # define SZFLOAT 32 X! # define SZDOUBLE 64 X! # define SZLONG 32 X! # define SZSHORT 16 X! # define SZPOINT 16 X! # define ALCHAR 8 X! # define ALINT 16 X! # define ALFLOAT 16 X! # define ALDOUBLE 16 X! # define ALLONG 16 X! # define ALSHORT 16 X! # define ALPOINT 16 X! # define ALSTRUCT 16 X! # define ALSTACK 16 X X! /* size in which constants are converted */ X! /* should be long if feasable */ X X! # define CONSZ long X! # define CONFMT "%Ld" X X! /* size in which offsets are kept X! /* should be large enough to cover address space in bits X! */ X X! # define OFFSZ long X X! /* character set macro */ X X! # define CCTRANS(x) x X X! /* register cookie for stack poINTer */ X X! # define STKREG 5 X # define ARGREG 5 X! X! /* maximum and minimum register variables */ X! X # define MAXRVAR 4 X # define MINRVAR 2 X X! /* various standard pieces of code are used */ X! # define STDPRTREE X! # define LABFMT "L%d" X X! /* definition indicates automatics and/or temporaries X! are on a negative growing stack */ X X! # define BACKAUTO X! # define BACKTEMP X! X! # define RTOLBYTES X! # ifndef FORT X! # define ONEPASS X! # endif X! X! # ifndef FORT X! # define EXIT dexit X! # endif X! X! # define ENUMSIZE(high,low) INT X--- 1,68 ---- X! #ifndef _MACDEFS_ X! #define _MACDEFS_ X X! #define makecc(val,i) lastcon = i ? (val<<8)|lastcon : val X X! #define ARGINIT 32 X! #define AUTOINIT 0 X X! /* X! * Storage space requirements X! */ X! #define SZCHAR 8 X! #define SZINT 16 X! #define SZFLOAT 32 X! #define SZDOUBLE 64 X! #define SZLONG 32 X! #define SZSHORT 16 X! #define SZPOINT 16 X X! /* X! * Alignment constraints X! */ X! #define ALCHAR 8 X! #define ALINT 16 X! #define ALFLOAT 16 X! #define ALDOUBLE 16 X! #define ALLONG 16 X! #define ALSHORT 16 X! #define ALPOINT 16 X! #define ALSTRUCT 16 X! #define ALSTACK 16 X X! typedef long CONSZ; /* size in which constants are converted */ X! typedef long OFFSZ; /* size in which offsets are kept */ X X! #define CONFMT "%ld" /* format for printing constants */ X! #define LABFMT "L%d" /* format for printing labels */ X X! #define CCTRANS(x) x /* character set macro */ X X! /* X! * Register cookies for stack pointer and argument pointer X! */ X X! # define STKREG 5 X # define ARGREG 5 X! /* X! * Maximum and minimum register variables X! */ X # define MAXRVAR 4 X # define MINRVAR 2 X X! #define BACKAUTO /* stack grows negatively for automatics */ X! #define BACKTEMP /* stack grows negatively for temporaries */ X! #ifdef vax X! #define FIELDOPS /* show field hardware support on VAX */ X! #endif X! #define RTOLBYTES /* bytes are numbered from right to left */ X X! #define ENUMSIZE(high,low) INT /* enums are always stored in full int */ X X! #define ADDROREG X! #define FIXDEF(p) outstab(p) X! #define FIXARG(p) fixarg(p) X! #ifndef ncopy X! #define ncopy(q, p) ((q)->in = (p)->in) X! #endif X! #endif X*** order.c.old Fri Jul 10 17:36:10 1981 X--- order.c Sat Aug 3 12:41:06 1991 X*************** X*** 1,4 **** X! # include "mfile2" X X int fltused = 0; X X--- 1,4 ---- X! # include "pass2.h" X X int fltused = 0; X X*************** X*** 6,57 **** X /* should the assignment op p be stored, X given that it lies as the right operand of o X (or the left, if o==UNARY MUL) */ X! return( shltype(p->left->op, p->left ) ); X X } X X deltest( p ) register NODE *p; { X /* should we delay the INCR or DECR operation p */ X! if( p->op == INCR && p->left->op == REG && spsz( p->left->type, p->right->lval ) ){ X /* STARREG */ X return( 0 ); X } X X! p = p->left; X! if( p->op == UNARY MUL ) p = p->left; X! return( p->op == NAME || p->op == OREG || p->op == REG ); X } X X mkadrs(p) register NODE *p; { X register o; X X! o = p->op; X X if( asgop(o) ){ X! if( p->left->su >= p->right->su ){ X! if( p->left->op == UNARY MUL ){ X! if( p->left->su > 0 ) X! SETSTO( p->left->left, INTEMP ); X else { X! if( p->right->su > 0 ) SETSTO( p->right, INTEMP ); X else cerror( "store finds both sides trivial" ); X } X } X! else if( p->left->op == FLD && p->left->left->op == UNARY MUL ){ X! SETSTO( p->left->left->left, INTEMP ); X } X else { /* should be only structure assignment */ X! SETSTO( p->left, INTEMP ); X } X } X! else SETSTO( p->right, INTEMP ); X } X else { X! if( p->left->su > p->right->su ){ X! SETSTO( p->left, INTEMP ); X } X else { X! SETSTO( p->right, INTEMP ); X } X } X } X--- 6,67 ---- X /* should the assignment op p be stored, X given that it lies as the right operand of o X (or the left, if o==UNARY MUL) */ X! return( shltype(p->in.left->in.op, p->in.left ) ); X X } X X deltest( p ) register NODE *p; { X /* should we delay the INCR or DECR operation p */ X! if( p->in.op == INCR && p->in.left->in.op == REG && spsz( p->in.left->in.type, p->in.right->tn.lval ) ){ X /* STARREG */ X return( 0 ); X } X X! p = p->in.left; X! if( p->in.op == UNARY MUL ) p = p->in.left; X! return( p->in.op == NAME || p->in.op == OREG || p->in.op == REG ); X } X X+ autoincr( p ) NODE *p; { X+ register NODE *q = p->in.left; X+ X+ if( q->in.op == INCR && q->in.left->in.op == REG && X+ ISPTR(q->in.type) && p->in.type == DECREF(q->in.type) && X+ tlen(p) == q->in.right->tn.lval ) return(1); X+ X+ return(0); X+ } X+ X mkadrs(p) register NODE *p; { X register o; X X! o = p->in.op; X X if( asgop(o) ){ X! if( p->in.left->in.su >= p->in.right->in.su ){ X! if( p->in.left->in.op == UNARY MUL ){ X! if( p->in.left->in.su > 0 ) X! SETSTO( p->in.left->in.left, INTEMP ); X else { X! if( p->in.right->in.su > 0 ) SETSTO( p->in.right, INTEMP ); X else cerror( "store finds both sides trivial" ); X } X } X! else if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){ X! SETSTO( p->in.left->in.left->in.left, INTEMP ); X } X else { /* should be only structure assignment */ X! SETSTO( p->in.left, INTEMP ); X } X } X! else SETSTO( p->in.right, INTEMP ); X } X else { X! if( p->in.left->in.su > p->in.right->in.su ){ X! SETSTO( p->in.left, INTEMP ); X } X else { X! SETSTO( p->in.right, INTEMP ); X } X } X } X*************** X*** 61,67 **** X /* offset of off, (from a register of r), if the X /* resulting thing had type t */ X X! /* return( 1 ); /* NO */ X return(0); /* YES */ X } X X--- 71,77 ---- X /* offset of off, (from a register of r), if the X /* resulting thing had type t */ X X! /* if( r == R0 ) return( 1 ); /* NO */ X return(0); /* YES */ X } X X*************** X*** 80,104 **** X X register su; X X! su = p->su; X X! switch( p->type ){ X X case CHAR: X case UCHAR: X if( !(zap&ZCHAR) ) break; X! if( su == 0 ) p->su = su = 1; X break; X X case LONG: X case ULONG: X if( !(zap&ZLONG) ) break; X! if( p->op == UNARY MUL && su == 0 ) p->su = su = 2; X break; X X case FLOAT: X if( !(zap&ZFLOAT) ) break; X! if( su == 0 ) p->su = su = 1; X X } X X--- 90,114 ---- X X register su; X X! su = p->in.su; X X! switch( p->in.type ){ X X case CHAR: X case UCHAR: X if( !(zap&ZCHAR) ) break; X! if( su == 0 ) p->in.su = su = 1; X break; X X case LONG: X case ULONG: X if( !(zap&ZLONG) ) break; X! if( p->in.op == UNARY MUL && su == 0 ) p->in.su = su = 2; X break; X X case FLOAT: X if( !(zap&ZFLOAT) ) break; X! if( su == 0 ) p->in.su = su = 1; X X } X X*************** X*** 113,124 **** X register o, ty, sul, sur; X register nr; X X! ty = optype( o=p->op); X! nr = szty( p->type ); X! p->su = 0; X X if( ty == LTYPE ) { X! if( p->type==FLOAT ) p->su = 1; X return; X } X else if( ty == UTYPE ){ X--- 123,134 ---- X register o, ty, sul, sur; X register nr; X X! ty = optype( o=p->in.op); X! nr = szty( p->in.type ); X! p->in.su = 0; X X if( ty == LTYPE ) { X! if( p->in.type==FLOAT ) p->in.su = 1; X return; X } X else if( ty == UTYPE ){ X*************** X*** 125,138 **** X switch( o ) { X case UNARY CALL: X case UNARY STCALL: X! p->su = fregs; /* all regs needed */ X return; X X case UNARY MUL: X! if( shumul( p->left ) ) return; X X default: X! p->su = max( p->left->su, nr); X return; X } X } X--- 135,148 ---- X switch( o ) { X case UNARY CALL: X case UNARY STCALL: X! p->in.su = fregs; /* all regs needed */ X return; X X case UNARY MUL: X! if( shumul( p->in.left ) ) return; X X default: X! p->in.su = max( p->in.left->in.su, nr); X return; X } X } X*************** X*** 140,153 **** X X /* If rhs needs n, lhs needs m, regular su computation */ X X! sul = p->left->su; X! sur = p->right->su; X X if( o == ASSIGN ){ X asop: /* also used for +=, etc., to memory */ X if( sul==0 ){ X /* don't need to worry about the left side */ X! p->su = max( sur, nr ); X } X else { X /* right, left address, op */ X--- 150,163 ---- X X /* If rhs needs n, lhs needs m, regular su computation */ X X! sul = p->in.left->in.su; X! sur = p->in.right->in.su; X X if( o == ASSIGN ){ X asop: /* also used for +=, etc., to memory */ X if( sul==0 ){ X /* don't need to worry about the left side */ X! p->in.su = max( sur, nr ); X } X else { X /* right, left address, op */ X*************** X*** 154,164 **** X if( sur == 0 ){ X /* just get the lhs address into a register, and mov */ X /* the `nr' covers the case where value is in reg afterwards */ X! p->su = max( sul, nr ); X } X else { X /* right, left address, op */ X! p->su = max( sur, nr+sul ); X } X } X return; X--- 164,174 ---- X if( sur == 0 ){ X /* just get the lhs address into a register, and mov */ X /* the `nr' covers the case where value is in reg afterwards */ X! p->in.su = max( sul, nr ); X } X else { X /* right, left address, op */ X! p->in.su = max( sur, nr+sul ); X } X } X return; X*************** X*** 166,178 **** X X if( o == CALL || o == STCALL ){ X /* in effect, takes all free registers */ X! p->su = fregs; X return; X } X X if( o == STASG ){ X /* right, then left */ X! p->su = max( max( sul+nr, sur), fregs ); X return; X } X X--- 176,188 ---- X X if( o == CALL || o == STCALL ){ X /* in effect, takes all free registers */ X! p->in.su = fregs; X return; X } X X if( o == STASG ){ X /* right, then left */ X! p->in.su = max( max( sul+nr, sur), fregs ); X return; X } X X*************** X*** 181,190 **** X /* left then right, max(sul,sur+nr) */ X /* right then left, max(sur,sul+nr) */ X /* to hold both sides in regs: nr+nr */ X! nr = szty( p->left->type ); X! sul = zum( p->left, ZLONG|ZCHAR|ZFLOAT ); X! sur = zum( p->right, ZLONG|ZCHAR|ZFLOAT ); X! p->su = min( max(sul,sur+nr), max(sur,sul+nr) ); X return; X } X X--- 191,200 ---- X /* left then right, max(sul,sur+nr) */ X /* right then left, max(sur,sul+nr) */ X /* to hold both sides in regs: nr+nr */ X! nr = szty( p->in.left->in.type ); X! sul = zum( p->in.left, ZLONG|ZCHAR|ZFLOAT ); X! sur = zum( p->in.right, ZLONG|ZCHAR|ZFLOAT ); X! p->in.su = min( max(sul,sur+nr), max(sur,sul+nr) ); X return; X } X X*************** X*** 199,205 **** X case ASG DIV: X case ASG MOD: X case ASG MUL: X! if( p->type!=FLOAT && p->type!=DOUBLE ) nr = fregs; X goto gencase; X X case ASG PLUS: X--- 209,215 ---- X case ASG DIV: X case ASG MOD: X case ASG MUL: X! if( p->in.type!=FLOAT && p->in.type!=DOUBLE ) nr = fregs; X goto gencase; X X case ASG PLUS: X*************** X*** 206,228 **** X case ASG MINUS: X case ASG AND: /* really bic */ X case ASG OR: X! if( p->type == INT || p->type == UNSIGNED || ISPTR(p->type) ) goto asop; X X gencase: X default: X! sur = zum( p->right, ZCHAR|ZLONG|ZFLOAT ); X if( sur == 0 ){ /* easy case: if addressable, X do left value, op, store */ X! if( sul == 0 ) p->su = nr; X /* harder: left adr, val, op, store */ X! else p->su = max( sul, nr+1 ); X } X else { /* do right, left adr, left value, op, store */ X if( sul == 0 ){ /* right, left value, op, store */ X! p->su = max( sur, nr+nr ); X } X else { X! p->su = max( sur, max( sul+nr, 1+nr+nr ) ); X } X } X return; X--- 216,238 ---- X case ASG MINUS: X case ASG AND: /* really bic */ X case ASG OR: X! if( p->in.type == INT || p->in.type == UNSIGNED || ISPTR(p->in.type) ) goto asop; X X gencase: X default: X! sur = zum( p->in.right, ZCHAR|ZLONG|ZFLOAT ); X if( sur == 0 ){ /* easy case: if addressable, X do left value, op, store */ X! if( sul == 0 ) p->in.su = nr; X /* harder: left adr, val, op, store */ X! else p->in.su = max( sul, nr+1 ); X } X else { /* do right, left adr, left value, op, store */ X if( sul == 0 ){ /* right, left value, op, store */ X! p->in.su = max( sur, nr+nr ); X } X else { X! p->in.su = max( sur, max( sul+nr, 1+nr+nr ) ); X } X } X return; X*************** X*** 235,246 **** X case QUEST: X case COLON: X case COMOP: X! p->su = max( max(sul,sur), nr); X return; X } X X if( ( o==DIV || o==MOD || o==MUL ) X! && p->type!=FLOAT && p->type!=DOUBLE ) nr = fregs; X if( o==PLUS || o==MUL || o==OR || o==ER ){ X /* AND is ruined by the hardware */ X /* permute: get the harder on the left */ X--- 245,256 ---- X case QUEST: X case COLON: X case COMOP: X! p->in.su = max( max(sul,sur), nr); X return; X } X X if( ( o==DIV || o==MOD || o==MUL ) X! && p->in.type!=FLOAT && p->in.type!=DOUBLE ) nr = fregs; X if( o==PLUS || o==MUL || o==OR || o==ER ){ X /* AND is ruined by the hardware */ X /* permute: get the harder on the left */ X*************** X*** 247,259 **** X X register rt, lt; X X! if( istnode( p->left ) || sul > sur ) goto noswap; /* don't do it! */ X X /* look for a funny type on the left, one on the right */ X X X! lt = p->left->type; X! rt = p->right->type; X X if( rt == FLOAT && lt == DOUBLE ) goto swap; X X--- 257,269 ---- X X register rt, lt; X X! if( istnode( p->in.left ) || sul > sur ) goto noswap; /* don't do it! */ X X /* look for a funny type on the left, one on the right */ X X X! lt = p->in.left->in.type; X! rt = p->in.right->in.type; X X if( rt == FLOAT && lt == DOUBLE ) goto swap; X X*************** X*** 262,272 **** X if( lt==LONG || lt==ULONG ){ X if( rt==LONG || rt==ULONG ){ X /* if one is a STARNM, swap */ X! if( p->left->op == UNARY MUL && sul==0 ) goto noswap; X! if( p->right->op == UNARY MUL && p->left->op != UNARY MUL ) goto swap; X goto noswap; X } X! else if( p->left->op == UNARY MUL && sul == 0 ) goto noswap; X else goto swap; /* put long on right, unless STARNM */ X } X X--- 272,282 ---- X if( lt==LONG || lt==ULONG ){ X if( rt==LONG || rt==ULONG ){ X /* if one is a STARNM, swap */ X! if( p->in.left->in.op == UNARY MUL && sul==0 ) goto noswap; X! if( p->in.right->in.op == UNARY MUL && p->in.left->in.op != UNARY MUL ) goto swap; X goto noswap; X } X! else if( p->in.left->in.op == UNARY MUL && sul == 0 ) goto noswap; X else goto swap; /* put long on right, unless STARNM */ X } X X*************** X*** 279,297 **** X X swap: X ssu = sul; sul = sur; sur = ssu; X! s = p->left; p->left = p->right; p->right = s; X } X } X noswap: X X! sur = zum( p->right, ZCHAR|ZLONG|ZFLOAT ); X if( sur == 0 ){ X /* get left value into a register, do op */ X! p->su = max( nr, sul ); X } X else { X /* do harder into a register, then easier */ X! p->su = max( nr+nr, min( max( sul, nr+sur ), max( sur, nr+sul ) ) ); X } X } X X--- 289,307 ---- X X swap: X ssu = sul; sul = sur; sur = ssu; X! s = p->in.left; p->in.left = p->in.right; p->in.right = s; X } X } X noswap: X X! sur = zum( p->in.right, ZCHAR|ZLONG|ZFLOAT ); X if( sur == 0 ){ X /* get left value into a register, do op */ X! p->in.su = max( nr, sul ); X } X else { X /* do harder into a register, then easier */ X! p->in.su = max( nr+nr, min( max( sul, nr+sur ), max( sur, nr+sul ) ) ); X } X } X X*************** X*** 301,320 **** X /* insure that the use of p gets done with register r; in effect, */ X /* simulate offstar */ X X! if( p->op == FLD ){ X! p->left->rall = p->rall; X! p = p->left; X } X X! if( p->op != UNARY MUL ) return; /* no more to do */ X! p = p->left; X! if( p->op == UNARY MUL ){ X! p->rall = r; X! p = p->left; X } X! if( p->op == PLUS && p->right->op == ICON ){ X! p->rall = r; X! p = p->left; X } X rallo( p, r ); X } X--- 311,330 ---- X /* insure that the use of p gets done with register r; in effect, */ X /* simulate offstar */ X X! if( p->in.op == FLD ){ X! p->in.left->in.rall = p->in.rall; X! p = p->in.left; X } X X! if( p->in.op != UNARY MUL ) return; /* no more to do */ X! p = p->in.left; X! if( p->in.op == UNARY MUL ){ X! p->in.rall = r; X! p = p->in.left; X } X! if( p->in.op == PLUS && p->in.right->in.op == ICON ){ X! p->in.rall = r; X! p = p->in.left; X } X rallo( p, r ); X } X*************** X*** 326,336 **** X if( radebug ) printf( "rallo( %o, %o )\n", p, down ); X X down2 = NOPREF; X! p->rall = down; X down1 = ( down &= ~MUSTDO ); X X! ty = optype( o = p->op ); X! type = p->type; X X X if( type == DOUBLE || type == FLOAT ){ X--- 336,346 ---- X if( radebug ) printf( "rallo( %o, %o )\n", p, down ); X X down2 = NOPREF; X! p->in.rall = down; X down1 = ( down &= ~MUSTDO ); X X! ty = optype( o = p->in.op ); X! type = p->in.type; X X X if( type == DOUBLE || type == FLOAT ){ X*************** X*** 355,368 **** X } X /* at least 3 regs free */ X /* compute lhs in (r0,r1), address of left in r2 */ X! p->left->rall = R1|MUSTDO; X! mkrall( p->left, R2|MUSTDO ); X /* now, deal with right */ X! if( fregs == 3 ) rallo( p->right, NOPREF ); X else { X /* put address of long or value here */ X! p->right->rall = R3|MUSTDO; X! mkrall( p->right, R3|MUSTDO ); X } X return; X X--- 365,378 ---- X } X /* at least 3 regs free */ X /* compute lhs in (r0,r1), address of left in r2 */ X! p->in.left->in.rall = R1|MUSTDO; X! mkrall( p->in.left, R2|MUSTDO ); X /* now, deal with right */ X! if( fregs == 3 ) rallo( p->in.right, NOPREF ); X else { X /* put address of long or value here */ X! p->in.right->in.rall = R3|MUSTDO; X! mkrall( p->in.right, R3|MUSTDO ); X } X return; X X*************** X*** 369,384 **** X case MUL: X case DIV: X case MOD: X! rallo( p->left, R1|MUSTDO ); X X if( fregs == 2 ){ X! rallo( p->right, NOPREF ); X return; X } X /* compute addresses, stay away from (r0,r1) */ X X! p->right->rall = (fregs==3) ? R2|MUSTDO : R3|MUSTDO ; X! mkrall( p->right, R2|MUSTDO ); X return; X X case CALL: X--- 379,394 ---- X case MUL: X case DIV: X case MOD: X! rallo( p->in.left, R1|MUSTDO ); X X if( fregs == 2 ){ X! rallo( p->in.right, NOPREF ); X return; X } X /* compute addresses, stay away from (r0,r1) */ X X! p->in.right->in.rall = (fregs==3) ? R2|MUSTDO : R3|MUSTDO ; X! mkrall( p->in.right, R2|MUSTDO ); X return; X X case CALL: X*************** X*** 401,445 **** X X } X X! if( ty != LTYPE ) rallo( p->left, down1 ); X! if( ty == BITYPE ) rallo( p->right, down2 ); X X } X X offstar( p ) register NODE *p; { X! /* handle indirections */ X! X! if( p->op == UNARY MUL ) p = p->left; X! X! if( p->op == PLUS || p->op == MINUS ){ X! if( p->right->op == ICON ){ X! order( p->left , INTAREG|INAREG ); X return; X } X } X order( p, INTAREG|INAREG ); X } X X! setincr( p ) NODE *p; { X! return( 0 ); /* for the moment, don't bother */ X } X X niceuty( p ) register NODE *p; { X register TWORD t; X X! return( p->op == UNARY MUL && (t=p->type)!=CHAR && X t!= UCHAR && t!= FLOAT && X! shumul( p->left) != STARREG ); X } X setbin( p ) register NODE *p; { X register NODE *r, *l; X X! r = p->right; X! l = p->left; X X! if( p->right->su == 0 ){ /* rhs is addressable */ X! if( logop( p->op ) ){ X! if( l->op == UNARY MUL && l->type != FLOAT && shumul( l->left ) != STARREG ) offstar( l->left ); X else order( l, INAREG|INTAREG|INBREG|INTBREG|INTEMP ); X return( 1 ); X } X--- 411,492 ---- X X } X X! if( ty != LTYPE ) rallo( p->in.left, down1 ); X! if( ty == BITYPE ) rallo( p->in.right, down2 ); X X } X X offstar( p ) register NODE *p; { X! if( p->in.op == PLUS ) { X! if( p->in.left->in.su == fregs ) { X! order( p->in.left, INTAREG|INAREG ); X return; X+ } else if( p->in.right->in.su == fregs ) { X+ order( p->in.right, INTAREG|INAREG ); X+ return; X+ } X+ if( p->in.left->in.op==LS && X+ (p->in.left->in.left->in.op!=REG || tlen(p->in.left->in.left)!=sizeof(int) ) ) { X+ order( p->in.left->in.left, INTAREG|INAREG ); X+ return; X+ } X+ if( p->in.right->in.op==LS && X+ (p->in.right->in.left->in.op!=REG || tlen(p->in.right->in.left)!=sizeof(int) ) ) { X+ order( p->in.right->in.left, INTAREG|INAREG ); X+ return; X+ } X+ if( p->in.type == (PTR|CHAR) || p->in.type == (PTR|UCHAR) ) { X+ if( p->in.left->in.op!=REG || tlen(p->in.left)!=sizeof(int) ) { X+ order( p->in.left, INTAREG|INAREG ); X+ return; X } X+ else if( p->in.right->in.op!=REG || tlen(p->in.right)!=sizeof(int) ) { X+ order(p->in.right, INTAREG|INAREG); X+ return; X+ } X } X+ } X+ if( p->in.op == PLUS || p->in.op == MINUS ){ X+ if( p->in.right->in.op == ICON ){ X+ p = p->in.left; X+ order( p , INTAREG|INAREG); X+ return; X+ } X+ } X+ X+ if( p->in.op == UNARY MUL && !canaddr(p) ) { X+ offstar( p->in.left ); X+ return; X+ } X+ X order( p, INTAREG|INAREG ); X } X X! setincr( p ) register NODE *p; { X! p = p->in.left; X! if( p->in.op == UNARY MUL ){ X! offstar( p ); X! return( 1 ); X! } X! return( 0 ); X } X X niceuty( p ) register NODE *p; { X register TWORD t; X X! return( p->in.op == UNARY MUL && (t=p->in.type)!=CHAR && X t!= UCHAR && t!= FLOAT && X! shumul( p->in.left) != STARREG ); X } X setbin( p ) register NODE *p; { X register NODE *r, *l; X X! r = p->in.right; X! l = p->in.left; X X! if( p->in.right->in.su == 0 ){ /* rhs is addressable */ X! if( logop( p->in.op ) ){ X! if( l->in.op == UNARY MUL && l->in.type != FLOAT && shumul( l->in.left ) != STARREG ) offstar( l->in.left ); X else order( l, INAREG|INTAREG|INBREG|INTBREG|INTEMP ); X return( 1 ); X } X*************** X*** 453,464 **** X /* now, rhs is complicated: must do both sides into registers */ X /* do the harder side first */ X X! if( logop( p->op ) ){ X /* relational: do both sides into regs if need be */ X X! if( r->su > l->su ){ X if( niceuty(r) ){ X! offstar( r->left ); X return( 1 ); X } X else if( !istnode( r ) ){ X--- 500,511 ---- X /* now, rhs is complicated: must do both sides into registers */ X /* do the harder side first */ X X! if( logop( p->in.op ) ){ X /* relational: do both sides into regs if need be */ X X! if( r->in.su > l->in.su ){ X if( niceuty(r) ){ X! offstar( r->in.left ); X return( 1 ); X } X else if( !istnode( r ) ){ X*************** X*** 467,477 **** X } X } X if( niceuty(l) ){ X! offstar( l->left ); X return( 1 ); X } X else if( niceuty(r) ){ X! offstar( r->left ); X return( 1 ); X } X else if( !istnode( l ) ){ X--- 514,524 ---- X } X } X if( niceuty(l) ){ X! offstar( l->in.left ); X return( 1 ); X } X else if( niceuty(r) ){ X! offstar( r->in.left ); X return( 1 ); X } X else if( !istnode( l ) ){ X*************** X*** 482,496 **** X order( r, INTAREG|INAREG|INTBREG|INBREG|INTEMP ); X return( 1 ); X } X! cerror( "setbin can't deal with %s", opst[p->op] ); X } X X /* ordinary operator */ X X! if( !istnode(r) && r->su > l->su ){ X /* if there is a chance of making it addressable, try it... */ X if( niceuty(r) ){ X! offstar( r->left ); X return( 1 ); /* hopefully, it is addressable by now */ X } X order( r, INTAREG|INAREG|INTBREG|INBREG|INTEMP ); /* anything goes on rhs */ X--- 529,543 ---- X order( r, INTAREG|INAREG|INTBREG|INBREG|INTEMP ); X return( 1 ); X } X! cerror( "setbin can't deal with %s", opst[p->in.op] ); X } X X /* ordinary operator */ X X! if( !istnode(r) && r->in.su > l->in.su ){ X /* if there is a chance of making it addressable, try it... */ X if( niceuty(r) ){ X! offstar( r->in.left ); X return( 1 ); /* hopefully, it is addressable by now */ X } X order( r, INTAREG|INAREG|INTBREG|INBREG|INTEMP ); /* anything goes on rhs */ X*************** X*** 507,520 **** X } X X setstr( p ) register NODE *p; { /* structure assignment */ X! if( p->right->op != REG ){ X! order( p->right, INTAREG ); X return(1); X } X! p = p->left; X! if( p->op != NAME && p->op != OREG ){ X! if( p->op != UNARY MUL ) cerror( "bad setstr" ); X! order( p->left, INTAREG ); X return( 1 ); X } X return( 0 ); X--- 554,567 ---- X } X X setstr( p ) register NODE *p; { /* structure assignment */ X! if( p->in.right->in.op != REG ){ X! order( p->in.right, INTAREG ); X return(1); X } X! p = p->in.left; X! if( p->in.op != NAME && p->in.op != OREG ){ X! if( p->in.op != UNARY MUL ) cerror( "bad setstr" ); X! order( p->in.left, INTAREG ); X return( 1 ); X } X return( 0 ); X*************** X*** 523,550 **** X setasg( p ) register NODE *p; { X /* setup for assignment operator */ X X! if( p->right->su != 0 && p->right->op != REG ) { X! if( p->right->op == UNARY MUL ) X! offstar( p->right->left ); X else X! order( p->right, INAREG|INBREG|SOREG|SNAME|SCON ); X return(1); X } X! if( p->right->op != REG && ( p->type == FLOAT || p->type == DOUBLE ) ) { X! order( p->right, INBREG ); X return(1); X } X! if( p->left->op == UNARY MUL && !tshape( p->left, STARREG|STARNM ) ){ X! offstar( p->left->left ); X return(1); X } X! if( p->left->op == FLD && p->left->left->op == UNARY MUL ){ X! offstar( p->left->left->left ); X return(1); X } X /* if things are really strange, get rhs into a register */ X! if( p->right->op != REG ){ X! order( p->right, INAREG|INBREG ); X return( 1 ); X } X return(0); X--- 570,597 ---- X setasg( p ) register NODE *p; { X /* setup for assignment operator */ X X! if( p->in.right->in.su != 0 && p->in.right->in.op != REG ) { X! if( p->in.right->in.op == UNARY MUL ) X! offstar( p->in.right->in.left ); X else X! order( p->in.right, INAREG|INBREG|SOREG|SNAME|SCON ); X return(1); X } X! if( p->in.right->in.op != REG && ( p->in.type == FLOAT || p->in.type == DOUBLE ) ) { X! order( p->in.right, INBREG ); X return(1); X } X! if( p->in.left->in.op == UNARY MUL && !tshape( p->in.left, STARREG|STARNM ) ){ X! offstar( p->in.left->in.left ); X return(1); X } X! if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){ X! offstar( p->in.left->in.left->in.left ); X return(1); X } X /* if things are really strange, get rhs into a register */ X! if( p->in.right->in.op != REG ){ X! order( p->in.right, INAREG|INBREG ); X return( 1 ); X } X return(0); X*************** X*** 555,579 **** X register sul, sur; X register NODE *q, *p2; X X! sul = p->left->su; X! sur = p->right->su; X X! switch( p->op ){ X X case ASG PLUS: X case ASG OR: X case ASG MINUS: X! if( p->type != INT && p->type != UNSIGNED && !ISPTR(p->type) ) break; X! if( p->right->type == CHAR || p->right->type == UCHAR ){ X! order( p->right, INAREG ); X return( 1 ); X } X break; X X case ASG ER: X! if( sul == 0 || p->left->op == REG ){ X! if( p->left->type == CHAR || p->left->type == UCHAR ) goto rew; /* rewrite */ X! order( p->right, INAREG|INBREG ); X return( 1 ); X } X goto leftadr; X--- 602,626 ---- X register sul, sur; X register NODE *q, *p2; X X! sul = p->in.left->in.su; X! sur = p->in.right->in.su; X X! switch( p->in.op ){ X X case ASG PLUS: X case ASG OR: X case ASG MINUS: X! if( p->in.type != INT && p->in.type != UNSIGNED && !ISPTR(p->in.type) ) break; X! if( p->in.right->in.type == CHAR || p->in.right->in.type == UCHAR ){ X! order( p->in.right, INAREG ); X return( 1 ); X } X break; X X case ASG ER: X! if( sul == 0 || p->in.left->in.op == REG ){ X! if( p->in.left->in.type == CHAR || p->in.left->in.type == UCHAR ) goto rew; /* rewrite */ X! order( p->in.right, INAREG|INBREG ); X return( 1 ); X } X goto leftadr; X*************** X*** 587,631 **** X X /* harder; make aleft address, val, op, and store */ X X! if( p->left->op == UNARY MUL ){ X! offstar( p->left->left ); X return( 1 ); X } X! if( p->left->op == FLD && p->left->left->op == UNARY MUL ){ X! offstar( p->left->left->left ); X return( 1 ); X } X rew: /* rewrite, accounting for autoincrement and autodecrement */ X X! q = p->left; X! if( q->op == FLD ) q = q->left; X! if( q->op != UNARY MUL || shumul(q->left) != STARREG ) return(0); /* let reader.c do it */ X X /* mimic code from reader.c */ X X p2 = tcopy( p ); X! p->op = ASSIGN; X! reclaim( p->right, RNULL, 0 ); X! p->right = p2; X X /* now, zap INCR on right, ASG MINUS on left */ X X! if( q->left->op == INCR ){ X! q = p2->left; X! if( q->op == FLD ) q = q->left; X! if( q->left->op != INCR ) cerror( "bad incr rewrite" ); X } X! else if( q->left->op != ASG MINUS ) cerror( " bad -= rewrite" ); X X! q->left->right->op = FREE; X! q->left->op = FREE; X! q->left = q->left->left; X X /* now, resume reader.c rewriting code */ X X canon(p); X! rallo( p, p->rall ); X! order( p2->left, INTBREG|INTAREG ); X order( p2, INTBREG|INTAREG ); X return( 1 ); X } X--- 634,678 ---- X X /* harder; make aleft address, val, op, and store */ X X! if( p->in.left->in.op == UNARY MUL ){ X! offstar( p->in.left->in.left ); X return( 1 ); X } X! if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){ X! offstar( p->in.left->in.left->in.left ); X return( 1 ); X } X rew: /* rewrite, accounting for autoincrement and autodecrement */ X X! q = p->in.left; X! if( q->in.op == FLD ) q = q->in.left; X! if( q->in.op != UNARY MUL || shumul(q->in.left) != STARREG ) return(0); /* let reader.c do it */ X X /* mimic code from reader.c */ X X p2 = tcopy( p ); X! p->in.op = ASSIGN; X! reclaim( p->in.right, RNULL, 0 ); X! p->in.right = p2; X X /* now, zap INCR on right, ASG MINUS on left */ X X! if( q->in.left->in.op == INCR ){ X! q = p2->in.left; X! if( q->in.op == FLD ) q = q->in.left; X! if( q->in.left->in.op != INCR ) cerror( "bad incr rewrite" ); X } X! else if( q->in.left->in.op != ASG MINUS ) cerror( " bad -= rewrite" ); X X! q->in.left->in.right->in.op = FREE; X! q->in.left->in.op = FREE; X! q->in.left = q->in.left->in.left; X X /* now, resume reader.c rewriting code */ X X canon(p); X! rallo( p, p->in.rall ); X! order( p2->in.left, INTBREG|INTAREG ); X order( p2, INTBREG|INTAREG ); X return( 1 ); X } X*************** X*** 632,651 **** X X /* harder case: do right, left address, left value, op, store */ X X! if( p->right->op == UNARY MUL ){ X! offstar( p->right->left ); X return( 1 ); X } X /* sur> 0, since otherwise, done above */ X! if( p->right->op == REG ) goto leftadr; /* make lhs addressable */ X! order( p->right, INAREG|INBREG ); X return( 1 ); X } X X! int crslab = 10000; X X getlab(){ X! return( crslab++ ); X } X X deflab( l ){ X--- 679,698 ---- X X /* harder case: do right, left address, left value, op, store */ X X! if( p->in.right->in.op == UNARY MUL ){ X! offstar( p->in.right->in.left ); X return( 1 ); X } X /* sur> 0, since otherwise, done above */ X! if( p->in.right->in.op == REG ) goto leftadr; /* make lhs addressable */ X! order( p->in.right, INAREG|INBREG ); X return( 1 ); X } X X! int crslab = 32767; X X getlab(){ X! return( crslab-- ); X } X X deflab( l ){ X*************** X*** 652,696 **** X printf( "L%d:\n", l ); X } X X! genargs( p) register NODE *p; { X register size; X X /* generate code for the arguments */ X X! /* first, do the arguments on the right (last->first) */ X! while( p->op == CM ){ X! genargs( p->right ); X! p->op = FREE; X! p = p->left; X } X X! if( p->op == STARG ){ /* structure valued argument */ X X! size = p->stsize; X! if( p->left->op == ICON ){ X! /* make into a name node */ X! p->op = FREE; X! p= p->left; X! p->op = NAME; X } X else { X /* make it look beautiful... */ X! p->op = UNARY MUL; X canon( p ); /* turn it into an oreg */ X! if( p->op != OREG ){ X! offstar( p->left ); X canon( p ); X- if( p->op != OREG ) cerror( "stuck starg" ); X } X } X X! p->lval += size; /* end of structure */ X! /* put on stack backwards */ X! for( ; size>0; size -= 2 ){ X! p->lval -= 2; X! expand( p, RNOP, " mov AR,Z-\n" ); X! } X! reclaim( p, RNULL, 0 ); X return; X } X X--- 699,746 ---- X printf( "L%d:\n", l ); X } X X! genargs( p ) register NODE *p; { X! register NODE *pasg; X! register align; X register size; X+ int count; X X /* generate code for the arguments */ X X! /* first, do the arguments on the right */ X! while( p->in.op == CM ){ X! genargs( p->in.right ); X! p->in.op = FREE; X! p = p->in.left; X } X X! if( p->in.op == STARG ){ /* structure valued argument */ X X! size = p->stn.stsize; X! align = p->stn.stalign; X! if( p->in.left->in.op == ICON ){ X! p->in.op = FREE; X! p = p->in.left; X } X else { X /* make it look beautiful... */ X! p->in.op = UNARY MUL; X canon( p ); /* turn it into an oreg */ X! for( count = 0; p->in.op != OREG && count < 10; ++count ){ X! offstar( p->in.left ); X canon( p ); X } X+ if( p->in.op != OREG ) cerror( "stuck starg" ); X } X X! pasg = talloc(); X! pasg->in.op = STARG; X! pasg->in.rall = NOPREF; X! pasg->stn.stsize = size; X! pasg->stn.stalign = align; X! pasg->in.left = p; X! X! order( pasg, FORARG ); X return; X } X X*************** X*** 699,722 **** X order( p, FORARG ); X } X X argsize( p ) register NODE *p; { X! register t; X t = 0; X! if( p->op == CM ){ X! t = argsize( p->left ); X! p = p->right; X } X! if( p->type == DOUBLE || p->type == FLOAT ){ X SETOFF( t, 2 ); X return( t+8 ); X } X! else if( p->type == LONG || p->type == ULONG ) { X SETOFF( t, 2); X return( t+4 ); X } X! else if( p->op == STARG ){ X! SETOFF( t, p->stalign ); /* alignment */ X! return( t + p->stsize ); /* size */ X } X else { X SETOFF( t, 2 ); X--- 749,773 ---- X order( p, FORARG ); X } X X+ OFFSZ X argsize( p ) register NODE *p; { X! OFFSZ t; X t = 0; X! if( p->in.op == CM ){ X! t = argsize( p->in.left ); X! p = p->in.right; X } X! if( p->in.type == DOUBLE || p->in.type == FLOAT ){ X SETOFF( t, 2 ); X return( t+8 ); X } X! else if( p->in.type == LONG || p->in.type == ULONG ) { X SETOFF( t, 2); X return( t+4 ); X } X! else if( p->in.op == STARG ){ X! SETOFF( t, p->stn.stalign ); /* alignment */ X! return( t + p->stn.stsize ); /* size */ X } X else { X SETOFF( t, 2 ); X*** table.c.old Fri Jul 10 17:36:11 1981 X--- table.c Tue Jul 30 17:11:48 1991 X*************** X*** 1,4 **** X! # include "mfile2" X X # define AWD SNAME|SOREG|SCON|STARNM|STARREG|SAREG X # define LWD SNAME|SOREG|SCON|SAREG X--- 1,4 ---- X! # include "pass2.h" X X # define AWD SNAME|SOREG|SCON|STARNM|STARREG|SAREG X # define LWD SNAME|SOREG|SCON|SAREG X*************** X*** 282,288 **** X X OPLOG, FORCC, X AWD, TCHAR|TUCHAR, X! SCCON, TINT, /* look for constants between -128 and 127 */ X 0, RESCC, X " cmpb AL,AR\nZI", X X--- 282,288 ---- X X OPLOG, FORCC, X AWD, TCHAR|TUCHAR, X! SSCON, TINT, /* look for constants between -128 and 127 */ X 0, RESCC, X " cmpb AL,AR\nZI", X X*************** X*** 506,512 **** X X ASG PLUS, INAREG, X LWD, TLONG|TULONG, X! SICON, TINT|TLONG|TULONG, X 0, RLEFT, X " add UR,UL\n adc AL\n", X X--- 506,512 ---- X X ASG PLUS, INAREG, X LWD, TLONG|TULONG, X! SCCON, TINT|TLONG|TULONG, X 0, RLEFT, X " add UR,UL\n adc AL\n", X X*************** X*** 530,536 **** X X ASG MINUS, INAREG, X LWD, TLONG|TULONG, X! SICON, TINT|TLONG|TULONG, X 0, RLEFT, X " sub UR,UL\n sbc AL\n", X X--- 530,536 ---- X X ASG MINUS, INAREG, X LWD, TLONG|TULONG, X! SCCON, TINT|TLONG|TULONG, X 0, RLEFT, X " sub UR,UL\n sbc AL\n", X SHAR_EOF fi exit 0 # End of shell archive