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


On Thu, 2003-03-06 at 06:22, Nick Clifton wrote:
> It seems to me that your proposed patch would disallow multiple
> instructions on a single line inside macro blocks (for the IA64 at least).

This is correct.  For a testcase like this:
        .macro foo ; add r0 = r1, r2 ; .endm
        foo
I get with the patch
tmp3.s: Assembler messages:
tmp3.s:1: Error: unexpected end of file in macro definition

get_line_sb must exit when an end-of-line character is seen so that
buffer_and_nest can scan for the .endm.  The patch from Tim Connors
breaks this.

> 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:

As Tim pointed out, this doesn't work, because the first ; gets treated
correctly, but the second one gets dropped.  We would need additional
changes to make this work.

get_line_sb inserts characters until it sees an end-of-line character,
and then returns to buffer_and_nest.  buffer_and_nest then inserts a
newline character.  We can get the right behavior for IA-64 if
buffer_and_nest inserts the original end-of-line character.  Also,
get_line_sb has to stop skipping multiple end-of-line characters.
That gives me the first following patch.  The fact that 0 is an end of
line character makes this a little ugly, but otherwise it seems OK.

If we want something like Tim's patch, then we need to recognize the
stop bit only in the new hook as Nick suggested, and then we also need
the loop in get_line_sb to copy two characters to the sb instead of
one.  I modified the hook to return the extra number of characters to
copy.  This gives me the second patch.  I didn't flesh this one out
further since the first patch seems like a better idea.

Jim

First patch:

2003-03-09  James E Wilson  <wilson at tuliptree dot org>

	* macro.c (buffer_and_nest): Store more to sb instead of '\n'.
	* read.c (get_line_sb): Return end of line character or '\n' if
	it is zero or non-existent.

Index: macro.c
===================================================================
RCS file: /cvs/src/src/gas/macro.c,v
retrieving revision 1.20
diff -p -r1.20 macro.c
*** macro.c	3 Jan 2003 21:47:20 -0000	1.20
--- macro.c	9 Mar 2003 21:58:50 -0000
*************** buffer_and_nest (from, to, ptr, get_line
*** 222,229 ****
  	    }
  	}
  
!       /* Add a CR to the end and keep running.  */
!       sb_add_char (ptr, '\n');
        line_start = ptr->len;
        more = get_line (ptr);
      }
--- 222,229 ----
  	    }
  	}
  
!       /* Add the original end-of-line char to the end and keep running.  */
!       sb_add_char (ptr, more);
        line_start = ptr->len;
        more = get_line (ptr);
      }
Index: read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.58
diff -p -r1.58 read.c
*** read.c	11 Jan 2003 06:24:12 -0000	1.58
--- read.c	9 Mar 2003 21:58:54 -0000
*************** get_line_sb (line)
*** 2285,2299 ****
        sb_add_char (line, *input_line_pointer++);
      }
  
!   while (input_line_pointer < buffer_limit
  	 && is_end_of_line[(unsigned char) *input_line_pointer])
      {
!       if (input_line_pointer[-1] == '\n')
! 	bump_line_counters ();
!       ++input_line_pointer;
      }
! 
!   return 1;
  }
  
  /* Define a macro.  This is an interface to macro.c.  */
--- 2285,2305 ----
        sb_add_char (line, *input_line_pointer++);
      }
  
!   /* Don't skip multiple end-of-line characters, because that breaks support
!      for the IA-64 stop bit (;;) which looks like two consecutive end-of-line
!      characters but isn't.  Return the end-of-line character so that the
!      caller can insert it if necessary.  */
!   if (input_line_pointer < buffer_limit
  	 && is_end_of_line[(unsigned char) *input_line_pointer])
      {
!       char c = *input_line_pointer++;
!       if (c != 0)
! 	return c;
!       else
! 	return '\n';
      }
!   else
!     return '\n';
  }
  
  /* Define a macro.  This is an interface to macro.c.  */

