Only one half-precision instruction has been added to this group.
Signed-off-by: Alex Bennée
---
v2
- checkpatch fixes
v3
- use vfp_expand_imm
---
target/arm/translate-a64.c | 35 +--
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index faec8084fa..806f2eb34a 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -6234,6 +6234,8 @@ static void disas_simd_copy(DisasContext *s, uint32_t
insn)
* MVNI - move inverted (shifted) imm into register
* ORR - bitwise OR of (shifted) imm with register
* BIC - bitwise clear of (shifted) imm with register
+ * With ARMv8.2 we also have:
+ * FMOV half-precision
*/
static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
{
@@ -6248,8 +6250,11 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t
insn)
uint64_t imm = 0;
if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
-unallocated_encoding(s);
-return;
+/* Check for FMOV (vector, immediate) - half-precision */
+if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
+unallocated_encoding(s);
+return;
+}
}
if (!fp_access_check(s)) {
@@ -6307,19 +6312,29 @@ static void disas_simd_mod_imm(DisasContext *s,
uint32_t insn)
imm |= 0x4000ULL;
}
} else {
-imm = (abcdefgh & 0x3f) << 19;
-if (abcdefgh & 0x80) {
-imm |= 0x8000;
-}
-if (abcdefgh & 0x40) {
-imm |= 0x3e00;
+if (o2) {
+/* FMOV (vector, immediate) - half-precision */
+imm = vfp_expand_imm(MO_16, abcdefgh);
+/* now duplicate across the lanes */
+imm = bitfield_replicate(imm, 16);
} else {
-imm |= 0x4000;
+imm = (abcdefgh & 0x3f) << 19;
+if (abcdefgh & 0x80) {
+imm |= 0x8000;
+}
+if (abcdefgh & 0x40) {
+imm |= 0x3e00;
+} else {
+imm |= 0x4000;
+}
+imm |= (imm << 32);
}
-imm |= (imm << 32);
}
}
break;
+default:
+fprintf(stderr, "%s: cmode_3_1: %x\n", __func__, cmode_3_1);
+g_assert_not_reached();
}
if (cmode_3_1 != 7 && is_neg) {
--
2.15.1