Fix compile warnings building previous delta in a 32-bit environment.

* config/tc-arm.c (is_double_a_single): Make conditional upon the
	availablity of a 64-bit type.  Use this type for the argument and
	mantissa.
	(double_to_single): Likewise.
	* config/tc-arm.c (move_or_literal_pool): Use a 64-bit type for
	the constant value, if available.  Generate a 64-bit value from a
	bignum if supported.  Only perform the second optimization for
	PR 18500 if the 64-bit type is available.
This commit is contained in:
Nick Clifton
2015-06-17 16:10:36 +01:00
parent 2093d2d314
commit 5fc177c895
2 changed files with 43 additions and 8 deletions

View File

@ -1,3 +1,14 @@
2015-06-17 Nick Clifton <nickc@redhat.com>
* config/tc-arm.c (is_double_a_single): Make conditional upon the
availablity of a 64-bit type. Use this type for the argument and
mantissa.
(double_to_single): Likewise.
* config/tc-arm.c (move_or_literal_pool): Use a 64-bit type for
the constant value, if available. Generate a 64-bit value from a
bignum if supported. Only perform the second optimization for
PR 18500 if the 64-bit type is available.
2015-06-17 Alessandro Marzocchi <alessandro.marzocchi@gmail.com> 2015-06-17 Alessandro Marzocchi <alessandro.marzocchi@gmail.com>
PR gas/18500 PR gas/18500

View File

@ -7752,14 +7752,15 @@ neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
return FAIL; return FAIL;
} }
#if defined BFD_HOST_64_BIT
/* Returns TRUE if double precision value V may be cast /* Returns TRUE if double precision value V may be cast
to single precision without loss of accuracy. */ to single precision without loss of accuracy. */
static bfd_boolean static bfd_boolean
is_double_a_single (long int v) is_double_a_single (bfd_int64_t v)
{ {
int exp = (int) (v >> 52) & 0x7FF; int exp = (int)((v >> 52) & 0x7FF);
long int mantissa = (v & 0xFFFFFFFFFFFFFl); bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFF);
return (exp == 0 || exp == 0x7FF return (exp == 0 || exp == 0x7FF
|| (exp >= 1023 - 126 && exp <= 1023 + 127)) || (exp >= 1023 - 126 && exp <= 1023 + 127))
@ -7770,11 +7771,11 @@ is_double_a_single (long int v)
(ignoring the least significant bits in exponent and mantissa). */ (ignoring the least significant bits in exponent and mantissa). */
static int static int
double_to_single (long int v) double_to_single (bfd_int64_t v)
{ {
int sign = (int) ((v >> 63) & 1l); int sign = (int) ((v >> 63) & 1l);
int exp = (int) (v >> 52) & 0x7FF; int exp = (int) ((v >> 52) & 0x7FF);
long int mantissa = (v & 0xFFFFFFFFFFFFFl); bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFF);
if (exp == 0x7FF) if (exp == 0x7FF)
exp = 0xFF; exp = 0xFF;
@ -7797,6 +7798,7 @@ double_to_single (long int v)
mantissa >>= 29; mantissa >>= 29;
return (sign << 31) | (exp << 23) | mantissa; return (sign << 31) | (exp << 23) | mantissa;
} }
#endif /* BFD_HOST_64_BIT */
enum lit_type enum lit_type
{ {
@ -7845,8 +7847,11 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
if (inst.reloc.exp.X_op == O_constant if (inst.reloc.exp.X_op == O_constant
|| inst.reloc.exp.X_op == O_big) || inst.reloc.exp.X_op == O_big)
{ {
#if defined BFD_HOST_64_BIT
bfd_int64_t v;
#else
offsetT v; offsetT v;
#endif
if (inst.reloc.exp.X_op == O_big) if (inst.reloc.exp.X_op == O_big)
{ {
LITTLENUM_TYPE w[X_PRECISION]; LITTLENUM_TYPE w[X_PRECISION];
@ -7861,8 +7866,19 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
else else
l = generic_bignum; l = generic_bignum;
#if defined BFD_HOST_64_BIT
v =
((((((((bfd_int64_t) l[3] & LITTLENUM_MASK)
<< LITTLENUM_NUMBER_OF_BITS)
| ((bfd_int64_t) l[2] & LITTLENUM_MASK))
<< LITTLENUM_NUMBER_OF_BITS)
| ((bfd_int64_t) l[1] & LITTLENUM_MASK))
<< LITTLENUM_NUMBER_OF_BITS)
| ((bfd_int64_t) l[0] & LITTLENUM_MASK));
#else
v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
| (l[0] & LITTLENUM_MASK); | (l[0] & LITTLENUM_MASK);
#endif
} }
else else
v = inst.reloc.exp.X_add_number; v = inst.reloc.exp.X_add_number;
@ -8005,6 +8021,13 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
do_vfp_nsyn_opcode ("fconsts"); do_vfp_nsyn_opcode ("fconsts");
return TRUE; return TRUE;
} }
/* If our host does not support a 64-bit type then we cannot perform
the following optimization. This mean that there will be a
discrepancy between the output produced by an assembler built for
a 32-bit-only host and the output produced from a 64-bit host, but
this cannot be helped. */
#if defined BFD_HOST_64_BIT
else if (!inst.operands[1].issingle else if (!inst.operands[1].issingle
&& ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3)) && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
{ {
@ -8017,6 +8040,7 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
return TRUE; return TRUE;
} }
} }
#endif
} }
} }
@ -23137,7 +23161,7 @@ md_apply_fix (fixS * fixP,
if (subtract || value & ~0x3fc) if (subtract || value & ~0x3fc)
as_bad_where (fixP->fx_file, fixP->fx_line, as_bad_where (fixP->fx_file, fixP->fx_line,
_("invalid immediate for address calculation (value = 0x%08lX)"), _("invalid immediate for address calculation (value = 0x%08lX)"),
(unsigned long) value); (unsigned long) (subtract ? - value : value));
newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP); newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
newval |= rd << 8; newval |= rd << 8;
newval |= value >> 2; newval |= value >> 2;