From: "Jan Beulich" <JBeulich@novell.com>
To: <binutils@sources.redhat.com>
Subject: [PATCH] Re: .macro behavior
Date: Tue, 08 Feb 2005 17:52:00 -0000 [thread overview]
Message-ID: <s208dfe7.067@emea1-mh.id2.novell.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 14943 bytes --]
>>> Ian Lance Taylor <ian@airs.com> 14.01.05 17:50:05 >>>
>"Jan Beulich" <JBeulich@novell.com> writes:
>
>> Is it intentional that .macro
>>
>> - ignores the (configurable) set of symbol name characters and
instead
>> only allows [[:alpha:]_$][[:alnum:]_$]*
>> - silently inserts a zero-length named macro if the name starts
with
>> any non-token character
>> - silently ignores the rest of the line if a formal argument starts
>> with any non-token character
>>
>> If not, I'd like to fix this. One major concern here is that with
these
>> restrictions one can't build trivial things like a .bss
>> pseudo-directive...
>
>None of these behaviours are intentional.
>
>But you're still not going to be able to define a macro which starts
>with '.'. Those are handled specially in read_a_source_file().
>Although I suppose that could also be changed.
This is a resubmission of the patch to address the inconsistent
acceptance
of identifiers between the macro handling code and the rest of the
assembler,
including the unability to use a macro the name of which starts with a
dot.
It now also includes a fix for the previously failing mmix testcase.
Built and tested natively on ia64-unknown-linux-gnu and as cross tools
for a large number of targets.
Jan
gas/
2005-02-08 Jan Beulich <jbeulich@novell.com>
* macro.c (get_token): Use is_name_beginner/is_part_of_name/
is_name_ender.
(check_macro): Likewise.
(buffer_and_nest): Likewise. Permit multiple labels. Don't
discard
labels together with the closing pseudo-op.
(macro_expand_body): Adjust comment. Range-check input before
use.
Adjust mis-spelled diagnostic. Use is_name_beginner.
* read.c (try_macro): New.
(read_a_source_file): New static variable last_eol. Don't list
macro expansion lines more than once. Call try_macro.
(s_macro): Set section of line_label to absolute instead of
undefined.
gas/testsuite/
2005-02-08 Jan Beulich <jbeulich@novell.com>
* gas/macros/dot.[ls]: New.
* gas/macros/macros.exp: Run new test.
* gas/mmix/relax2.s: Use .altmacro and & to separate macro
parameter
references.
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/macro.c 2005-01-31
15:27:07.000000000 +0100
+++ 2005-02-01/gas/macro.c 2005-02-03 15:12:04.000000000 +0100
@@ -187,21 +187,37 @@ buffer_and_nest (const char *from, const
the first column, since we can't tell what's a label and
whats a pseudoop. */
- /* Skip leading whitespace. */
- while (i < ptr->len && ISWHITE (ptr->ptr[i]))
- i++;
-
- /* Skip over a label. */
- while (i < ptr->len
- && (ISALNUM (ptr->ptr[i])
- || ptr->ptr[i] == '_'
- || ptr->ptr[i] == '$'))
- i++;
-
- /* And a colon. */
- if (i < ptr->len
- && ptr->ptr[i] == ':')
- i++;
+ if (! LABELS_WITHOUT_COLONS)
+ {
+ /* Skip leading whitespace. */
+ while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+ i++;
+ }
+
+ for (;;)
+ {
+ /* Skip over a label, if any. */
+ if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+ break;
+ i++;
+ while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+ i++;
+ if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+ i++;
+ if (LABELS_WITHOUT_COLONS)
+ break;
+ /* Skip whitespace. */
+ while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+ i++;
+ /* Check for the colon. */
+ if (i >= ptr->len || ptr->ptr[i] != ':')
+ {
+ i = line_start;
+ break;
+ }
+ i++;
+ line_start = i;
+ }
}
/* Skip trailing whitespace. */
@@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const
? strncasecmp (ptr->ptr + i, from, from_len) == 0
: from_len > 0)
&& (ptr->len == (i + from_len)
- || ! ISALNUM (ptr->ptr[i + from_len])))
+ || ! (is_part_of_name (ptr->ptr[i + from_len])
+ || is_name_ender (ptr->ptr[i + from_len]))))
depth++;
if (strncasecmp (ptr->ptr + i, to, to_len) == 0
&& (ptr->len == (i + to_len)
- || ! ISALNUM (ptr->ptr[i + to_len])))
+ || ! (is_part_of_name (ptr->ptr[i + to_len])
+ || is_name_ender (ptr->ptr[i + to_len]))))
{
depth--;
if (depth == 0)
@@ -258,15 +276,16 @@ static int
get_token (int idx, sb *in, sb *name)
{
if (idx < in->len
- && (ISALPHA (in->ptr[idx])
- || in->ptr[idx] == '_'
- || in->ptr[idx] == '$'))
+ && is_name_beginner (in->ptr[idx]))
{
sb_add_char (name, in->ptr[idx++]);
while (idx < in->len
- && (ISALNUM (in->ptr[idx])
- || in->ptr[idx] == '_'
- || in->ptr[idx] == '$'))
+ && is_part_of_name (in->ptr[idx]))
+ {
+ sb_add_char (name, in->ptr[idx++]);
+ }
+ if (idx < in->len
+ && is_name_ender (in->ptr[idx]))
{
sb_add_char (name, in->ptr[idx++]);
}
@@ -692,13 +711,14 @@ macro_expand_body (sb *in, sb *out, form
else
{
/* FIXME: Why do we do this? */
+ /* At least in alternate mode this seems correct. */
src = sub_actual (src + 1, in, &t, formal_hash, '&', out,
0);
}
}
else if (in->ptr[src] == '\\')
{
src++;
- if (in->ptr[src] == '(')
+ if (src < in->len && in->ptr[src] == '(')
{
/* Sub in till the next ')' literally. */
src++;
@@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form
if (in->ptr[src] == ')')
src++;
else
- return _("missplaced )");
+ return _("misplaced `)'");
}
- else if (in->ptr[src] == '@')
+ else if (src < in->len && in->ptr[src] == '@')
{
/* Sub in the macro invocation number. */
@@ -720,7 +740,7 @@ macro_expand_body (sb *in, sb *out, form
sprintf (buffer, "%d", macro_number);
sb_add_string (out, buffer);
}
- else if (in->ptr[src] == '&')
+ else if (src < in->len && in->ptr[src] == '&')
{
/* This is a preprocessor variable name, we don't do them
here. */
@@ -728,7 +748,7 @@ macro_expand_body (sb *in, sb *out, form
sb_add_char (out, '&');
src++;
}
- else if (macro_mri && ISALNUM (in->ptr[src]))
+ else if (macro_mri && src < in->len && ISALNUM
(in->ptr[src]))
{
int ind;
formal_entry *f;
@@ -759,9 +779,7 @@ macro_expand_body (sb *in, sb *out, form
}
}
else if ((macro_alternate || macro_mri)
- && (ISALPHA (in->ptr[src])
- || in->ptr[src] == '_'
- || in->ptr[src] == '$')
+ && is_name_beginner (in->ptr[src])
&& (! inquote
|| ! macro_strip_at
|| (src > 0 && in->ptr[src - 1] == '@')))
@@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan
macro_entry *macro;
sb line_sb;
- if (! ISALPHA (*line)
- && *line != '_'
- && *line != '$'
+ if (! is_name_beginner (*line)
&& (! macro_mri || *line != '.'))
return 0;
s = line + 1;
- while (ISALNUM (*s)
- || *s == '_'
- || *s == '$')
+ while (is_part_of_name (*s))
+ ++s;
+ if (is_name_ender (*s))
++s;
copy = (char *) alloca (s - line + 1);
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/read.c 2005-01-26
08:33:13.000000000 +0100
+++ 2005-02-01/gas/read.c 2005-02-03 15:12:04.000000000 +0100
@@ -499,6 +499,32 @@ scrub_from_string (char *buf, int buflen
return copy;
}
+/* Helper function of read_a_source_file, which tries to expand a
macro. */
+static int
+try_macro (char term, const char *line)
+{
+ sb out;
+ const char *err;
+ macro_entry *macro;
+
+ if (check_macro (line, &out, &err, ¯o))
+ {
+ if (err != NULL)
+ as_bad ("%s", err);
+ *input_line_pointer++ = term;
+ input_scrub_include_sb (&out,
+ input_line_pointer, 1);
+ sb_kill (&out);
+ buffer_limit =
+ input_scrub_next_buffer (&input_line_pointer);
+#ifdef md_macro_info
+ md_macro_info (macro);
+#endif
+ return 1;
+ }
+ return 0;
+}
+
/* We read the file, putting things into a web that represents what
we
have been reading. */
void
@@ -526,6 +552,13 @@ read_a_source_file (char *name)
while ((buffer_limit = input_scrub_next_buffer
(&input_line_pointer)) != 0)
{ /* We have another line to parse. */
+#ifndef NO_LISTING
+ /* In order to avoid listing macro expansion lines with labels
+ multiple times, keep track of which line was last issued. */
+ static char *last_eol;
+
+ last_eol = NULL;
+#endif
know (buffer_limit[-1] == '\n'); /* Must have a sentinel.
*/
while (input_line_pointer < buffer_limit)
@@ -645,17 +678,21 @@ read_a_source_file (char *name)
if (is_end_of_line[(unsigned char) *s])
break;
- /* Copy it for safe keeping. Also give an indication
of
- how much macro nesting is involved at this point.
*/
- len = s - (input_line_pointer - 1);
- copy = (char *) xmalloc (len + macro_nest + 2);
- memset (copy, '>', macro_nest);
- copy[macro_nest] = ' ';
- memcpy (copy + macro_nest + 1, input_line_pointer - 1,
len);
- copy[macro_nest + 1 + len] = '\0';
+ if (s != last_eol)
+ {
+ last_eol = s;
+ /* Copy it for safe keeping. Also give an
indication of
+ how much macro nesting is involved at this
point. */
+ len = s - (input_line_pointer - 1);
+ copy = (char *) xmalloc (len + macro_nest + 2);
+ memset (copy, '>', macro_nest);
+ copy[macro_nest] = ' ';
+ memcpy (copy + macro_nest + 1, input_line_pointer
- 1, len);
+ copy[macro_nest + 1 + len] = '\0';
- /* Install the line with the listing facility. */
- listing_newline (copy);
+ /* Install the line with the listing facility.
*/
+ listing_newline (copy);
+ }
}
else
listing_newline (NULL);
@@ -795,9 +832,17 @@ read_a_source_file (char *name)
/* Print the error msg now, while we still can.
*/
if (pop == NULL)
{
- as_bad (_("unknown pseudo-op: `%s'"), s);
+ char *end = input_line_pointer;
+
*input_line_pointer = c;
s_ignore (0);
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ if (! macro_defined || ! try_macro (c, s))
+ {
+ *end = '\0';
+ as_bad (_("unknown pseudo-op: `%s'"), s);
+ }
continue;
}
@@ -853,28 +898,8 @@ read_a_source_file (char *name)
generate_lineno_debug ();
- if (macro_defined)
- {
- sb out;
- const char *err;
- macro_entry *macro;
-
- if (check_macro (s, &out, &err, ¯o))
- {
- if (err != NULL)
- as_bad ("%s", err);
- *input_line_pointer++ = c;
- input_scrub_include_sb (&out,
-
input_line_pointer, 1);
- sb_kill (&out);
- buffer_limit =
- input_scrub_next_buffer
(&input_line_pointer);
-#ifdef md_macro_info
- md_macro_info (macro);
-#endif
- continue;
- }
- }
+ if (macro_defined && try_macro (c, s))
+ continue;
if (mri_pending_align)
{
@@ -2299,7 +2324,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
{
if (line_label != NULL)
{
- S_SET_SEGMENT (line_label, undefined_section);
+ S_SET_SEGMENT (line_label, absolute_section);
S_SET_VALUE (line_label, 0);
symbol_set_frag (line_label, &zero_address_frag);
}
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/dot.l 1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/dot.l 2005-02-04
10:54:39.000000000 +0100
@@ -0,0 +1,22 @@
+.*: Assembler messages:
+.*:[1-9][0-9]*: Warning: attempt to redefine pseudo-op `.macro'
ignored
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.xyz'
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.y.z'
+(.* )?GAS .*
+#...
+[ ]*[1-9][0-9]*[ ]+m 4, 2
+[ ]*[1-9][0-9]*[ ]+> \.data
+[ ]*[1-9][0-9]*[ ]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
+[ ]*[1-9][0-9]*[ ]+>> \.align 4
+[ ]*[1-9][0-9]*[ ]+\?+[ ]+0606[ ]+>> \.byte 4\+2,4\+2
+[ ]*[1-9][0-9]*[ ]+\?+[ ]+0000[ ]+> \.skip 2
+[ ]*[1-9][0-9]*[ ]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
+[ ]*[1-9][0-9]*[ ]+>> \.align 8
+[ ]*[1-9][0-9]*[ ]+\?+[ ]+0202[ ]+>> \.byte 4-2,4-2
+[ ]*[1-9][0-9]*[ ]+\?+[ ]+0000 ?0000[ ]+> \.skip 4\*2
+[ ]*[1-9][0-9]*[ ]+0000 ?0000[ ]*
+[ ]*[1-9][0-9]*[ ]+> label9:label8:label7:label6:
+[ ]*[1-9][0-9]*[ ]+
+[ ]*[1-9][0-9]*[ ]+\.purgem \.xyz, x\.y\.z
+[ ]*[1-9][0-9]*[ ]+\.xyz 0
+[ ]*[1-9][0-9]*[ ]+x\.y\.z 0
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/dot.s 1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/dot.s 2005-02-08
09:57:12.000000000 +0100
@@ -0,0 +1,28 @@
+.altmacro
+
+.macro x.y.z val
+ .align 4
+ .byte val, val
+.endm
+
+.macro .xyz val
+ .align 8
+ .byte val, val
+.endm
+
+.macro .macro
+.endm
+
+label1:label2 : label3 :label4: m: .macro arg.1, arg.2
+ .data
+labelA:labelB : labelC :labelD: x.y.z arg.1+arg.2
+ .skip arg.2
+labelZ:labelY : labelX :labelW: .xyz arg.1-arg.2
+ .skip arg.1*arg.2
+label9:label8 : label7 :label6: .endm
+
+m 4, 2
+
+.purgem .xyz, x.y.z
+.xyz 0
+x.y.z 0
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/macros.exp 2005-01-31
15:27:07.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/macros.exp 2005-02-04
16:44:31.000000000 +0100
@@ -63,5 +63,14 @@ run_dump_test app3
run_dump_test app4
run_list_test badarg ""
+case $target_triplet in {
+ { *c54x*-*-* } { }
+ { *c4x*-*-* } { }
+ { h8500-*-* } { }
+ { m68*-*-* } { }
+ { m88*-*-* } { }
+ { mmix-* } { }
+ default { run_list_test dot "-alm" }
+}
run_list_test end ""
run_list_test redef ""
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/mmix/relax2.s 2003-10-18
18:00:21.000000000 +0200
+++ 2005-02-01/gas/testsuite/gas/mmix/relax2.s 2005-02-08
09:38:12.000000000 +0100
@@ -1,35 +1,37 @@
# PUSHJ stub border-cases: two with either or both stubs unreachable,
# local symbols, ditto non-local labels, similar with three PUSHJs.
+.altmacro
+
Main SWYM
.irp x,0,1,2,3,4,5,6,7,8,9,10,11,12
- .section .text.a\x,"ax"
-aa\x: .space 4,0
-a\x: .space 65536*4,0
- PUSHJ $33,aa\x
- PUSHJ $22,a\x
- .space 65535*4-4*\x
-
- .section .text.b\x,"ax"
-bbb\x: .space 4,0
-bb\x: .space 4,0
-b\x: .space 65535*4
- PUSHJ $12,bbb\x
- PUSHJ $13,bb\x
- PUSHJ $14,b\x
- .space 65535*4-4*\x
-
- .section .text.c\x,"ax"
-c\x: PUSHJ $100,ca\x
- PUSHJ $101,cb\x
- .space 65535*4-4*\x
-
- .section .text.d\x,"ax"
-d\x: PUSHJ $99,da\x
- PUSHJ $98,db\x
- PUSHJ $97,dc\x
- .space 65535*4-4*\x
+ .section .text.a&x,"ax"
+aa&x&: .space 4,0
+a&x&: .space 65536*4,0
+ PUSHJ $33,aa&x
+ PUSHJ $22,a&x
+ .space 65535*4-4*x
+
+ .section .text.b&x,"ax"
+bbb&x&: .space 4,0
+bb&x&: .space 4,0
+b&x&: .space 65535*4
+ PUSHJ $12,bbb&x
+ PUSHJ $13,bb&x
+ PUSHJ $14,b&x
+ .space 65535*4-4*x
+
+ .section .text.c&x,"ax"
+c&x&: PUSHJ $100,ca&x
+ PUSHJ $101,cb&x
+ .space 65535*4-4*x
+
+ .section .text.d&x,"ax"
+d&x&: PUSHJ $99,da&x
+ PUSHJ $98,db&x
+ PUSHJ $97,dc&x
+ .space 65535*4-4*x
.endr
[-- Attachment #2: binutils-mainline-macro-identifiers.patch --]
[-- Type: text/plain, Size: 14088 bytes --]
This is a resubmission of the patch to address the inconsistent acceptance
of identifiers between the macro handling code and the rest of the assembler,
including the unability to use a macro the name of which starts with a dot.
It now also includes a fix for the previously failing mmix testcase.
Built and tested natively on ia64-unknown-linux-gnu and as cross tools
for a large number of targets.
Jan
gas/
2005-02-08 Jan Beulich <jbeulich@novell.com>
* macro.c (get_token): Use is_name_beginner/is_part_of_name/
is_name_ender.
(check_macro): Likewise.
(buffer_and_nest): Likewise. Permit multiple labels. Don't discard
labels together with the closing pseudo-op.
(macro_expand_body): Adjust comment. Range-check input before use.
Adjust mis-spelled diagnostic. Use is_name_beginner.
* read.c (try_macro): New.
(read_a_source_file): New static variable last_eol. Don't list
macro expansion lines more than once. Call try_macro.
(s_macro): Set section of line_label to absolute instead of undefined.
gas/testsuite/
2005-02-08 Jan Beulich <jbeulich@novell.com>
* gas/macros/dot.[ls]: New.
* gas/macros/macros.exp: Run new test.
* gas/mmix/relax2.s: Use .altmacro and & to separate macro parameter
references.
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/macro.c 2005-01-31 15:27:07.000000000 +0100
+++ 2005-02-01/gas/macro.c 2005-02-03 15:12:04.000000000 +0100
@@ -187,21 +187,37 @@ buffer_and_nest (const char *from, const
the first column, since we can't tell what's a label and
whats a pseudoop. */
- /* Skip leading whitespace. */
- while (i < ptr->len && ISWHITE (ptr->ptr[i]))
- i++;
-
- /* Skip over a label. */
- while (i < ptr->len
- && (ISALNUM (ptr->ptr[i])
- || ptr->ptr[i] == '_'
- || ptr->ptr[i] == '$'))
- i++;
-
- /* And a colon. */
- if (i < ptr->len
- && ptr->ptr[i] == ':')
- i++;
+ if (! LABELS_WITHOUT_COLONS)
+ {
+ /* Skip leading whitespace. */
+ while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+ i++;
+ }
+
+ for (;;)
+ {
+ /* Skip over a label, if any. */
+ if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+ break;
+ i++;
+ while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+ i++;
+ if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+ i++;
+ if (LABELS_WITHOUT_COLONS)
+ break;
+ /* Skip whitespace. */
+ while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+ i++;
+ /* Check for the colon. */
+ if (i >= ptr->len || ptr->ptr[i] != ':')
+ {
+ i = line_start;
+ break;
+ }
+ i++;
+ line_start = i;
+ }
}
/* Skip trailing whitespace. */
@@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const
? strncasecmp (ptr->ptr + i, from, from_len) == 0
: from_len > 0)
&& (ptr->len == (i + from_len)
- || ! ISALNUM (ptr->ptr[i + from_len])))
+ || ! (is_part_of_name (ptr->ptr[i + from_len])
+ || is_name_ender (ptr->ptr[i + from_len]))))
depth++;
if (strncasecmp (ptr->ptr + i, to, to_len) == 0
&& (ptr->len == (i + to_len)
- || ! ISALNUM (ptr->ptr[i + to_len])))
+ || ! (is_part_of_name (ptr->ptr[i + to_len])
+ || is_name_ender (ptr->ptr[i + to_len]))))
{
depth--;
if (depth == 0)
@@ -258,15 +276,16 @@ static int
get_token (int idx, sb *in, sb *name)
{
if (idx < in->len
- && (ISALPHA (in->ptr[idx])
- || in->ptr[idx] == '_'
- || in->ptr[idx] == '$'))
+ && is_name_beginner (in->ptr[idx]))
{
sb_add_char (name, in->ptr[idx++]);
while (idx < in->len
- && (ISALNUM (in->ptr[idx])
- || in->ptr[idx] == '_'
- || in->ptr[idx] == '$'))
+ && is_part_of_name (in->ptr[idx]))
+ {
+ sb_add_char (name, in->ptr[idx++]);
+ }
+ if (idx < in->len
+ && is_name_ender (in->ptr[idx]))
{
sb_add_char (name, in->ptr[idx++]);
}
@@ -692,13 +711,14 @@ macro_expand_body (sb *in, sb *out, form
else
{
/* FIXME: Why do we do this? */
+ /* At least in alternate mode this seems correct. */
src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
}
}
else if (in->ptr[src] == '\\')
{
src++;
- if (in->ptr[src] == '(')
+ if (src < in->len && in->ptr[src] == '(')
{
/* Sub in till the next ')' literally. */
src++;
@@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form
if (in->ptr[src] == ')')
src++;
else
- return _("missplaced )");
+ return _("misplaced `)'");
}
- else if (in->ptr[src] == '@')
+ else if (src < in->len && in->ptr[src] == '@')
{
/* Sub in the macro invocation number. */
@@ -720,7 +740,7 @@ macro_expand_body (sb *in, sb *out, form
sprintf (buffer, "%d", macro_number);
sb_add_string (out, buffer);
}
- else if (in->ptr[src] == '&')
+ else if (src < in->len && in->ptr[src] == '&')
{
/* This is a preprocessor variable name, we don't do them
here. */
@@ -728,7 +748,7 @@ macro_expand_body (sb *in, sb *out, form
sb_add_char (out, '&');
src++;
}
- else if (macro_mri && ISALNUM (in->ptr[src]))
+ else if (macro_mri && src < in->len && ISALNUM (in->ptr[src]))
{
int ind;
formal_entry *f;
@@ -759,9 +779,7 @@ macro_expand_body (sb *in, sb *out, form
}
}
else if ((macro_alternate || macro_mri)
- && (ISALPHA (in->ptr[src])
- || in->ptr[src] == '_'
- || in->ptr[src] == '$')
+ && is_name_beginner (in->ptr[src])
&& (! inquote
|| ! macro_strip_at
|| (src > 0 && in->ptr[src - 1] == '@')))
@@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan
macro_entry *macro;
sb line_sb;
- if (! ISALPHA (*line)
- && *line != '_'
- && *line != '$'
+ if (! is_name_beginner (*line)
&& (! macro_mri || *line != '.'))
return 0;
s = line + 1;
- while (ISALNUM (*s)
- || *s == '_'
- || *s == '$')
+ while (is_part_of_name (*s))
+ ++s;
+ if (is_name_ender (*s))
++s;
copy = (char *) alloca (s - line + 1);
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/read.c 2005-01-26 08:33:13.000000000 +0100
+++ 2005-02-01/gas/read.c 2005-02-03 15:12:04.000000000 +0100
@@ -499,6 +499,32 @@ scrub_from_string (char *buf, int buflen
return copy;
}
+/* Helper function of read_a_source_file, which tries to expand a macro. */
+static int
+try_macro (char term, const char *line)
+{
+ sb out;
+ const char *err;
+ macro_entry *macro;
+
+ if (check_macro (line, &out, &err, ¯o))
+ {
+ if (err != NULL)
+ as_bad ("%s", err);
+ *input_line_pointer++ = term;
+ input_scrub_include_sb (&out,
+ input_line_pointer, 1);
+ sb_kill (&out);
+ buffer_limit =
+ input_scrub_next_buffer (&input_line_pointer);
+#ifdef md_macro_info
+ md_macro_info (macro);
+#endif
+ return 1;
+ }
+ return 0;
+}
+
/* We read the file, putting things into a web that represents what we
have been reading. */
void
@@ -526,6 +552,13 @@ read_a_source_file (char *name)
while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
{ /* We have another line to parse. */
+#ifndef NO_LISTING
+ /* In order to avoid listing macro expansion lines with labels
+ multiple times, keep track of which line was last issued. */
+ static char *last_eol;
+
+ last_eol = NULL;
+#endif
know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */
while (input_line_pointer < buffer_limit)
@@ -645,17 +678,21 @@ read_a_source_file (char *name)
if (is_end_of_line[(unsigned char) *s])
break;
- /* Copy it for safe keeping. Also give an indication of
- how much macro nesting is involved at this point. */
- len = s - (input_line_pointer - 1);
- copy = (char *) xmalloc (len + macro_nest + 2);
- memset (copy, '>', macro_nest);
- copy[macro_nest] = ' ';
- memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
- copy[macro_nest + 1 + len] = '\0';
+ if (s != last_eol)
+ {
+ last_eol = s;
+ /* Copy it for safe keeping. Also give an indication of
+ how much macro nesting is involved at this point. */
+ len = s - (input_line_pointer - 1);
+ copy = (char *) xmalloc (len + macro_nest + 2);
+ memset (copy, '>', macro_nest);
+ copy[macro_nest] = ' ';
+ memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
+ copy[macro_nest + 1 + len] = '\0';
- /* Install the line with the listing facility. */
- listing_newline (copy);
+ /* Install the line with the listing facility. */
+ listing_newline (copy);
+ }
}
else
listing_newline (NULL);
@@ -795,9 +832,17 @@ read_a_source_file (char *name)
/* Print the error msg now, while we still can. */
if (pop == NULL)
{
- as_bad (_("unknown pseudo-op: `%s'"), s);
+ char *end = input_line_pointer;
+
*input_line_pointer = c;
s_ignore (0);
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ if (! macro_defined || ! try_macro (c, s))
+ {
+ *end = '\0';
+ as_bad (_("unknown pseudo-op: `%s'"), s);
+ }
continue;
}
@@ -853,28 +898,8 @@ read_a_source_file (char *name)
generate_lineno_debug ();
- if (macro_defined)
- {
- sb out;
- const char *err;
- macro_entry *macro;
-
- if (check_macro (s, &out, &err, ¯o))
- {
- if (err != NULL)
- as_bad ("%s", err);
- *input_line_pointer++ = c;
- input_scrub_include_sb (&out,
- input_line_pointer, 1);
- sb_kill (&out);
- buffer_limit =
- input_scrub_next_buffer (&input_line_pointer);
-#ifdef md_macro_info
- md_macro_info (macro);
-#endif
- continue;
- }
- }
+ if (macro_defined && try_macro (c, s))
+ continue;
if (mri_pending_align)
{
@@ -2299,7 +2324,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
{
if (line_label != NULL)
{
- S_SET_SEGMENT (line_label, undefined_section);
+ S_SET_SEGMENT (line_label, absolute_section);
S_SET_VALUE (line_label, 0);
symbol_set_frag (line_label, &zero_address_frag);
}
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/dot.l 1970-01-01 01:00:00.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/dot.l 2005-02-04 10:54:39.000000000 +0100
@@ -0,0 +1,22 @@
+.*: Assembler messages:
+.*:[1-9][0-9]*: Warning: attempt to redefine pseudo-op `.macro' ignored
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.xyz'
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.y.z'
+(.* )?GAS .*
+#...
+[ ]*[1-9][0-9]*[ ]+m 4, 2
+[ ]*[1-9][0-9]*[ ]+> \.data
+[ ]*[1-9][0-9]*[ ]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
+[ ]*[1-9][0-9]*[ ]+>> \.align 4
+[ ]*[1-9][0-9]*[ ]+\?+[ ]+0606[ ]+>> \.byte 4\+2,4\+2
+[ ]*[1-9][0-9]*[ ]+\?+[ ]+0000[ ]+> \.skip 2
+[ ]*[1-9][0-9]*[ ]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
+[ ]*[1-9][0-9]*[ ]+>> \.align 8
+[ ]*[1-9][0-9]*[ ]+\?+[ ]+0202[ ]+>> \.byte 4-2,4-2
+[ ]*[1-9][0-9]*[ ]+\?+[ ]+0000 ?0000[ ]+> \.skip 4\*2
+[ ]*[1-9][0-9]*[ ]+0000 ?0000[ ]*
+[ ]*[1-9][0-9]*[ ]+> label9:label8:label7:label6:
+[ ]*[1-9][0-9]*[ ]+
+[ ]*[1-9][0-9]*[ ]+\.purgem \.xyz, x\.y\.z
+[ ]*[1-9][0-9]*[ ]+\.xyz 0
+[ ]*[1-9][0-9]*[ ]+x\.y\.z 0
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/dot.s 1970-01-01 01:00:00.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/dot.s 2005-02-08 09:57:12.000000000 +0100
@@ -0,0 +1,28 @@
+.altmacro
+
+.macro x.y.z val
+ .align 4
+ .byte val, val
+.endm
+
+.macro .xyz val
+ .align 8
+ .byte val, val
+.endm
+
+.macro .macro
+.endm
+
+label1:label2 : label3 :label4: m: .macro arg.1, arg.2
+ .data
+labelA:labelB : labelC :labelD: x.y.z arg.1+arg.2
+ .skip arg.2
+labelZ:labelY : labelX :labelW: .xyz arg.1-arg.2
+ .skip arg.1*arg.2
+label9:label8 : label7 :label6: .endm
+
+m 4, 2
+
+.purgem .xyz, x.y.z
+.xyz 0
+x.y.z 0
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/macros.exp 2005-01-31 15:27:07.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/macros.exp 2005-02-04 16:44:31.000000000 +0100
@@ -63,5 +63,14 @@ run_dump_test app3
run_dump_test app4
run_list_test badarg ""
+case $target_triplet in {
+ { *c54x*-*-* } { }
+ { *c4x*-*-* } { }
+ { h8500-*-* } { }
+ { m68*-*-* } { }
+ { m88*-*-* } { }
+ { mmix-* } { }
+ default { run_list_test dot "-alm" }
+}
run_list_test end ""
run_list_test redef ""
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/mmix/relax2.s 2003-10-18 18:00:21.000000000 +0200
+++ 2005-02-01/gas/testsuite/gas/mmix/relax2.s 2005-02-08 09:38:12.000000000 +0100
@@ -1,35 +1,37 @@
# PUSHJ stub border-cases: two with either or both stubs unreachable,
# local symbols, ditto non-local labels, similar with three PUSHJs.
+.altmacro
+
Main SWYM
.irp x,0,1,2,3,4,5,6,7,8,9,10,11,12
- .section .text.a\x,"ax"
-aa\x: .space 4,0
-a\x: .space 65536*4,0
- PUSHJ $33,aa\x
- PUSHJ $22,a\x
- .space 65535*4-4*\x
-
- .section .text.b\x,"ax"
-bbb\x: .space 4,0
-bb\x: .space 4,0
-b\x: .space 65535*4
- PUSHJ $12,bbb\x
- PUSHJ $13,bb\x
- PUSHJ $14,b\x
- .space 65535*4-4*\x
-
- .section .text.c\x,"ax"
-c\x: PUSHJ $100,ca\x
- PUSHJ $101,cb\x
- .space 65535*4-4*\x
-
- .section .text.d\x,"ax"
-d\x: PUSHJ $99,da\x
- PUSHJ $98,db\x
- PUSHJ $97,dc\x
- .space 65535*4-4*\x
+ .section .text.a&x,"ax"
+aa&x&: .space 4,0
+a&x&: .space 65536*4,0
+ PUSHJ $33,aa&x
+ PUSHJ $22,a&x
+ .space 65535*4-4*x
+
+ .section .text.b&x,"ax"
+bbb&x&: .space 4,0
+bb&x&: .space 4,0
+b&x&: .space 65535*4
+ PUSHJ $12,bbb&x
+ PUSHJ $13,bb&x
+ PUSHJ $14,b&x
+ .space 65535*4-4*x
+
+ .section .text.c&x,"ax"
+c&x&: PUSHJ $100,ca&x
+ PUSHJ $101,cb&x
+ .space 65535*4-4*x
+
+ .section .text.d&x,"ax"
+d&x&: PUSHJ $99,da&x
+ PUSHJ $98,db&x
+ PUSHJ $97,dc&x
+ .space 65535*4-4*x
.endr
next reply other threads:[~2005-02-08 15:51 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-02-08 17:52 Jan Beulich [this message]
2005-02-08 20:22 ` Hans-Peter Nilsson
2005-02-08 20:55 Jan Beulich
2005-02-08 23:05 ` Hans-Peter Nilsson
2005-02-08 23:58 ` Hans-Peter Nilsson
2005-02-09 10:28 Jan Beulich
2005-02-09 11:32 Jan Beulich
[not found] <s209c8b9.060@emea1-mh.id2.novell.com>
2005-02-09 11:42 ` Hans-Peter Nilsson
2005-02-09 14:06 Jan Beulich
[not found] <s209c6d8.000@emea1-mh.id2.novell.com>
2005-02-09 14:11 ` Hans-Peter Nilsson
[not found] <s209d602.092@emea1-mh.id2.novell.com>
2005-02-09 14:14 ` Hans-Peter Nilsson
2005-02-09 14:32 Jan Beulich
2005-02-09 15:03 ` Hans-Peter Nilsson
2005-02-28 13:37 Jan Beulich
2005-02-28 17:14 ` Hans-Peter Nilsson
[not found] ` <20050228222944.GF5299@bubble.modra.org>
2005-03-01 6:27 ` Hans-Peter Nilsson
2005-03-01 6:45 ` Hans-Peter Nilsson
2005-03-01 7:07 ` Alan Modra
2005-02-28 19:22 Jan Beulich
2005-02-28 23:47 ` Hans-Peter Nilsson
2005-03-02 8:28 Jan Beulich
2005-03-02 14:42 ` Ian Lance Taylor
2005-03-02 15:04 Jan Beulich
[not found] <s225d5fa.098@emea1-mh.id2.novell.com>
2005-03-02 15:20 ` Ian Lance Taylor
2005-03-29 16:26 Jan Beulich
2005-04-01 14:30 ` Nick Clifton
2005-04-11 12:48 Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s208dfe7.067@emea1-mh.id2.novell.com \
--to=jbeulich@novell.com \
--cc=binutils@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).