This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
64-bit host failures, crx
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 27 Feb 2012 17:06:27 +1030
- Subject: 64-bit host failures, crx
- Authentication-results: mr.google.com; spf=pass (google.com: domain of amodra@gmail.com designates 10.68.212.73 as permitted sender) smtp.mail=amodra@gmail.com; dkim=pass header.i=amodra@gmail.com
- References: <20120227063137.GB3613@bubble.grove.modra.org>
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