BSD 4 release
[unix-history] / usr / src / cmd / pi / put.c
index 1cd9c90..7e4180f 100644 (file)
@@ -1,15 +1,14 @@
 /* Copyright (c) 1979 Regents of the University of California */
 /* 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[] = "@(#)put.c 1.3 10/2/80";
+
+#include "whoami.h"
 #include "opcode.h"
 #include "0.h"
 #include "opcode.h"
 #include "0.h"
+#include "objfmt.h"
+#ifdef PC
+#   include    "pc.h"
+#endif PC
 
 short  *obufp  = obuf;
 
 
 short  *obufp  = obuf;
 
@@ -18,9 +17,7 @@ short *obufp  = obuf;
  * of the printing opcode names.
  */
 #ifdef DEBUG
  * of the printing opcode names.
  */
 #ifdef DEBUG
-char   *otext[] = {
 #include "OPnames.h"
 #include "OPnames.h"
-};
 #endif
 
 #ifdef OBJ
 #endif
 
 #ifdef OBJ
@@ -46,7 +43,7 @@ put(a)
         * etc.
         */
        oldlc = lc;
         * etc.
         */
        oldlc = lc;
-       if (cgenflg)
+       if (cgenflg < 0)
                /*
                 * code disabled - do nothing
                 */
                /*
                 * code disabled - do nothing
                 */
