This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: GASP really obsolete?


Hi Frank,

> > Can you use local labels ?  ie how about this:
> 
> Unfortunately, not.
> What about nesting of IFNZ/ELSE/ENDIF?

Ah, OK.

In that case please could you try out the following patch.  It adds a
new feature to gas: "macro local labels".  These are local labels that
are designed to work inside .macro constructs and which can be nested.
(via a set of new pseudo ops).  Here is an example that uses them:

	.macro IFNZ val1, val2
	  .start_macro_labels
	  .push_macro_labels
          cmpl \val1, \val2
          jnz 1f
	  .stop_macro_labels
        .endm

        .macro ELSE
	  .start_macro_labels
          jmp 2f
	  1:	
	  .stop_macro_labels
        .endm

        .macro ENDIF
	  .start_macro_labels
          1:	
          2:
	  .pop_macro_labels
	  .stop_macro_labels
        .endm

I think that this solution should be more efficient that the one that
Ian was suggesting, since it does not affect normal symbol parsing.
If it works, please let me know and I will check it into the binutils
sources.

Cheers
        Nick

2002-06-13  Nick Clifton  <nickc@cambridge.redhat.com>

	* NEWS: Mention new macro local labels.
        * read.c (potable): Add pop_macro_labels, push_macro_labels,
        start_macro_labels, stop_macro_labels.
	* symbols.c (MACRO_LABEL_CHAR): Define.
        (MACRO_LABEL_MAX_VAL): Define.
        (in_macro_labels): New variable.  True if macro labels are
        active.
        (macro_label_nesting_level): New variable.  Record level of
        macro label nesting.
        (append_number): New function: Append a number to a string.
        (dollar_label_name): Use append_number;
        (macro_labels, macro_label_instances, macro_label_count,
        macro_label_max): New sparse array for macro labels.
        (macro_label_instance_inc): New function: Increment the
        instance of a macro label.
        (macro_label_instance): New function: Return the instance
        number for a macro label.
        (fb_label_instance_inc): Use macro_label_instance_inc.
        (fb_label_instance): Use macro_label_instance.
        (fb_label_name): Construct macro local labels as well.
        (decode_local_label_name): Decode macro local labels as well.
        (start_macro_labels): New function: Enable macro labels.
        (stop_macro_labels): New function: Disable macro labels.
        (push_macro_labels): New function: Increment nesting level of
        macro local labels.
        (pop_macro_labels): New function: Decrement nesting level of
        macro local labels.
        * symbols.h: Provide prototypes for start_macro_labels,
        stop_macro_labels, push_macro_labels and pop_macro_labels.
        * doc/as.texinfo: Document macro labels and the new pseudo
        ops.

Index: NEWS
===================================================================
RCS file: /cvs/src/src/gas/NEWS,v
retrieving revision 1.28
diff -c -3 -p -w -r1.28 NEWS
*** NEWS	28 May 2002 14:20:42 -0000	1.28
--- NEWS	13 Jun 2002 14:54:20 -0000
***************
*** 1,4 ****
--- 1,7 ----
  -*- text -*-
+ New pseudo macros added: .start_macro_labels .stop_macro_labels .push_macro_labels
+   .pop_macro_labels
+   
  Support for DLX processor added.
  
  GASP has now been deprecated and will be removed in a future release.  Use the

