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

64-bit host failures, crx


Lots of issues here in check_range.  Rewritten to use uint32_t.
Patch fixes these failures on 64-bit hosts:
crx-elf  +FAIL: arith_insn
crx-elf  +FAIL: bit_insn
crx-elf  +FAIL: br_insn
crx-elf  +FAIL: cmpbr_insn
crx-elf  +FAIL: load_stor_insn

gas/
	* config/tc-crx.c: Include bfd_stdint.h.
	(getconstant): Remove irrelevant comment.  Don't fail due to
	sign-extension of int mask.
	(check_range): Rewrite using unsigned arithmetic throughout.
opcodes/
	* crx-dis.c (print_arg): Mask constant to 32 bits.
	* crx-opc.c (cst4_map): Use int array.
include/opcode/
	* crx.h (cst4_map): Update declaration.

Index: gas/config/tc-crx.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-crx.c,v
retrieving revision 1.25
diff -u -p -r1.25 tc-crx.c
--- gas/config/tc-crx.c	28 Jun 2010 14:06:57 -0000	1.25
+++ gas/config/tc-crx.c	26 Feb 2012 03:49:26 -0000
@@ -1,5 +1,5 @@
 /* tc-crx.c -- Assembler code for the CRX CPU core.
-   Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
    Free Software Foundation, Inc.
 
    Contributed by Tomer Levi, NSC, Israel.
@@ -24,6 +24,7 @@
    MA 02110-1301, USA.  */
 
 #include "as.h"
+#include "bfd_stdint.h"
 #include "safe-ctype.h"
 #include "dwarf2dbg.h"
 #include "opcode/crx.h"
@@ -1173,9 +1174,7 @@ getreg_image (reg r)
 static long
 getconstant (long x, int nbits)
 {
-  /* The following expression avoids overflow if
-     'nbits' is the number of bits in 'bfd_vma'.  */
-  return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
+  return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
 }
 
 /* Print a constant value to 'output_opcode':
@@ -1326,17 +1325,14 @@ get_number_of_operands (void)
 static op_err
 check_range (long *num, int bits, int unsigned flags, int update)
 {
-  long min, max;
+  uint32_t max;
   int retval = OP_LEGAL;
   int bin;
-  long upper_64kb = 0xFFFF0000;
-  long value = *num;
+  uint32_t upper_64kb = 0xffff0000;
+  uint32_t value = *num;
 
-  /* For hosts witah longs bigger than 32-bits make sure that the top 
-     bits of a 32-bit negative value read in by the parser are set,
-     so that the correct comparisons are made.  */
-  if (value & 0x80000000)
-    value |= (-1L << 31);
+  /* Trim all values to 32 bits.  uint32_t can be more than 32 bits.  */
+  value &= 0xffffffff;
 
   /* Verify operand value is even.  */
   if (flags & OP_EVEN)
