home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / pcc / code.c next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  6.9 KB  |  342 lines

  1. # include <stdio.h>
  2. # include <signal.h>
  3.  
  4. # include "mfile1"
  5.  
  6. int proflag;
  7. int strftn = 0;    /* is the current function one which returns a value */
  8. FILE *tmpfile;
  9. FILE *outfile = stdout;
  10.  
  11. branch( n ){
  12.     /* output a branch to label n */
  13.     /* exception is an ordinary function branching to retlab: then, return */
  14.     if( n == retlab && !strftn ){
  15.         printf( "    jmp    cret\n" );
  16.         }
  17.     else printf( "    jbr    L%d\n", n );
  18.     }
  19.  
  20. int lastloc = PROG;
  21.  
  22. defalign(n) {
  23.     /* cause the alignment to become a multiple of n */
  24.     n /= SZCHAR;
  25.     if( lastloc != PROG && n > 1 ) printf( "    .even\n" );
  26.     }
  27.  
  28. locctr( l ){
  29.     register temp;
  30.     /* l is PROG, ADATA, DATA, STRNG, ISTRNG, or STAB */
  31.  
  32.     if( l == lastloc ) return(l);
  33.     temp = lastloc;
  34.     lastloc = l;
  35.     switch( l ){
  36.  
  37.     case PROG:
  38.         outfile = stdout;
  39.         printf( "    .text\n" );
  40.         break;
  41.  
  42.     case DATA:
  43.     case ADATA:
  44.         outfile = stdout;
  45.         if( temp != DATA && temp != ADATA )
  46.             printf( "    .data\n" );
  47.         break;
  48.  
  49.     case STRNG:
  50.     case ISTRNG:
  51.         outfile = tmpfile;
  52.         break;
  53.  
  54.     case STAB:
  55.         cerror( "locctr: STAB unused" );
  56.         break;
  57.  
  58.     default:
  59.         cerror( "illegal location counter" );
  60.         }
  61.  
  62.     return( temp );
  63.     }
  64.  
  65. deflab( n ){
  66.     /* output something to define the current position as label n */
  67.     fprintf( outfile, "L%d:\n", n );
  68.     }
  69.  
  70. int crslab = 10;
  71.  
  72. getlab(){
  73.     /* return a number usable for a label */
  74.     return( ++crslab );
  75.     }
  76.  
  77. efcode(){
  78.     /* code for the end of a function */
  79.  
  80.     if( strftn ){  /* copy output (in r0) to caller */
  81.         register struct symtab *p;
  82.         register int stlab;
  83.         register int count;
  84.         int size;
  85.  
  86.         p = &stab[curftn];
  87.  
  88.         deflab( retlab );
  89.  
  90.         stlab = getlab();
  91.         printf( "    mov    $L%d,r1\n", stlab );
  92.         size = tsize( DECREF(p->stype), p->dimoff, p->sizoff ) / SZCHAR;
  93.         count = size/2;
  94.         while( count-- ) {
  95.             printf( "    mov    (r0)+,(r1)+\n" );
  96.             }
  97.         printf( "    mov    $L%d,r0\n", stlab );
  98.         printf( "    .bss\nL%d:    .=.+%d.\n    .text\n", stlab, size );
  99.         /* turn off strftn flag, so return sequence will be generated */
  100.         strftn = 0;
  101.         }
  102.     branch( retlab );
  103.     p2bend();
  104.     }
  105.  
  106. bfcode( a, n ) int a[]; {
  107.     /* code for the beginning of a function; a is an array of
  108.         indices in stab for the arguments; n is the number */
  109.     register i;
  110.     register temp;
  111.     register struct symtab *p;
  112.     int off;
  113.  
  114.     locctr( PROG );
  115.     p = &stab[curftn];
  116.     defnam( p );
  117.     temp = p->stype;
  118.     temp = DECREF(temp);
  119.     strftn = (temp==STRTY) || (temp==UNIONTY);
  120.  
  121.     retlab = getlab();
  122.     if( proflag ){
  123.         int plab;
  124.         plab = getlab();
  125.         printf( "    mov    $L%d,r0\n", plab );
  126.         printf( "    jsr    pc,mcount\n" );
  127.         printf( "    .bss\nL%d:    .=.+2\n    .text\n", plab );
  128.         }
  129.  
  130.     /* routine prolog */
  131.  
  132.     printf( "    jsr    r5,csv\n" );
  133.     /* adjust stack for autos */
  134.     printf( "    sub    $.F%d,sp\n", ftnno );
  135.  
  136.     off = ARGINIT;
  137.  
  138.     for( i=0; i<n; ++i ){
  139.         p = &stab[a[i]];
  140.         if( p->sclass == REGISTER ){
  141.             temp = p->offset;  /* save register number */
  142.             p->sclass = PARAM;  /* forget that it is a register */
  143.             p->offset = NOOFFSET;
  144.             oalloc( p, &off );
  145.             printf( "    mov    %d.(r5),r%d\n", p->offset/SZCHAR, temp );
  146.             p->offset = temp;  /* remember register number */
  147.             p->sclass = REGISTER;   /* remember that it is a register */
  148.             }
  149.         else {
  150.             if( oalloc( p, &off ) ) cerror( "bad argument" );
  151.             }
  152.  
  153.         }
  154.     }
  155.  
  156. bccode(){ /* called just before the first executable statment */
  157.         /* by now, the automatics and register variables are allocated */
  158.     SETOFF( autooff, SZINT );
  159.     /* set aside store area offset */
  160.     p2bbeg( autooff, regvar );
  161.     }
  162.  
  163. ejobcode( flag ){
  164.     /* called just before final exit */
  165.     /* flag is 1 if errors, 0 if none */
  166.     }
  167.  
  168. aobeg(){
  169.     /* called before removing automatics from stab */
  170.     }
  171.  
  172. aocode(p) struct symtab *p; {
  173.     /* called when automatic p removed from stab */
  174.     }
  175.  
  176. aoend(){
  177.     /* called after removing all automatics from stab */
  178.     }
  179.  
  180. defnam( p ) register struct symtab *p; {
  181.     /* define the current location as the name p->sname */
  182.  
  183.     if( p->sclass == EXTDEF ){
  184.         printf( "    .globl    %s\n", exname( p->sname ) );
  185.         }
  186.     if( p->sclass == STATIC && p->slevel>1 ) deflab( p->offset );
  187.     else printf( "%s:\n", exname( p->sname ) );
  188.  
  189.     }
  190.  
  191. bycode( t, i ){
  192.     /* put byte i+1 in a string */
  193.  
  194.     i &= 07;
  195.     if( t < 0 ){ /* end of the string */
  196.         if( i != 0 ) fprintf( outfile, "\n" );
  197.         }
  198.  
  199.     else { /* stash byte t into string */
  200.         if( i == 0 ) fprintf( outfile, "    .byte    " );
  201.         else fprintf( outfile, "," );
  202.         fprintf( outfile, "%o", t );
  203.         if( i == 07 ) fprintf( outfile, "\n" );
  204.         }
  205.     }
  206.  
  207. zecode( n ){
  208.     /* n integer words of zeros */
  209.     OFFSZ temp;
  210.     register i;
  211.  
  212.     if( n <= 0 ) return;
  213.     printf( "    " );
  214.     for( i=1; i<n; i++ ) {
  215.         if( i%8 == 0 )
  216.             printf( "\n    " );
  217.         printf( "0; " );
  218.         }
  219.     printf( "0\n" );
  220.     temp = n;
  221.     inoff += temp*SZINT;
  222.     }
  223.  
  224. fldal( t ) unsigned t; { /* return the alignment of field of type t */
  225.     uerror( "illegal field type" );
  226.     return( ALINT );
  227.     }
  228.  
  229. fldty( p ) struct symtab *p; { /* fix up type of field p */
  230.     ;
  231.     }
  232.  
  233. where(c){ /* print location of error  */
  234.     /* c is either 'u', 'c', or 'w' */
  235.     fprintf( stderr, "%s, line %d: ", ftitle, lineno );
  236.     }
  237.  
  238. char *tmpname = "/tmp/pcXXXXXX";
  239.  
  240. main( argc, argv ) char *argv[]; {
  241.     int dexit();
  242.     register int c;
  243.     register int i;
  244.     int r;
  245.  
  246.     for( i=1; i<argc; ++i )
  247.         if( argv[i][0] == '-' && argv[i][1] == 'X' && argv[i][2] == 'p' ) {
  248.             proflag = 1;
  249.             }
  250.  
  251.     mktemp(tmpname);
  252.     if(signal( SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, dexit);
  253.     if(signal( SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, dexit);
  254.     if(signal( SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, dexit);
  255.     tmpfile = fopen( tmpname, "w" );
  256.  
  257.     r = mainp1( argc, argv );
  258.  
  259.     tmpfile = freopen( tmpname, "r", tmpfile );
  260.     if( tmpfile != NULL )
  261.         while((c=getc(tmpfile)) != EOF )
  262.             putchar(c);
  263.     else cerror( "Lost temp file" );
  264.     unlink(tmpname);
  265.     return( r );
  266.     }
  267.  
  268. dexit( v ) {
  269.     unlink(tmpname);
  270.     exit(1);
  271.     }
  272.  
  273. genswitch(p,n) register struct sw *p;{
  274.     /*    p points to an array of structures, each consisting
  275.         of a constant value and a label.
  276.         The first is >=0 if there is a default label;
  277.         its value is the label number
  278.         The entries p[1] to p[n] are the nontrivial cases
  279.         */
  280.     register i;
  281.     register CONSZ j, range;
  282.     register dlab, swlab;
  283.  
  284.     range = p[n].sval-p[1].sval;
  285.  
  286.     if( range>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */
  287.  
  288.         dlab = p->slab >= 0 ? p->slab : getlab();
  289.  
  290.         if( p[1].sval ){
  291.             printf( "    sub    $" );
  292.             printf( CONFMT, p[1].sval );
  293.             printf( ".,r0\n" );
  294.             }
  295.  
  296.         /* note that this is a cl; it thus checks
  297.            for numbers below range as well as out of range.
  298.            */
  299.         printf( "    cmp    r0,$%ld.\n", range );
  300.         printf( "    jhi    L%d\n", dlab );
  301.  
  302.         printf( "    asl    r0\n" );
  303.         printf( "    jmp    *L%d(r0)\n", swlab = getlab() );
  304.  
  305.         /* output table */
  306.  
  307.         locctr( ADATA );
  308.         defalign( ALPOINT );
  309.         deflab( swlab );
  310.  
  311.         for( i=1,j=p[1].sval; i<=n; ++j ){
  312.  
  313.             printf( "    L%d\n", ( j == p[i].sval ) ?
  314.                 p[i++].slab : dlab );
  315.             }
  316.  
  317.         locctr( PROG );
  318.  
  319.         if( p->slab< 0 ) deflab( dlab );
  320.         return;
  321.  
  322.         }
  323.  
  324.     /* debugging code */
  325.  
  326.     /* out for the moment
  327.     if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
  328.     */
  329.  
  330.     /* simple switch code */
  331.  
  332.     for( i=1; i<=n; ++i ){
  333.         /* already in r0 */
  334.  
  335.         printf( "    cmp    r0,$" );
  336.         printf( CONFMT, p[i].sval );
  337.         printf( ".\n    jeq    L%d\n", p[i].slab );
  338.         }
  339.  
  340.     if( p->slab>=0 ) branch( p->slab );
  341.     }
  342.