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: GAS macro formals as expression


Hi Clemens,

> Is there any possibility to evaluate an expression and store it in a
> macro formal? Like \y = \x+1?
>
> I hope that's possible but neither the docs nor the source looks like there
> is a possibility for this.
>
> Big picture: I'd like to do something like:
> 	concat  "jmp skProc_",\keysize,_,\n+4,_,\cpuname
>
> But \n+4 isn't evaluated as an expression, so I'm in trouble.
> Any hits?

At the moment GAS's macro code cannot do this. :-(

What you need is a patch something like the one below.  With this you
can assemble code like this:

	.macro concat keysize, n, cpuname, prefix="skProc", sep="_"
	jmp \prefix\sep\keysize\sep\n\sep\cpuname
	.endm
	
	.macro jump_to_name keysize, n, cpuname
	concat \keysize, :\n+4, \cpuname
	.endm

	jump_to_name 20,2,jim

and get:

        % as macro_test.s --macro-arg-eval-prefix-char=:
        % objdump -r a.out
        a.out:     file format elf32-i386
 
        RELOCATION RECORDS FOR [.text]:
        OFFSET   TYPE              VALUE
        00000001 R_386_PC32        skProc_20_6_jim

Of course this patch needs tidying up.  But worst of all it is really
a case of creeping featurism.  So I am not sure if it should be
applied at all...
                
Cheers
        Nick

2003-09-09  Nick Clifton  <nickc@redhat.com>

        * as.c: Add support for new switch
        --macro-arg-eval-prefix-char.  Use it to set macro_prefix_char.
        * macro.h (macro_prefix_char): Declare.
        * macro.c (macro_prefix_char): Define.
        (macro_expand): If a macro arg has been prefixed by
        macro_prefix_char then evaluated whilst expanding the
        macro.
        * doc/as.texinfo: Document new switch.
        * NEWS: Mention new feature.
	* Makefile.am: Update dependencies for macro.c
        * Makefile.in: Regenerate.

Index: gas/Makefile.am
===================================================================
RCS file: /cvs/src/src/gas/Makefile.am,v
retrieving revision 1.80
diff -c -3 -p -r1.80 Makefile.am
*** gas/Makefile.am	14 Aug 2003 07:04:09 -0000	1.80
--- gas/Makefile.am	9 Sep 2003 17:12:26 -0000
*************** input-scrub.o: input-scrub.c $(INCDIR)/s
*** 2441,2447 ****
  listing.o: listing.c $(INCDIR)/symcat.h $(INCDIR)/obstack.h \
    $(INCDIR)/safe-ctype.h input-file.h subsegs.h
  literal.o: literal.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h
! macro.o: macro.c $(INCDIR)/safe-ctype.h sb.h macro.h
  messages.o: messages.c $(INCDIR)/symcat.h
  output-file.o: output-file.c $(INCDIR)/symcat.h output-file.h
  read.o: read.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
--- 2441,2447 ----
  listing.o: listing.c $(INCDIR)/symcat.h $(INCDIR)/obstack.h \
    $(INCDIR)/safe-ctype.h input-file.h subsegs.h
  literal.o: literal.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h
! macro.o: macro.c $(INCDIR)/safe-ctype.h sb.h macro.h as.h expr.h symbols.h
  messages.o: messages.c $(INCDIR)/symcat.h
  output-file.o: output-file.c $(INCDIR)/symcat.h output-file.h
  read.o: read.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
Index: gas/NEWS
===================================================================
RCS file: /cvs/src/src/gas/NEWS,v
retrieving revision 1.44
diff -c -3 -p -r1.44 NEWS
*** gas/NEWS	4 Sep 2003 11:04:35 -0000	1.44
--- gas/NEWS	9 Sep 2003 17:12:30 -0000
***************
*** 1,5 ****
--- 1,8 ----
  -*- text -*-
  
+ * Add --macro-arg-eval-prefix=<char> switch to allow certain arguments to
+   macros to be evaluated as the macro is expanded.
+   
  * Added support for v850e1.
  
  * Added -n switch for x86 assembler.  By default, x86 GAS replaces
