This is the mail archive of the binutils@sourceware.cygnus.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]

Re: gas will miscompile with SPARCompiler 3.0.1 on Solaris7


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

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