This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]