Index: gas/as.c
===================================================================
RCS file: /cvs/src/src/gas/as.c,v
retrieving revision 1.46
diff -c -3 -p -r1.46 as.c
*** gas/as.c	4 Jun 2003 16:54:45 -0000	1.46
--- gas/as.c	9 Sep 2003 17:12:31 -0000
*************** Options:\n\
*** 297,302 ****
--- 297,305 ----
    fprintf (stream, _("\
    --MD FILE               write dependency information in FILE (default none)\n"));
    fprintf (stream, _("\
+   --macro-arg-eval-prefix=<char>\n\
+                           force macro args to be evaluated if prefixed by <char>\n"));
+   fprintf (stream, _("\
    -nocpp                  ignored\n"));
    fprintf (stream, _("\
    -o OBJFILE              name the object-file output OBJFILE (default a.out)\n"));
*************** parse_args (pargc, pargv)
*** 450,458 ****
      {"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK},
  #endif
  #define OPTION_WARN_FATAL (OPTION_STD_BASE + 22)
!     {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL}
      /* When you add options here, check that they do not collide with
         OPTION_MD_BASE.  See as.h.  */
    };
  
    /* Construct the option lists from the standard list and the target
--- 453,464 ----
      {"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK},
  #endif
  #define OPTION_WARN_FATAL (OPTION_STD_BASE + 22)
!     {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL},
      /* When you add options here, check that they do not collide with
         OPTION_MD_BASE.  See as.h.  */
+ #define OPTION_MACRO_PREFIX_CHAR (OPTION_STD_BASE + 23)
+     {"macro-arg-eval-prefix-char", required_argument, NULL, OPTION_MACRO_PREFIX_CHAR}
+     
    };
  
    /* Construct the option lists from the standard list and the target
*************** the GNU General Public License.  This pr
*** 798,803 ****
--- 804,816 ----
  
  	case 'X':
  	  /* -X means treat warnings as errors.  */
+ 	  break;
+ 
+ 	case OPTION_MACRO_PREFIX_CHAR:
+ 	  if (optarg == NULL || * optarg == 0 || optarg[1] != 0)
+ 	    as_fatal (_("invalid argument to -- macro-arg-eval-prefix-char"));
+ 	  else
+ 	    macro_prefix_char = * optarg;
  	  break;
  	}
      }
Index: gas/macro.c
===================================================================
RCS file: /cvs/src/src/gas/macro.c,v
retrieving revision 1.22
diff -c -3 -p -r1.22 macro.c
*** gas/macro.c	2 Jun 2003 15:03:20 -0000	1.22
--- gas/macro.c	9 Sep 2003 17:12:32 -0000
*************** extern void *alloca ();
*** 59,65 ****
  #include "sb.h"
  #include "hash.h"
  #include "macro.h"
! 
  #include "asintl.h"
  
  /* The routines in this file handle macro definition and expansion.
--- 59,65 ----
  #include "sb.h"
  #include "hash.h"
  #include "macro.h"
! #include "as.h"
  #include "asintl.h"
  
  /* The routines in this file handle macro definition and expansion.
*************** static int (*macro_expr) PARAMS ((const 
*** 119,124 ****
--- 119,128 ----
  
  static int macro_number;
  
+ /* If not NUL, a character that prefixes macro arguments
+    when the user wants them to be evaluated before expansion.  */
+ char macro_prefix_char = 0;
+ 
  /* Initialize macro processing.  */
  
  void
*************** macro_expand (idx, in, m, out)
*** 1007,1012 ****
--- 1012,1048 ----
  	  idx = get_any_string (idx, in, &f->actual, 1, 0);
  	  if (f->actual.len > 0)
  	    ++narg;
