mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-04-06 14:21:43 +08:00
Add new assembler macro pseudo-variable \+ which counts the number of times a macro has been invoked.
This commit is contained in:
parent
7143ed1205
commit
83b972fc27
4
gas/NEWS
4
gas/NEWS
@ -1,5 +1,9 @@
|
||||
-*- text -*-
|
||||
|
||||
* Assembler macros can now use the syntax \+ to access the number of times a
|
||||
given macro has been executed. This is similar to the already existing \@
|
||||
syntax, except that the count is maintained on a per-macro basis.
|
||||
|
||||
* Support the NF feature in Intel APX.
|
||||
|
||||
* Remove KEYLOCKER and SHA promotions from EVEX MAP4.
|
||||
|
@ -6362,6 +6362,14 @@ Exit early from the current macro definition.
|
||||
executed in this pseudo-variable; you can copy that number to your
|
||||
output with @samp{\@@}, but @emph{only within a macro definition}.
|
||||
|
||||
@cindex number of times a macro has been executed
|
||||
@cindex macro, execution count
|
||||
@item \+
|
||||
Similar to the @code{\@@} pseudo-variable, @command{@value{AS}} also maintains
|
||||
a per-macro count of the number of times that that macro has been executed.
|
||||
You can copy that number to your output with @samp{\+}, but
|
||||
@emph{only within a macro definition}.
|
||||
|
||||
@item LOCAL @var{name} [ , @dots{} ]
|
||||
@emph{Warning: @code{LOCAL} is only available if you select ``alternate
|
||||
macro syntax'' with @samp{--alternate} or @code{.altmacro}.}
|
||||
|
21
gas/macro.c
21
gas/macro.c
@ -56,7 +56,7 @@ int macro_defined;
|
||||
|
||||
/* Number of macro expansions that have been done. */
|
||||
|
||||
static int macro_number;
|
||||
static unsigned int macro_number;
|
||||
|
||||
static void free_macro (macro_entry *);
|
||||
|
||||
@ -668,6 +668,7 @@ define_macro (sb *in, sb *label, size_t (*get_line) (sb *))
|
||||
macro->formal_count = 0;
|
||||
macro->formals = 0;
|
||||
macro->formal_hash = str_htab_create ();
|
||||
macro->count = 0;
|
||||
|
||||
idx = sb_skip_white (0, in);
|
||||
if (! buffer_and_nest ("MACRO", "ENDM", ¯o->sub, get_line))
|
||||
@ -846,11 +847,20 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
|
||||
}
|
||||
else if (src < in->len && in->ptr[src] == '@')
|
||||
{
|
||||
/* Sub in the macro invocation number. */
|
||||
/* Sub in the total macro invocation number. */
|
||||
|
||||
char buffer[12];
|
||||
src++;
|
||||
sprintf (buffer, "%d", macro_number);
|
||||
sprintf (buffer, "%u", macro_number);
|
||||
sb_add_string (out, buffer);
|
||||
}
|
||||
else if (src < in->len && in->ptr[src] == '+')
|
||||
{
|
||||
/* Sub in the current macro invocation number. */
|
||||
|
||||
char buffer[12];
|
||||
src++;
|
||||
sprintf (buffer, "%d", macro->count);
|
||||
sb_add_string (out, buffer);
|
||||
}
|
||||
else if (src < in->len && in->ptr[src] == '&')
|
||||
@ -1227,7 +1237,10 @@ macro_expand (size_t idx, sb *in, macro_entry *m, sb *out)
|
||||
|
||||
sb_kill (&t);
|
||||
if (!err)
|
||||
macro_number++;
|
||||
{
|
||||
macro_number++;
|
||||
m->count++;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
15
gas/macro.h
15
gas/macro.h
@ -60,13 +60,14 @@ typedef struct formal_struct {
|
||||
|
||||
typedef struct macro_struct
|
||||
{
|
||||
sb sub; /* Substitution text. */
|
||||
int formal_count; /* Number of formal args. */
|
||||
formal_entry *formals; /* List of formal_structs. */
|
||||
htab_t formal_hash; /* Hash table of formals. */
|
||||
const char *name; /* Macro name. */
|
||||
const char *file; /* File the macro was defined in. */
|
||||
unsigned int line; /* Line number of definition. */
|
||||
sb sub; /* Substitution text. */
|
||||
int formal_count; /* Number of formal args. */
|
||||
formal_entry * formals; /* List of formal_structs. */
|
||||
htab_t formal_hash; /* Hash table of formals. */
|
||||
const char * name; /* Macro name. */
|
||||
const char * file; /* File the macro was defined in. */
|
||||
unsigned int line; /* Line number of definition. */
|
||||
unsigned int count; /* Invocation count. */
|
||||
} macro_entry;
|
||||
|
||||
/* Whether any macros have been defined. */
|
||||
|
@ -1,3 +1,2 @@
|
||||
local
|
||||
.LL0001
|
||||
.LL0002
|
||||
#name: Local label generation in alternate macros (altmacro)
|
||||
|
||||
|
3
gas/testsuite/gas/macros/altmacro.l
Normal file
3
gas/testsuite/gas/macros/altmacro.l
Normal file
@ -0,0 +1,3 @@
|
||||
local.*
|
||||
.*LL0001
|
||||
.*LL0002
|
3
gas/testsuite/gas/macros/count.d
Normal file
3
gas/testsuite/gas/macros/count.d
Normal file
@ -0,0 +1,3 @@
|
||||
#name: Macro counters (count.d)
|
||||
# Tests that \@ counts total macro invocation count
|
||||
# and that \+ counts individual macro invocation count.
|
10
gas/testsuite/gas/macros/count.l
Normal file
10
gas/testsuite/gas/macros/count.l
Normal file
@ -0,0 +1,10 @@
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
2
|
||||
0
|
||||
3
|
||||
1
|
||||
4
|
||||
2
|
19
gas/testsuite/gas/macros/count.s
Normal file
19
gas/testsuite/gas/macros/count.s
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
.macro mac1 count=10
|
||||
.print "\@"
|
||||
.print "\+"
|
||||
.if \count > 1
|
||||
mac1 \count-1
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro mac2 count=100
|
||||
.print "\@"
|
||||
.print "\+"
|
||||
.if \count > 1
|
||||
mac2 \count-1
|
||||
.endif
|
||||
.endm
|
||||
|
||||
mac1 2
|
||||
mac2 3
|
@ -100,3 +100,6 @@ if [string match "" [lindex [gas_run ../all/excl.s "-o /dev/null" ""] 0]] {
|
||||
# prevented the assembler from parsing the rest of the file,
|
||||
# and hence catching an erroroneous instruction.
|
||||
gas_test_error "exit.s" "" ".exitm outside of a macro"
|
||||
|
||||
run_list_test altmacro
|
||||
run_list_test count
|
||||
|
Loading…
x
Reference in New Issue
Block a user