home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / p2put.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  18.9 KB  |  787 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[] = "@(#)p2put.c    5.5 (Berkeley) 4/16/91";
  36. #endif /* not lint */
  37.  
  38.     /*
  39.      *    functions to help pi put out
  40.      *    polish postfix binary portable c compiler intermediate code
  41.      *    thereby becoming the portable pascal compiler
  42.      */
  43.  
  44. #include    "whoami.h"
  45. #ifdef PC
  46. #include    "0.h"
  47. #include    "objfmt.h"
  48. #include    <pcc.h>
  49. #include    "pc.h"
  50. #include    "align.h"
  51. #include    "tmps.h"
  52.  
  53.     /*
  54.      *    emits an ftext operator and a string to the pcstream
  55.      */
  56. puttext( string )
  57.     char    *string;
  58.     {
  59.     int    length = str4len( string );
  60.  
  61.     if ( !CGENNING )
  62.         return;
  63.     p2word( PCCM_TRIPLE( PCCF_FTEXT , length , 0 ) );
  64. #    ifdef DEBUG
  65.         if ( opt( 'k' ) ) {
  66.         fprintf( stdout , "PCCF_FTEXT | %3d | 0    " , length );
  67.         }
  68. #    endif
  69.     p2string( string );
  70.     }
  71.  
  72. int
  73. str4len( string )
  74.     char    *string;
  75.     {
  76.     
  77.     return ( ( strlen( string ) + 3 ) / 4 );
  78.     }
  79.  
  80.     /*
  81.      *    put formatted text into a buffer for printing to the pcstream.
  82.      *    a call to putpflush actually puts out the text.
  83.      *    none of arg1 .. arg5 need be present.
  84.      *    and you can add more if you need them.
  85.      */
  86. /* VARARGS */
  87. putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 )
  88.     char    *format;
  89.     int        incomplete;
  90.     {
  91.     static char    ppbuffer[ BUFSIZ ];
  92.     static char    *ppbufp = ppbuffer;
  93.  
  94.     if ( !CGENNING )
  95.         return;
  96.     sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 );
  97.     ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] );
  98.     if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) )
  99.         panic( "putprintf" );
  100.     if ( ! incomplete ) {
  101.         puttext( ppbuffer );
  102.         ppbufp = ppbuffer;
  103.     }
  104.     }
  105.  
  106.     /*
  107.      *    emit a left bracket operator to pcstream
  108.      *    with function number, the maximum temp register, and total local bytes
  109.      */
  110. putlbracket(ftnno, sizesp)
  111.     int        ftnno;
  112.     struct om    *sizesp;
  113. {
  114.     int    maxtempreg;    
  115.     int    alignedframesize;
  116.  
  117. #   if defined(vax) || defined(tahoe)
  118.     maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL];
  119. #   endif vax || tahoe
  120. #   ifdef mc68000
  121.         /*
  122.          *    this is how /lib/f1 wants it.
  123.          */
  124.     maxtempreg =    (sizesp->curtmps.next_avail[REG_ADDR] << 4)
  125.               | (sizesp->curtmps.next_avail[REG_DATA]);
  126. #   endif mc68000
  127.     alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off),
  128.     (long)(BITSPERBYTE * A_STACK));
  129.     p2word( PCCM_TRIPLE( PCCF_FLBRAC , maxtempreg , ftnno ) );
  130.     p2word(alignedframesize);
  131. #   ifdef DEBUG
  132.     if ( opt( 'k' ) ) {
  133.         fprintf(stdout, "PCCF_FLBRAC | %3d | %d    %d\n",
  134.         maxtempreg, ftnno, alignedframesize);
  135.     }
  136. #   endif
  137. }
  138.  
  139.     /*
  140.      *    emit a right bracket operator
  141.      *    which for the binary interface
  142.      *    forces the stack allocate and register mask
  143.      */
  144. putrbracket( ftnno )
  145.     int    ftnno;
  146.     {
  147.  
  148.     p2word( PCCM_TRIPLE( PCCF_FRBRAC , 0 , ftnno ) );
  149. #    ifdef DEBUG
  150.         if ( opt( 'k' ) ) {
  151.         fprintf( stdout , "PCCF_FRBRAC |   0 | %d\n" , ftnno );
  152.         }
  153. #    endif
  154.     }
  155.  
  156.     /*
  157.      *    emit an eof operator
  158.      */
  159. puteof()
  160.     {
  161.     
  162.     p2word( PCCF_FEOF );
  163. #    ifdef DEBUG
  164.         if ( opt( 'k' ) ) {
  165.         fprintf( stdout , "PCCF_FEOF\n" );
  166.         }
  167. #    endif
  168.     }
  169.  
  170.     /*
  171.      *    emit a dot operator,
  172.      *    with a source file line number and name
  173.      *    if line is negative, there was an error on that line, but who cares?
  174.      */
  175. putdot( filename , line )
  176.     char    *filename;
  177.     int        line;
  178.     {
  179.     int    length = str4len( filename );
  180.  
  181.     if ( line < 0 ) {
  182.         line = -line;
  183.     }
  184.     p2word( PCCM_TRIPLE( PCCF_FEXPR , length , line ) );
  185. #    ifdef DEBUG
  186.         if ( opt( 'k' ) ) {
  187.         fprintf( stdout , "PCCF_FEXPR | %3d | %d    " , length , line );
  188.         }
  189. #    endif
  190.     p2string( filename );
  191.     }
  192.  
  193.     /*
  194.      *    put out a leaf node
  195.      */
  196. putleaf( op , lval , rval , type , name )
  197.     int        op;
  198.     int        lval;
  199.     int        rval;
  200.     int        type;
  201.     char    *name;
  202.     {
  203.     if ( !CGENNING )
  204.         return;
  205.     switch ( op ) {
  206.         default:
  207.         panic( "[putleaf]" );
  208.         case PCC_ICON:
  209.         p2word( PCCM_TRIPLE( PCC_ICON , name != NIL , type ) );
  210.         p2word( lval );
  211. #        ifdef DEBUG
  212.             if ( opt( 'k' ) ) {
  213.             fprintf( stdout , "PCC_ICON | %3d | 0x%x    " 
  214.                    , name != NIL , type );
  215.             fprintf( stdout , "%d\n" , lval );
  216.             }
  217. #        endif
  218.         if ( name )
  219.             p2name( name );
  220.         break;
  221.         case PCC_NAME:
  222.         p2word( PCCM_TRIPLE( PCC_NAME , lval != 0 , type ) );
  223.         if ( lval ) 
  224.             p2word( lval );
  225. #        ifdef DEBUG
  226.             if ( opt( 'k' ) ) {
  227.             fprintf( stdout , "PCC_NAME | %3d | 0x%x    " 
  228.                    , lval != 0 , type );
  229.             if ( lval )
  230.                 fprintf( stdout , "%d    " , lval );
  231.             }
  232. #        endif
  233.         p2name( name );
  234.         break;
  235.         case PCC_REG:
  236.         p2word( PCCM_TRIPLE( PCC_REG , rval , type ) );
  237. #        ifdef DEBUG
  238.             if ( opt( 'k' ) ) {
  239.             fprintf( stdout , "PCC_REG | %3d | 0x%x\n" ,
  240.                 rval , type );
  241.             }
  242. #        endif
  243.         break;
  244.     }
  245.     }
  246.  
  247.     /*
  248.      *    rvalues are just lvalues with indirection, except
  249.      *    special cases for registers and for named globals,
  250.      *    whose names are their rvalues.
  251.      */
  252. putRV( name , level , offset , other_flags , type )
  253.     char    *name;
  254.     int        level;
  255.     int        offset;
  256.     char    other_flags;
  257.     int        type;
  258.     {
  259.     char    extname[ BUFSIZ ];
  260.     char    *printname;
  261.  
  262.     if ( !CGENNING )
  263.         return;
  264.     if ( other_flags & NREGVAR ) {
  265.         if ( ( offset < 0 ) || ( offset > P2FP ) ) {
  266.         panic( "putRV regvar" );
  267.         }
  268.         putleaf( PCC_REG , 0 , offset , type , (char *) 0 );
  269.         return;
  270.     }
  271.     if ( whereis( offset , other_flags ) == GLOBALVAR ) {
  272.         if ( name != 0 ) {
  273.         if ( name[0] != '_' ) {
  274.             sprintf( extname , EXTFORMAT , name );
  275.             printname = extname;
  276.         } else {
  277.             printname = name;
  278.         }
  279.         putleaf( PCC_NAME , offset , 0 , type , printname );
  280.         return;
  281.         } else {
  282.         panic( "putRV no name" );
  283.         }
  284.     }
  285.     putLV( name , level , offset , other_flags , type );
  286.     putop( PCCOM_UNARY PCC_MUL , type );
  287.     }
  288.  
  289.     /*
  290.      *    put out an lvalue 
  291.      *    given a level and offset
  292.      *    special case for
  293.      *        named globals, whose lvalues are just their names as constants.
  294.      */
  295. putLV( name , level , offset , other_flags , type )
  296.     char    *name;
  297.     int        level;
  298.     int        offset;
  299.     char    other_flags;
  300.     int        type;
  301. {
  302.     char        extname[ BUFSIZ ];
  303.     char        *printname;
  304.  
  305.     if ( !CGENNING )
  306.     return;
  307.     if ( other_flags & NREGVAR ) {
  308.     panic( "putLV regvar" );
  309.     }
  310.     switch ( whereis( offset , other_flags ) ) {
  311.     case GLOBALVAR:
  312.         if ( ( name != 0 ) ) {
  313.         if ( name[0] != '_' ) {
  314.             sprintf( extname , EXTFORMAT , name );
  315.             printname = extname;
  316.         } else {
  317.             printname = name;
  318.         }
  319.         putleaf( PCC_ICON , offset , 0 , PCCM_ADDTYPE( type , PCCTM_PTR )
  320.             , printname );
  321.         return;
  322.         } else {
  323.         panic( "putLV no name" );
  324.         }
  325.     case PARAMVAR:
  326.         if ( level == cbn ) {
  327.         putleaf( PCC_REG, 0, P2AP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
  328.         } else {
  329.         putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + AP_OFFSET
  330.             , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
  331.         parts[ level ] |= NONLOCALVAR;
  332.         }
  333.         putleaf( PCC_ICON , offset , 0 , PCCT_INT , (char *) 0 );
  334.         putop( PCC_PLUS , PCCTM_PTR | PCCT_CHAR );
  335.         break;
  336.     case LOCALVAR:
  337.         if ( level == cbn ) {
  338.         putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
  339.         } else {
  340.         putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
  341.             , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
  342.         parts[ level ] |= NONLOCALVAR;
  343.         }
  344.         putleaf( PCC_ICON , -offset , 0 , PCCT_INT , (char *) 0 );
  345.         putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR );
  346.         break;
  347.     case NAMEDLOCALVAR:
  348.         if ( level == cbn ) {
  349.         putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
  350.         } else {
  351.         putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
  352.             , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
  353.         parts[ level ] |= NONLOCALVAR;
  354.         }
  355.         putleaf( PCC_ICON , 0 , 0 , PCCT_INT , name );
  356.         putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR );
  357.         break;
  358.     }
  359.     return;
  360. }
  361.  
  362.     /*
  363.      *    put out a floating point constant leaf node
  364.      *    the constant is declared in aligned data space
  365.      *    and a PCC_NAME leaf put out for it
  366.      */
  367. putCON8( val )
  368.     double    val;
  369.     {
  370.     char    *label;
  371.     char    name[ BUFSIZ ];
  372.  
  373.     if ( !CGENNING )
  374.         return;
  375.     label = getlab();
  376.     putprintf( "    .data" , 0 );
  377.     aligndot(A_DOUBLE);
  378.     (void) putlab( label );
  379. #    if defined(vax) || defined(tahoe)
  380.         putprintf( "    .double 0d%.20e" , 0 , val );
  381. #    endif vax || tahoe
  382. #    ifdef mc68000
  383.         putprintf( "    .long     0x%x,0x%x", 0, val);
  384. #    endif mc68000
  385.     putprintf( "    .text" , 0 );
  386.     sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
  387.     putleaf( PCC_NAME , 0 , 0 , PCCT_DOUBLE , name );
  388.     }
  389.  
  390.     /*
  391.      * put out either an lvalue or an rvalue for a constant string.
  392.      * an lvalue (for assignment rhs's) is the name as a constant, 
  393.      * an rvalue (for parameters) is just the name.
  394.      */
  395. putCONG( string , length , required )
  396.     char    *string;
  397.     int        length;
  398.     int        required;
  399.     {
  400.     char    name[ BUFSIZ ];
  401.     char    *label;
  402.     char    *cp;
  403.     int    pad;
  404.     int    others;
  405.  
  406.     if ( !CGENNING )
  407.         return;
  408.     putprintf( "    .data" , 0 );
  409.     aligndot(A_STRUCT);
  410.     label = getlab();
  411.     (void) putlab( label );
  412.     cp = string;
  413.     while ( *cp ) {
  414.         putprintf( "    .byte    0%o" , 1 , *cp ++ );
  415.         for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) {
  416.         putprintf( ",0%o" , 1 , *cp++ );
  417.         }
  418.         putprintf( "" , 0 );
  419.     }
  420.     pad = length - strlen( string );
  421.     while ( pad-- > 0 ) {
  422.         putprintf( "    .byte    0%o" , 1 , ' ' );
  423.         for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) {
  424.         putprintf( ",0%o" , 1 , ' ' );
  425.         }
  426.         putprintf( "" , 0 );
  427.     }
  428.     putprintf( "    .byte    0" , 0 );
  429.     putprintf( "    .text"  , 0 );
  430.     sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
  431.     if ( required == RREQ ) {
  432.         putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name );
  433.     } else {
  434.         putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name );
  435.     }
  436.     }
  437.  
  438.     /*
  439.      *    map a pascal type to a c type
  440.      *    this would be tail recursive, but i unfolded it into a for (;;).
  441.      *    this is sort of like isa and lwidth
  442.      *    a note on the types used by the portable c compiler:
  443.      *        they are divided into a basic type (char, short, int, long, etc.)
  444.      *        and qualifications on those basic types (pointer, function, array).
  445.      *        the basic type is kept in the low 4 bits of the type descriptor,
  446.      *        and the qualifications are arranged in two bit chunks, with the
  447.      *        most significant on the right,
  448.      *        and the least significant on the left
  449.      *        e.g. int *foo();
  450.      *            (a function returning a pointer to an integer)
  451.      *        is stored as
  452.      *            <ptr><ftn><int>
  453.      *    so, we build types recursively
  454.      *    also, we know that /lib/f1 can only deal with 6 qualifications
  455.      *    so we stop the recursion there.  this stops infinite type recursion
  456.      *    through mutually recursive pointer types.
  457.      */
  458. #define    MAXQUALS    6
  459. int
  460. p2type( np )
  461.     struct nl    *np;
  462. {
  463.  
  464.     return typerecur( np , 0 );
  465. }
  466. typerecur( np , quals )
  467.     struct nl    *np;
  468.     int        quals;
  469.     {
  470.     
  471.     if ( np == NIL || quals > MAXQUALS ) {
  472.         return PCCT_UNDEF;
  473.     }
  474.     switch ( np -> class ) {
  475.         case SCAL :
  476.         case RANGE :
  477.         case CRANGE :
  478.         if ( np -> type == ( nl + TDOUBLE ) ) {
  479.             return PCCT_DOUBLE;
  480.         }
  481.         switch ( bytes( np -> range[0] , np -> range[1] ) ) {
  482.             case 1:
  483.             return PCCT_CHAR;
  484.             case 2:
  485.             return PCCT_SHORT;
  486.             case 4:
  487.             return PCCT_INT;
  488.             default:
  489.             panic( "p2type int" );
  490.             /* NOTREACHED */
  491.         }
  492.         case STR :
  493.         return ( PCCTM_ARY | PCCT_CHAR );
  494.         case RECORD :
  495.         case SET :
  496.         return PCCT_STRTY;
  497.         case FILET :
  498.         return ( PCCTM_PTR | PCCT_STRTY );
  499.         case CONST :
  500.         case VAR :
  501.         case FIELD :
  502.         return p2type( np -> type );
  503.         case TYPE :
  504.         switch ( nloff( np ) ) {
  505.             case TNIL :
  506.             return ( PCCTM_PTR | PCCT_UNDEF );
  507.             case TSTR :
  508.             return ( PCCTM_ARY | PCCT_CHAR );
  509.             case TSET :
  510.             return PCCT_STRTY;
  511.             default :
  512.             return ( p2type( np -> type ) );
  513.         }
  514.         case REF:
  515.         case WITHPTR:
  516.         case PTR :
  517.         return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR );
  518.         case ARRAY :
  519.         return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY );
  520.         case FUNC :
  521.             /*
  522.              * functions are really pointers to functions
  523.              * which return their underlying type.
  524.              */
  525.         return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) ,
  526.                     PCCTM_FTN ) , PCCTM_PTR );
  527.         case PROC :
  528.             /*
  529.              * procedures are pointers to functions 
  530.              * which return integers (whether you look at them or not)
  531.              */
  532.         return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR );
  533.         case FFUNC :
  534.         case FPROC :
  535.             /*
  536.              *    formal procedures and functions are pointers
  537.              *    to structures which describe their environment.
  538.              */
  539.         return ( PCCTM_PTR | PCCT_STRTY );
  540.         default :
  541.         panic( "p2type" );
  542.         /* NOTREACHED */
  543.     }
  544.     }
  545.  
  546.     /*
  547.      *    put a typed operator to the pcstream
  548.      */
  549. putop( op , type )
  550.     int        op;
  551.     int        type;
  552.     {
  553.     extern char    *p2opname();
  554.     
  555.     if ( !CGENNING )
  556.         return;
  557.     p2word( PCCM_TRIPLE( op , 0 , type ) );
  558. #    ifdef DEBUG
  559.         if ( opt( 'k' ) ) {
  560.         fprintf( stdout , "%s (%d) |   0 | 0x%x\n"
  561.             , p2opname( op ) , op , type );
  562.         }
  563. #    endif
  564.     }
  565.  
  566.     /*
  567.      *    put out a structure operator (STASG, STARG, STCALL, UNARY STCALL )
  568.      *    which looks just like a regular operator, only the size and
  569.      *    alignment go in the next consecutive words
  570.      */
  571. putstrop( op , type , size , alignment )
  572.     int    op;
  573.     int    type;
  574.     int    size;
  575.     int    alignment;
  576.     {
  577.     extern char    *p2opname();
  578.     
  579.     if ( !CGENNING )
  580.         return;
  581.     p2word( PCCM_TRIPLE( op , 0 , type ) );
  582.     p2word( size );
  583.     p2word( alignment );
  584. #    ifdef DEBUG
  585.         if ( opt( 'k' ) ) {
  586.         fprintf( stdout , "%s (%d) |   0 | 0x%x    %d %d\n"
  587.             , p2opname( op ) , op , type , size , alignment );
  588.         }
  589. #    endif
  590.     }
  591.  
  592.     /*
  593.      *    the string names of p2ops
  594.      */
  595.  
  596. struct p2op {
  597.     int op;
  598.     char *name;
  599. };
  600.  
  601. static struct p2op    p2opnames[] = {
  602.     PCC_ERROR, "PCC_ERROR",
  603.     PCC_NAME, "PCC_NAME",
  604.     PCC_STRING, "PCC_STRING",
  605.     PCC_ICON, "PCC_ICON",
  606.     PCC_FCON, "PCC_FCON",
  607.     PCC_PLUS, "PCC_PLUS",
  608.     PCC_MINUS, "PCC_MINUS",
  609.     PCC_UMINUS, "PCC_UMINUS",
  610.     PCC_MUL, "PCC_MUL",
  611.     PCC_DEREF, "PCC_DEREF",
  612.     PCC_AND, "PCC_AND",
  613.     PCC_ADDROF, "PCC_ADDROF",
  614.     PCC_OR, "PCC_OR",
  615.     PCC_ER, "PCC_ER",
  616.     PCC_QUEST, "PCC_QUEST",
  617.     PCC_COLON, "PCC_COLON",
  618.     PCC_ANDAND, "PCC_ANDAND",
  619.     PCC_OROR, "PCC_OROR",
  620.     PCC_CM, "PCC_CM",
  621.     PCC_ASSIGN, "PCC_ASSIGN",
  622.     PCC_COMOP, "PCC_COMOP",
  623.     PCC_DIV, "PCC_DIV",
  624.     PCC_MOD, "PCC_MOD",
  625.     PCC_LS, "PCC_LS",
  626.     PCC_RS, "PCC_RS",
  627.     PCC_DOT, "PCC_DOT",
  628.     PCC_STREF, "PCC_STREF",
  629.     PCC_CALL, "PCC_CALL",
  630.     PCC_UCALL, "PCC_UCALL",
  631.     PCC_FORTCALL, "PCC_FORTCALL",
  632.     PCC_UFORTCALL, "PCC_UFORTCALL",
  633.     PCC_NOT, "PCC_NOT",
  634.     PCC_COMPL, "PCC_COMPL",
  635.     PCC_INCR, "PCC_INCR",
  636.     PCC_DECR, "PCC_DECR",
  637.     PCC_EQ, "PCC_EQ",
  638.     PCC_NE, "PCC_NE",
  639.     PCC_LE, "PCC_LE",
  640.     PCC_LT, "PCC_LT",
  641.     PCC_GE, "PCC_GE",
  642.     PCC_GT, "PCC_GT",
  643.     PCC_ULE, "PCC_ULE",
  644.     PCC_ULT, "PCC_ULT",
  645.     PCC_UGE, "PCC_UGE",
  646.     PCC_UGT, "PCC_UGT",
  647.     PCC_REG, "PCC_REG",
  648.     PCC_OREG, "PCC_OREG",
  649.     PCC_CCODES, "PCC_CCODES",
  650.     PCC_FREE, "PCC_FREE",
  651.     PCC_STASG, "PCC_STASG",
  652.     PCC_STARG, "PCC_STARG",
  653.     PCC_STCALL, "PCC_STCALL",
  654.     PCC_USTCALL, "PCC_USTCALL",
  655.     PCC_FLD, "PCC_FLD",
  656.     PCC_SCONV, "PCC_SCONV",
  657.     PCC_PCONV, "PCC_PCONV",
  658.     PCC_PMCONV, "PCC_PMCONV",
  659.     PCC_PVCONV, "PCC_PVCONV",
  660.     PCC_FORCE, "PCC_FORCE",
  661.     PCC_CBRANCH, "PCC_CBRANCH",
  662.     PCC_INIT, "PCC_INIT",
  663.     PCC_CAST, "PCC_CAST",
  664.     -1, ""
  665.     };
  666.  
  667. char *
  668. p2opname( op )
  669.     register int    op;
  670.     {
  671.     static char        *p2map[PCC_MAXOP+1];
  672.     static bool        mapready = FALSE;
  673.     register struct p2op    *pp;
  674.  
  675.     if ( mapready == FALSE ) {
  676.         for ( pp = p2opnames; pp->op >= 0; pp++ )
  677.         p2map[ pp->op ] = pp->name;
  678.         mapready = TRUE;
  679.     }
  680.     return ( p2map[ op ] ? p2map[ op ] : "unknown" );
  681.     }
  682.  
  683.     /*
  684.      *    low level routines
  685.      */
  686.  
  687.     /*
  688.      *    puts a long word on the pcstream
  689.      */
  690. p2word( word )
  691.     int        word;
  692.     {
  693.  
  694.     putw( word , pcstream );
  695.     }
  696.  
  697.     /*
  698.      *    put a length 0 mod 4 null padded string onto the pcstream
  699.      */
  700. p2string( string )
  701.     char    *string;
  702.     {
  703.     int    slen = strlen( string );
  704.     int    wlen = ( slen + 3 ) / 4;
  705.     int    plen = ( wlen * 4 ) - slen;
  706.     char    *cp;
  707.     int    p;
  708.  
  709.     for ( cp = string ; *cp ; cp++ )
  710.         putc( *cp , pcstream );
  711.     for ( p = 1 ; p <= plen ; p++ )
  712.         putc( '\0' , pcstream );
  713. #    ifdef DEBUG
  714.         if ( opt( 'k' ) ) {
  715.         fprintf( stdout , "\"%s" , string );
  716.         for ( p = 1 ; p <= plen ; p++ )
  717.             fprintf( stdout , "\\0" );
  718.         fprintf( stdout , "\"\n" );
  719.         }
  720. #    endif
  721.     }
  722.  
  723.     /*
  724.      *    puts a name on the pcstream
  725.      */
  726. p2name( name )
  727.     char    *name;
  728.     {
  729.     int    pad;
  730.  
  731.     fprintf( pcstream , NAMEFORMAT , name );
  732.     pad = strlen( name ) % sizeof (long);
  733.     for ( ; pad < sizeof (long) ; pad++ ) {
  734.         putc( '\0' , pcstream );
  735.     }
  736. #    ifdef DEBUG
  737.         if ( opt( 'k' ) ) {
  738.         fprintf( stdout , NAMEFORMAT , name );
  739.         pad = strlen( name ) % sizeof (long);
  740.         for ( ; pad < sizeof (long) ; pad++ ) {
  741.             fprintf( stdout , "\\0" );
  742.         }
  743.         fprintf( stdout , "\n" );
  744.         }
  745. #    endif
  746.     }
  747.     
  748.     /*
  749.      *    put out a jump to a label
  750.      */
  751. putjbr( label )
  752.     long    label;
  753.     {
  754.  
  755.     printjbr( LABELPREFIX , label );
  756.     }
  757.  
  758.     /*
  759.      *    put out a jump to any kind of label
  760.      */
  761. printjbr( prefix , label )
  762.     char    *prefix;
  763.     long    label;
  764.     {
  765.  
  766. #    if defined(vax) || defined(tahoe)
  767.         putprintf( "    jbr    " , 1 );
  768.         putprintf( PREFIXFORMAT , 0 , prefix , label );
  769. #    endif vax || tahoe
  770. #    ifdef mc68000
  771.         putprintf( "    jra    " , 1 );
  772.         putprintf( PREFIXFORMAT , 0 , prefix , label );
  773. #    endif mc68000
  774.     }
  775.  
  776.     /*
  777.      *    another version of put to catch calls to put
  778.      */
  779. /* VARARGS */
  780. put()
  781.     {
  782.  
  783.     panic("put()");
  784.     }
  785.  
  786. #endif PC
  787.