Index: read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.51
diff -c -3 -p -w -r1.51 read.c
*** read.c	3 May 2002 02:25:33 -0000	1.51
--- read.c	13 Jun 2002 14:54:21 -0000
*************** static const pseudo_typeS potable[] = {
*** 378,386 ****
--- 378,388 ----
    {"p2alignl", s_align_ptwo, -4},
    {"page", listing_eject, 0},
    {"plen", listing_psize, 0},
+   {"pop_macro_labels", pop_macro_labels, 0},
    {"print", s_print, 0},
    {"psize", listing_psize, 0},	/* Set paper size.  */
    {"purgem", s_purgem, 0},
+   {"push_macro_labels", push_macro_labels, 0},
    {"quad", cons, 8},
    {"rep", s_rept, 0},
    {"rept", s_rept, 0},
*************** static const pseudo_typeS potable[] = {
*** 399,404 ****
--- 401,408 ----
    {"stabd", s_stab, 'd'},
    {"stabn", s_stab, 'n'},
    {"stabs", s_stab, 's'},
+   {"start_macro_labels", start_macro_labels, 0},
+   {"stop_macro_labels", stop_macro_labels, 0},
    {"string", stringer, 1},
    {"struct", s_struct, 0},
  /* tag  */

Index: symbols.c
===================================================================
RCS file: /cvs/src/src/gas/symbols.c,v
retrieving revision 1.36
diff -c -3 -p -w -r1.36 symbols.c
*** symbols.c	12 Jun 2002 16:39:29 -0000	1.36
--- symbols.c	13 Jun 2002 14:54:22 -0000
*************** symbolS abs_symbol;
*** 57,65 ****
  
  #define DOLLAR_LABEL_CHAR	'\001'
  #define LOCAL_LABEL_CHAR	'\002'
! 
  struct obstack notes;
  
  static char *save_symbol_name PARAMS ((const char *));
  static void fb_label_init PARAMS ((void));
  static long dollar_label_instance PARAMS ((long));
--- 57,73 ----
  
  #define DOLLAR_LABEL_CHAR	'\001'
  #define LOCAL_LABEL_CHAR	'\002'
! #define MACRO_LABEL_CHAR	'\003'
! #define MACRO_LABEL_MAX_VAL	0xe0000
  struct obstack notes;
  
+ static int           in_macro_labels = 0;
+ static unsigned int  macro_label_nesting_level = 0;
+ 
+ static char * append_number PARAMS ((long, char *));
+ static void macro_label_instance_inc PARAMS ((long));
+ static long macro_label_instance PARAMS ((long));
+ 
  static char *save_symbol_name PARAMS ((const char *));
  static void fb_label_init PARAMS ((void));
  static long dollar_label_instance PARAMS ((long));
*************** colon (sym_name)		/* Just seen "x:" - ra
*** 380,386 ****
  #ifdef N_UNDF
  	      know (N_UNDF == 0);
  #endif /* if we have one, it better be zero.  */
- 
  	    }
  	  else
  	    {
--- 388,393 ----
*************** colon (sym_name)		/* Just seen "x:" - ra
*** 412,421 ****
  			 this symbol.  */
  		      if (S_GET_VALUE (symbolP)
  			  < ((unsigned) frag_now_fix ()))
- 			{
  			  S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
  			}
- 		    }
  		  else
  		    {
  		      /* It is a .comm/.lcomm being converted to initialized
--- 419,426 ----
*************** colon (sym_name)		/* Just seen "x:" - ra
*** 449,455 ****
  			    od_buf,
  			    (long) S_GET_VALUE (symbolP));
  		}
! 	    }			/* if the undefined symbol has no value  */
  	}
        else
  	{
--- 454,460 ----
  			    od_buf,
  			    (long) S_GET_VALUE (symbolP));
  		}
! 	    }
  	}
        else
  	{
*************** symbol_find_or_make (name)
*** 562,570 ****
        symbolP = symbol_make (name);
  
        symbol_table_insert (symbolP);
!     }				/* if symbol wasn't found */
  
!   return (symbolP);
  }
  
  symbolS *
--- 567,575 ----
        symbolP = symbol_make (name);
  
        symbol_table_insert (symbolP);
!     }
  
!   return symbolP;
  }
  
  symbolS *
*************** symbol_make (name)
*** 579,585 ****
    if (!symbolP)
      symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
  
!   return (symbolP);
  }
  
  /* Implement symbol table lookup.
--- 584,590 ----
    if (!symbolP)
      symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
  
!   return symbolP;
  }
  
  /* Implement symbol table lookup.
*************** symbol_append (addme, target, rootPP, la
*** 684,709 ****
        *rootPP = addme;
        *lastPP = addme;
        return;
!     }				/* if the list is empty  */
  
    if (target->sy_next != NULL)
      {
  #ifdef SYMBOLS_NEED_BACKPOINTERS
        target->sy_next->sy_previous = addme;
! #endif /* SYMBOLS_NEED_BACKPOINTERS */
      }
    else
      {
        know (*lastPP == target);
        *lastPP = addme;
!     }				/* if we have a next  */
  
    addme->sy_next = target->sy_next;
    target->sy_next = addme;
  
  #ifdef SYMBOLS_NEED_BACKPOINTERS
    addme->sy_previous = target;
! #endif /* SYMBOLS_NEED_BACKPOINTERS */
  
    debug_verify_symchain (symbol_rootP, symbol_lastP);
  }
--- 689,714 ----
        *rootPP = addme;
        *lastPP = addme;
        return;
!     }
  
    if (target->sy_next != NULL)
      {
  #ifdef SYMBOLS_NEED_BACKPOINTERS
        target->sy_next->sy_previous = addme;
! #endif
      }
    else
      {
        know (*lastPP == target);
        *lastPP = addme;
!     }
  
    addme->sy_next = target->sy_next;
    target->sy_next = addme;
  
  #ifdef SYMBOLS_NEED_BACKPOINTERS
    addme->sy_previous = target;
