public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
@ 2002-01-08 15:09 H . J . Lu
  2002-01-08 16:42 ` H . J . Lu
  2002-01-08 18:05 ` Richard Henderson
  0 siblings, 2 replies; 10+ messages in thread
From: H . J . Lu @ 2002-01-08 15:09 UTC (permalink / raw)
  To: binutils

Any ideas?


H.J.
---
----- Forwarded message from Johannes Stezenbach <js@convergence.de> -----

Delivered-To: hjl@lucon.org
Date: Tue, 8 Jan 2002 22:18:23 +0100
From: Johannes Stezenbach <js@convergence.de>
To: "H . J . Lu" <hjl@lucon.org>
Cc: Jun Sun <jsun@mvista.com>
Subject: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi
User-Agent: Mutt/1.3.25i

Hello H. J.,

the assembler of binutils-2.11.92.0.12.3 for MIPS has a bug which
shows up when parsing percent-ops like %hi and %lo with
nested parentheses, e.g.

   lui t0, %hi((0xa0000000 + 0x10001000))

produces parsing errors because of unmatched parens
(sorry, I don't have the exact error message right now).

Code like that is output from the preprocessor for
linux/arch/mips/vr4181/common/int_handler.S in
http://linux-mips.sourceforge.net/, which has

   lui     t3,%hi(VR4181_SYSINT1REG)

where linux/include/asm-mips/vr4181/vr4181.h has

  #ifndef _LANGUAGE_ASSEMBLY
  #define __preg16        (volatile unsigned short*)
  #else
  #define __preg16
  #endif
  #define VR4181_SYSINT1REG       __preg16(KSEG1 + 0x0A000080)    /* Level 1 System interrupt register 1 (R) */


AFAIK this used to work with binutils-2.10.91.0.2.

I attempted to fix this problem (patch attached), but unfortunately
my understanding of gas' expression parser is very limited.
My patch is thus more a workaround-hack than a fix.

I tried hard to figure out how my_getSmallExpression() in
gas/config/tc-mips.c works for nested precent-ops, but
either I failed or the thing is totally broken.

I dont't know all the details of the MIPS assembler syntax,
but wouldn't it be the right way to use expr() (in gas/expr.c) for
parsing, and provide support for percent-ops via the
md_operand() hook?  This should work since is_name_beginner('%')
returns FALSE and LITERAL_PREFIXPERCENT_BIN is #undef'd.


Regards,
Johannes

----- End forwarded message -----

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-08 15:09 [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi] H . J . Lu
@ 2002-01-08 16:42 ` H . J . Lu
  2002-01-08 22:33   ` Eric Christopher
  2002-01-12 17:00   ` Thiemo Seufer
  2002-01-08 18:05 ` Richard Henderson
  1 sibling, 2 replies; 10+ messages in thread
From: H . J . Lu @ 2002-01-08 16:42 UTC (permalink / raw)
  To: binutils; +Cc: seufer

[-- Attachment #1: Type: text/plain, Size: 2080 bytes --]

On Tue, Jan 08, 2002 at 02:10:09PM -0800, H . J . Lu wrote:
> Any ideas?
> 

I am forwarding a patch here.


H.J.
---
> ---
> ----- Forwarded message from Johannes Stezenbach <js@convergence.de> -----
> 
> Delivered-To: hjl@lucon.org
> Date: Tue, 8 Jan 2002 22:18:23 +0100
> From: Johannes Stezenbach <js@convergence.de>
> To: "H . J . Lu" <hjl@lucon.org>
> Cc: Jun Sun <jsun@mvista.com>
> Subject: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi
> User-Agent: Mutt/1.3.25i
> 
> Hello H. J.,
> 
> the assembler of binutils-2.11.92.0.12.3 for MIPS has a bug which
> shows up when parsing percent-ops like %hi and %lo with
> nested parentheses, e.g.
> 
>    lui t0, %hi((0xa0000000 + 0x10001000))
> 
> produces parsing errors because of unmatched parens
> (sorry, I don't have the exact error message right now).
> 
> Code like that is output from the preprocessor for
> linux/arch/mips/vr4181/common/int_handler.S in
> http://linux-mips.sourceforge.net/, which has
> 
>    lui     t3,%hi(VR4181_SYSINT1REG)
> 
> where linux/include/asm-mips/vr4181/vr4181.h has
> 
>   #ifndef _LANGUAGE_ASSEMBLY
>   #define __preg16        (volatile unsigned short*)
>   #else
>   #define __preg16
>   #endif
>   #define VR4181_SYSINT1REG       __preg16(KSEG1 + 0x0A000080)    /* Level 1 System interrupt register 1 (R) */
> 
> 
> AFAIK this used to work with binutils-2.10.91.0.2.
> 
> I attempted to fix this problem (patch attached), but unfortunately
> my understanding of gas' expression parser is very limited.
> My patch is thus more a workaround-hack than a fix.
> 
> I tried hard to figure out how my_getSmallExpression() in
> gas/config/tc-mips.c works for nested precent-ops, but
> either I failed or the thing is totally broken.
> 
> I dont't know all the details of the MIPS assembler syntax,
> but wouldn't it be the right way to use expr() (in gas/expr.c) for
> parsing, and provide support for percent-ops via the
> md_operand() hook?  This should work since is_name_beginner('%')
> returns FALSE and LITERAL_PREFIXPERCENT_BIN is #undef'd.
> 
> 
> Regards,
> Johannes
> 

[-- Attachment #2: gas-mips-hilo.patch --]
[-- Type: text/plain, Size: 722 bytes --]

--- binutils-2.11.92.0.12.3/gas/config/tc-mips.c.orig	Tue Jan  8 11:56:48 2002
+++ binutils-2.11.92.0.12.3/gas/config/tc-mips.c	Tue Jan  8 12:16:14 2002
@@ -9287,7 +9287,20 @@
 	}
 
       /* Some other expression in the braces.  */
-      *len = strcspn (*str, ")") + 1;
+      /* Attempt to find the matching parenthesis. */
+      {
+	int pcnt = 1;
+	char *s;
+
+	*len = 0;
+	for (s = *str; *s && pcnt; s++, (*len)++)
+	  {
+	    if (*s == '(')
+	      pcnt++;
+	    else if (*s == ')')
+	      pcnt--;
+	  }
+      }
     }
   /* Check for percent_op.  */
   else if (*str[0] == '%')
@@ -9373,7 +9386,7 @@
 	}
       else
 	{
-	  expr_end = strchr (str, ')') + 1;
+	  expr_end = str + len;
 	}
       c = oldc;
     }

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-08 15:09 [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi] H . J . Lu
  2002-01-08 16:42 ` H . J . Lu
@ 2002-01-08 18:05 ` Richard Henderson
  2002-01-10  2:11   ` H . J . Lu
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2002-01-08 18:05 UTC (permalink / raw)
  To: H . J . Lu; +Cc: binutils

On Tue, Jan 08, 2002 at 02:10:09PM -0800, H . J . Lu wrote:
>    lui t0, %hi((0xa0000000 + 0x10001000))

Correct solution is for %hi to remove the first parenthesis,
call expr to read the inner expression, then check for the
final close parenthesis.


r~

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-08 16:42 ` H . J . Lu
@ 2002-01-08 22:33   ` Eric Christopher
  2002-01-08 23:04     ` H . J . Lu
  2002-01-12 17:00   ` Thiemo Seufer
  1 sibling, 1 reply; 10+ messages in thread
From: Eric Christopher @ 2002-01-08 22:33 UTC (permalink / raw)
  To: H . J . Lu; +Cc: binutils, seufer

On Tue, 2002-01-08 at 15:13, H . J . Lu wrote:
> On Tue, Jan 08, 2002 at 02:10:09PM -0800, H . J . Lu wrote:
> > Any ideas?
> > 
> 
> I am forwarding a patch here.
>

Can you write a testcase for this as well?

-eric

-- 
I will not use abbrev.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-08 22:33   ` Eric Christopher
@ 2002-01-08 23:04     ` H . J . Lu
  2002-01-09  2:48       ` Eric Christopher
  0 siblings, 1 reply; 10+ messages in thread
