[PATCH] Re: .macro behavior
Jan Beulich
JBeulich@novell.com
Mon Feb 28 13:37:00 GMT 2005
This is a resubmission of the patch at
http://sourceware.org/ml/binutils/2005-02/msg00120.html 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.
Over the previously submitted revisions, this has just cosmetic
changes
(NEWS entry, change to MMIX testcase removed again based on that
target's
maintainer's request) and thus I did not re-build or re-run the tests.
I'm
not sure why there wasn't any comment of non-cosmetic nature so far; I
had
hoped to at least get pointers to and reasons for what needs to change
to
make this acceptable.
Originally built and tested natively on ia64-unknown-linux-gnu and as
cross
tools for a large number of targets.
Jan
gas/
2005-02-28 Jan Beulich <jbeulich@novell.com>
* NEWS: Mention these changes and their effects.
* 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-28 Jan Beulich <jbeulich@novell.com>
* gas/macros/dot.[ls]: New.
* gas/macros/macros.exp: Run new test.
---
/home/jbeulich/src/binutils/mainline/2005-02-28/gas/NEWS 2005-02-28
08:27:12.000000000 +0100
+++ 2005-02-28/gas/NEWS 2005-02-28 09:52:47.000000000 +0100
@@ -1,5 +1,11 @@
-*- text -*-
+* Macro names and macro parameter names can now be any identifier that
would
+ also be legal as a symbol elsewhere. For macro parameter names, this
is
+ known to cause problems in certain sources when the respective
target uses
+ characters inconsistently (like MMIX's use of ':'), and thus macro
+ parameter references are no longer recognized as such.
+
* New command line option -mhint.b=[ok|warning|error] for IA64
targets.
* New command line option -munwind-check=[warning|error] for IA64
---
/home/jbeulich/src/binutils/mainline/2005-02-28/gas/macro.c 2005-01-31
15:27:07.000000000 +0100
+++ 2005-02-28/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-28/gas/read.c 2005-02-28
08:27:13.000000000 +0100
+++ 2005-02-28/gas/read.c 2005-02-28 09:39:16.502014184 +0100
@@ -520,6 +520,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
@@ -547,6 +573,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)
@@ -666,17 +699,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);
@@ -816,9 +853,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;
}
@@ -874,28 +919,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)
{
@@ -2320,7 +2345,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-28/gas/testsuite/gas/macros/dot.l 1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-28/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-28/gas/testsuite/gas/macros/dot.s 1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-28/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-28/gas/testsuite/gas/macros/macros.exp 2005-01-31
15:27:07.000000000 +0100
+++ 2005-02-28/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 ""
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: binutils-mainline-macro-identifiers.patch
URL: <https://sourceware.org/pipermail/binutils/attachments/20050228/e5bd60e7/attachment.ksh>
More information about the Binutils
mailing list