Annotation of 3BSD/cmd/pi/put.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #
                      3: /*
                      4:  * pi - Pascal interpreter code translator
                      5:  *
                      6:  * Charles Haley, Bill Joy UCB
                      7:  * Version 1.2 November 1978
                      8:  */
                      9: 
                     10: #include "whoami"
                     11: #include "opcode.h"
                     12: #include "0.h"
                     13: 
                     14: short  *obufp  = obuf;
                     15: 
                     16: /*
                     17:  * If DEBUG is defined, include the table
                     18:  * of the printing opcode names.
                     19:  */
                     20: #ifdef DEBUG
                     21: char   *otext[] = {
                     22: #include "OPnames.h"
                     23: };
                     24: #endif
                     25: 
                     26: #ifdef OBJ
                     27: /*
                     28:  * Put is responsible for the interpreter equivalent of code
                     29:  * generation.  Since the interpreter is specifically designed
                     30:  * for Pascal, little work is required here.
                     31:  */
                     32: put(a)
                     33: {
                     34:        register int *p, i;
                     35:        register char *cp;
                     36:        int n, subop, suboppr, op, oldlc, w;
                     37:        char *string;
                     38:        static int casewrd;
                     39: 
                     40:        /*
                     41:         * It would be nice to do some more
                     42:         * optimizations here.  The work
                     43:         * done to collapse offsets in lval
                     44:         * should be done here, the IFEQ etc
                     45:         * relational operators could be used
                     46:         * etc.
                     47:         */
                     48:        oldlc = lc;
                     49:        if (cgenflg)
                     50:                /*
                     51:                 * code disabled - do nothing
                     52:                 */
                     53:                return (oldlc);
                     54:        p = &a;
                     55:        n = *p++;
                     56:        suboppr = subop = (*p>>8) & 0377;
                     57:        op = *p & 0377;
                     58:        string = 0;
                     59: #ifdef DEBUG
                     60:        if ((cp = otext[op]) == NIL) {
                     61:                printf("op= %o\n", op);
                     62:                panic("put");
                     63:        }
                     64: #endif
                     65:        switch (op) {
                     66: /*****
                     67:                case O_LINO:
                     68:                        if (line == codeline)
                     69:                                return (oldlc);
                     70:                        codeline = line;
                     71: *****/
                     72:                case O_PUSH:
                     73:                case O_POP:
                     74:                        if (p[1] == 0)
                     75:                                return (oldlc);
                     76:                case O_NEW:
                     77:                case O_DISPOSE:
                     78:                case O_AS:
                     79:                case O_IND:
                     80:                case O_OFF:
                     81:                case O_INX2:
                     82:                case O_INX4:
                     83:                case O_CARD:
                     84:                case O_ADDT:
                     85:                case O_SUBT:
                     86:                case O_MULT:
                     87:                case O_IN:
                     88:                case O_CASE1OP:
                     89:                case O_CASE2OP:
                     90:                case O_CASE4OP:
                     91:                case O_PACK:
                     92:                case O_UNPACK:
                     93:                case O_RANG2:
                     94:                case O_RSNG2:
                     95:                case O_RANG42:
                     96:                case O_RSNG42:
                     97:                        if (p[1] == 0)
                     98:                                break;
                     99:                case O_CON2:
                    100:                        if (p[1] < 128 && p[1] >= -128) {
                    101:                                suboppr = subop = p[1];
                    102:                                p++;
                    103:                                n--;
                    104:                                if (op == O_CON2)
                    105:                                        op = O_CON1;
                    106:                        }
                    107:                        break;
                    108:                case O_CON8:
                    109:                    {
                    110:                        short   *sp = &p[1];
                    111: 
                    112: #ifdef DEBUG
                    113:                        if ( opt( 'c' ) )
                    114:                            printf ( ")#%5d\tCON8\t%10.3f\n" ,
                    115:                                        lc - HEAD_BYTES ,
                    116:                                        * ( ( double * ) &p[1] ) );
                    117: #endif
                    118:                        word ( op );
                    119:                        for ( i = 1 ; i <= 4 ; i ++ )
                    120:                            word ( *sp ++ );
                    121:                        return ( oldlc );
                    122:                    }
                    123:                default:
                    124:                        if (op >= O_REL2 && op <= O_REL84) {
                    125:                                if ((i = (subop >> 1) * 5 ) >= 30)
                    126:                                        i -= 30;
                    127:                                else
                    128:                                        i += 2;
                    129: #ifdef DEBUG
                    130:                                string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i];
                    131: #endif
                    132:                                suboppr = 0;
                    133:                        }
                    134:                        break;
                    135:                case O_IF:
                    136:                case O_TRA:
                    137: /*****
                    138:                        codeline = 0;
                    139: *****/
                    140:                case O_FOR1U:
                    141:                case O_FOR2U:
                    142:                case O_FOR4U:
                    143:                case O_FOR1D:
                    144:                case O_FOR2D:
                    145:                case O_FOR4D:
                    146:                        /* relative addressing */
                    147:                        p[1] -= ( unsigned ) lc + 2;
                    148:                        break;
                    149:                case O_WRIT82:
                    150: #ifdef DEBUG
                    151:                        string = &"22\024\042\044"[subop*3];
                    152: #endif
                    153:                        suboppr = 0;
                    154:                        break;
                    155:                case O_CONG:
                    156:                        i = p[1];
                    157:                        cp = * ( ( char ** ) &p[2] ) ;
                    158: #ifdef DEBUG
                    159:                        if (opt('c'))
                    160:                                printf(")#%5d\tCONG:%d\t%s\n",
                    161:                                        lc - HEAD_BYTES, i, cp);
                    162: #endif
                    163:                        if (i <= 127)
                    164:                                word(O_CON | i << 8);
                    165:                        else {
                    166:                                word(O_CON);
                    167:                                word(i);
                    168:                        }
                    169:                        while (i > 0) {
                    170:                                w = *cp ? *cp++ : ' ';
                    171:                                w |= (*cp ? *cp++ : ' ') << 8;
                    172:                                word(w);
                    173:                                i -= 2;
                    174:                        }
                    175:                        return (oldlc);
                    176:                case O_CONC:
                    177: #ifdef DEBUG
                    178:                        (string = "'x'")[1] = p[1];
                    179: #endif
                    180:                        suboppr = 0;
                    181:                        op = O_CON1;
                    182:                        subop = p[1];
                    183:                        goto around;
                    184:                case O_CON1:
                    185:                        suboppr = subop = p[1];
                    186: around:
                    187:                        n--;
                    188:                        break;
                    189:                case O_CASEBEG:
                    190:                        casewrd = 0;
                    191:                        return (oldlc);
                    192:                case O_CASEEND:
                    193:                        if ((unsigned) lc & 1) {
                    194:                                lc--;
                    195:                                word(casewrd);
                    196:                        }
                    197:                        return (oldlc);
                    198:                case O_CASE1:
                    199: #ifdef DEBUG
                    200:                        if (opt('c'))
                    201:                                printf(")#%5d\tCASE1\t%d\n"
                    202:                                        , lc - HEAD_BYTES
                    203:                                        , ( int ) *( ( long * ) &p[1] ) );
                    204: #endif
                    205:                        /*
                    206:                         * this to build a byte size case table 
                    207:                         * saving bytes across calls in casewrd
                    208:                         * so they can be put out by word()
                    209:                         */
                    210:                        lc++;
                    211:                        if ((unsigned) lc & 1)
                    212:                                casewrd = *( ( long * ) &p[1] );
                    213:                        else {
                    214:                                lc -= 2;
                    215:                                word (   casewrd
                    216:                                       | ( ( int ) *( ( long * ) &p[1] ) << 8 ) );
                    217:                        }
                    218:                        return (oldlc);
                    219:                case O_CASE2:
                    220: #ifdef DEBUG
                    221:                        if (opt('c'))
                    222:                                printf(")#%5d\tCASE2\t%d\n"
                    223:                                        , lc - HEAD_BYTES
                    224:                                        , ( int ) *( ( long * ) &p[1] ) );
                    225: #endif
                    226:                        word( ( short ) *( ( long * ) &p[1] ) );
                    227:                        return (oldlc);
                    228:                case O_TRA4:
                    229:                case O_CALL:
                    230:                case O_GOTO:
                    231:                case O_TRACNT:
                    232:                        /* absolute long addressing */
                    233:                        p[1] -= HEAD_BYTES;
                    234:                        n++;
                    235:                case O_CON4:
                    236:                case O_CASE4:
                    237:                case O_RANG4:
                    238:                case O_RANG4 + 1:       /* O_RANG24 */
                    239:                case O_RSNG4:
                    240:                case O_RSNG4 + 1:       /* O_RSNG24 */
                    241:                    {
                    242:                        short   *sp = &p[1];
                    243:                        long    *lp = &p[1];
                    244: 
                    245: #ifdef DEBUG
                    246:                        if (opt('c'))
                    247:                            {
                    248:                                printf( ")#%5d\t%s" , lc - HEAD_BYTES , cp );
                    249:                                if (suboppr)
                    250:                                        printf(":%1d", suboppr);
                    251:                                for ( i = 1 ; i < n 
                    252:                                    ; i += sizeof ( long )/sizeof ( short ) )
                    253:                                        printf( "\t%D " , *lp ++ );
                    254:                                pchr ( '\n' );
                    255:                            }
                    256: #endif
                    257:                        if ( op != O_CASE4 )
                    258:                            word ( op | subop<<8 );
                    259:                        for ( i = 1 ; i < n ; i ++ )
                    260:                            word ( *sp ++ );
                    261:                        return ( oldlc );
                    262:                    }
                    263:        }
                    264: #ifdef DEBUG
                    265:        if (opt('c')) {
                    266:                printf(")#%5d\t%s", lc - HEAD_BYTES, cp);
                    267:                if (suboppr)
                    268:                        printf(":%d", suboppr);
                    269:                if (string)
                    270:                        printf("\t%s",string);
                    271:                if (n > 1)
                    272:                        pchr('\t');
                    273:                for (i=1; i<n; i++)
                    274:                        printf("%d ", ( short ) p[i]);
                    275:                pchr('\n');
                    276:        }
                    277: #endif
                    278:        if (op != NIL)
                    279:                word(op | subop << 8);
                    280:        for (i=1; i<n; i++)
                    281:                word(p[i]);
                    282:        return (oldlc);
                    283: }
                    284: #endif OBJ
                    285: 
                    286: /*
                    287:  * Putspace puts out a table
                    288:  * of nothing to leave space
                    289:  * for the case branch table e.g.
                    290:  */
                    291: putspace(n)
                    292:        int n;
                    293: {
                    294:        register i;
                    295: #ifdef DEBUG
                    296:        if (opt('c'))
                    297:                printf(")#%5d\t.=.+%d\n", lc - HEAD_BYTES, n);
                    298: #endif
                    299:        for (i = even(n); i > 0; i -= 2)
                    300:                word(0);
                    301: }
                    302: 
                    303: /*
                    304:  * Patch repairs the branch
                    305:  * at location loc to come
                    306:  * to the current location.
                    307:  */
                    308: patch(loc)
                    309: {
                    310: 
                    311:        patchfil(loc, lc-loc-2, 1);
                    312: }
                    313: 
                    314: patch4(loc)
                    315: {
                    316: 
                    317:        patchfil(loc, lc - HEAD_BYTES, 2);
                    318: }
                    319: 
                    320: /*
                    321:  * Patchfil makes loc+2 have value
                    322:  * as its contents.
                    323:  */
                    324: patchfil(loc, value, words)
                    325: #ifdef VAX
                    326:        unsigned long loc;
                    327: #endif
                    328: #ifdef PDP11
                    329:        char *loc;
                    330: #endif
                    331:        int value, words;
                    332: {
                    333:        register i;
                    334: 
                    335:        if (cgenflg < 0)
                    336:                return;
                    337:        if (loc > (unsigned) lc)
                    338:                panic("patchfil");
                    339: #ifdef DEBUG
                    340:        if (opt('c'))
                    341:                printf(")#\tpatch %u %d\n", loc - HEAD_BYTES, value);
                    342: #endif
                    343:        do {
                    344:                i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
                    345:                if (i >= 0 && i < 1024)
                    346:                        obuf[i] = value;
                    347:                else {
                    348:                        lseek(ofil, (long) loc+2, 0);
                    349:                        write(ofil, &value, 2);
                    350:                        lseek(ofil, (long) 0, 2);
                    351:                }
                    352:                loc += 2;
                    353:                value = value >> 16;
                    354:        } while (--words);
                    355: }
                    356: 
                    357: /*
                    358:  * Put the word o into the code
                    359:  */
                    360: word(o)
                    361:        int o;
                    362: {
                    363: 
                    364:        *obufp = o;
                    365:        obufp++;
                    366:        lc += 2;
                    367:        if (obufp >= obuf+512)
                    368:                pflush();
                    369: }
                    370: 
                    371: extern char    *obj;
                    372: /*
                    373:  * Flush the code buffer
                    374:  */
                    375: pflush()
                    376: {
                    377:        register i;
                    378: 
                    379:        i = (obufp - ( ( short * ) obuf ) ) * 2;
                    380:        if (i != 0 && write(ofil, obuf, i) != i)
                    381:                perror(obj), pexit(DIED);
                    382:        obufp = obuf;
                    383: }
                    384: 
                    385: /*
                    386:  * Getlab - returns the location counter.
                    387:  * included here for the eventual code generator.
                    388:  */
                    389: getlab()
                    390: {
                    391: 
                    392:        return (lc);
                    393: }
                    394: 
                    395: /*
                    396:  * Putlab - lay down a label.
                    397:  */
                    398: putlab(l)
                    399:        int l;
                    400: {
                    401: 
                    402:        return (l);
                    403: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.