Second patch, based on Tim's patch:

Index: read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.58
diff -p -r1.58 read.c
*** read.c	11 Jan 2003 06:24:12 -0000	1.58
--- read.c	9 Mar 2003 22:38:18 -0000
*************** get_line_sb (line)
*** 2242,2247 ****
--- 2242,2248 ----
       sb *line;
  {
    char quote1, quote2, inquote;
+   int count;
  
    if (input_line_pointer[-1] == '\n')
      bump_line_counters ();
*************** get_line_sb (line)
*** 2269,2276 ****
  
    inquote = '\0';
  
    while (!is_end_of_line[(unsigned char) *input_line_pointer]
! 	 || (inquote != '\0' && *input_line_pointer != '\n'))
      {
        if (inquote == *input_line_pointer)
  	inquote = '\0';
--- 2270,2284 ----
  
    inquote = '\0';
  
+   /* This returns the number of extra characters to copy to the sb.  */
+ #ifndef md_keep_end_line_char_sb
+ #define md_keep_end_line_char_sb(c) 0
+ #endif
+ 
+   count = 0;
    while (!is_end_of_line[(unsigned char) *input_line_pointer]
! 	 || (inquote != '\0' && *input_line_pointer != '\n')
! 	 || (count = md_keep_end_line_char_sb (input_line_pointer)))
      {
        if (inquote == *input_line_pointer)
  	inquote = '\0';
*************** get_line_sb (line)
*** 2280,2285 ****
--- 2288,2299 ----
  	    inquote = quote1;
  	  else if (*input_line_pointer == quote2)
  	    inquote = quote2;
+ 	}
+ 
+       while (count)
+ 	{
+ 	  sb_add_char (line, *input_line_pointer++);
+ 	  count--;
  	}
  
        sb_add_char (line, *input_line_pointer++);
Index: config/tc-ia64.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ia64.c,v
retrieving revision 1.80
diff -p -r1.80 tc-ia64.c
*** config/tc-ia64.c	28 Jan 2003 03:24:12 -0000	1.80
--- config/tc-ia64.c	9 Mar 2003 22:36:10 -0000
*************** ia64_start_line ()
*** 6877,6882 ****
--- 6877,6893 ----
      }
  }
  
+ int
+ ia64_keep_end_line_char_sb (ptr)
+      char *ptr;
+ {
+   if (ptr[0] == ';' && ptr[1] == ';')
+     {
+       return 1;
+     }
+   return 0;
+ }
+ 
  /* This is a hook for ia64_frob_label, so that it can distinguish tags from
     labels.  */
  static int defining_tag = 0;
Index: config/tc-ia64.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ia64.h,v
retrieving revision 1.21
diff -p -r1.21 tc-ia64.h
*** config/tc-ia64.h	5 Sep 2002 00:01:18 -0000	1.21
--- config/tc-ia64.h	9 Mar 2003 22:36:10 -0000
*************** struct ia64_fix
*** 68,73 ****
--- 68,74 ----
  extern void ia64_do_align PARAMS((int n));
  extern void ia64_end_of_source PARAMS((void));
  extern void ia64_start_line PARAMS((void));
+ extern int ia64_keep_end_line_char_sb PARAMS((char *ptr));
  extern int ia64_unrecognized_line PARAMS((int ch));
  extern void ia64_frob_label PARAMS((struct symbol *sym));
  extern void ia64_flush_pending_output PARAMS((void));
*************** extern void ia64_after_parse_args PARAMS
*** 92,97 ****
--- 93,99 ----
  
  #define md_end()       			ia64_end_of_source ()
  #define md_start_line_hook()		ia64_start_line ()
+ #define md_keep_end_line_char_sb(c)    ia64_keep_end_line_char_sb (c)
  #define tc_unrecognized_line(ch)	ia64_unrecognized_line (ch)
  #define tc_frob_label(s)		ia64_frob_label (s)
  #define md_flush_pending_output()	ia64_flush_pending_output ()


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