+ 
+ 	  if (macro_prefix_char && f->actual.ptr[0] == macro_prefix_char)
+ 	    {
+ 	      char * saved_ilp = input_line_pointer;
+ 	      expressionS exp;
+ 	      
+ 	      input_line_pointer = f->actual.ptr + 1;
+ 	      expression (& exp);
+ 	      input_line_pointer = saved_ilp;
+ 	      switch (exp.X_op)
+ 		{
+ 		case O_constant:
+ 		  {
+ 		    char buf[20];
+ 
+ 		    sb_reset (& f->actual);
+ 		    sprintf (buf, "%ld", exp.X_add_number);
+ 		    sb_add_string (& f->actual, buf);
+ 		    break;
+ 		  }
+ 		  
+ 		case O_symbol:
+ 		  sb_reset (& f->actual);
+ 		  sb_add_string (& f->actual, S_GET_NAME (exp.X_add_symbol));
+ 		  break;
+ 		  
+ 		default:
+ 		  return _("unable to evaluate argument");
+ 		}
+ 	    }
+ 	  
  	  do
  	    {
  	      f = f->next;
Index: gas/macro.h
===================================================================
RCS file: /cvs/src/src/gas/macro.h,v
retrieving revision 1.7
diff -c -3 -p -r1.7 macro.h
*** gas/macro.h	2 Dec 2002 15:42:08 -0000	1.7
--- gas/macro.h	9 Sep 2003 17:12:32 -0000
*************** extern int macro_defined;
*** 70,75 ****
--- 70,79 ----
  
  extern int macro_nest;
  
+ /* If not NUL, a character that prefixes macro arguments
+    when the user wants them to be evaluated before expansion.  */
+ extern char macro_prefix_char;
+ 
  extern int buffer_and_nest
    PARAMS ((const char *, const char *, sb *, int (*) PARAMS ((sb *))));
  extern void macro_init
Index: gas/doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.90
diff -c -3 -p -r1.90 as.texinfo
*** gas/doc/as.texinfo	7 Sep 2003 12:28:09 -0000	1.90
--- gas/doc/as.texinfo	9 Sep 2003 17:12:42 -0000
*************** gcc(1), ld(1), and the Info entries for 
*** 269,275 ****
   [@b{--listing-rhs-width}=@var{NUM}] [@b{--listing-cont-lines}=@var{NUM}]
   [@b{--keep-locals}] [@b{-o} @var{objfile}] [@b{-R}] [@b{--statistics}] [@b{-v}]
   [@b{-version}] [@b{--version}] [@b{-W}] [@b{--warn}] [@b{--fatal-warnings}] 
!  [@b{-w}] [@b{-x}] [@b{-Z}] [@b{--target-help}] [@var{target-options}] 
   [@b{--}|@var{files} @dots{}]
  @c
  @c Target dependent options are listed below.  Keep the list sorted.
--- 269,277 ----
   [@b{--listing-rhs-width}=@var{NUM}] [@b{--listing-cont-lines}=@var{NUM}]
   [@b{--keep-locals}] [@b{-o} @var{objfile}] [@b{-R}] [@b{--statistics}] [@b{-v}]
   [@b{-version}] [@b{--version}] [@b{-W}] [@b{--warn}] [@b{--fatal-warnings}] 
!  [@b{-w}] [@b{-x}] [@b{-Z}] [@b{--target-help}]
!  [@b{--macro-arg-eval-prefix-char=@var{CHAR}}]
!  [@var{target-options}] 
   [@b{--}|@var{files} @dots{}]
  @c
  @c Target dependent options are listed below.  Keep the list sorted.
*************** Set the maximum width of an input source
*** 561,566 ****
--- 563,572 ----
  Set the maximum number of lines printed in a listing for a single line of input
  to @var{number} + 1.
  
+ @item --macro-arg-eval-prefix=@var{char}
+ Force arguments to macros to be evaluated if they are prefixed by @var{char}.
+ By default this is NUL, so no arguments are evaluated.
+ 
  @item -o @var{objfile}
  Name the object-file output from @command{@value{AS}} @var{objfile}.
  
*************** separate macro expansion.  @code{LOCAL} 
*** 4873,4878 ****
--- 4879,4905 ----
  define symbols, without fear of conflict between separate macro expansions.
  @end ignore
  @end ftable
+ 
+ Note - by default the arguments to a macro are not evaluated during the
+ expansion of the macro.  Instead they are evaluated when the body of macro is
+ re-parsed by the assembler.  You can force certain arguments to be evaluated by
+ using the @option{--macro-arg-eval-prefix-char=} option.  If the character that
+ this option specifies is detected as the first letter of a macro argument, then
+ the remainder if the argument will be evaluated during the expansion of the
+ macro.  This allows code like this:
+ @smallexample
+   .set number_of_bugs 1
+   
+   .macro foo count
+   .string "This code contains " \count " bugs"
+   .endm
+ 
+   foo ^number_of_bugs+1
+ @end smallexample
+ 
+ to work, provided that the assembler is invoked with
+ @option{--macro-arg-eval-prefix-char=^}.
+ 
  
  @node Nolist
  @section @code{.nolist}
        


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