Line 1... |
Line 1... |
/* tc-h8300.c -- Assemble code for the Renesas H8/300
|
/* tc-h8300.c -- Assemble code for the Renesas H8/300
|
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
|
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.
|
Free Software Foundation, Inc.
|
|
|
This file is part of GAS, the GNU Assembler.
|
This file is part of GAS, the GNU Assembler.
|
|
|
GAS is free software; you can redistribute it and/or modify
|
GAS is free software; you can redistribute it and/or modify
|
Line 556... |
Line 556... |
@@aa[:8] memory indirect. */
|
@@aa[:8] memory indirect. */
|
|
|
static int
|
static int
|
constant_fits_width_p (struct h8_op *operand, unsigned int width)
|
constant_fits_width_p (struct h8_op *operand, unsigned int width)
|
{
|
{
|
return ((operand->exp.X_add_number & ~width) == 0
|
offsetT num;
|
|| (operand->exp.X_add_number | (offsetT) width) == (offsetT)(~0));
|
|
|
num = ((operand->exp.X_add_number & 0xffffffff) ^ 0x80000000) - 0x80000000;
|
|
return (num & ~width) == 0 || (num | width) == ~0;
|
}
|
}
|
|
|
static int
|
static int
|
constant_fits_size_p (struct h8_op *operand, int size, int no_symbols)
|
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
|
if (no_symbols
|
&& (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0))
|
&& (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0))
|
return 0;
|
return 0;
|
|
num = operand->exp.X_add_number & 0xffffffff;
|
switch (size)
|
switch (size)
|
{
|
{
|
case L_2:
|
case L_2:
|
return (num & ~3) == 0;
|
return (num & ~3) == 0;
|
case L_3:
|
case L_3:
|
Line 580... |
Line 584... |
case L_4:
|
case L_4:
|
return (num & ~15) == 0;
|
return (num & ~15) == 0;
|
case L_5:
|
case L_5:
|
return num >= 1 && num < 32;
|
return num >= 1 && num < 32;
|
case L_8:
|
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:
|
case L_8U:
|
return (num & ~0xFF) == 0;
|
return (num & ~0xFF) == 0;
|
case L_16:
|
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:
|
case L_16U:
|
return (num & ~0xFFFF) == 0;
|
return (num & ~0xFFFF) == 0;
|
case L_32:
|
case L_32:
|
return 1;
|
return 1;
|
default:
|
default:
|
Line 1182... |
Line 1188... |
&& (op_mode & SIZE) != L_32)
|
&& (op_mode & SIZE) != L_32)
|
found = 0;
|
found = 0;
|
}
|
}
|
else if (x_mode == IMM && op_mode != IMM)
|
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)
|
if (op_mode == KBIT || op_mode == DBIT)
|
/* This is ok if the immediate value is sensible. */;
|
/* This is ok if the immediate value is sensible. */;
|
else if (op_mode == CONST_2)
|
else if (op_mode == CONST_2)
|
found = num == 2;
|
found = num == 2;
|
else if (op_mode == CONST_4)
|
else if (op_mode == CONST_4)
|
Line 1864... |
Line 1870... |
/* Pick a 24-bit address unless we know that a 16-bit address
|
/* Pick a 24-bit address unless we know that a 16-bit address
|
is safe. get_specific() will relax L_24 into L_32 where
|
is safe. get_specific() will relax L_24 into L_32 where
|
necessary. */
|
necessary. */
|
if (Hmode
|
if (Hmode
|
&& !Nmode
|
&& !Nmode
|
&& (operand->exp.X_add_number < -32768
|
&& ((((addressT) operand->exp.X_add_number + 0x8000)
|
|| operand->exp.X_add_number > 32767
|
& 0xffffffff) > 0xffff
|
|| operand->exp.X_add_symbol != 0
|
|| operand->exp.X_add_symbol != 0
|
|| operand->exp.X_op_symbol != 0))
|
|| operand->exp.X_op_symbol != 0))
|
operand->mode |= L_24;
|
operand->mode |= L_24;
|
else
|
else
|
operand->mode |= L_16;
|
operand->mode |= L_16;
|
break;
|
break;
|
|
|
case PCREL:
|
case PCREL:
|
/* This condition is long standing, though somewhat suspect. */
|
if ((((addressT) operand->exp.X_add_number + 0x80)
|
if (operand->exp.X_add_number > -128
|
& 0xffffffff) <= 0xff)
|
&& operand->exp.X_add_number < 127)
|
|
{
|
{
|
if (operand->exp.X_add_symbol != NULL)
|
if (operand->exp.X_add_symbol != NULL)
|
operand->mode |= bsize;
|
operand->mode |= bsize;
|
else
|
else
|
operand->mode |= L_8;
|
operand->mode |= L_8;
|