This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: gas will miscompile with SPARCompiler 3.0.1 on Solaris7
- To: Alan Modra <alan at linuxcare dot com dot au>
- Subject: Re: gas will miscompile with SPARCompiler 3.0.1 on Solaris7
- From: Alexandre Oliva <aoliva at cygnus dot com>
- Date: 07 Apr 2000 01:07:56 -0300
- Cc: binutils at sourceware dot cygnus dot com, jakub at redhat dot com
- Organization: Cygnus Solutions, a Red Hat Company
- References: <Pine.LNX.4.21.0004071303500.6764-100000@front.linuxcare.com.au>
On Apr 7, 2000, Alan Modra <alan@linuxcare.com.au> wrote:
> Alexandre, to get this result your sun compiler apparently is sign
> extending 0xffffffff.
Precisely. So, it's a compiler bug. Anyway, it would be nice to fix
it, wouldn't it? Here's a patch that fixes this and a few other
similar bugs. With this patch, `make check-{gas,binutils}' passes all
tests. Ok to install? Release branch?
Index: gas/ChangeLog
from Alexandre Oliva <oliva@lsd.ic.unicamp.br>
* config/tc-sparc.c (in_signed_range): Cast to unsigned hex
literals with bit 31 set, to work around compiler bug.
(synthetize_setuw, synthetize_setsw, synthetize_setx): Likewise.
Index: gas/config/tc-sparc.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-sparc.c,v
retrieving revision 1.13.2.2
diff -u -r1.13.2.2 tc-sparc.c
--- gas/config/tc-sparc.c 2000/04/05 09:36:19 1.13.2.2
+++ gas/config/tc-sparc.c 2000/04/07 04:05:26
@@ -861,7 +861,7 @@
if (sparc_arch_size == 32)
{
bfd_signed_vma sign = (bfd_signed_vma)1 << 31;
- val = ((val & 0xffffffff) ^ sign) - sign;
+ val = ((val & (unsigned)0xffffffff) ^ sign) - sign;
}
if (val > max)
return 0;
@@ -963,14 +963,14 @@
{
if (sizeof(offsetT) > 4
&& (the_insn.exp.X_add_number < 0
- || the_insn.exp.X_add_number > (offsetT) 0xffffffff))
+ || the_insn.exp.X_add_number > (offsetT)(unsigned)0xffffffff))
as_warn (_("set: number not in 0..4294967295 range"));
}
else
{
if (sizeof(offsetT) > 4
- && (the_insn.exp.X_add_number < -(offsetT) 0x80000000
- || the_insn.exp.X_add_number > (offsetT) 0xffffffff))
+ && (the_insn.exp.X_add_number < -(offsetT)(unsigned)0x80000000
+ || the_insn.exp.X_add_number > (offsetT)(unsigned)0xffffffff))
as_warn (_("set: number not in -2147483648..4294967295 range"));
the_insn.exp.X_add_number = (int)the_insn.exp.X_add_number;
}
@@ -1029,8 +1029,8 @@
}
if (sizeof(offsetT) > 4
- && (the_insn.exp.X_add_number < -(offsetT) 0x80000000
- || the_insn.exp.X_add_number > (offsetT) 0xffffffff))
+ && (the_insn.exp.X_add_number < -(offsetT)(unsigned)0x80000000
+ || the_insn.exp.X_add_number > (offsetT)(unsigned)0xffffffff))
as_warn (_("setsw: number not in -2147483648..4294967295 range"));
low32 = the_insn.exp.X_add_number;
@@ -1059,7 +1059,7 @@
output_insn (insn, &the_insn);
}
-/* Handle the setsw synthetic instruction. */
+/* Handle the setx synthetic instruction. */
static void
synthetize_setx (insn)
const struct sparc_opcode *insn;
@@ -1071,7 +1071,8 @@
int need_hh22_p = 0, need_hm10_p = 0, need_hi22_p = 0, need_lo10_p = 0;
int need_xor10_p = 0;
-#define SIGNEXT32(x) ((((x) & 0xffffffff) ^ 0x80000000) - 0x80000000)
+#define SIGNEXT32(x) ((((x) & (unsigned)0xffffffff) ^ (unsigned)0x80000000) \
+ - (unsigned)0x80000000)
lower32 = SIGNEXT32 (the_insn.exp.X_add_number);
upper32 = SIGNEXT32 (BSR (the_insn.exp.X_add_number, 32));
#undef SIGNEXT32
Index: opcodes/ChangeLog
from Alexandre Oliva <oliva@lsd.ic.unicamp.br>
* sparc-dis.c (print_insn_sparc): Cast to unsigned hex literals
with bit 31 set, to work around compiler bug.
Index: opcodes/sparc-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/sparc-dis.c,v
retrieving revision 1.2
diff -u -r1.2 sparc-dis.c
--- opcodes/sparc-dis.c 1999/07/08 16:14:07 1.2
+++ opcodes/sparc-dis.c 2000/04/07 04:05:27
@@ -1,5 +1,5 @@
/* Print SPARC instructions.
- Copyright (C) 1989, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 91-97, 1998, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -418,7 +418,7 @@
case 'h':
(*info->fprintf_func) (stream, "%%hi(%#x)",
- (0xFFFFFFFF
+ ((unsigned)0xFFFFFFFF
& ((int) X_IMM22 (insn) << 10)));
break;
@@ -711,7 +711,8 @@
{
(*info->fprintf_func) (stream, "\t! ");
info->target =
- (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10);
+ ((unsigned)0xFFFFFFFF
+ & ((int) X_IMM22 (prev_insn) << 10));
if (imm_added_to_rs1)
info->target += X_SIMM (insn, 13);
else
--
Alexandre Oliva Enjoy Guaranį, see http://www.ic.unicamp.br/~oliva/
Cygnus Solutions, a Red Hat company aoliva@{redhat, cygnus}.com
Free Software Developer and Evangelist CS PhD student at IC-Unicamp
oliva@{lsd.ic.unicamp.br, gnu.org} Write to mailing lists, not to me