mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 19:09:31 +08:00
[AArch64][PATCH 2/3] Adjust a utility function for floating point values.
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 change made to the function is to treat a request for a 16-bit float as a request for a 32-bit float. opcodes/ 2015-11-27 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. Change-Id: I1ae3df3864be375d71925197ab03397ed1ad2d15
This commit is contained in:
@ -1,3 +1,13 @@
|
|||||||
|
2015-11-27 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.
|
||||||
|
|
||||||
2015-11-27 Matthew Wahab <matthew.wahab@arm.com>
|
2015-11-27 Matthew Wahab <matthew.wahab@arm.com>
|
||||||
|
|
||||||
* aarch64-tbl.h (aarch64_feature_fp_f16): New.
|
* aarch64-tbl.h (aarch64_feature_fp_f16): New.
|
||||||
|
@ -2172,14 +2172,22 @@ typedef union
|
|||||||
float f;
|
float f;
|
||||||
} single_conv_t;
|
} 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
|
/* 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
|
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
|
(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
|
single-precision floating-point value (SIZE == 4) or a double-precision
|
||||||
floating-point value (IS_DP == 1). The expanded value is returned. */
|
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
|
static uint64_t
|
||||||
expand_fp_imm (int is_dp, uint32_t imm8)
|
expand_fp_imm (int size, uint32_t imm8)
|
||||||
{
|
{
|
||||||
uint64_t imm;
|
uint64_t imm;
|
||||||
uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
|
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 = imm8_6_0 >> 6; /* imm8<6> */
|
||||||
imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
|
imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
|
||||||
| (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
|
| (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
|
||||||
if (is_dp)
|
if (size == 8)
|
||||||
{
|
{
|
||||||
imm = (imm8_7 << (63-32)) /* imm8<7> */
|
imm = (imm8_7 << (63-32)) /* imm8<7> */
|
||||||
| ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6) */
|
| ((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> */
|
| (imm8_6_0 << (48-32)); /* imm8<6>:imm8<5:0> */
|
||||||
imm <<= 32;
|
imm <<= 32;
|
||||||
}
|
}
|
||||||
else
|
else if (size == 4 || size == 2)
|
||||||
{
|
{
|
||||||
imm = (imm8_7 << 31) /* imm8<7> */
|
imm = (imm8_7 << 31) /* imm8<7> */
|
||||||
| ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
|
| ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
|
||||||
| (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
|
| (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
|
||||||
| (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
|
| (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* An unsupported size. */
|
||||||
|
assert (0);
|
||||||
|
}
|
||||||
|
|
||||||
return imm;
|
return imm;
|
||||||
}
|
}
|
||||||
@ -2533,17 +2546,24 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
|
|||||||
case AARCH64_OPND_SIMD_FPIMM:
|
case AARCH64_OPND_SIMD_FPIMM:
|
||||||
switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
|
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>. */
|
case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
|
||||||
{
|
{
|
||||||
single_conv_t c;
|
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);
|
snprintf (buf, size, "#%.18e", c.f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8: /* e.g. FMOV <Sd>, #<imm>. */
|
case 8: /* e.g. FMOV <Sd>, #<imm>. */
|
||||||
{
|
{
|
||||||
double_conv_t c;
|
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);
|
snprintf (buf, size, "#%.18e", c.d);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user