@@ -63,20 +60,21 @@ put(a)
        }
 #endif
        switch (op) {
        }
 #endif
        switch (op) {
-/*****
+               case O_ABORT:
+                       cp = "*";
+                       break;
                case O_LINO:
                case O_LINO:
+/*****
                        if (line == codeline)
                                return (oldlc);
                        codeline = line;
 *****/
                        if (line == codeline)
                                return (oldlc);
                        codeline = line;
 *****/
-               case O_PUSH:
-               case O_POP:
-                       if (p[1] == 0)
-                               return (oldlc);
                case O_NEW:
                case O_DISPOSE:
                case O_AS:
                case O_IND:
                case O_NEW:
                case O_DISPOSE:
                case O_AS:
                case O_IND:
+               case O_LVCON:
+               case O_CON:
                case O_OFF:
                case O_INX2:
                case O_INX4:
                case O_OFF:
                case O_INX2:
                case O_INX4:
@@ -88,8 +86,16 @@ put(a)
                case O_CASE1OP:
                case O_CASE2OP:
                case O_CASE4OP:
                case O_CASE1OP:
                case O_CASE2OP:
                case O_CASE4OP:
+               case O_FRTN:
+               case O_WRITES:
+               case O_WRITEF:
+               case O_MAX:
+               case O_MIN:
                case O_PACK:
                case O_UNPACK:
                case O_PACK:
                case O_UNPACK:
+               case O_ARGV:
+               case O_CTTOT:
+               case O_INCT:
                case O_RANG2:
                case O_RSNG2:
                case O_RANG42:
                case O_RANG2:
                case O_RSNG2:
                case O_RANG42:
@@ -97,12 +103,19 @@ put(a)
                        if (p[1] == 0)
                                break;
                case O_CON2:
                        if (p[1] == 0)
                                break;
                case O_CON2:
+               case O_CON24:
                        if (p[1] < 128 && p[1] >= -128) {
                                suboppr = subop = p[1];
                                p++;
                                n--;
                        if (p[1] < 128 && p[1] >= -128) {
                                suboppr = subop = p[1];
                                p++;
                                n--;
-                               if (op == O_CON2)
+                               if (op == O_CON2) {
                                        op = O_CON1;
                                        op = O_CON1;
+                                       cp = otext[O_CON1];
+                               }
+                               if (op == O_CON24) {
+                                       op = O_CON14;
+                                       cp = otext[O_CON14];
+                               }
                        }
                        break;
                case O_CON8:
                        }
                        break;
                case O_CON8:
@@ -110,9 +123,9 @@ put(a)
                        short   *sp = &p[1];
 
 #ifdef DEBUG
                        short   *sp = &p[1];
 
 #ifdef DEBUG
-                       if ( opt( 'c' ) )
+                       if ( opt( 'k' ) )
                            printf ( ")#%5d\tCON8\t%10.3f\n" ,
                            printf ( ")#%5d\tCON8\t%10.3f\n" ,
-                                       lc - HEAD_BYTES ,
+                                       lc - HEADER_BYTES ,
                                        * ( ( double * ) &p[1] ) );
 #endif
                        word ( op );
                                        * ( ( double * ) &p[1] ) );
 #endif
                        word ( op );
@@ -146,19 +159,13 @@ put(a)
                        /* relative addressing */
                        p[1] -= ( unsigned ) lc + 2;
                        break;
                        /* relative addressing */
                        p[1] -= ( unsigned ) lc + 2;
                        break;
-               case O_WRIT82:
-#ifdef DEBUG
-                       string = &"22\024\042\044"[subop*3];
-#endif
-                       suboppr = 0;
-                       break;
                case O_CONG:
                        i = p[1];
                        cp = * ( ( char ** ) &p[2] ) ;
 #ifdef DEBUG
                case O_CONG:
                        i = p[1];
                        cp = * ( ( char ** ) &p[2] ) ;
 #ifdef DEBUG
-                       if (opt('c'))
+                       if (opt('k'))
                                printf(")#%5d\tCONG:%d\t%s\n",
                                printf(")#%5d\tCONG:%d\t%s\n",
-                                       lc - HEAD_BYTES, i, cp);
+                                       lc - HEADER_BYTES, i, cp);
 #endif
                        if (i <= 127)
                                word(O_CON | i << 8);
 #endif
                        if (i <= 127)
                                word(O_CON | i << 8);
@@ -179,9 +186,19 @@ put(a)
 #endif
                        suboppr = 0;
                        op = O_CON1;
 #endif
                        suboppr = 0;
                        op = O_CON1;
+                       cp = otext[O_CON1];
+                       subop = p[1];
+                       goto around;
+               case O_CONC4:
+#ifdef DEBUG
+                       (string = "'x'")[1] = p[1];
+#endif
+                       suboppr = 0;
+                       op = O_CON14;
                        subop = p[1];
                        goto around;
                case O_CON1:
                        subop = p[1];
                        goto around;
                case O_CON1:
+               case O_CON14:
                        suboppr = subop = p[1];
 around:
                        n--;
                        suboppr = subop = p[1];
 around:
                        n--;
@@ -197,9 +214,9 @@ around:
                        return (oldlc);
                case O_CASE1:
 #ifdef DEBUG
                        return (oldlc);
                case O_CASE1:
 #ifdef DEBUG
-                       if (opt('c'))
+                       if (opt('k'))
                                printf(")#%5d\tCASE1\t%d\n"
                                printf(")#%5d\tCASE1\t%d\n"
-                                       , lc - HEAD_BYTES
+                                       , lc - HEADER_BYTES
                                        , ( int ) *( ( long * ) &p[1] ) );
 #endif
                        /*
                                        , ( int ) *( ( long * ) &p[1] ) );
 #endif
                        /*
@@ -209,7 +226,7 @@ around:
                         */
                        lc++;
                        if ((unsigned) lc & 1)
                         */
                        lc++;
                        if ((unsigned) lc & 1)
-                               casewrd = *( ( long * ) &p[1] );
+                               casewrd = *( ( long * ) &p[1] ) & 0377;
                        else {
                                lc -= 2;
                                word (   casewrd
                        else {
                                lc -= 2;
                                word (   casewrd
@@ -218,34 +235,70 @@ around:
                        return (oldlc);
                case O_CASE2:
 #ifdef DEBUG
                        return (oldlc);
                case O_CASE2:
 #ifdef DEBUG
-                       if (opt('c'))
+                       if (opt('k'))
                                printf(")#%5d\tCASE2\t%d\n"
                                printf(")#%5d\tCASE2\t%d\n"
-                                       , lc - HEAD_BYTES
+                                       , lc - HEADER_BYTES
                                        , ( int ) *( ( long * ) &p[1] ) );
 #endif
                        word( ( short ) *( ( long * ) &p[1] ) );
                        return (oldlc);
                                        , ( int ) *( ( long * ) &p[1] ) );
 #endif
                        word( ( short ) *( ( long * ) &p[1] ) );
                        return (oldlc);
+               case O_FCALL:
+                       if (p[1] == 0)
+                               goto longgen;
+                       /* and fall through */
+               case O_PUSH:
+                       if (p[1] == 0)
+                               return (oldlc);
+                       if (p[1] < 128 && p[1] >= -128) {
+                               suboppr = subop = p[1];
+                               p++;
+                               n--;
+                               break;
+                       }
+                       goto longgen;
                case O_TRA4:
                case O_CALL:
                case O_TRA4:
                case O_CALL:
+               case O_FSAV:
                case O_GOTO:
                case O_GOTO:
-               case O_TRACNT:
+               case O_NAM:
+               case O_READE:
                        /* absolute long addressing */
                        /* absolute long addressing */
-                       p[1] -= HEAD_BYTES;
-                       n++;
+                       p[1] -= HEADER_BYTES;
+                       goto longgen;
+               case O_RV1:
+               case O_RV14:
+               case O_RV2:
+               case O_RV24:
+               case O_RV4:
+               case O_RV8:
+               case O_RV:
+               case O_LV:
+                       if (p[1] < SHORTADDR && p[1] >= -SHORTADDR)
+                               break;
+                       else {
+                               op += O_LRV - O_RV;
+                               cp = otext[op];
+                       }
+               case O_BEG:
+               case O_NODUMP:
                case O_CON4:
                case O_CASE4:
                case O_RANG4:
                case O_CON4:
                case O_CASE4:
                case O_RANG4:
-               case O_RANG4 + 1:       /* O_RANG24 */
+               case O_RANG24:
                case O_RSNG4:
                case O_RSNG4:
-               case O_RSNG4 + 1:       /* O_RSNG24 */
+               case O_RSNG24:
+               longgen:
                    {
                        short   *sp = &p[1];
                        long    *lp = &p[1];
 
                    {
                        short   *sp = &p[1];
                        long    *lp = &p[1];
 
+                       n = (n << 1) - 1;
+                       if ( op == O_LRV )
+                               n--;
 #ifdef DEBUG
 #ifdef DEBUG
-                       if (opt('c'))
+                       if (opt('k'))
                            {
                            {
-                               printf( ")#%5d\t%s" , lc - HEAD_BYTES , cp );
+                               printf( ")#%5d\t%s" , lc - HEADER_BYTES , cp+1 );
                                if (suboppr)
                                        printf(":%1d", suboppr);
                                for ( i = 1 ; i < n 
                                if (suboppr)
                                        printf(":%1d", suboppr);
                                for ( i = 1 ; i < n 
@@ -262,8 +315,8 @@ around:
                    }
        }
 #ifdef DEBUG
                    }
        }
 #ifdef DEBUG
-       if (opt('c')) {
-               printf(")#%5d\t%s", lc - HEAD_BYTES, cp);
+       if (opt('k')) {
+               printf(")#%5d\t%s", lc - HEADER_BYTES, cp+1);
                if (suboppr)
                        printf(":%d", suboppr);
                if (string)
                if (suboppr)
                        printf(":%d", suboppr);
                if (string)
@@ -282,7 +335,121 @@ around:
        return (oldlc);
 }
 #endif OBJ
        return (oldlc);
 }
 #endif OBJ
+\f
+/*
+ * listnames outputs a list of enumerated type names which
+ * can then be selected from to output a TSCAL
+ * a pointer to the address in the code of the namelist
+ * is kept in value[ NL_ELABEL ].
+ */
+listnames(ap)
+
+       register struct nl *ap;
+{
+       struct nl *next;
+       register int oldlc, len;
+       register unsigned w;
+       register char *strptr;
+
+       if (cgenflg < 0)
+               /* code is off - do nothing */
+               return(NIL);
+       if (ap->class != TYPE)
+               ap = ap->type;
+       if (ap->value[ NL_ELABEL ] != 0) {
+               /* the list already exists */
+               return( ap -> value[ NL_ELABEL ] );
+       }
+#      ifdef OBJ
+           oldlc = lc;
+           put(2, O_TRA, lc);
+           ap->value[ NL_ELABEL ] = lc;
+#      endif OBJ
+#      ifdef PC
+           putprintf( "        .data" , 0 );
+           putprintf( "        .align 1" , 0 );
+           ap -> value[ NL_ELABEL ] = getlab();
+           putlab( ap -> value[ NL_ELABEL ] );
+#      endif PC
+       /* number of scalars */
+       next = ap->type;
+       len = next->range[1]-next->range[0]+1;
+#      ifdef OBJ
+           put(2, O_CASE2, len);
+#      endif OBJ
+#      ifdef PC
+           putprintf( "        .word %d" , 0 , len );
+#      endif PC
+       /* offsets of each scalar name */
+       len = (len+1)*sizeof(short);
+#      ifdef OBJ
+           put(2, O_CASE2, len);
+#      endif OBJ
+#      ifdef PC
+           putprintf( "        .word %d" , 0 , len );
+#      endif PC
+       next = ap->chain;
+       do      {
+               for(strptr = next->symbol;  *strptr++;  len++)
+                       continue;
+               len++;
+#              ifdef OBJ
+                   put(2, O_CASE2, len);
+#              endif OBJ
+#              ifdef PC
+                   putprintf( "        .word %d" , 0 , len );
+#              endif PC
+       } while (next = next->chain);
+       /* list of scalar names */
+       strptr = getnext(ap, &next);
+#      ifdef OBJ
+           do  {
+                   w = (unsigned) *strptr;
+                   if (!*strptr++)
+                           strptr = getnext(next, &next);
+                   w |= *strptr << 8;
+                   if (!*strptr++)
+                           strptr = getnext(next, &next);
+                   word(w);
+           } while (next);
+           /* jump over the mess */
+           patch(oldlc);
+#      endif OBJ
+#      ifdef PC
+           while ( next ) {
+               while ( *strptr ) {
+                   putprintf( "        .byte   0%o" , 1 , *strptr++ );
+                   for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) {
+                       putprintf( ",0%o" , 1 , *strptr++ );
+                   }
+                   putprintf( "" , 0 );
+               }
+               putprintf( "    .byte   0" , 0 );
+               strptr = getnext( next , &next );
+           }
+           putprintf( "        .text" , 0 );
+#      endif PC
+       return( ap -> value[ NL_ELABEL ] );
+}
+
+getnext(next, new)
 
 
+       struct nl *next, **new;
+{
+       if (next != NIL) {
+               next = next->chain;
+               *new = next;
+       }
+       if (next == NIL)
+               return("");
+#ifdef OBJ
+       if (opt('k') && cgenflg >= 0)
+               printf(")#%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol);
+#endif
+       return(next->symbol);
+}
+\f
+#ifdef OBJ
 /*
  * Putspace puts out a table
  * of nothing to leave space
 /*
  * Putspace puts out a table
  * of nothing to leave space
@@ -292,29 +459,110 @@ putspace(n)
        int n;
 {
        register i;
        int n;
 {
        register i;
+
+       if (cgenflg < 0)
+               /*
+                * code disabled - do nothing
+                */
+               return(lc);
 #ifdef DEBUG
 #ifdef DEBUG
-       if (opt('c'))
-               printf(")#%5d\t.=.+%d\n", lc - HEAD_BYTES, n);
+       if (opt('k'))
+               printf(")#%5d\t.=.+%d\n", lc - HEADER_BYTES, n);
 #endif
        for (i = even(n); i > 0; i -= 2)
                word(0);
 }
 
 #endif
        for (i = even(n); i > 0; i -= 2)
                word(0);
 }
 
+putstr(sptr, padding)
+
+       char *sptr;
+       int padding;
+{
+       register unsigned short w;
+       register char *strptr = sptr;
+       register int pad = padding;
+
+       if (cgenflg < 0)
+               /*
+                * code disabled - do nothing
+                */
+               return(lc);
+#ifdef DEBUG
+       if (opt('k'))
+               printf(")#%5D\t\t\"%s\"\n", lc-HEADER_BYTES, strptr);
+#endif
+       if (pad == 0) {
+               do      {
+                       w = (unsigned short) * strptr;
+                       if (w)
+                               w |= *++strptr << 8;
+                       word(w);
+               } while (*strptr++);
+       } else {
+               do      {
+                       w = (unsigned short) * strptr;
+                       if (w) {
+                               if (*++strptr)
+                                       w |= *strptr << 8;
+                               else {
+                                       w |= ' ' << 8;
+                                       pad--;
+                               }
+                               word(w);
+                       }
+               } while (*strptr++);
+               while (pad > 1) {
+                       word('  ');
+                       pad -= 2;
+               }
+               if (pad == 1)
+                       word(' ');
+               else
+                       word(0);
+       }
+}
+#endif OBJ
+
+lenstr(sptr, padding)
+
+       char *sptr;
+       int padding;
+
+{
+       register int cnt;
+       register char *strptr = sptr;
+
+       cnt = padding;
+       do      {
+               cnt++;
+       } while (*strptr++);
+       return((++cnt) & ~1);
+}
+\f
 /*
  * Patch repairs the branch
  * at location loc to come
  * to the current location.
 /*
  * Patch repairs the branch
  * at location loc to come
  * to the current location.
+ *     for PC, this puts down the label
+ *     and the branch just references that label.
+ *     lets here it for two pass assemblers.
  */
 patch(loc)
 {
 
  */
 patch(loc)
 {
 
-       patchfil(loc, lc-loc-2, 1);
+#      ifdef OBJ
+           patchfil(loc, lc-loc-2, 1);
+#      endif OBJ
+#      ifdef PC
+           putlab( loc );
+#      endif PC
 }
 
 }
 
+#ifdef OBJ
 patch4(loc)
 {
 
 patch4(loc)
 {
 
-       patchfil(loc, lc - HEAD_BYTES, 2);
+       patchfil(loc, lc - HEADER_BYTES, 2);
 }
 
 /*
 }
 
 /*
@@ -322,12 +570,7 @@ patch4(loc)
  * as its contents.
  */
 patchfil(loc, value, words)
  * as its contents.
  */
 patchfil(loc, value, words)
-#ifdef VAX
-       unsigned long loc;
-#endif
-#ifdef PDP11
-       char *loc;
-#endif
+       PTR_DCL loc;
        int value, words;
 {
        register i;
        int value, words;
 {
        register i;
@@ -337,8 +580,8 @@ patchfil(loc, value, words)
        if (loc > (unsigned) lc)
                panic("patchfil");
 #ifdef DEBUG
        if (loc > (unsigned) lc)
                panic("patchfil");
 #ifdef DEBUG
-       if (opt('c'))
-               printf(")#\tpatch %u %d\n", loc - HEAD_BYTES, value);
+       if (opt('k'))
+               printf(")#\tpatch %u %d\n", loc - HEADER_BYTES, value);
 #endif
        do {
                i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
 #endif
        do {
                i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
@@ -353,7 +596,7 @@ patchfil(loc, value, words)
                value = value >> 16;
        } while (--words);
 }
                value = value >> 16;
        } while (--words);
 }
-
+\f
 /*
  * Put the word o into the code
  */
 /*
  * Put the word o into the code
  */
@@ -381,23 +624,38 @@ pflush()
                perror(obj), pexit(DIED);
        obufp = obuf;
 }
                perror(obj), pexit(DIED);
        obufp = obuf;
 }
+#endif OBJ
 
 /*
  * Getlab - returns the location counter.
  * included here for the eventual code generator.
 
 /*
  * Getlab - returns the location counter.
  * included here for the eventual code generator.
+ *     for PC, thank you!
  */
 getlab()
 {
  */
 getlab()
 {
+#      ifdef OBJ
 
 
-       return (lc);
+           return (lc);
+#      endif OBJ
+#      ifdef PC
+           static long lastlabel;
+
+           return ( ++lastlabel );
+#      endif PC
 }
 
 /*
  * Putlab - lay down a label.
 }
 
 /*
  * Putlab - lay down a label.
+ *     for PC, just print the label name with a colon after it.
  */
 putlab(l)
        int l;
 {
 
  */
 putlab(l)
        int l;
 {
 
+#      ifdef PC
+           putprintf( PREFIXFORMAT , 1 , LABELPREFIX , l );
+           putprintf( ":" , 0 );
+#      endif PC
        return (l);
 }
        return (l);
 }
+