diff options
author | Alan Modra <amodra@gmail.com> | 2012-02-27 06:37:40 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-02-27 06:37:40 +0000 |
commit | 1f42f8b31d2ef0cd0e4967f7d9414e0671be288e (patch) | |
tree | cb8a7af5589b95844855e6bad01d1d8fd0d41c5a /gas | |
parent | cdb062354ec534d97597dcfa20fd032c799dd0c1 (diff) | |
download | binutils-1f42f8b31d2ef0cd0e4967f7d9414e0671be288e.zip binutils-1f42f8b31d2ef0cd0e4967f7d9414e0671be288e.tar.gz binutils-1f42f8b31d2ef0cd0e4967f7d9414e0671be288e.tar.bz2 |
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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 7 | ||||
-rw-r--r-- | gas/config/tc-crx.c | 52 |
2 files changed, 35 insertions, 24 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 6e6f70a..dbbfcdb 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2012-02-27 Alan Modra <amodra@gmail.com> + + * 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 <walt@tilera.com> * 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 b347d8b..775781b 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; |