This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: GAS macro formals as expression
- From: Nick Clifton <nickc at redhat dot com>
- To: Fruhwirth Clemens <clemens-dated-1063971140 dot ab89 at endorphin dot org>
- Cc: binutils at sources dot redhat dot com
- Date: Tue, 09 Sep 2003 18:19:17 +0100
- Subject: Re: GAS macro formals as expression
- References: <20030909113220.GA1868@leto2.endorphin.org>
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}