! #endif
  
    debug_verify_symchain (symbol_rootP, symbol_lastP);
  }
*************** symbol_remove (symbolP, rootPP, lastPP)
*** 735,758 ****
      abort ();
  
    if (symbolP == *rootPP)
-     {
        *rootPP = symbolP->sy_next;
-     }				/* if it was the root  */
  
    if (symbolP == *lastPP)
-     {
        *lastPP = symbolP->sy_previous;
-     }				/* if it was the tail  */
  
    if (symbolP->sy_next != NULL)
-     {
        symbolP->sy_next->sy_previous = symbolP->sy_previous;
-     }				/* if not last  */
  
    if (symbolP->sy_previous != NULL)
-     {
        symbolP->sy_previous->sy_next = symbolP->sy_next;
-     }				/* if not first  */
  
    debug_verify_symchain (*rootPP, *lastPP);
  }
--- 740,755 ----
*************** symbol_insert (addme, target, rootPP, la
*** 768,785 ****
  {
    if (LOCAL_SYMBOL_CHECK (addme))
      abort ();
    if (LOCAL_SYMBOL_CHECK (target))
      abort ();
  
    if (target->sy_previous != NULL)
-     {
        target->sy_previous->sy_next = addme;
-     }
    else
      {
        know (*rootPP == target);
        *rootPP = addme;
!     }				/* if not first  */
  
    addme->sy_previous = target->sy_previous;
    target->sy_previous = addme;
--- 765,781 ----
  {
    if (LOCAL_SYMBOL_CHECK (addme))
      abort ();
+ 
    if (LOCAL_SYMBOL_CHECK (target))
      abort ();
  
    if (target->sy_previous != NULL)
      target->sy_previous->sy_next = addme;
    else
      {
        know (*rootPP == target);
        *rootPP = addme;
!     }
  
    addme->sy_previous = target->sy_previous;
    target->sy_previous = addme;
*************** verify_symbol_chain (rootP, lastP)
*** 810,816 ****
  #else
        /* Walk the list anyways, to make sure pointers are still good.  */
        ;
! #endif /* SYMBOLS_NEED_BACKPOINTERS */
      }
  
    assert (lastP == symbolP);
--- 806,812 ----
  #else
        /* Walk the list anyways, to make sure pointers are still good.  */
        ;
! #endif
      }
  
    assert (lastP == symbolP);
*************** define_dollar_label (label)
*** 1352,1357 ****
--- 1348,1376 ----
    ++dollar_label_count;
  }
  
