This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [AArch64][SVE 08/32] Generalise aarch64_double_precision_fmovable


On 23/08/16 10:10, Richard Sandiford wrote:
> SVE has single-bit floating-point constants that don't really
> have any relation to the AArch64 8-bit floating-point encoding.
> (E.g. one of the constants selects between 0 and 1.)  The easiest
> way of representing them in the aarch64_opnd_info seemed to be
> to use the IEEE float representation directly, rather than invent
> some new scheme.
> 
> This patch paves the way for that by making the code that converts IEEE
> doubles to IEEE floats accept any value in the range of an IEEE float,
> not just zero and 8-bit floats.  It leaves the range checking to the
> caller (which already handles it).
> 
> OK to install?
> 
> Thanks,
> Richard
> 
> 
> gas/
> 	* config/tc-aarch64.c (aarch64_double_precision_fmovable): Rename
> 	to...
> 	(can_convert_double_to_float): ...this.  Accept any double-precision
> 	value that converts to single precision without loss of precision.
> 	(parse_aarch64_imm_float): Update accordingly.

OK.

R.

> 
> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index eec08c7..40f6253 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -2093,56 +2093,52 @@ aarch64_imm_float_p (uint32_t imm)
>      && ((imm & 0x7e000000) == pattern);	/* bits 25 - 29 == ~ bit 30.  */
>  }
>  
> -/* Like aarch64_imm_float_p but for a double-precision floating-point value.
> -
> -   Return TRUE if the value encoded in IMM can be expressed in the AArch64
> -   8-bit signed floating-point format with 3-bit exponent and normalized 4
> -   bits of precision (i.e. can be used in an FMOV instruction); return the
> -   equivalent single-precision encoding in *FPWORD.
> -
> -   Otherwise return FALSE.  */
> +/* Return TRUE if the IEEE double value encoded in IMM can be expressed
> +   as an IEEE float without any loss of precision.  Store the value in
> +   *FPWORD if so.  */
>  
>  static bfd_boolean
> -aarch64_double_precision_fmovable (uint64_t imm, uint32_t *fpword)
> +can_convert_double_to_float (uint64_t imm, uint32_t *fpword)
>  {
>    /* If a double-precision floating-point value has the following bit
> -     pattern, it can be expressed in the AArch64 8-bit floating-point
> -     format:
> +     pattern, it can be expressed in a float:
>  
> -     6 66655555555 554444444...21111111111
> -     3 21098765432 109876543...098765432109876543210
> -     n Eeeeeeeeexx xxxx00000...000000000000000000000
> +     6 66655555555 5544 44444444 33333333 33222222 22221111 111111
> +     3 21098765432 1098 76543210 98765432 10987654 32109876 54321098 76543210
> +     n E~~~eeeeeee ssss ssssssss ssssssss SSS00000 00000000 00000000 00000000
>  
> -     where n, e and each x are either 0 or 1 independently, with
> -     E == ~ e.  */
> +       ----------------------------->     nEeeeeee esssssss ssssssss sssssSSS
> +	 if Eeee_eeee != 1111_1111
> +
> +     where n, e, s and S are either 0 or 1 independently and where ~ is the
> +     inverse of E.  */
>  
>    uint32_t pattern;
>    uint32_t high32 = imm >> 32;
> +  uint32_t low32 = imm;
>  
> -  /* Lower 32 bits need to be 0s.  */
> -  if ((imm & 0xffffffff) != 0)
> +  /* Lower 29 bits need to be 0s.  */
> +  if ((imm & 0x1fffffff) != 0)
>      return FALSE;
>  
>    /* Prepare the pattern for 'Eeeeeeeee'.  */
>    if (((high32 >> 30) & 0x1) == 0)
> -    pattern = 0x3fc00000;
> +    pattern = 0x38000000;
>    else
>      pattern = 0x40000000;
>  
> -  if ((high32 & 0xffff) == 0			/* bits 32 - 47 are 0.  */
> -      && (high32 & 0x7fc00000) == pattern)	/* bits 54 - 61 == ~ bit 62.  */
> -    {
> -      /* Convert to the single-precision encoding.
> -         i.e. convert
> -	   n Eeeeeeeeexx xxxx00000...000000000000000000000
> -	 to
> -	   n Eeeeeexx xxxx0000000000000000000.  */
> -      *fpword = ((high32 & 0xfe000000)			/* nEeeeee.  */
> -		 | (((high32 >> 16) & 0x3f) << 19));	/* xxxxxx.  */
> -      return TRUE;
> -    }
> -  else
> +  /* Check E~~~.  */
> +  if ((high32 & 0x78000000) != pattern)
>      return FALSE;
> +
> +  /* Check Eeee_eeee != 1111_1111.  */
> +  if ((high32 & 0x7ff00000) == 0x47f00000)
> +    return FALSE;
> +
> +  *fpword = ((high32 & 0xc0000000)		/* 1 n bit and 1 E bit.  */
> +	     | ((high32 << 3) & 0x3ffffff8)	/* 7 e and 20 s bits.  */
> +	     | (low32 >> 29));			/* 3 S bits.  */
> +  return TRUE;
>  }
>  
>  /* Parse a floating-point immediate.  Return TRUE on success and return the
> @@ -2181,7 +2177,7 @@ parse_aarch64_imm_float (char **ccp, int *immed, bfd_boolean dp_p,
>  
>        if (dp_p)
>  	{
> -	  if (! aarch64_double_precision_fmovable (val, &fpword))
> +	  if (!can_convert_double_to_float (val, &fpword))
>  	    goto invalid_fp;
>  	}
>        else if ((uint64_t) val > 0xffffffff)
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]