home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / nasm20b / nasm_src / labels.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  12KB  |  439 lines

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1991 by Natürlich!                     */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. /*    In the faint hope that it will help searching speed, labels will    */
  7. /*      be alphabetisized (also I do have already code for that...)       */
  8. /* ---------------------------------------------------------------------- */
  9. #include <stdio.h>
  10. #include "defines.h"
  11. #include "nasm.h"
  12. #include "debug.h"
  13. #include "labels.h"
  14. #define  KEINE_CODE_INNEREIEN
  15. #include "code.h"
  16. #include "fix.h"
  17. #include "exprfast.h"
  18. #include "op.h"
  19.  
  20. #if ! DORECLAIM
  21. # define  expr_tryfree( x)
  22. #endif
  23.  
  24. extern label huge *h_local[SEP],  huge *t_local[SEP],  huge *l_local,
  25.              huge *h_global[SEP], huge *t_global[SEP], huge *l_global,
  26.              huge *h_macro[SEP],  huge *t_macro[SEP],  huge *l_macro;
  27. extern int        u_local, u_global, u_macro;
  28. extern lword      l_hash;
  29.  
  30. extern char    err_defined[], warn_0fwd[], warn_equfwd[], buf[];
  31. extern int     _in_macro, runnable;
  32. int            _in_instr;
  33. extern char    *str_alloc();
  34.  
  35. /* ---------------------------------------------------------- */
  36. /*             This routine is called when a label            */
  37. /* that is PC-relative is encountered:                        */
  38. /*       foo:  lda #56                                        */
  39. /*       bar   *= $600                                        */
  40. /* not:  foo   = 46                                           */
  41. /* not:        lda foo                                        */
  42. /* ---------------------------------------------------------- */
  43. void  enter_pclabel( s)
  44. register char  *s;
  45. {
  46.    register label huge  *p;
  47.    int                  is_local = (*s == '?' || *s == ':');
  48.  
  49.    ENTER("enterlabel");
  50. #if DEBUG
  51.    fprintf( ESTREAM, "\t\tWith %s as name @$%4.4X\n", s, __pc);
  52. #endif
  53.    u_local = u_global = -1;   /* if we find a macro label this remains -1 */
  54.    if( ! (p = find_label( s)))
  55.    {
  56.       if( is_local)
  57.          p = llab_alloc();
  58.       else
  59.          p = lab_alloc();
  60.       p->name = s;
  61.       p->hash = l_hash;
  62.       p->type = __pc < 0x100 ? (L_ZERO | L_PC) : L_PC;
  63.       p->val  = __pc;
  64.       p->refs = 0;
  65.  
  66.       if( is_local)
  67.       {
  68.          MESS("linking into local");
  69.          einlinker( h_local, t_local, l_local, u_local, p);
  70.       }
  71.       else
  72.          if( _in_macro)
  73.          {
  74.             MESS("linking into macro");
  75.             einlinker( h_macro, t_macro, l_macro, u_macro, p);
  76.          }
  77.          else
  78.          {
  79.             MESS("linking into global");
  80.             einlinker( h_global, t_global, l_global, u_global, p);
  81.          }
  82.    }
  83.    else
  84.    {
  85.       IMESS("p->refs =  $%8.8X", (lword) p->refs, 4);
  86.       if( p->refs)
  87.       {
  88.          if( __pc < 0x100)
  89.             nswarning( warn_0fwd, p->name);
  90.          p->val   = __pc;
  91.          p->type |= L_PC;
  92.          if( ! _in_macro && u_local < 0 && u_global < 0) /* was assumed   */
  93.          {                                               /* macro, but is */
  94.             auslinker( h_macro, t_macro, l_macro, u_macro, p);  /* global */
  95.             (void) find_label( s);
  96.             if( is_local)
  97.             {
  98.                MESS("linking into local");
  99.                einlinker( h_local, t_local, l_local, u_local, p);
  100.             }
  101.             else
  102.             {
  103.                MESS("linking into global");
  104.                einlinker( h_global, t_global, l_global, u_global, p);
  105.             }
  106.          }           
  107.          if( p->type & L_EQU)
  108.             nswarning( warn_equfwd, p->name);
  109.          entrefer( p);
  110.       }
  111.       else
  112.          if( _in_macro)
  113.          {
  114.             p->val   = __pc;
  115.             p->type |= L_PC;
  116.          }
  117.          else
  118.             nserror( err_defined, s);
  119.    }
  120.    LEAVE();
  121. }
  122.  
  123. /* ---------------------------------------------------------- */
  124. /*         This routine is called when a equ label            */
  125. /*         or .= label is encountered:                        */
  126. /* e.g.:                                                      */
  127. /*       bar  .= $600                                         */
  128. /*       foo   = 462                                          */
  129. /*       bar  == 67                                           */
  130. /* not:        lda foo                                        */
  131. /* not:  foo:  lda #56                                        */
  132. /* not:  foo   *=$600                                         */
  133. /* ---------------------------------------------------------- */
  134. static expr  edummy =
  135. {
  136.    0,
  137.    0, 0, 0,
  138.    0, FIX_NOTHING,
  139.    0,
  140.    0,
  141.    0
  142. };
  143.  
  144. label *enter_elabel( s, ex, type)
  145. char                 *s;
  146. register expr huge   *ex;
  147. register int         type;
  148. {
  149.    register label huge  *p;
  150.    int                  is_local = (*s == '?' || *s == ':');
  151.  
  152.    ENTER("enterlabel/expression");
  153. #if DEBUG
  154.    fprintf( ESTREAM, "Name=%s type=$%4.4X + some s_expr @$%lX\n", s, type, ex);
  155. #endif
  156.    if( ! (p = find_label( s)))        /* if not found or at end of table */
  157.    {
  158.       if( is_local)
  159.          p = llab_alloc();
  160.       else
  161.          p = lab_alloc();
  162.       p->refs = 0;
  163.       p->name = s;
  164.       p->hash = l_hash;
  165.       if( unvalued( ex))         /* top is not value */
  166.       {
  167. jump1984:
  168.          if( type == L_ZERO && e_pcrel( ex))
  169.             nerror("You can't assign a fwd ref to a zeropage label");
  170. #if LOCALDEBUG
  171.          fprintf( ESTREAM, "label %s is yet undefined\n", s);
  172. #endif
  173.          p->type = type | (e_pcrel( ex) ? L_PC : 0);
  174.          fix_lup( ex, p);
  175.          (void) refer( p, &edummy);    /* casting for prettyness */
  176.       }
  177.       else
  178.       {
  179.          p->val = ex->val;
  180.          if( type)
  181.          {
  182.             if( type & L_ZERO && p->val >= 0x100)
  183.                nswarning( "zeropage label >= $100", s);
  184.          }
  185.          else
  186.             if( p->val < 0x100 || ex->op & O_ZEROP)
  187.                type |= L_ZERO;
  188.          if( e_pcrel( ex))
  189.             type |= L_PC;
  190.          if( (type & (L_PC | L_ZERO)) == (L_PC | L_ZERO))
  191.             nserror("Conflict between PC relativism and zeropageism", s);
  192.          p->type = type;
  193.          expr_tryfree( ex);
  194.       }
  195.       if( is_local)
  196.       {
  197.          MESS("linking into local");
  198.          einlinker( h_local, t_local, l_local, u_local, p);
  199.       }
  200.       else
  201.          if( _in_macro)
  202.          {
  203.             MESS("linking into macro");
  204.             einlinker( h_macro, t_macro, l_macro, u_macro, p);
  205.          }
  206.          else
  207.          {
  208.             MESS("linking into global");
  209.             einlinker( h_global, t_global, l_global, u_global, p);
  210.          }
  211.       LEAVE();
  212.       return( p);
  213.    }
  214.    else
  215.       if( type & L_EQU)
  216.       {
  217.          if( ! (p->type & L_EQU))
  218.             nswarning( ".= assignment for a normal label", s);
  219.          if( valued( ex))
  220.          {
  221.             p->val = ex->val;
  222.             if( e_pcrel( ex))
  223.                p->type |= L_PC;
  224.             if( p->refs)
  225.             {
  226.                if( p->type & L_EQU)
  227.                   nswarning( warn_equfwd, p->name);
  228.                entrefer( p);
  229.             }
  230.             expr_tryfree( ex);
  231.             p->type |= L_EQU;
  232.          }
  233.          else
  234.             if( p->refs)
  235.             {
  236.                ex->fix = FIX_NOTHING;
  237.                nserror( "Label still has open references", p->name);
  238.             }
  239.             else
  240.                goto jump1984;
  241.       }
  242.       else
  243.          if( p->refs)
  244.             if( valued( ex))   
  245.             {
  246.                if( ex->val < 0x100)
  247.                   nswarning( warn_0fwd, s);
  248.                p->val  = ex->val;
  249.                if( (e_pcrel( ex) ? L_PC : 0) ^ (p->type & L_PC))
  250.                   nserror("Label was assumed to be pc relative", s); 
  251.                if( p->type & L_EQU)
  252.                   nswarning( warn_equfwd, s);
  253.                entrefer( p);
  254.                expr_tryfree( ex);
  255.             }
  256.             else
  257.                goto jump1984;
  258.          else
  259.             nserror( err_defined, s);
  260.    LEAVE();
  261.    return( p);
  262. }
  263.  
  264. void def_label( name, val)       /* Pyromania */
  265. char     *name;
  266. word    val;
  267. {
  268. #if ! VERSION
  269.    name = strcpy( str_alloc( strlen( name) + 1), name);
  270. #endif
  271.    (void) enter_elabel( name, ival_pl( val), L_SPECIAL);
  272. }
  273.  
  274. is_ref(s)
  275. char  *s;
  276. {
  277.    label huge  *q;
  278.  
  279.    if( ! (q = find_label( s)))
  280.       return( 0);
  281.    return( q->type & L_REF);
  282. }
  283.  
  284.  
  285. is_def(s)
  286. char  *s;
  287. {
  288.    label huge  *q;
  289.    return( (q = find_label( s)) && ! q->refs);
  290. }
  291.  
  292. void openrefs( table, message)
  293. label huge  **table;
  294. char        *message;
  295. {
  296.    register int         i, j, f = 0;
  297.    register label huge  *p;
  298.  
  299.    ENTER("openrefs");
  300.    for( i = 0; i != SEP; i++)
  301.    {
  302.       p = table[ i];
  303.       while( p)
  304.       {
  305.          if( p->refs)
  306.          {
  307.             if( ! f)
  308.             {
  309.                f = 1;
  310.                j = 0;
  311.                sprintf( buf, "Some %s labels remain undefined", message);
  312.                nerror( buf);
  313.                putc( '\t', ESTREAM);
  314.             }
  315.             if( j++ == 4)
  316.             {
  317.                j = 0;
  318.                putc( '\n', ESTREAM);
  319.                putc( '\t', ESTREAM);
  320.             }
  321.             fputs( p->name, ESTREAM);
  322.             putc( '\t', ESTREAM);
  323.          }
  324.          p = p->next;
  325.       }
  326.    }
  327.    if( f)
  328.       putc( '\n', ESTREAM);
  329.    LEAVE();
  330. }
  331.  
  332.  
  333. void err_undefs()
  334. {
  335.    register int         i, j, k,
  336.                         f = 0;
  337.    register label huge  *p;
  338.    
  339.    ENTER("err_undefs");
  340.    if( runnable)
  341.    {
  342.       openrefs( h_global, "global");
  343.       openrefs( h_macro,  "macro");
  344.    }               
  345.    else
  346.       for( k = 0; k != 2; k++)
  347.          for( i = 0; i != SEP;)
  348.             if( p =  k ? h_macro[ i++] : h_global[i++])
  349.                do
  350.                   if( ! (! p->refs || q_pcrel( p) || 
  351.                          (p->type & (L_SPECIAL | L_LINKZERO)) ))
  352.                   {
  353.                      if( ! f)
  354.                      {
  355.                         f = 1;
  356.                         j = 0;
  357.                         nerror( "Some global non PC-relative labels remain undefined");
  358.                         putc( '\t', ESTREAM);
  359.                      }
  360.                      if( j++ == 4)
  361.                      {
  362.                         j = 0;
  363.                         putc( '\n', ESTREAM);
  364.                         putc( '\t', ESTREAM);
  365.                      }
  366.                      fputs( p->name, ESTREAM);
  367.                      putc( '\t', ESTREAM);
  368.                   }
  369.                while( p = p->next);
  370.    if( f)
  371.       putc( '\n', ESTREAM);
  372.    LEAVE();
  373. }
  374.  
  375.  
  376. void do_local()
  377. {
  378.    register int   i;
  379.  
  380.    ENTER("do_local");
  381. #if LOCALDEBUG
  382.    show_all();
  383. #endif
  384.    openrefs( h_local, "local");
  385.    llab_free();
  386.    for( i = 0; i != SEP; i++)
  387.       h_local[ i] =  t_local[ i] = 0;
  388.    LEAVE();
  389. }
  390.  
  391.  
  392. #if LOCALDEBUG || DEBUG
  393. #define oref   p->refs ? '*' : ' '
  394. static char format[] =
  395.    "%c\"%8.8s\" type=$%2.2X value=$%4.4X hash=$%8.8lX\n";
  396.  
  397. void show_all()
  398. {
  399.    label huge  *p;
  400.    int         i;
  401.  
  402.    fprintf( ESTREAM, "Dumping global table:\n");
  403.    for( i = 0; i != SEP; i++)
  404.       if( p = h_global[ i])
  405.       {
  406.          do
  407.             fprintf( ESTREAM, format, oref, p->name,
  408.                               p->type, p->val, p->hash);
  409.          while( p = p->next);
  410.          putc( '\n', ESTREAM);
  411.       }
  412.  
  413.    fprintf( ESTREAM, "\n\nDumping local table:\n");
  414.    for( i = 0; i != SEP; i++)
  415.       if( p = h_local[ i] )
  416.       {
  417.          do
  418.             fprintf( ESTREAM, format, oref, p->name,
  419.                               p->type, p->val, p->hash);
  420.          while( p = p->next);
  421.          putc( '\n', ESTREAM);
  422.       }
  423.  
  424.    fprintf( ESTREAM, "\n\nDumping macro label table:\n");
  425.    for( i = 0; i != SEP; i++)
  426.       if( p = h_macro[ i])
  427.       {
  428.          do
  429.             fprintf( ESTREAM, format, oref, p->name,
  430.                               p->type, p->val, p->hash);
  431.          while( p = p->next);
  432.          putc( '\n', ESTREAM);
  433.       }
  434. }
  435. #endif
  436.  
  437.  
  438.  
  439.