This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
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)
>