X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/2b84abb596f52ab2068d52108adc96838ad4340a..31cef89cb428866f787983e68246030321893df4:/usr/src/cmd/pi/var.c diff --git a/usr/src/cmd/pi/var.c b/usr/src/cmd/pi/var.c index 266e160726..0287e9f415 100644 --- a/usr/src/cmd/pi/var.c +++ b/usr/src/cmd/pi/var.c @@ -1,14 +1,15 @@ /* Copyright (c) 1979 Regents of the University of California */ -# -/* - * pi - Pascal interpreter code translator - * - * Charles Haley, Bill Joy UCB - * Version 1.2 November 1978 - */ -#include "whoami" +static char sccsid[] = "@(#)var.c 1.3 9/2/80"; + +#include "whoami.h" #include "0.h" +#include "align.h" +#ifdef PC +# include "pc.h" +# include "pcops.h" +# include "iorec.h" +#endif PC /* * Declare variables of a var part. DPOFF1 is @@ -20,14 +21,39 @@ varbeg() { +/* this allows for multiple declaration + * parts except when the "standard" + * option has been specified. + * If routine segment is being compiled, + * do level one processing. + */ + #ifndef PI1 - if (parts & VPRT) - error("All variables must be declared in one var part"); - parts |= VPRT; -#endif -#ifndef PI0 - sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1; + if (!progseen) + level1(); + if ( parts[ cbn ] & RPRT ) { + if ( opt( 's' ) ) { + standard(); + } else { + warning(); + } + error("Variable declarations should precede routine declarations"); + } + if ( parts[ cbn ] & VPRT ) { + if ( opt( 's' ) ) { + standard(); + } else { + warning(); + } + error("All variables should be declared in one var part"); + } + parts[ cbn ] |= VPRT; #endif + /* + * #ifndef PI0 + * sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1; + * #endif + */ forechain = NIL; #ifdef PI0 send(REVVBEG); @@ -43,8 +69,9 @@ var(vline, vidl, vtype) np = gtype(vtype); line = vline; - for (vl = vidl; vl != NIL; vl = vl[2]) - enter(defnl(vl[1], VAR, np, 0)); + for (vl = vidl; vl != NIL; vl = vl[2]) { + } + } send(REVVAR, vline, vidl, vtype); } #else @@ -60,12 +87,46 @@ var(vline, vidl, vtype) np = gtype(vtype); line = vline; + /* + * widths are evened out + */ w = (lwidth(np) + 1) &~ 1; op = &sizes[cbn]; for (; vidl != NIL; vidl = vidl[2]) { - op->om_off -= w; - o2 = op->om_off; +# ifdef OBJ + op -> om_off = roundup( op -> om_off - w , align( np ) ); + o2 = op -> om_off; +# endif OBJ +# ifdef PC + if ( cbn == 1 ) { + /* + * global variables are not accessed off the fp + * but rather by their names. + */ + o2 = 0; + } else { + /* + * locals are aligned, too. + */ + op -> om_off = roundup( op -> om_off - w + , align( np ) ); + o2 = op -> om_off; + } +# endif PC enter(defnl(vidl[1], VAR, np, o2)); + if ( np -> nl_flags & NFILES ) { + dfiles[ cbn ] = TRUE; + } +# ifdef PC + if ( cbn == 1 ) { + putprintf( " .data" , 0 ); + putprintf( " .comm " , 1 ); + putprintf( EXTFORMAT , 1 , vidl[1] ); + putprintf( ",%d" , 0 , w ); + putprintf( " .text" , 0 ); + } + stabvar( vidl[1] , p2type( np ) , cbn , o2 , w , line ); +# endif PC } # ifdef PTREE { @@ -113,7 +174,8 @@ width(np) return (lwidth(np)); } -long lwidth(np) +long +lwidth(np) struct nl *np; { register struct nl *p; @@ -138,8 +200,15 @@ loop: case ARRAY: return (aryconst(p, 0)); case PTR: - case FILET: return ( sizeof ( int * ) ); + case FILET: +# ifdef OBJ + return ( sizeof ( int * ) ); +# endif OBJ +# ifdef PC + return ( sizeof(struct iorec) + + lwidth( p -> type ) ); +# endif PC case RANGE: if (p->type == nl+TDOUBLE) #ifdef DEBUG @@ -151,7 +220,7 @@ loop: return (bytes(p->range[0], p->range[1])); case SET: setran(p->type); - return ( (set.uprbp>>3) + 1); + return roundup( ( set.uprbp >> 3 ) + 1 , A_SET ); case STR: case RECORD: return ( p->value[NL_OFFS] ); @@ -160,6 +229,112 @@ loop: } } + /* + * round up x to a multiple of y + * for computing offsets of aligned things. + * y had better be positive. + * rounding is in the direction of x. + */ +long +roundup( x , y ) + long x; + register long y; + { + + if ( y == 0 ) { + return 0; + } + if ( x >= 0 ) { + return ( ( ( x + ( y - 1 ) ) / y ) * y ); + } else { + return ( ( ( x - ( y - 1 ) ) / y ) * y ); + } + } + + /* + * alignment of an object using the c alignment scheme + */ +int +align( np ) + struct nl *np; + { + register struct nl *p; + + p = np; + if ( p == NIL ) { + return 0; + } +alignit: + switch ( p -> class ) { + case TYPE: + switch ( nloff( p ) ) { + case TNIL: + return A_POINT; + case TSTR: + return A_CHAR; + case TSET: + return A_SET; + default: + p = p -> type; + goto alignit; + } + case ARRAY: + /* + * arrays are aligned as their component types + */ + p = p -> type; + goto alignit; + case PTR: + return A_POINT; + case FILET: + return A_FILET; + case RANGE: + if ( p -> type == nl+TDOUBLE ) { + return A_DOUBLE; + } + /* else, fall through */ + case SCAL: + switch ( bytes( p -> range[0] , p -> range[1] ) ) { + case 4: + return A_LONG; + case 2: + return A_SHORT; + case 1: + return A_CHAR; + default: + panic( "align: scal" ); + } + case SET: + return A_SET; + case STR: + return A_CHAR; + case RECORD: + /* + * follow chain through all fields in record, + * taking max of alignments of types of fields. + * short circuit out if i reach the maximum alignment. + * this is pretty likely, as A_MAX is only 4. + */ + { + register long recalign; + register long fieldalign; + + recalign = A_MIN; + p = p -> chain; + while ( ( p != NIL ) && ( recalign < A_MAX ) ) { + fieldalign = align( p -> type ); + if ( fieldalign > recalign ) { + recalign = fieldalign; + } + p = p -> chain; + } + return recalign; + } + default: + panic( "align" ); + } + } + /* * Return the width of an element * of a n time subscripted np. @@ -175,7 +350,7 @@ long aryconst(np, n) return (NIL); if (p->class != ARRAY) panic("ary"); - s = width(p->type); + s = lwidth(p->type); /* * Arrays of anything but characters are word aligned. */