From: H . J . Lu @ 2002-01-08 23:04 UTC (permalink / raw)
  To: Eric Christopher; +Cc: binutils, seufer

On Tue, Jan 08, 2002 at 06:14:53PM -0800, Eric Christopher wrote:
> On Tue, 2002-01-08 at 15:13, H . J . Lu wrote:
> > On Tue, Jan 08, 2002 at 02:10:09PM -0800, H . J . Lu wrote:
> > > Any ideas?
> > > 
> > 
> > I am forwarding a patch here.
> >
> 
> Can you write a testcase for this as well?
> 

How about this?


H.J.
---
2002-01-08  H.J. Lu <hjl@gnu.org>

	* gas/mips/elf-rel.s: Test nested ().

Index: gas/mips/elf-rel.s
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/testsuite/gas/mips/elf-rel.s,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 elf-rel.s
--- gas/mips/elf-rel.s	1999/10/09 16:13:45	1.1.1.1
+++ gas/mips/elf-rel.s	2002/01/09 06:29:51
@@ -6,11 +6,11 @@ l2	= l0+49150
 	.set	noat
 	.set	noreorder
 	lui	$at,%hi(l1)
-	lui	$at,%hi(l1+4)
-	lui	$at,%hi(l1+0x10000)
-	lui	$at,%hi(l1+0x10004)
-	lui	$at,%hi(l0-4)
-	lui	$at,%hi(l1+0x8000)
+	lui	$at,%hi((l1+4))
+	lui	$at,%hi(((l1+0x10000)))
+	lui	$at,%hi((((l1+0x10004))))
+	lui	$at,%hi(((((l0-4)))))
+	lui	$at,%hi((((((l1+0x8000))))))
 l1:		
 	addi	$at,$at,%lo(l1)
 	addi	$at,$at,%lo(l1+0x10004)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-08 23:04     ` H . J . Lu
@ 2002-01-09  2:48       ` Eric Christopher
  2002-01-09  3:34         ` H . J . Lu
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Christopher @ 2002-01-09  2:48 UTC (permalink / raw)
  To: H . J . Lu; +Cc: binutils, seufer


> How about this?
> 
> 
Can you fix elf-rel.d as well and just include both variations?

-eric

-- 
I will not use abbrev.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-09  2:48       ` Eric Christopher
@ 2002-01-09  3:34         ` H . J . Lu
  0 siblings, 0 replies; 10+ messages in thread
From: H . J . Lu @ 2002-01-09  3:34 UTC (permalink / raw)
  To: Eric Christopher; +Cc: binutils, seufer

On Tue, Jan 08, 2002 at 10:36:28PM -0800, Eric Christopher wrote:
> 
> > How about this?
> > 
> > 
> Can you fix elf-rel.d as well and just include both variations?
> 
> -eric
> 

Like this?


H.J.
---
2002-01-08  H.J. Lu <hjl@gnu.org>

	* gas/mips/elf-rel.s: New tests for nested ().

	* gas/mips/elf-rel.d: Modified for nested () tests.
	* gas/mips/elfel-rel.d: Likewise.

Index: gas/mips/elf-rel.d
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/testsuite/gas/mips/elf-rel.d,v
retrieving revision 1.1.1.3
diff -d -u -p -r1.1.1.3 elf-rel.d
--- gas/mips/elf-rel.d	2001/08/10 20:44:31	1.1.1.3
+++ gas/mips/elf-rel.d	2002/01/09 07:01:18
@@ -21,16 +21,28 @@ OFFSET [ ]+ TYPE              VALUE 
 0+000002c R_MIPS_LO16       \.text
 0+0000030 R_MIPS_HI16       \.text
 0+0000048 R_MIPS_LO16       \.text
-0+0000034 R_MIPS_HI16       \.text
+0+0000064 R_MIPS_HI16       \.text
 0+000004c R_MIPS_LO16       \.text
-0+0000038 R_MIPS_HI16       \.text
+0+0000068 R_MIPS_HI16       \.text
 0+0000050 R_MIPS_LO16       \.text
-0+000003c R_MIPS_HI16       \.text
+0+000006c R_MIPS_HI16       \.text
 0+0000054 R_MIPS_LO16       \.text
-0+0000044 R_MIPS_HI16       \.text
+0+0000074 R_MIPS_HI16       \.text
 0+0000058 R_MIPS_LO16       \.text
-0+0000040 R_MIPS_HI16       \.text
+0+0000070 R_MIPS_HI16       \.text
 0+000005c R_MIPS_LO16       \.text
+0+0000060 R_MIPS_HI16       \.text
+0+0000078 R_MIPS_LO16       \.text
+0+0000034 R_MIPS_HI16       \.text
+0+000007c R_MIPS_LO16       \.text
+0+0000038 R_MIPS_HI16       \.text
+0+0000080 R_MIPS_LO16       \.text
+0+000003c R_MIPS_HI16       \.text
+0+0000084 R_MIPS_LO16       \.text
+0+0000044 R_MIPS_HI16       \.text
+0+0000088 R_MIPS_LO16       \.text
+0+0000040 R_MIPS_HI16       \.text
+0+000008c R_MIPS_LO16       \.text
 
 
 Contents of section \.text:
@@ -40,9 +52,9 @@ Contents of section \.text:
  0030 3c010001 3c010001 3c010002 3c010002  .*
  0040 3c010001 3c010001 2021bffe 2021c002  .*
  0050 2021bffe 2021c002 20213ffe 2021bffa  .*
- 0060 00000000 00000000 00000000 00000000  ................
- 0070 00000000 00000000 00000000 00000000  ................
- 0080 00000000 00000000 00000000 00000000  ................
+ 0060 3c010001 3c010001 3c010002 3c010002  .*
+ 0070 3c010001 3c010001 2021bffe 2021c002  .*
+ 0080 2021bffe 2021c002 20213ffe 2021bffa  .*
  0090 00000000 00000000 00000000 00000000  ................
  00a0 00000000 00000000 00000000 00000000  ................
  00b0 00000000 00000000 00000000 00000000  ................
Index: gas/mips/elf-rel.s
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/testsuite/gas/mips/elf-rel.s,v
retrieving revision 1.1.1.1
diff -d -u -p -r1.1.1.1 elf-rel.s
--- gas/mips/elf-rel.s	1999/10/09 16:13:45	1.1.1.1
+++ gas/mips/elf-rel.s	2002/01/09 07:01:18
@@ -31,3 +31,16 @@ l1:		
 	addi	$at,$at,%lo(l2+0x10004)
 	addi	$at,$at,%lo(l2+0x8000)
 	addi	$at,$at,%lo(l2-4)
+
+	lui	$at,%hi((l2))
+	lui	$at,%hi(((l2+4)))
+	lui	$at,%hi((((l2+0x10000))))
+	lui	$at,%hi(((((l2+0x10004)))))
+	lui	$at,%hi((((((l2-4))))))
+	lui	$at,%hi(((((((l2+0x8000)))))))
+	addi	$at,$at,%lo((l2))
+	addi	$at,$at,%lo(((l2+4)))
+	addi	$at,$at,%lo((((l2+0x10000))))
+	addi	$at,$at,%lo(((((l2+0x10004)))))
+	addi	$at,$at,%lo((((((l2+0x8000))))))
+	addi	$at,$at,%lo(((((((l2-4)))))))
Index: gas/mips/elfel-rel.d
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/testsuite/gas/mips/elfel-rel.d,v
retrieving revision 1.1.1.2
diff -d -u -p -r1.1.1.2 elfel-rel.d
--- gas/mips/elfel-rel.d	2001/08/10 20:44:39	1.1.1.2
+++ gas/mips/elfel-rel.d	2002/01/09 07:01:18
@@ -22,16 +22,28 @@ OFFSET [ ]+ TYPE              VALUE 
 0+000002c R_MIPS_LO16       \.text
 0+0000030 R_MIPS_HI16       \.text
 0+0000048 R_MIPS_LO16       \.text
-0+0000034 R_MIPS_HI16       \.text
+0+0000064 R_MIPS_HI16       \.text
 0+000004c R_MIPS_LO16       \.text
-0+0000038 R_MIPS_HI16       \.text
+0+0000068 R_MIPS_HI16       \.text
 0+0000050 R_MIPS_LO16       \.text
-0+000003c R_MIPS_HI16       \.text
+0+000006c R_MIPS_HI16       \.text
 0+0000054 R_MIPS_LO16       \.text
-0+0000044 R_MIPS_HI16       \.text
+0+0000074 R_MIPS_HI16       \.text
 0+0000058 R_MIPS_LO16       \.text
-0+0000040 R_MIPS_HI16       \.text
+0+0000070 R_MIPS_HI16       \.text
 0+000005c R_MIPS_LO16       \.text
+0+0000060 R_MIPS_HI16       \.text
+0+0000078 R_MIPS_LO16       \.text
+0+0000034 R_MIPS_HI16       \.text
+0+000007c R_MIPS_LO16       \.text
+0+0000038 R_MIPS_HI16       \.text
+0+0000080 R_MIPS_LO16       \.text
+0+000003c R_MIPS_HI16       \.text
+0+0000084 R_MIPS_LO16       \.text
+0+0000044 R_MIPS_HI16       \.text
+0+0000088 R_MIPS_LO16       \.text
+0+0000040 R_MIPS_HI16       \.text
+0+000008c R_MIPS_LO16       \.text
 
 
 Contents of section \.text:
@@ -41,9 +53,9 @@ Contents of section \.text:
  0030 0100013c 0100013c 0200013c 0200013c  .*
  0040 0100013c 0100013c febf2120 02c02120  .*
  0050 febf2120 02c02120 fe3f2120 fabf2120  .*
- 0060 00000000 00000000 00000000 00000000  ................
- 0070 00000000 00000000 00000000 00000000  ................
- 0080 00000000 00000000 00000000 00000000  ................
+ 0060 0100013c 0100013c 0200013c 0200013c  .*
+ 0070 0100013c 0100013c febf2120 02c02120  .*
+ 0080 febf2120 02c02120 fe3f2120 fabf2120  .*
  0090 00000000 00000000 00000000 00000000  ................
  00a0 00000000 00000000 00000000 00000000  ................
  00b0 00000000 00000000 00000000 00000000  ................

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-08 18:05 ` Richard Henderson
@ 2002-01-10  2:11   ` H . J . Lu
  0 siblings, 0 replies; 10+ messages in thread
From: H . J . Lu @ 2002-01-10  2:11 UTC (permalink / raw)
  To: Richard Henderson; +Cc: binutils

On Tue, Jan 08, 2002 at 04:34:58PM -0800, Richard Henderson wrote:
> On Tue, Jan 08, 2002 at 02:10:09PM -0800, H . J . Lu wrote:
> >    lui t0, %hi((0xa0000000 + 0x10001000))
> 
> Correct solution is for %hi to remove the first parenthesis,
> call expr to read the inner expression, then check for the
> final close parenthesis.

It is a generic problem, at least for mips. The current assembler
doesn't support nested () at all.


H.J.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-08 16:42 ` H . J . Lu
  2002-01-08 22:33   ` Eric Christopher
@ 2002-01-12 17:00   ` Thiemo Seufer
  2002-01-14  9:25     ` Johannes Stezenbach
  1 sibling, 1 reply; 10+ messages in thread
From: Thiemo Seufer @ 2002-01-12 17:00 UTC (permalink / raw)
  To: Johannes Stezenbach; +Cc: binutils, H . J . Lu

> > ----- Forwarded message from Johannes Stezenbach <js@convergence.de> -----
[snip]
> > the assembler of binutils-2.11.92.0.12.3 for MIPS has a bug which
> > shows up when parsing percent-ops like %hi and %lo with
> > nested parentheses, e.g.
> > 
> >    lui t0, %hi((0xa0000000 + 0x10001000))
> > 
> > produces parsing errors because of unmatched parens
> > (sorry, I don't have the exact error message right now).

I overlooked this possibility when I changed/reimplemented this
functions to support NewABI's nested percent op's like

	lui $1, %hi(%neg(%pc_rel(symbol)))

[snip]
> > I attempted to fix this problem (patch attached), but unfortunately
> > my understanding of gas' expression parser is very limited.
> > My patch is thus more a workaround-hack than a fix.
> > 
> > I tried hard to figure out how my_getSmallExpression() in
> > gas/config/tc-mips.c works for nested precent-ops, but
> > either I failed or the thing is totally broken.

It is broken in several ways as I found out now.

> > I dont't know all the details of the MIPS assembler syntax,
> > but wouldn't it be the right way to use expr() (in gas/expr.c) for
> > parsing, and provide support for percent-ops via the
> > md_operand() hook?  This should work since is_name_beginner('%')
> > returns FALSE and LITERAL_PREFIXPERCENT_BIN is #undef'd.

AFAICS this does not work for nested percent op's, so I expanded
your patch to fix some more flaws and did also some code cleanup.
It still looks ugly.


Thiemo


2002-01-12  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
            Johannes Stezenbach <js@convergence.de>

	/gas/ChangeLog
	* config/tc-mips.c (percent_op): Ensure longer percent_op's are
	matched before the shorter ones.
	(my_getSmallParser): Fix handling of nested parentheses in
	percent_op's. Code cleanup.
	(my_getPercentOp): New function, code from my_getSmallParser.
	(my_getSmallExpression): Fix handling of closing parentheses.
	Code cleanup. Better comments.


diff -BurpNX /bigdisk/src/binutils-exclude src-orig/gas/config/tc-mips.c src/gas/config/tc-mips.c
--- src-orig/gas/config/tc-mips.c	Thu Jan 10 21:14:28 2002
+++ src/gas/config/tc-mips.c	Sat Jan 12 12:42:30 2002
@@ -702,6 +702,7 @@ static void mips16_ip PARAMS ((char *str
 static void mips16_immed PARAMS ((char *, unsigned int, int, offsetT, boolean,
 				  boolean, boolean, unsigned long *,
 				  boolean *, unsigned short *));
+static int my_getPercentOp PARAMS ((char **, unsigned int *, int *));
 static int my_getSmallParser PARAMS ((char **, unsigned int *, int *));
 static int my_getSmallExpression PARAMS ((expressionS *, char *));
 static void my_getExpression PARAMS ((expressionS *, char *));
@@ -9314,26 +9380,24 @@ static struct percent_op_match
    const enum small_ex_type type;
 } percent_op[] =
 {
-#ifdef OBJ_ELF
-  {"%half", S_EX_HALF},
-#endif
-  {"%hi", S_EX_HI},
   {"%lo", S_EX_LO},
 #ifdef OBJ_ELF
-  {"%gp_rel", S_EX_GP_REL},
-  {"%got", S_EX_GOT},
+  {"%call_hi", S_EX_CALL_HI},
+  {"%call_lo", S_EX_CALL_LO},
   {"%call16", S_EX_CALL16},
   {"%got_disp", S_EX_GOT_DISP},
   {"%got_page", S_EX_GOT_PAGE},
   {"%got_ofst", S_EX_GOT_OFST},
   {"%got_hi", S_EX_GOT_HI},
   {"%got_lo", S_EX_GOT_LO},
-  {"%neg", S_EX_NEG},
-  {"%higher", S_EX_HIGHER},
+  {"%got", S_EX_GOT},
+  {"%gp_rel", S_EX_GP_REL},
+  {"%half", S_EX_HALF},
   {"%highest", S_EX_HIGHEST},
-  {"%call_hi", S_EX_CALL_HI},
-  {"%call_lo", S_EX_CALL_LO}
+  {"%higher", S_EX_HIGHER},
+  {"%neg", S_EX_NEG},
 #endif
+  {"%hi", S_EX_HI}
 };
 
 /* Parse small expression input.  STR gets adjusted to eat up whitespace.
@@ -9347,10 +9411,9 @@ my_getSmallParser (str, len, nestlevel)
      unsigned int *len;
      int *nestlevel;
 {
-  int type = S_EX_NONE;
-
   *len = 0;
   *str += strspn (*str, " \t");
+  /* Check for expression in parentheses.  */
   if (**str == '(')
     {
       char *b = *str + 1 + strspn (*str + 1, " \t");
@@ -9377,50 +9440,68 @@ my_getSmallParser (str, len, nestlevel)
 		 }
 	    }
 	}
+      /* Check for percent_op (in parentheses).  */
       else if (b[0] == '%')
 	{
 	  *str = b;
-	  goto percent_op;
+	  return my_getPercentOp (str, len, nestlevel);
 	}
 
-      /* Some other expression in the braces.  */
-      *len = strcspn (*str, ")") + 1;
+      /* Some other expression in the parentheses, which can contain
+	 parentheses itself. Attempt to find the matching one.  */
+      {
+	int pcnt = 1;
+	char *s;
+
+	*len = 1;
+	for (s = *str + 1; *s && pcnt; s++, (*len)++)
+	  {
+	    if (*s == '(')
+	      pcnt++;
+	    else if (*s == ')')
+	      pcnt--;
+	  }
+      }
     }
-  /* Check for percent_op.  */
+  /* Check for percent_op (outside of parentheses).  */
   else if (*str[0] == '%')
-    {
-      char *tmp;
-      unsigned int i;
+    return my_getPercentOp (str, len, nestlevel);
 
-percent_op:
-      tmp = *str + 1;
-      i = 0;
+  /* Any other expression.  */
+  return S_EX_NONE;
+}
 
-      while (ISALPHA (*tmp) || *tmp == '_')
-	{
-	  *tmp = TOLOWER (*tmp);
-	  tmp++;
-	}
-      while (i < (sizeof (percent_op) / sizeof (struct percent_op_match)))
+static int
+my_getPercentOp (str, len, nestlevel)
+     char **str;
+     unsigned int *len;
+     int *nestlevel;
+{
+  char *tmp = *str + 1;
+  unsigned int i = 0;
+
+  while (ISALPHA (*tmp) || *tmp == '_')
+    {
+      *tmp = TOLOWER (*tmp);
+      tmp++;
+    }
+  while (i < (sizeof (percent_op) / sizeof (struct percent_op_match)))
+    {
+      if (strncmp (*str, percent_op[i].str, strlen (percent_op[i].str)))
+	  i++;
+      else
 	{
-	  if (strncmp (*str, percent_op[i].str, strlen (percent_op[i].str)))
-	      i++;
-	  else
-	    {
-	      type = percent_op[i].type;
+	  int type = percent_op[i].type;
 
-	      /* Only %hi and %lo are allowed for OldABI.  */
-	      if (! HAVE_NEWABI && type != S_EX_HI && type != S_EX_LO)
-		return S_EX_NONE;
-
-	      *len = strlen (percent_op[i].str);
-	      (*nestlevel)++;
-	      return type;
-	    }
+	  /* Only %hi and %lo are allowed for OldABI.  */
+	  if (! HAVE_NEWABI && type != S_EX_HI && type != S_EX_LO)
+	    return S_EX_NONE;
+
+	  *len = strlen (percent_op[i].str);
+	  (*nestlevel)++;
+	  return type;
 	}
     }
-
-  /* Any other expression.  */
   return S_EX_NONE;
 }
 
@@ -9432,46 +9513,59 @@ my_getSmallExpression (ep, str)
   static char *oldstr = NULL;
   int c = S_EX_NONE;
   int oldc;
-  int nest_level = 0;
+  int nestlevel = -1;
   unsigned int len;
 
-  /* Don't update oldstr if the last call had nested percent_op's.  */
+  /* Don't update oldstr if the last call had nested percent_op's. We need
+     it to parse the outer ones later.  */
   if (! oldstr)
     oldstr = str;
 
   do
     {
       oldc = c;
-      c = my_getSmallParser (&str, &len, &nest_level);
+      c = my_getSmallParser (&str, &len, &nestlevel);
       if (c != S_EX_NONE && c != S_EX_REGISTER)
 	str += len;
     }
   while (c != S_EX_NONE && c != S_EX_REGISTER);
 
-  /* A percent_op was encountered.  */
-  if (nest_level)
+  if (nestlevel >= 0)
     {
-      /* Don't try to get an expression if it is already blanked out.  */
+      /* A percent_op was encountered.  Don't try to get an expression if
+	 it is already blanked out.  */
       if (*(str + strspn (str + 1, " )")) != ')')
 	{
 	  char save;
 
+	  /* Let my_getExpression() stop at the closing parenthesis.  */
 	  save = *(str + len);
 	  *(str + len) = '\0';
 	  my_getExpression (ep, str);
 	  *(str + len) = save;
 	}
-      if (nest_level > 1)
+      if (nestlevel > 0)
 	{
-	  /* blank out including the % sign.  */
-	  char *p = strrchr (oldstr, '%');
-	  memset (p, ' ', str - p + len);
+	  /* Blank out including the % sign and the proper matching
+	     parenthesis.  */
+	  int pcnt = 1;
+	  char *s = strrchr (oldstr, '%');
+	  char *end;
+
+	  for (end = strchr (s, '(') + 1; *end && pcnt; end++)
+	    {
+	      if (*end == '(')
+		pcnt++;
+	      else if (*end == ')')
+		pcnt--;
+	    }
+
+	  memset (s, ' ', end - s);
 	  str = oldstr;
 	}
       else
-	{
-	  expr_end = strchr (str, ')') + 1;
-	}
+	expr_end = str + len;
+
       c = oldc;
     }
   else if (c == S_EX_NONE)
@@ -9491,7 +9585,8 @@ my_getSmallExpression (ep, str)
       as_fatal(_("internal error"));
     }
 
-  if (nest_level <= 1)
+  if (nestlevel <= 0)
+    /* All percent_op's have been handled.  */
     oldstr = NULL;
 
   return c;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi]
  2002-01-12 17:00   ` Thiemo Seufer
