From 1f42f8b31d2ef0cd0e4967f7d9414e0671be288e Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 27 Feb 2012 06:37:40 +0000 Subject: [PATCH] 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. --- gas/ChangeLog | 7 ++++++ gas/config/tc-crx.c | 52 +++++++++++++++++++++------------------- include/opcode/ChangeLog | 4 ++++ include/opcode/crx.h | 4 ++-- opcodes/ChangeLog | 5 ++++ opcodes/crx-dis.c | 12 +++++----- opcodes/crx-opc.c | 4 ++-- 7 files changed, 54 insertions(+), 34 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 6e6f70a5bae..dbbfcdbb704 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2012-02-27 Alan Modra + + * 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. + 2012-02-25 Walter Lee * tc-tilepro.c (emit_tilepro_instruction): Check if symbol is diff --git a/gas/config/tc-crx.c b/gas/config/tc-crx.c index b347d8b828a..775781bf3f7 100644 --- a/gas/config/tc-crx.c +++ b/gas/config/tc-crx.c @@ -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 unsigned flags, int update) 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 unsigned flags, int update) { 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 unsigned flags, int update) 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 unsigned flags, int update) } 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; diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 5241b37312b..71018b0890d 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2012-02-27 Alan Modra + + * crx.h (cst4_map): Update declaration. + 2012-02-25 Walter Lee * tilegx.h (tilegx_mnemonic): Add TILEGX_OPC_LD4S_TLS, diff --git a/include/opcode/crx.h b/include/opcode/crx.h index 5c484bf26bc..6081ea3548d 100644 --- a/include/opcode/crx.h +++ b/include/opcode/crx.h @@ -1,5 +1,5 @@ /* crx.h -- Header file for CRX opcode and register tables. - Copyright 2004, 2010 Free Software Foundation, Inc. + Copyright 2004, 2010, 2012 Free Software Foundation, Inc. Contributed by Tomer Levi, NSC, Israel. Originally written for GAS 2.12 by Tomer Levi, NSC, Israel. Updates, BFDizing, GNUifying and ELF support by Tomer Levi. @@ -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. */ diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index cc0af8e420a..81b4e64434b 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2012-02-27 Alan Modra + + * crx-dis.c (print_arg): Mask constant to 32 bits. + * crx-opc.c (cst4_map): Use int array. + 2012-02-27 Alan Modra * arc-dis.c (BITS): Don't use shifts to mask off bits. diff --git a/opcodes/crx-dis.c b/opcodes/crx-dis.c index f909897444d..35168bc97d4 100644 --- a/opcodes/crx-dis.c +++ b/opcodes/crx-dis.c @@ -1,5 +1,5 @@ /* Disassembler code for CRX. - Copyright 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright 2004, 2005, 2006, 2007, 2012 Free Software Foundation, Inc. Contributed by Tomer Levi, NSC, Israel. Written by Tomer Levi. @@ -548,7 +548,7 @@ print_arg (argument *a, bfd_vma memaddr, struct disassemble_info *info) 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, struct disassemble_info *info) } } 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, struct disassemble_info *info) 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, "+"); diff --git a/opcodes/crx-opc.c b/opcodes/crx-opc.c index b046c913e33..65e2e86cf77 100644 --- a/opcodes/crx-opc.c +++ b/opcodes/crx-opc.c @@ -1,5 +1,5 @@ /* crx-opc.c -- Table of opcodes for the CRX processor. - Copyright 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright 2004, 2005, 2007, 2012 Free Software Foundation, Inc. Contributed by Tomer Levi NSC, Israel. Originally written for GAS 2.12 by Tomer Levi. @@ -701,7 +701,7 @@ The value in entry is mapped to the value 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 }; -- 2.30.2