This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[AArch64][PATCH 2/3] Adjust a utility function for floating point values.
- From: Matthew Wahab <matthew dot wahab at foss dot arm dot com>
- To: binutils at sourceware dot org
- Date: Tue, 24 Nov 2015 11:52:31 +0000
- Subject: [AArch64][PATCH 2/3] Adjust a utility function for floating point values.
- Authentication-results: sourceware.org; auth=none
- References: <56544EB9 dot 9000909 at foss dot arm dot com>
Hello,
ARMv8.2 adds 16-bit floating point operations as an optional
extension. This patch adjusts the utility function expand_fp_imm to
support 16-bit values.
The function is intended to convert an 8-bit immediate representing a
floating point value to a representation that can be passed to
fprintf. Because of the limited use of the results, the only made to the
function is to treat a request for a 16-bit float as a request for a
32-bit float.
Tested the series for aarch64-none-linux gnu with cross-compiled
check-binutils and check-gas.
Ok for trunk?
Matthew
opcodes/
2015-11-24 Matthew Wahab <matthew.wahab@arm.com>
* aarch64-opc.c (half_conv_t): New.
(expand_fp_imm): Replace is_dp flag with the parameter size to
specify the number of bytes for the required expansion. Treat
a 16-bit expansion like a 32-bit expansion. Add check for an
unsupported size request. Update comment.
(aarch64_print_operand): Update to support 16-bit floating point
values. Update for changes to expand_fp_imm.
>From 3bad8c08f4305e9cdec5d02789c56d0cd1f46165 Mon Sep 17 00:00:00 2001
From: Matthew Wahab <matthew.wahab@arm.com>
Date: Thu, 24 Sep 2015 18:37:14 +0100
Subject: [PATCH 2/3] [AArch64][PATCH 2/3] Adjust a utility function for
floating point values.
Change-Id: I1c5caff2b7321bfd06f44142e0064a5feed87c9a
---
opcodes/aarch64-opc.c | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 9d1aa56..db14ce2 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -2172,14 +2172,22 @@ typedef union
float f;
} single_conv_t;
+typedef union
+{
+ uint32_t i;
+ float f;
+} half_conv_t;
+
/* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
(depending on the type of the instruction). IMM8 will be expanded to a
- single-precision floating-point value (IS_DP == 0) or a double-precision
- floating-point value (IS_DP == 1). The expanded value is returned. */
+ single-precision floating-point value (SIZE == 4) or a double-precision
+ floating-point value (SIZE == 8). A half-precision floating-point value
+ (SIZE == 2) is expanded to a single-precision floating-point value. The
+ expanded value is returned. */
static uint64_t
-expand_fp_imm (int is_dp, uint32_t imm8)
+expand_fp_imm (int size, uint32_t imm8)
{
uint64_t imm;
uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
@@ -2189,7 +2197,7 @@ expand_fp_imm (int is_dp, uint32_t imm8)
imm8_6 = imm8_6_0 >> 6; /* imm8<6> */
imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
| (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
- if (is_dp)
+ if (size == 8)
{
imm = (imm8_7 << (63-32)) /* imm8<7> */
| ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6) */
@@ -2198,13 +2206,18 @@ expand_fp_imm (int is_dp, uint32_t imm8)
| (imm8_6_0 << (48-32)); /* imm8<6>:imm8<5:0> */
imm <<= 32;
}
- else
+ else if (size == 4 || size == 2)
{
imm = (imm8_7 << 31) /* imm8<7> */
| ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
| (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
| (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
}
+ else
+ {
+ /* An unsupported size. */
+ assert (0);
+ }
return imm;
}
@@ -2533,17 +2546,24 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_SIMD_FPIMM:
switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
{
+ case 2: /* e.g. FMOV <Hd>, #<imm>. */
+ {
+ half_conv_t c;
+ c.i = expand_fp_imm (2, opnd->imm.value);
+ snprintf (buf, size, "#%.18e", c.f);
+ }
+ break;
case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
{
single_conv_t c;
- c.i = expand_fp_imm (0, opnd->imm.value);
+ c.i = expand_fp_imm (4, opnd->imm.value);
snprintf (buf, size, "#%.18e", c.f);
}
break;
case 8: /* e.g. FMOV <Sd>, #<imm>. */
{
double_conv_t c;
- c.i = expand_fp_imm (1, opnd->imm.value);
+ c.i = expand_fp_imm (8, opnd->imm.value);
snprintf (buf, size, "#%.18e", c.d);
}
break;
--
2.1.4