@ 2002-01-14  9:25     ` Johannes Stezenbach
  0 siblings, 0 replies; 10+ messages in thread
From: Johannes Stezenbach @ 2002-01-14  9:25 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

On Sat, Jan 12, 2002 at 03:23:23PM +0100, Thiemo Seufer wrote:
> > >    lui t0, %hi((0xa0000000 + 0x10001000))
> > > 
> > > produces parsing errors because of unmatched parens
> > > (sorry, I don't have the exact error message right now).
> 
> I overlooked this possibility when I changed/reimplemented this
> functions to support NewABI's nested percent op's like
> 
> 	lui $1, %hi(%neg(%pc_rel(symbol)))
...
> > > I dont't know all the details of the MIPS assembler syntax,
> > > but wouldn't it be the right way to use expr() (in gas/expr.c) for
> > > parsing, and provide support for percent-ops via the
> > > md_operand() hook?  This should work since is_name_beginner('%')
> > > returns FALSE and LITERAL_PREFIXPERCENT_BIN is #undef'd.
> 
> AFAICS this does not work for nested percent op's, so I expanded
> your patch to fix some more flaws and did also some code cleanup.

Thanks!

> It still looks ugly.

I read the code some more, and the interaction between mips_ip() and
my_getSmallExpression() is too complex for me to understand ;-),
especially without proper knowledge of the NewABI's % ops.
So, I think I can't help here. I will test your patch within
the next few days, though.


Regards,
Johannes

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2002-01-14 17:23 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-01-08 15:09 [js@convergence.de: binutils-2.11.92.0.12.3 gas MIPS bug: nested parens in %hi] H . J . Lu
2002-01-08 16:42 ` H . J . Lu
2002-01-08 22:33   ` Eric Christopher
2002-01-08 23:04     ` H . J . Lu
2002-01-09  2:48       ` Eric Christopher
2002-01-09  3:34         ` H . J . Lu
2002-01-12 17:00   ` Thiemo Seufer
2002-01-14  9:25     ` Johannes Stezenbach
2002-01-08 18:05 ` Richard Henderson
2002-01-10  2:11   ` H . J . Lu

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).