+ static char *
+ append_number (number, string)
+      long number;
+      char * string;
+ {
+   /* Build up a number, BACKWARDS.  */
+   char symbol_name_temporary[20];
+   char * q;
+   unsigned i;
+   
+   q = symbol_name_temporary;
+   for (*q++ = 0, i = number; i; ++q)
+     {
+       *q = i % 10 + '0';
+       i /= 10;
+     }
+ 
+   while ((*string = *--q) != '\0')
+     ++string;
+ 
+   return string;
+ }
+ 
  /* Caller must copy returned name: we re-use the area for the next name.
  
     The mth occurence of label n: is turned into the symbol "Ln^Am"
*************** dollar_label_name (n, augend)
*** 1368,1379 ****
       register long n;		/* we just saw "n$:" : n a number.  */
       register int augend;	/* 0 for current instance, 1 for new instance.  */
  {
-   long i;
    /* Returned to caller, then copied.  Used for created names ("4f").  */
    static char symbol_name_build[24];
    register char *p;
-   register char *q;
-   char symbol_name_temporary[20];	/* Build up a number, BACKWARDS.  */
  
    know (n >= 0);
    know (augend == 0 || augend == 1);
--- 1387,1395 ----
*************** dollar_label_name (n, augend)
*** 1385,1409 ****
  
    /* Next code just does sprintf( {}, "%d", n);  */
    /* Label number.  */
!   q = symbol_name_temporary;
!   for (*q++ = 0, i = n; i; ++q)
!     {
!       *q = i % 10 + '0';
!       i /= 10;
!     }
!   while ((*p = *--q) != '\0')
!     ++p;
  
    *p++ = DOLLAR_LABEL_CHAR;		/* ^A  */
  
    /* Instance number.  */
!   q = symbol_name_temporary;
!   for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
!     {
!       *q = i % 10 + '0';
!       i /= 10;
!     }
!   while ((*p++ = *--q) != '\0');;
  
    /* The label, as a '\0' ended string, starts at symbol_name_build.  */
    return symbol_name_build;
--- 1401,1412 ----
  
    /* Next code just does sprintf( {}, "%d", n);  */
    /* Label number.  */
!   p = append_number (n, p);
  
    *p++ = DOLLAR_LABEL_CHAR;		/* ^A  */
  
    /* Instance number.  */
!   p = append_number (dollar_label_instance (n) + augend, p);
  
    /* The label, as a '\0' ended string, starts at symbol_name_build.  */
    return symbol_name_build;
*************** dollar_label_name (n, augend)
*** 1424,1430 ****
     crufty compilers have done just that.
  
     Since there could be a LOT of these things, treat them as a sparse
!    array.  */
  
  #define FB_LABEL_SPECIAL (10)
  
--- 1427,1440 ----
     crufty compilers have done just that.
  
     Since there could be a LOT of these things, treat them as a sparse
!    array.
! 
!    Macro labels are just like local labels except that they are intended to
!    be used inside .macro constructs.  To this end they use a different magic
!    identifier (^C instead of ^B) and they have the ability to be explicitly
!    nested (via the .push_macro_labels and .pop_macro_labels pseudo ops).
!    This also means that these labels are restricted to having a number between
!    0 and MACRO_LABEL_MAX_VAL.  */
  
  #define FB_LABEL_SPECIAL (10)
  
*************** static long fb_label_max;
*** 1437,1448 ****
--- 1447,1535 ----
  /* This must be more than FB_LABEL_SPECIAL.  */
  #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
  
+ static long * macro_labels;
+ static long * macro_label_instances;
+ static long   macro_label_count;
+ static long   macro_label_max;
+ 
+ #define MACRO_LABEL_BUMP_BY 6
+ 
  static void
  fb_label_init ()
  {
    memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
  }
  
+ static void
+ macro_label_instance_inc (label)
+      long label;
+ {
+   if (label > MACRO_LABEL_MAX_VAL)
+     return;
+ 
+   label += macro_label_nesting_level * MACRO_LABEL_MAX_VAL;
+ 
+   if (macro_labels != NULL)
+     {
+       long * entry;
+ 
+       for (entry = macro_labels;
+ 	   entry < macro_labels + macro_label_count;
+ 	   ++ entry)
+ 	{
+ 	  if (* entry == label)
+ 	    {
+ 	      ++ macro_label_instances [entry - macro_labels];
+ 	      return;
+ 	    }
+ 	}
+     }
+ 
+   /* If we get to here, we don't have label listed yet.  */
+   if (macro_labels == NULL)
+     {
+       macro_labels = (long *) xmalloc (MACRO_LABEL_BUMP_BY * sizeof (* macro_labels));
+       macro_label_instances = (long *) xmalloc (MACRO_LABEL_BUMP_BY * sizeof (* macro_label_instances));
+       macro_label_max = MACRO_LABEL_BUMP_BY;
+       macro_label_count = 0;
+     }
+   else if (macro_label_count == macro_label_max)
+     {
+       macro_label_max += MACRO_LABEL_BUMP_BY;
+       macro_labels = (long *) xrealloc ((char *) macro_labels, macro_label_max * sizeof (* macro_labels));
+       macro_label_instances = (long *) xrealloc ((char *) macro_label_instances, macro_label_max * sizeof (* macro_label_instances));
+     }
+ 
+   macro_labels [macro_label_count] = label;
+   macro_label_instances [macro_label_count] = 1;
+   ++ macro_label_count;
+ }
+ 
+ static long
+ macro_label_instance (label)
+      long label;
+ {
+   long * entry;
+ 
+   if (label > MACRO_LABEL_MAX_VAL)
+     return 0;
+ 
+   label += macro_label_nesting_level * MACRO_LABEL_MAX_VAL;
+ 
+   if (macro_labels == NULL)
+     return 0;
+ 
+   for (entry = macro_labels;
+        entry < macro_labels + macro_label_count;
+        ++ entry)
+     if (* entry == label)
+       return macro_label_instances [entry - macro_labels];
+ 
+   /* We didn't find the label, so this must be
+      a reference to the first instance.  */
+   return 0;
+ }
+ 
  /* Add one to the instance number of this fb label.  */
  
  void
*************** fb_label_instance_inc (label)
*** 1451,1456 ****
--- 1538,1549 ----
  {
    long *i;
  
+   if (in_macro_labels)
+     {
+       macro_label_instance_inc (label);
+       return;
+     }
+ 
    if (label < FB_LABEL_SPECIAL)
      {
        ++fb_low_counter[label];
*************** fb_label_instance_inc (label)
*** 1460,1473 ****
    if (fb_labels != NULL)
      {
        for (i = fb_labels + FB_LABEL_SPECIAL;
! 	   i < fb_labels + fb_label_count; ++i)
  	{
  	  if (*i == label)
  	    {
  	      ++fb_label_instances[i - fb_labels];
  	      return;
! 	    }			/* if we find it  */
! 	}			/* for each existing label  */
      }
  
    /* If we get to here, we don't have label listed yet.  */
--- 1553,1567 ----
    if (fb_labels != NULL)
      {
        for (i = fb_labels + FB_LABEL_SPECIAL;
! 	   i < fb_labels + fb_label_count;
! 	   ++i)
  	{
  	  if (*i == label)
  	    {
  	      ++fb_label_instances[i - fb_labels];
  	      return;
! 	    }
! 	}
      }
  
    /* If we get to here, we don't have label listed yet.  */
*************** fb_label_instance_inc (label)
*** 1487,1493 ****
  				     fb_label_max * sizeof (long));
        fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
  					      fb_label_max * sizeof (long));
!     }				/* if we needed to grow  */
  
    fb_labels[fb_label_count] = label;
    fb_label_instances[fb_label_count] = 1;