@@ -1360,7 +1356,12 @@ check_range (long *num, int bits, int un
 
   if (flags & OP_SHIFT)
     {
+      /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
+	 sign.  However, right shift of a signed type with a negative
+	 value is implementation defined.  See ISO C 6.5.7.  So we use
+	 an unsigned type and sign extend afterwards.  */
       value >>= 1;
+      value = ((value ^ 0x40000000) - 0x40000000) & 0xffffffff;
       if (update)
 	*num = value;
     }
@@ -1382,13 +1383,14 @@ check_range (long *num, int bits, int un
     {
       int is_dispu4 = 0;
 
-      int mul = (instruction->flags & DISPUB4) ? 1 
-		: (instruction->flags & DISPUW4) ? 2
-		: (instruction->flags & DISPUD4) ? 4 : 0;
+      uint32_t mul = (instruction->flags & DISPUB4 ? 1 
+		      : instruction->flags & DISPUW4 ? 2
+		      : instruction->flags & DISPUD4 ? 4
+		      : 0);
       
       for (bin = 0; bin < cst4_maps; bin++)
 	{
-	  if (value == (mul * bin))
+	  if (value == mul * bin)
 	    {
 	      is_dispu4 = 1;
 	      if (update)
@@ -1405,7 +1407,7 @@ check_range (long *num, int bits, int un
 
       for (bin = 0; bin < cst4_maps; bin++)
 	{
-	  if (value == cst4_map[bin])
+	  if (value == ((uint32_t) cst4_map[bin] & 0xffffffff))
 	    {
 	      is_cst4 = 1;
 	      if (update)
@@ -1418,17 +1420,19 @@ check_range (long *num, int bits, int un
     }
   else if (flags & OP_SIGNED)
     {
-      max = (1 << (bits - 1)) - 1;
-      min = - (1 << (bits - 1));
-      if ((value > max) || (value < min))
+      max = 1;
+      max = max << (bits - 1);
+      value += max;
+      max = ((max - 1) << 1) | 1;
+      if (value > max)
 	retval = OP_OUT_OF_RANGE;
     }
   else if (flags & OP_UNSIGNED)
     {
-      max = ((((1 << (bits - 1)) - 1) << 1) | 1);
-      min = 0;
-      if (((unsigned long) value > (unsigned long) max) 
-	    || ((unsigned long) value < (unsigned long) min))
+      max = 1;
+      max = max << (bits - 1);
+      max = ((max - 1) << 1) | 1;
+      if (value > max)
 	retval = OP_OUT_OF_RANGE;
     }
   return retval;
Index: include/opcode/crx.h
===================================================================
RCS file: /cvs/src/src/include/opcode/crx.h,v
retrieving revision 1.8
diff -u -p -r1.8 crx.h
--- include/opcode/crx.h	15 Apr 2010 10:26:09 -0000	1.8
+++ include/opcode/crx.h	26 Feb 2012 03:49:59 -0000
@@ -384,7 +384,7 @@ extern const int crx_num_traps;
 #define NUMTRAPS crx_num_traps
 
 /* cst4 operand mapping.  */
-extern const long cst4_map[];
+extern const int cst4_map[];
 extern const int cst4_maps;
 
 /* Table of instructions with no operands.  */
Index: opcodes/crx-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/crx-dis.c,v
retrieving revision 1.16
diff -u -p -r1.16 crx-dis.c
--- opcodes/crx-dis.c	11 Dec 2009 13:42:16 -0000	1.16
+++ opcodes/crx-dis.c	26 Feb 2012 03:50:08 -0000
@@ -548,7 +548,7 @@ print_arg (argument *a, bfd_vma memaddr,
 		    func (stream, "%s", string);
 		  }
 		else
-		  func (stream, "$0x%lx", a->constant);
+		  func (stream, "$0x%lx", a->constant & 0xffffffff);
 	    }
 	  else
             {
@@ -557,12 +557,12 @@ print_arg (argument *a, bfd_vma memaddr,
             }
         }
       else
-	func (stream, "$0x%lx", a->constant);
+	func (stream, "$0x%lx", a->constant & 0xffffffff);
       break;
 
     case arg_idxr:
-      func (stream, "0x%lx(%s,%s,%d)", a->constant, getregname (a->r),
-	    getregname (a->i_r), powerof2 (a->scale));
+      func (stream, "0x%lx(%s,%s,%d)", a->constant & 0xffffffff,
+	    getregname (a->r), getregname (a->i_r), powerof2 (a->scale));
       break;
 
     case arg_rbase:
@@ -570,7 +570,7 @@ print_arg (argument *a, bfd_vma memaddr,
       break;
 
     case arg_cr:
-      func (stream, "0x%lx(%s)", a->constant, getregname (a->r));
+      func (stream, "0x%lx(%s)", a->constant & 0xffffffff, getregname (a->r));
 
       if (IS_INSN_TYPE (LD_STOR_INS_INC))
 	func (stream, "+");
Index: opcodes/crx-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/crx-opc.c,v
retrieving revision 1.13
diff -u -p -r1.13 crx-opc.c
--- opcodes/crx-opc.c	2 Sep 2009 07:20:29 -0000	1.13
+++ opcodes/crx-opc.c	26 Feb 2012 03:50:09 -0000
@@ -701,7 +701,7 @@ The value in entry <N> is mapped to the 
 Example (for N=5):
 
     cst4_map[5]=-4  -->>	5		*/
-const long cst4_map[] =
+const int cst4_map[] =
 {
   0, 1, 2, 3, 4, -4, -1, 7, 8, 16, 32, 20, 12, 48
 };

-- 
Alan Modra
Australia Development Lab, IBM


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