[PATCH] frv: Handle out-of-range assembler constants on 64-bit hosts

Segher Boessenkool segher@kernel.crashing.org
Tue Mar 23 18:17:00 GMT 2010


Ping?

opcodes/ChangeLog:
2010-03-23  Segher Boessenkool  <segher@kernel.crashing.org>

	frv-ibld.c (insert_normal): Handle out-of-range
	assembler constants on 64-bit hosts.


> Tested on x86_64-linux cross to frv-elf, no new failures.  Okay to apply?
>
>
> Segher
> ---
>  opcodes/frv-ibld.c |   26 ++++++++++++++++++++++----
>  1 files changed, 22 insertions(+), 4 deletions(-)
>
> diff --git a/opcodes/frv-ibld.c b/opcodes/frv-ibld.c
> index 61db1bf..8e86457 100644
> --- a/opcodes/frv-ibld.c
> +++ b/opcodes/frv-ibld.c
> @@ -175,8 +175,9 @@ insert_normal (CGEN_CPU_DESC cd,
>  	 extended beyond 32 bits.  If so then ignore these higher sign bits
>  	 as the user is attempting to store a 32-bit signed value into an
>  	 unsigned 32-bit field which is allowed.  */
> -      if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
> -	val &= 0xFFFFFFFF;
> +      /* We also need to handle this for fields smaller than 32 bits.  */
> +      if (sizeof (unsigned long) > 4 && ((value << (32 - length) >> 32)
> == -1))
> +	val &= mask;
>
>        if (val > maxval)
>  	{
> @@ -193,8 +194,25 @@ insert_normal (CGEN_CPU_DESC cd,
>  	{
>  	  long minval = - (1L << (length - 1));
>  	  long maxval =   (1L << (length - 1)) - 1;
> -
> -	  if (value < minval || value > maxval)
> +
> +	  /* Some people write constants with the sign extension done by
> +	     hand but only up to 32 bits.  This shouldn't really be valid,
> +	     but, to permit this code to assemble on a 64-bit host, we
> +	     sign extend the 32-bit value to 64 bits if so doing makes the
> +	     value valid.  */
> +	  if (value > maxval
> +	      && (value - 0x80000000 - 0x80000000) >= minval
> +	      && (value - 0x80000000 - 0x80000000) <= maxval)
> +	    value = value - 0x80000000 - 0x80000000;
> +
> +	  /* Similarly, people write expressions like ~(1<<15), and expect
> +	     this to be OK for a 32-bit unsigned value.  */
> +	  else if (value < minval
> +		   && (value + 0x80000000 + 0x80000000) >= minval
> +		   && (value + 0x80000000 + 0x80000000) <= maxval)
> +	    value = value + 0x80000000 + 0x80000000;
> +
> +	  else if (value < minval || value > maxval)
>  	    {
>  	      sprintf
>  		/* xgettext:c-format */
> --
> 1.6.5.2.154.g549c
>



More information about the Binutils mailing list