--- 1581,1587 ----
  				     fb_label_max * sizeof (long));
        fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
  					      fb_label_max * sizeof (long));
!     }
  
    fb_labels[fb_label_count] = label;
    fb_label_instances[fb_label_count] = 1;
*************** fb_label_instance (label)
*** 1500,1521 ****
  {
    long *i;
  
    if (label < FB_LABEL_SPECIAL)
!     {
!       return (fb_low_counter[label]);
!     }
  
    if (fb_labels != NULL)
-     {
        for (i = fb_labels + FB_LABEL_SPECIAL;
  	   i < fb_labels + fb_label_count; ++i)
- 	{
  	  if (*i == label)
! 	    {
! 	      return (fb_label_instances[i - fb_labels]);
! 	    }			/* if we find it  */
! 	}			/* for each existing label  */
!     }
  
    /* We didn't find the label, so this must be a reference to the
       first instance.  */
--- 1594,1610 ----
  {
    long *i;
  
+   if (in_macro_labels)
+     return macro_label_instance (label);
+ 
    if (label < FB_LABEL_SPECIAL)
!     return fb_low_counter[label];
  
    if (fb_labels != NULL)
      for (i = fb_labels + FB_LABEL_SPECIAL;
  	 i < fb_labels + fb_label_count; ++i)
        if (*i == label)
! 	return fb_label_instances[i - fb_labels];
  
    /* We didn't find the label, so this must be a reference to the
       first instance.  */
*************** fb_label_name (n, augend)
*** 1538,1549 ****
       long n;			/* We just saw "n:", "nf" or "nb" : n a number.  */
       long augend;		/* 0 for nb, 1 for n:, nf.  */
  {
-   long i;
    /* Returned to caller, then copied.  Used for created names ("4f").  */
    static char symbol_name_build[24];
    register char *p;
-   register char *q;
-   char symbol_name_temporary[20];	/* Build up a number, BACKWARDS.  */
  
    know (n >= 0);
    know (augend == 0 || augend == 1);
--- 1627,1635 ----
*************** fb_label_name (n, augend)
*** 1555,1582 ****
  
    /* Next code just does sprintf( {}, "%d", n);  */
    /* Label number.  */
!   q = symbol_name_temporary;
!   for (*q++ = 0, i = n; i; ++q)
      {
!       *q = i % 10 + '0';
!       i /= 10;
!     }
!   while ((*p = *--q) != '\0')
!     ++p;
  
    *p++ = LOCAL_LABEL_CHAR;		/* ^B  */
  
    /* Instance number.  */
!   q = symbol_name_temporary;
!   for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
!     {
!       *q = i % 10 + '0';
!       i /= 10;
!     }
!   while ((*p++ = *--q) != '\0');;
  
    /* The label, as a '\0' ended string, starts at symbol_name_build.  */
!   return (symbol_name_build);
  }
  
  /* Decode name that may have been generated by foo_label_name() above.
--- 1641,1665 ----
  
    /* Next code just does sprintf( {}, "%d", n);  */
    /* Label number.  */
!   p = append_number (n, p);
! 
!   if (in_macro_labels)
      {
!       if (n >= MACRO_LABEL_MAX_VAL)
! 	as_fatal ("numeric value of macro label is too large");
  
+       *p++ = MACRO_LABEL_CHAR;		/* ^C  */
+       p = append_number (macro_label_nesting_level, p);
+       *p++ = '_';
+     }
+   else
      *p++ = LOCAL_LABEL_CHAR;		/* ^B  */
  
    /* Instance number.  */
!   p = append_number (fb_label_instance (n) + augend, p);
  
    /* The label, as a '\0' ended string, starts at symbol_name_build.  */
!   return symbol_name_build;
  }
  
  /* Decode name that may have been generated by foo_label_name() above.
*************** decode_local_label_name (s)
*** 1610,1615 ****
--- 1693,1706 ----
      type = "dollar";
    else if (*p == LOCAL_LABEL_CHAR)
      type = "fb";
+   else if (*p == MACRO_LABEL_CHAR)
+     {
+       type = "macro";
+       while (*p != '_' && *p != '\0')
+ 	++ p;
+       if (p == '\0')
+ 	-- p;
+     }
    else
      return s;
  
*************** S_IS_LOCAL (s)
*** 1802,1807 ****
--- 1893,1899 ----
  	  && ! S_IS_DEBUG (s)
  	  && (strchr (name, DOLLAR_LABEL_CHAR)
  	      || strchr (name, LOCAL_LABEL_CHAR)
+ 	      || strchr (name, MACRO_LABEL_CHAR)
  	      || (! flag_keep_locals
  		  && (bfd_is_local_label (stdoutput, s->bsym)
  		      || (flag_mri
*************** symbol_print_statistics (file)
*** 2582,2585 ****
--- 2674,2709 ----
    fprintf (file, "%lu mini local symbols created, %lu converted\n",
  	   local_symbol_count, local_symbol_conversion_count);
  #endif
+ }
+ 
+ void
+ start_macro_labels (ignore)
+      int ignore ATTRIBUTE_UNUSED;
+ {
+   in_macro_labels = 1;
+   demand_empty_rest_of_line ();
+ }
+ 
+ void
+ stop_macro_labels (ignore)
+      int ignore ATTRIBUTE_UNUSED;
+ {
+   in_macro_labels = 0;
+   demand_empty_rest_of_line ();
+ }
+ 
+ void
+ push_macro_labels (ignore)
+      int ignore ATTRIBUTE_UNUSED;
+ {
+   macro_label_nesting_level ++;
+   demand_empty_rest_of_line ();
+ }
+ 
+ void
+ pop_macro_labels (ignore)
+      int ignore ATTRIBUTE_UNUSED;
+ {
+   macro_label_nesting_level --;
+   demand_empty_rest_of_line ();
  }

Index: symbols.h
===================================================================
RCS file: /cvs/src/src/gas/symbols.h,v
retrieving revision 1.8
diff -c -3 -p -w -r1.8 symbols.h
*** symbols.h	7 Jun 2002 14:57:50 -0000	1.8
--- symbols.h	13 Jun 2002 14:54:22 -0000
*************** struct broken_word
*** 133,173 ****
  extern struct broken_word *broken_words;
  #endif /* ndef WORKING_DOT_WORD */
  
! /*
!  * Current means for getting from symbols to segments and vice verse.
!  * This will change for infinite-segments support (e.g. COFF).
!  */
  extern const segT N_TYPE_seg[];	/* subseg.c */
  
  #define	SEGMENT_TO_SYMBOL_TYPE(seg)  ( seg_N_TYPE [(int) (seg)] )
  extern const short seg_N_TYPE[];/* subseg.c */
  
! #define	N_REGISTER	30	/* Fake N_TYPE value for SEG_REGISTER */
  
! void symbol_clear_list_pointers PARAMS ((symbolS * symbolP));
  
  #ifdef SYMBOLS_NEED_BACKPOINTERS
  
! void symbol_insert PARAMS ((symbolS * addme, symbolS * target,
! 			    symbolS ** rootP, symbolS ** lastP));
! void symbol_remove PARAMS ((symbolS * symbolP, symbolS ** rootP,
! 			    symbolS ** lastP));
! 
  extern symbolS *symbol_previous PARAMS ((symbolS *));
  
  #endif /* SYMBOLS_NEED_BACKPOINTERS */
  
! void verify_symbol_chain PARAMS ((symbolS * rootP, symbolS * lastP));
! void verify_symbol_chain_2 PARAMS ((symbolS * symP));
! 
! void symbol_append PARAMS ((symbolS * addme, symbolS * target,
! 			    symbolS ** rootP, symbolS ** lastP));
! 
  extern symbolS *symbol_next PARAMS ((symbolS *));
- 
  extern expressionS *symbol_get_value_expression PARAMS ((symbolS *));
! extern void symbol_set_value_expression PARAMS ((symbolS *,
! 						 const expressionS *));
  extern void symbol_set_frag PARAMS ((symbolS *, fragS *));
  extern fragS *symbol_get_frag PARAMS ((symbolS *));
  extern void symbol_mark_used PARAMS ((symbolS *));
--- 133,163 ----
  extern struct broken_word *broken_words;
  #endif /* ndef WORKING_DOT_WORD */
  
! /* Current means for getting from symbols to segments and vice verse.
!    This will change for infinite-segments support (e.g. COFF).  */
  extern const segT N_TYPE_seg[];	/* subseg.c */
  
  #define	SEGMENT_TO_SYMBOL_TYPE(seg)  ( seg_N_TYPE [(int) (seg)] )
  extern const short seg_N_TYPE[];/* subseg.c */
  
! #define	N_REGISTER	30	/* Fake N_TYPE value for SEG_REGISTER.  */
  
! void symbol_clear_list_pointers PARAMS ((symbolS *));
  
  #ifdef SYMBOLS_NEED_BACKPOINTERS
  
! extern void      symbol_insert PARAMS ((symbolS *, symbolS *, symbolS **, symbolS **));
! extern void      symbol_remove PARAMS ((symbolS *, symbolS **, symbolS **));
  extern symbolS * symbol_previous PARAMS ((symbolS *));
  
  #endif /* SYMBOLS_NEED_BACKPOINTERS */
  
! extern void verify_symbol_chain PARAMS ((symbolS *, symbolS *));
! extern void verify_symbol_chain_2 PARAMS ((symbolS *));
! extern void symbol_append PARAMS ((symbolS *, symbolS *, symbolS **, symbolS **));
  extern symbolS *symbol_next PARAMS ((symbolS *));
  extern expressionS *symbol_get_value_expression PARAMS ((symbolS *));
! extern void symbol_set_value_expression PARAMS ((symbolS *, const expressionS *));
  extern void symbol_set_frag PARAMS ((symbolS *, fragS *));
  extern fragS *symbol_get_frag PARAMS ((symbolS *));
  extern void symbol_mark_used PARAMS ((symbolS *));
*************** void symbol_set_obj PARAMS ((symbolS *, 
*** 203,205 ****
--- 193,200 ----
  TC_SYMFIELD_TYPE *symbol_get_tc PARAMS ((symbolS *));
  void symbol_set_tc PARAMS ((symbolS *, TC_SYMFIELD_TYPE *));
  #endif
+ 
+ extern void start_macro_labels PARAMS ((int));
+ extern void stop_macro_labels PARAMS ((int));
+ extern void push_macro_labels PARAMS ((int));
+ extern void pop_macro_labels PARAMS ((int));

Index: doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.65
diff -c -3 -p -w -r1.65 as.texinfo
*** doc/as.texinfo	7 Jun 2002 23:07:19 -0000	1.65
--- doc/as.texinfo	13 Jun 2002 14:54:24 -0000
*************** name which uses ASCII character @samp{\0
*** 3134,3139 ****
--- 3134,3192 ----
  to distinguish them from ordinary labels.  Thus the 5th defintion of @samp{6$}
  is named @samp{L6@kbd{C-A}5}.
  
+ @subheading Macro Local Labels
+ @cindex macro local symbols
+ @code{@value{AS}} has a third form of local labels called macro local labels.
+ These labels are just like Local Symbols except that the intention is that
+ they can safely be used inside @code{.macro} constructs.  To this end they use
+ a different magic value to identify them (@kbd{C-C} instead of @kbd{C-B}), and
+ they have the ability to be nested.  Nesting is achieved via the
+ @code{.push_macro_labels} and the @code{.pop_macro_labels} pseudo ops and the
+ macro local labels are activated via the @code{.start_macro_labels} pseudo op
+ and terminated with the @code{.stop_macro_labels}.  Macro local labels do have
+ one restriction.  Their numeric value cannot be greater than 0xe000.
+ 
+ Here is an example:
+ 
+ @smallexample
+ 	.macro IFNZ val1, val2
+ 	  .start_macro_labels
+ 	  .push_macro_labels
+           compare        \val1, \val2
+           branch_if_eq   1f
+ 	  .stop_macro_labels
+         .endm
+ 
+         .macro ELSE
+ 	  .start_macro_labels
+           branch        2f
+ 	  1:	
+ 	  .stop_macro_labels
+         .endm
+ 
+         .macro ENDIF
+ 	  .start_macro_labels
+           1:	
+           2:
+ 	  .pop_macro_labels
+ 	  .stop_macro_labels
+         .endm
+ 
+ 	.global	foo
+ foo:
+ 	nop
+ 
+ 	IFNZ r0, #0
+ 	  IFNZ r1, #0
+ 	    nop
+ 	  ELSE
+ 	    nop
+ 	  ENDIF
+ 	ENDIF
+ 
+ 	nop
+ @end smallexample
+ 
  @node Dot
  @section The Special Dot Symbol
  
*************** Some machine configurations provide addi
*** 3656,3661 ****
--- 3709,3715 ----
  * Nolist::                      @code{.nolist}
  * Octa::                        @code{.octa @var{bignums}}
  * Org::                         @code{.org @var{new-lc} , @var{fill}}
+ * Pop_Macro_Labels::            @code{.pop_macro_labels}
  * P2align::                     @code{.p2align @var{abs-expr} , @var{abs-expr}}
  @ifset ELF
  * PopSection::                  @code{.popsection}
*************** Some machine configurations provide addi
*** 3669,3674 ****
--- 3723,3729 ----
  
  * Psize::                       @code{.psize @var{lines}, @var{columns}}
  * Purgem::			@code{.purgem @var{name}}
+ * Push_Macro_Labels::           @code{.push_macro_labels}
  @ifset ELF
  * PushSection::                 @code{.pushsection @var{name}}
  @end ifset
*************** Some machine configurations provide addi
*** 3692,3697 ****
--- 3747,3754 ----
  * Stab::                        @code{.stabd, .stabn, .stabs}
  @end ifset
  
+ * Start_Macro_Labels::          @code{.start_macro_labels}
+ * Stop_Macro_Labels::           @code{.stop_macro_labels}
  * String::                      @code{.string "@var{str}"}
  * Struct::			@code{.struct @var{expression}}
  @ifset ELF
*************** intervening bytes are filled with @var{f
*** 4756,4761 ****
--- 4813,4825 ----
  absolute expression.  If the comma and @var{fill} are omitted,
  @var{fill} defaults to zero.
  
+ @node Pop_Macro_Labels
+ @section @code{.pop_macro_labels}
+ @cindex Decrementing the macro label nesting levels
+ @cindex @code{pop_macro_labels} directive
+ This pseudo op is ths reverse of the @code{.push_macro_labels} pseudo op.  It
+ decrements the nesting level of macro local labels.
+ 
  @node P2align
  @section @code{.p2align[wl] @var{abs-expr}, @var{abs-expr}, @var{abs-expr}}
  
*************** those explicitly specified with @code{.e
*** 4880,4885 ****
--- 4944,4957 ----
  Undefine the macro @var{name}, so that later uses of the string will not be
  expanded.  @xref{Macro}.
  
+ @node Push_Macro_Labels
+ @section @code{.push_macro_labels}
+ @cindex Incrementing the macro label nesting levels
+ @cindex @code{push_macro_labels} directive
+ This pseudo op increments the nesting level of macro local labels.  From this
+ point until the corresponding @code{.pop_macro_labels} pseudo op, all macro
+ labels will be given a new, higher, nesting value.
+ 
  @ifset ELF
  @node PushSection
  @section @code{.pushsection @var{name} , @var{subsection}}
*************** All five fields are specified.
*** 5300,5305 ****
--- 5372,5394 ----
  @end table
  @end ifset
  @c end     have-stabs
+ 
+ @node Start_Macro_Labels
+ @section @code{.start_macro_labels}
+ @cindex Enable macro labels
+ @cindex @code{start_macro_labels} directive
+ This pseudo op changes the behaviour of local labels from this point on, until
+ a @code{.stop_macro_labels} pseudo op is encountered.  Local labels will now be
+ treated as macro local labels, with a different magic identifier and the
+ ability to be nested via the @code{.push_macro_labels} and
+ @code{.pop_macro_labels} pseudo ops.
+ 
+ @node Stop_Macro_Labels
+ @section @code{.stop_macro_labels}
+ @cindex Disable macro labels
+ @cindex @code{stop_macro_labels} directive
+ This pseudo op is the reverse of the @code{.start_macro_labels} pseudo op.  It
+ returns local labels to their normal behaviour.
  
  @node String
  @section @code{.string} "@var{str}"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]