This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: .macro bug in gas for IA64
- From: Tim Connors <connors at hpltsc dot hpl dot hp dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 7 Mar 2003 09:53:55 -0800
- Subject: Re: .macro bug in gas for IA64
Nick,
Thanks for looking at my submission to binutils at sources dot redhat dot com dot
> It seems to me that your proposed patch would disallow multiple
> instructions on a single line inside macro blocks (for the IA64 at least).
Actually, it doesn't do that. It simply makes sure that ALL ';'
characters in a macro definition find there way into the stored macro
body. That includes single runs of ';', as well as double runs ";;",
and even longer runs ";;;;;;;". Then, after macro expansion, the
normal parsing routines determine what's a separator and what's a stop
bit. In fact part of the goal, was to make sure that this determination
only occurs in one place.
> Instead would it not be easier to choose a different character to be
> the line separator character ? Then you would not have to add any new
> code, and instead you could just change the initialisation value of
> line_separator_chars[] in tc-ia64.c.
I thought of that. But I wanted to provide a fix that most people
would consider acceptable. Changing the syntax of the input seemed
like it would be a harder sell. Other non-gas assemblers for IA64 use
';' as a separator as well as ";;" for stop bit.
> If you cannot change the line separator, then at the very least you
> ought to change your new macro so that it takes the input line pointer
> and then it can scan ahead. ie something like:
I don't see how scanning ahead helps any (perhaps scanning "nearby"
might, more below). In particular,
> while (!is_end_of_line[(unsigned char) *input_line_pointer]
> #ifdef md_end_of_line_char
> || ! md_end_of_line_char (input_line_pointer)
> #endif
> || (inquote != '\0' && *input_line_pointer != '\n'))
> {
> ...
> sb_add_char (line, *input_line_pointer++);
> }
>
> ...
>
> int
> ia64_end_of_line_char (char * ilp)
> {
> /* ';;' is the stop bit and should not be treated as a line separator. */
> return (ilp[0] == ';' && ilp[1] != ';');
> }
Note that in your suggested code, the first ';' in a double run would
get true for md_end_of_line_char() and this first ';' would be
inserted into the stored macro body :-) But the second ';' in a double
run would give a false for the test and the second ';' would not make
it into the stored macro body. This has the affect of converting a
stop bit into a line separator :-( although a triple run would be
converted to a double. To fix this one might replace
> return (ilp[0] == ';' && ilp[1] != ';');
with
return ( (ilp[0] == ';' && ilp[1] != ';') ||
(ilp[-1] == ';' && ilp[0] != ';') );
ie, scan nearby. This test would have the affect of preserving all
double or greater runs while removing single runs :-). The downside
is that it puts the knowledge of what token is a stop bit in more
places in the tc-ia64 code.
Even though I've tried to explain how I came up with my fix, I have no
preference as to what the fix is. For now I've patched my assembler.
But unitl some fix ends up in the official code, I can't share my
sources with anyone.
Thanks for taking the time to look at this,
-Tim