aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-h8300.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-02-27 06:40:42 +0000
committerAlan Modra <amodra@gmail.com>2012-02-27 06:40:42 +0000
commit35a358074fc5d36cc1df4a33660ae1edc735c330 (patch)
tree6fa70d1e9148c1267c599562e99ad637710ba552 /gas/config/tc-h8300.c
parent1f42f8b31d2ef0cd0e4967f7d9414e0671be288e (diff)
downloadgdb-35a358074fc5d36cc1df4a33660ae1edc735c330.zip
gdb-35a358074fc5d36cc1df4a33660ae1edc735c330.tar.gz
gdb-35a358074fc5d36cc1df4a33660ae1edc735c330.tar.bz2
* 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.
Diffstat (limited to 'gas/config/tc-h8300.c')
-rw-r--r--gas/config/tc-h8300.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c
index cc46740..edfad44 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;