home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / put.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  15.9 KB  |  823 lines

  1. /*-
  2.  * Copyright (c) 1980 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)put.c    5.4 (Berkeley) 4/16/91";
  36. #endif /* not lint */
  37.  
  38. #include "whoami.h"
  39. #include "opcode.h"
  40. #include "0.h"
  41. #include "objfmt.h"
  42. #ifdef PC
  43. #   include    "pc.h"
  44. #   include    "align.h"
  45. #else
  46.     short    *obufp    = obuf;
  47. #endif
  48.  
  49. /*
  50.  * If DEBUG is defined, include the table
  51.  * of the printing opcode names.
  52.  */
  53. #ifdef DEBUG
  54. #include "OPnames.h"
  55. #endif
  56.  
  57. char showit[] = "'x'";
  58.  
  59. #ifdef OBJ
  60. /*
  61.  * Put is responsible for the interpreter equivalent of code
  62.  * generation.  Since the interpreter is specifically designed
  63.  * for Pascal, little work is required here.
  64.  *
  65.  * FIXME, this should be converted to use <varargs.h> or <stdarg.h>.
  66.  */
  67. /*VARARGS*/
  68. put(a)
  69. {
  70.     register int *p, i;
  71.     register char *cp;
  72.     register short *sp;
  73.     register long *lp;
  74.     int n, subop, suboppr, op, oldlc;
  75.     char *string;
  76.     static int casewrd;
  77.  
  78.     /*
  79.      * It would be nice to do some more
  80.      * optimizations here.  The work
  81.      * done to collapse offsets in lval
  82.      * should be done here, the IFEQ etc
  83.      * relational operators could be used
  84.      * etc.
  85.      */
  86.     oldlc = (int) lc; /* its either this or change put to return a char * */
  87.     if ( !CGENNING )
  88.         /*
  89.          * code disabled - do nothing
  90.          */
  91.         return (oldlc);
  92.     p = &a;
  93.     n = *p++;
  94.     suboppr = subop = (*p >> 8) & 0377;
  95.     op = *p & 0377;
  96.     string = 0;
  97. #ifdef DEBUG
  98.     if ((cp = otext[op]) == NIL) {
  99.         printf("op= %o\n", op);
  100.         panic("put");
  101.     }
  102. #endif
  103.     switch (op) {
  104.         case O_ABORT:
  105.             cp = "*";
  106.             break;
  107.         case O_AS:
  108.             switch(p[1]) {
  109.             case 0:
  110.                 break;
  111.             case 2:
  112.                 op = O_AS2;
  113.                 n = 1;
  114.                 break;
  115.             case 4:
  116.                 op = O_AS4;
  117.                 n = 1;
  118.                 break;
  119.             case 8:
  120.                 op = O_AS8;
  121.                 n = 1;
  122.                 break;
  123.             default:
  124.                 goto pack;
  125.             }
  126. #            ifdef DEBUG
  127.                 cp = otext[op];
  128. #            endif DEBUG
  129.             break;
  130.         case O_FOR1U:
  131.         case O_FOR2U:
  132.         case O_FOR4U:
  133.         case O_FOR1D:
  134.         case O_FOR2D:
  135.         case O_FOR4D:
  136.             /* relative addressing */
  137.             p[1] -= ( unsigned ) lc + sizeof(short);
  138.             /* try to pack the jump */
  139.             if (p[1] <= 127 && p[1] >= -128) {
  140.                 suboppr = subop = p[1];
  141.                 p++;
  142.                 n--;
  143.             } else {
  144.                 /* have to allow for extra displacement */
  145.                 p[1] -= sizeof(short);
  146.             }
  147.             break;
  148.         case O_CONG:
  149.         case O_LVCON:
  150.         case O_CON:
  151.         case O_LINO:
  152.         case O_NEW:
  153.         case O_DISPOSE:
  154.         case O_DFDISP:
  155.         case O_IND:
  156.         case O_OFF:
  157.         case O_INX2:
  158.         case O_INX4:
  159.         case O_CARD:
  160.         case O_ADDT:
  161.         case O_SUBT:
  162.         case O_MULT:
  163.         case O_IN:
  164.         case O_CASE1OP:
  165.         case O_CASE2OP:
  166.         case O_CASE4OP:
  167.         case O_FRTN:
  168.         case O_WRITES:
  169.         case O_WRITEC:
  170.         case O_WRITEF:
  171.         case O_MAX:
  172.         case O_MIN:
  173.         case O_ARGV:
  174.         case O_CTTOT:
  175.         case O_INCT:
  176.         case O_RANG2:
  177.         case O_RSNG2:
  178.         case O_RANG42:
  179.         case O_RSNG42:
  180.         case O_SUCC2:
  181.         case O_SUCC24:
  182.         case O_PRED2:
  183.         case O_PRED24:
  184.             if (p[1] == 0)
  185.                 break;
  186.         case O_CON2:
  187.         case O_CON24:
  188.         pack:
  189.             if (p[1] <= 127 && p[1] >= -128) {
  190.                 suboppr = subop = p[1];
  191.                 p++;
  192.                 n--;
  193.                 if (op == O_CON2) {
  194.                     op = O_CON1;
  195. #                    ifdef DEBUG
  196.                         cp = otext[O_CON1];
  197. #                    endif DEBUG
  198.                 }
  199.                 if (op == O_CON24) {
  200.                     op = O_CON14;
  201. #                    ifdef DEBUG
  202.                         cp = otext[O_CON14];
  203. #                    endif DEBUG
  204.                 }
  205.             }
  206.             break;
  207.         case O_CON8:
  208.             {
  209.             short    *sp = (short *) (&p[1]);
  210.  
  211. #ifdef    DEBUG
  212.             if ( opt( 'k' ) )
  213.                 printf ( "%5d\tCON8\t%22.14e\n" ,
  214.                     lc - HEADER_BYTES ,
  215.                     * ( ( double * ) &p[1] ) );
  216. #endif
  217. #            ifdef DEC11
  218.                 word(op);
  219. #            else
  220.                 word(op << 8);
  221. #            endif DEC11
  222.             for ( i = 1 ; i <= 4 ; i ++ )
  223.                 word ( *sp ++ );
  224.             return ( oldlc );
  225.             }
  226.         default:
  227.             if (op >= O_REL2 && op <= O_REL84) {
  228.                 if ((i = (subop >> INDX) * 5 ) >= 30)
  229.                     i -= 30;
  230.                 else
  231.                     i += 2;
  232. #ifdef DEBUG
  233.                 string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i];
  234. #endif
  235.                 suboppr = 0;
  236.             }
  237.             break;
  238.         case O_IF:
  239.         case O_TRA:
  240. /*****
  241.             codeline = 0;
  242. *****/
  243.             /* relative addressing */
  244.             p[1] -= ( unsigned ) lc + sizeof(short);
  245.             break;
  246.         case O_CONC:
  247. #ifdef DEBUG
  248.             (string = showit)[1] = p[1];
  249. #endif
  250.             suboppr = 0;
  251.             op = O_CON1;
  252. #            ifdef DEBUG
  253.                 cp = otext[O_CON1];
  254. #            endif DEBUG
  255.             subop = p[1];
  256.             goto around;
  257.         case O_CONC4:
  258. #ifdef DEBUG
  259.             (string = showit)[1] = p[1];
  260. #endif
  261.             suboppr = 0;
  262.             op = O_CON14;
  263.             subop = p[1];
  264.             goto around;
  265.         case O_CON1:
  266.         case O_CON14:
  267.             suboppr = subop = p[1];
  268. around:
  269.             n--;
  270.             break;
  271.         case O_CASEBEG:
  272.             casewrd = 0;
  273.             return (oldlc);
  274.         case O_CASEEND:
  275.             if ((unsigned) lc & 1) {
  276.                 lc--;
  277.                 word(casewrd);
  278.             }
  279.             return (oldlc);
  280.         case O_CASE1:
  281. #ifdef DEBUG
  282.             if (opt('k'))
  283.                 printf("%5d\tCASE1\t%d\n"
  284.                     , lc - HEADER_BYTES, p[1]);
  285. #endif
  286.             /*
  287.              * this to build a byte size case table 
  288.              * saving bytes across calls in casewrd
  289.              * so they can be put out by word()
  290.              */
  291.             lc++;
  292.             if ((unsigned) lc & 1)
  293. #                ifdef DEC11
  294.                     casewrd = p[1] & 0377;
  295. #                else
  296.                     casewrd = (p[1] & 0377) << 8;
  297. #                endif DEC11
  298.             else {
  299.                 lc -= 2;
  300. #                ifdef DEC11
  301.                     word(((p[1] & 0377) << 8) | casewrd);
  302. #                else
  303.                     word((p[1] & 0377) | casewrd);
  304. #                endif DEC11
  305.             }
  306.             return (oldlc);
  307.         case O_CASE2:
  308. #ifdef DEBUG
  309.             if (opt('k'))
  310.                 printf("%5d\tCASE2\t%d\n"
  311.                     , lc - HEADER_BYTES , p[1]);
  312. #endif
  313.             word(p[1]);
  314.             return (oldlc);
  315.         case O_PUSH:
  316.             lp = (long *)&p[1];
  317.             if (*lp == 0)
  318.                 return (oldlc);
  319.             /* and fall through */
  320.         case O_RANG4:
  321.         case O_RANG24:
  322.         case O_RSNG4:
  323.         case O_RSNG24:
  324.         case O_SUCC4:
  325.         case O_PRED4:
  326.             /* sub opcode optimization */
  327.             lp = (long *)&p[1];
  328.             if (*lp < 128 && *lp >= -128 && *lp != 0) {
  329.                 suboppr = subop = *lp;
  330.                 p += (sizeof(long) / sizeof(int));
  331.                 n--;
  332.             }
  333.             goto longgen;
  334.         case O_TRA4:
  335.         case O_CALL:
  336.         case O_FSAV:
  337.         case O_GOTO:
  338.         case O_NAM:
  339.         case O_READE:
  340.             /* absolute long addressing */
  341.             lp = (long *)&p[1];
  342.             *lp -= HEADER_BYTES;
  343.             goto longgen;
  344.         case O_RV1:
  345.         case O_RV14:
  346.         case O_RV2:
  347.         case O_RV24:
  348.         case O_RV4:
  349.         case O_RV8:
  350.         case O_RV:
  351.         case O_LV:
  352.             /*
  353.              * positive offsets represent arguments
  354.              * and must use "ap" display entry rather
  355.              * than the "fp" entry
  356.              */
  357.             if (p[1] >= 0) {
  358.                 subop++;
  359.                 suboppr++;
  360.             }
  361. #            ifdef PDP11
  362.                 break;
  363. #            else
  364.                 /*
  365.                  * offsets out of range of word addressing
  366.                  * must use long offset opcodes
  367.                  */
  368.                 if (p[1] < SHORTADDR && p[1] >= -SHORTADDR)
  369.                     break;
  370.                 else {
  371.                 op += O_LRV - O_RV;
  372. #                ifdef DEBUG
  373.                     cp = otext[op];
  374. #                endif DEBUG
  375.                 }
  376.                 /* and fall through */
  377. #            endif PDP11
  378.         case O_BEG:
  379.         case O_NODUMP:
  380.         case O_CON4:
  381.         case O_CASE4:
  382.         longgen:
  383.             n = (n << 1) - 1;
  384.             if ( op == O_LRV ) {
  385.                 n--;
  386. #                if defined(ADDR32) && !defined(DEC11)
  387.                     p[n / 2] <<= 16;
  388. #                endif
  389.             }
  390. #ifdef DEBUG
  391.             if (opt('k')) {
  392.                 printf("%5d\t%s", lc - HEADER_BYTES, cp+1);
  393.                 if (suboppr)
  394.                     printf(":%d", suboppr);
  395.                 for ( i = 2, lp = (long *)&p[1]; i < n 
  396.                     ; i += sizeof ( long )/sizeof ( short ) )
  397.                     printf( "\t%D " , *lp ++ );
  398.                 if (i == n) {
  399.                     sp = (short *)lp;
  400.                     printf( "\t%d ", *sp );
  401.                 }
  402.                 pchr ( '\n' );
  403.             }
  404. #endif
  405.             if ( op != O_CASE4 )
  406. #                ifdef DEC11
  407.                         word((op & 0377) | subop << 8);
  408. #                else
  409.                     word(op << 8 | (subop & 0377));
  410. #                endif DEC11
  411.             for ( i = 1, sp = (short *)&p[1]; i < n; i++)
  412.                 word ( *sp ++ );
  413.             return ( oldlc );
  414.     }
  415. #ifdef DEBUG
  416.     if (opt('k')) {
  417.         printf("%5d\t%s", lc - HEADER_BYTES, cp+1);
  418.         if (suboppr)
  419.             printf(":%d", suboppr);
  420.         if (string)
  421.             printf("\t%s",string);
  422.         if (n > 1)
  423.             pchr('\t');
  424.         for (i=1; i<n; i++)
  425.             printf("%d ", p[i]);
  426.         pchr('\n');
  427.     }
  428. #endif
  429.     if (op != NIL)
  430. #        ifdef DEC11
  431.             word((op & 0377) | subop << 8);
  432. #        else
  433.             word(op << 8 | (subop & 0377));
  434. #        endif DEC11
  435.     for (i=1; i<n; i++)
  436.         word(p[i]);
  437.     return (oldlc);
  438. }
  439. #endif OBJ
  440.  
  441. /*
  442.  * listnames outputs a list of enumerated type names which
  443.  * can then be selected from to output a TSCAL
  444.  * a pointer to the address in the code of the namelist
  445.  * is kept in value[ NL_ELABEL ].
  446.  */
  447. listnames(ap)
  448.  
  449.     register struct nl *ap;
  450. {
  451.     struct nl *next;
  452. #ifdef OBJ
  453.     register int oldlc;
  454. #endif
  455.     register int len;
  456.     register unsigned w;
  457.     register char *strptr;
  458.  
  459.     if ( !CGENNING )
  460.         /* code is off - do nothing */
  461.         return(NIL);
  462.     if (ap->class != TYPE)
  463.         ap = ap->type;
  464.     if (ap->value[ NL_ELABEL ] != 0) {
  465.         /* the list already exists */
  466.         return( ap -> value[ NL_ELABEL ] );
  467.     }
  468. #    ifdef OBJ
  469.         oldlc = (int) lc; /* same problem as put */
  470.         (void) put(2, O_TRA, lc);
  471.         ap->value[ NL_ELABEL ] = (int) lc;
  472. #    endif OBJ
  473. #    ifdef PC
  474.         putprintf("    .data", 0);
  475.         aligndot(A_STRUCT);
  476.         ap -> value[ NL_ELABEL ] = (int) getlab();
  477.         (void) putlab((char *) ap -> value[ NL_ELABEL ] );
  478. #    endif PC
  479.     /* number of scalars */
  480.     next = ap->type;
  481.     len = next->range[1]-next->range[0]+1;
  482. #    ifdef OBJ
  483.         (void) put(2, O_CASE2, len);
  484. #    endif OBJ
  485. #    ifdef PC
  486.         putprintf( "    .word %d" , 0 , len );
  487. #    endif PC
  488.     /* offsets of each scalar name */
  489.     len = (len+1)*sizeof(short);
  490. #    ifdef OBJ
  491.         (void) put(2, O_CASE2, len);
  492. #    endif OBJ
  493. #    ifdef PC
  494.         putprintf( "    .word %d" , 0 , len );
  495. #    endif PC
  496.     next = ap->chain;
  497.     do    {
  498.         for(strptr = next->symbol;  *strptr++;  len++)
  499.             continue;
  500.         len++;
  501. #        ifdef OBJ
  502.             (void) put(2, O_CASE2, len);
  503. #        endif OBJ
  504. #        ifdef PC
  505.             putprintf( "    .word %d" , 0 , len );
  506. #        endif PC
  507.     } while (next = next->chain);
  508.     /* list of scalar names */
  509.     strptr = getnext(ap, &next);
  510. #    ifdef OBJ
  511.         do    {
  512. #            ifdef DEC11
  513.             w = (unsigned) *strptr;
  514. #            else
  515.             w = *strptr << 8;
  516. #            endif DEC11
  517.             if (!*strptr++)
  518.                 strptr = getnext(next, &next);
  519. #            ifdef DEC11
  520.             w |= *strptr << 8;
  521. #            else
  522.             w |= (unsigned) *strptr;
  523. #            endif DEC11
  524.             if (!*strptr++)
  525.                 strptr = getnext(next, &next);
  526.             word((int) w);
  527.         } while (next);
  528.         /* jump over the mess */
  529.         patch((PTR_DCL) oldlc);
  530. #    endif OBJ
  531. #    ifdef PC
  532.         while ( next ) {
  533.         while ( *strptr ) {
  534.             putprintf( "    .byte    0%o" , 1 , *strptr++ );
  535.             for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) {
  536.             putprintf( ",0%o" , 1 , *strptr++ );
  537.             }
  538.             putprintf( "" , 0 );
  539.         }
  540.         putprintf( "    .byte    0" , 0 );
  541.         strptr = getnext( next , &next );
  542.         }
  543.         putprintf( "    .text" , 0 );
  544. #    endif PC
  545.     return( ap -> value[ NL_ELABEL ] );
  546. }
  547.  
  548. char *
  549. getnext(next, new)
  550.  
  551.     struct nl *next, **new;
  552. {
  553.     if (next != NIL) {
  554.         next = next->chain;
  555.         *new = next;
  556.     }
  557.     if (next == NLNIL)
  558.         return("");
  559. #ifdef OBJ
  560.     if (opt('k') && CGENNING )
  561.         printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol);
  562. #endif OBJ
  563.     return(next->symbol);
  564. }
  565.  
  566. #ifdef OBJ
  567. /*
  568.  * Putspace puts out a table
  569.  * of nothing to leave space
  570.  * for the case branch table e.g.
  571.  */
  572. putspace(n)
  573.     int n;
  574. {
  575.     register i;
  576.  
  577.     if ( !CGENNING )
  578.         /*
  579.          * code disabled - do nothing
  580.          */
  581.         return;
  582. #ifdef DEBUG
  583.     if (opt('k'))
  584.         printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n);
  585. #endif
  586.     for (i = n; i > 0; i -= 2)
  587.         word(0);
  588. }
  589.  
  590. putstr(sptr, padding)
  591.  
  592.     char *sptr;
  593.     int padding;
  594. {
  595.     register unsigned short w;
  596.     register char *strptr = sptr;
  597.     register int pad = padding;
  598.  
  599.     if ( !CGENNING )
  600.         /*
  601.          * code disabled - do nothing
  602.          */
  603.         return;
  604. #ifdef DEBUG
  605.     if (opt('k'))
  606.         printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr);
  607. #endif
  608.     if (pad == 0) {
  609.         do    {
  610. #            ifdef DEC11
  611.                 w = (unsigned short) * strptr;
  612. #            else
  613.                 w = (unsigned short)*strptr<<8;
  614. #            endif DEC11
  615.             if (w)
  616. #                ifdef DEC11
  617.                     w |= *++strptr << 8;
  618. #                else
  619.                     w |= *++strptr;
  620. #                endif DEC11
  621.             word((int) w);
  622.         } while (*strptr++);
  623.     } else {
  624. #        ifdef DEC11
  625.             do     {
  626.                 w = (unsigned short) * strptr;
  627.                 if (w) {
  628.                     if (*++strptr)
  629.                         w |= *strptr << 8;
  630.                     else {
  631.                         w |= ' ' << 8;
  632.                         pad--;
  633.                     }
  634.                     word((int) w);
  635.                 }
  636.             } while (*strptr++);
  637. #        else
  638.             do     {
  639.                 w = (unsigned short)*strptr<<8;
  640.                 if (w) {
  641.                     if (*++strptr)
  642.                         w |= *strptr;
  643.                     else {
  644.                         w |= ' ';
  645.                         pad--;
  646.                     }
  647.                     word(w);
  648.                 }
  649.             } while (*strptr++);
  650. #        endif DEC11
  651.         while (pad > 1) {
  652. #            ifdef DEC11
  653.                 word(' ' | (' ' << 8));
  654. #            else
  655.                 word((' ' << 8) | ' ');
  656. #            endif DEC11
  657.             pad -= 2;
  658.         }
  659.         if (pad == 1)
  660. #            ifdef DEC11
  661.                 word(' ');
  662. #            else
  663.                 word(' ' << 8);
  664. #            endif DEC11
  665.         else
  666.             word(0);
  667.     }
  668. }
  669. #endif OBJ
  670.  
  671. #ifndef PC
  672. lenstr(sptr, padding)
  673.  
  674.     char *sptr;
  675.     int padding;
  676.  
  677. {
  678.     register int cnt;
  679.     register char *strptr = sptr;
  680.  
  681.     cnt = padding;
  682.     do    {
  683.         cnt++;
  684.     } while (*strptr++);
  685.     return((++cnt) & ~1);
  686. }
  687. #endif
  688.  
  689. /*
  690.  * Patch repairs the branch
  691.  * at location loc to come
  692.  * to the current location.
  693.  *    for PC, this puts down the label
  694.  *    and the branch just references that label.
  695.  *    lets here it for two pass assemblers.
  696.  */
  697. patch(loc)
  698.     PTR_DCL loc;
  699. {
  700.  
  701. #    ifdef OBJ
  702.         patchfil(loc, (long)(lc-loc-2), 1);
  703. #    endif OBJ
  704. #    ifdef PC
  705.         (void) putlab((char *) loc );
  706. #    endif PC
  707. }
  708.  
  709. #ifdef OBJ
  710. patch4(loc)
  711. PTR_DCL loc;
  712. {
  713.     patchfil(loc, (long)(lc - HEADER_BYTES), 2);
  714. }
  715.  
  716. /*
  717.  * Patchfil makes loc+2 have jmploc
  718.  * as its contents.
  719.  */
  720. patchfil(loc, jmploc, words)
  721.     PTR_DCL loc;
  722.     long jmploc;
  723.     int words;
  724. {
  725.     register i;
  726.     extern long lseek();
  727.     short val;
  728.  
  729.     if ( !CGENNING )
  730.         return;
  731.     if (loc > (unsigned) lc)
  732.         panic("patchfil");
  733. #ifdef DEBUG
  734.     if (opt('k'))
  735.         printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc);
  736. #endif
  737.     val = jmploc;
  738.     do {
  739. #        ifndef DEC11
  740.             if (words > 1)
  741.                 val = jmploc >> 16;
  742.             else
  743.                 val = jmploc;
  744. #        endif DEC11
  745.         i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
  746.         if (i >= 0 && i < 1024) {
  747.             obuf[i] = val;
  748.         } else {
  749.             (void) lseek(ofil, (long) loc+2, 0);
  750.             write(ofil, (char *) (&val), 2);
  751.             (void) lseek(ofil, (long) 0, 2);
  752.         }
  753.         loc += 2;
  754. #        ifdef DEC11
  755.             val = jmploc >> 16;
  756. #        endif DEC11
  757.     } while (--words);
  758. }
  759.  
  760. /*
  761.  * Put the word o into the code
  762.  */
  763. word(o)
  764.     int o;
  765. {
  766.  
  767.     *obufp = o;
  768.     obufp++;
  769.     lc += 2;
  770.     if (obufp >= obuf+512)
  771.         pflush();
  772. }
  773.  
  774. extern char    *obj;
  775. /*
  776.  * Flush the code buffer
  777.  */
  778. pflush()
  779. {
  780.     register i;
  781.  
  782.     i = (obufp - ( ( short * ) obuf ) ) * 2;
  783.     if (i != 0 && write(ofil, (char *) obuf, i) != i)
  784.         perror(obj), pexit(DIED);
  785.     obufp = obuf;
  786. }
  787. #endif OBJ
  788.  
  789. /*
  790.  * Getlab - returns the location counter.
  791.  * included here for the eventual code generator.
  792.  *    for PC, thank you!
  793.  */
  794. char *
  795. getlab()
  796. {
  797. #    ifdef OBJ
  798.  
  799.         return (lc);
  800. #    endif OBJ
  801. #    ifdef PC
  802.         static long    lastlabel;
  803.  
  804.         return ( (char *) ++lastlabel );
  805. #    endif PC
  806. }
  807.  
  808. /*
  809.  * Putlab - lay down a label.
  810.  *    for PC, just print the label name with a colon after it.
  811.  */
  812. char *
  813. putlab(l)
  814.     char *l;
  815. {
  816.  
  817. #    ifdef PC
  818.         putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , (int) l );
  819.         putprintf( ":" , 0 );
  820. #    endif PC
  821.     return (l);
  822. }
  823.