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