From: Alan Modra Date: Mon, 27 Feb 2012 06:40:42 +0000 (+0000) Subject: * config/tc-h8300.c (constant_fits_width_p): Trim constant to 32 bits X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=35a358074fc5d36cc1df4a33660ae1edc735c330;p=binutils-gdb.git * config/tc-h8300.c (constant_fits_width_p): Trim constant to 32 bits and sign extend before range tests. (constant_fits_size_p): Similarly. (get_specific): Trim X_add_number to 32 bits. (fix_operand_size): Likewise, and use unsigned test for signed ranges. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index dbbfcdbb704..42d4ff1bcd2 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2012-02-27 Alan Modra + + * config/tc-h8300.c (constant_fits_width_p): Trim constant to 32 bits + and sign extend before range tests. + (constant_fits_size_p): Similarly. + (get_specific): Trim X_add_number to 32 bits. + (fix_operand_size): Likewise, and use unsigned test for signed + ranges. + 2012-02-27 Alan Modra * config/tc-crx.c: Include bfd_stdint.h. diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c index cc46740d3aa..edfad44d0e1 100644 --- a/gas/config/tc-h8300.c +++ b/gas/config/tc-h8300.c @@ -1,6 +1,6 @@ /* tc-h8300.c -- Assemble code for the Renesas H8/300 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -558,17 +558,21 @@ skip_colonthing (char *src, int *mode) static int constant_fits_width_p (struct h8_op *operand, unsigned int width) { - return ((operand->exp.X_add_number & ~width) == 0 - || (operand->exp.X_add_number | (offsetT) width) == (offsetT)(~0)); + offsetT num; + + num = ((operand->exp.X_add_number & 0xffffffff) ^ 0x80000000) - 0x80000000; + return (num & ~width) == 0 || (num | width) == ~0; } static int constant_fits_size_p (struct h8_op *operand, int size, int no_symbols) { - offsetT num = operand->exp.X_add_number; + offsetT num; + if (no_symbols && (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0)) return 0; + num = operand->exp.X_add_number & 0xffffffff; switch (size) { case L_2: @@ -582,11 +586,13 @@ constant_fits_size_p (struct h8_op *operand, int size, int no_symbols) case L_5: return num >= 1 && num < 32; case L_8: - return (num & ~0xFF) == 0 || ((unsigned)num | 0x7F) == ~0u; + num = (num ^ 0x80000000) - 0x80000000; + return (num & ~0xFF) == 0 || (num | 0x7F) == ~0; case L_8U: return (num & ~0xFF) == 0; case L_16: - return (num & ~0xFFFF) == 0 || ((unsigned)num | 0x7FFF) == ~0u; + num = (num ^ 0x80000000) - 0x80000000; + return (num & ~0xFFFF) == 0 || (num | 0x7FFF) == ~0; case L_16U: return (num & ~0xFFFF) == 0; case L_32: @@ -1184,7 +1190,7 @@ get_specific (const struct h8_instruction *instruction, } else if (x_mode == IMM && op_mode != IMM) { - offsetT num = operands[i].exp.X_add_number; + offsetT num = operands[i].exp.X_add_number & 0xffffffff; if (op_mode == KBIT || op_mode == DBIT) /* This is ok if the immediate value is sensible. */; else if (op_mode == CONST_2) @@ -1866,8 +1872,8 @@ fix_operand_size (struct h8_op *operand, int size) necessary. */ if (Hmode && !Nmode - && (operand->exp.X_add_number < -32768 - || operand->exp.X_add_number > 32767 + && ((((addressT) operand->exp.X_add_number + 0x8000) + & 0xffffffff) > 0xffff || operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0)) operand->mode |= L_24; @@ -1876,9 +1882,8 @@ fix_operand_size (struct h8_op *operand, int size) break; case PCREL: - /* This condition is long standing, though somewhat suspect. */ - if (operand->exp.X_add_number > -128 - && operand->exp.X_add_number < 127) + if ((((addressT) operand->exp.X_add_number + 0x80) + & 0xffffffff) <= 0xff) { if (operand->exp.X_add_symbol != NULL) operand->mode |= bsize;