arm/translate-a64: add FP16 FMOV to simd_mod_imm

Only one half-precision instruction has been added to this group.

Backports commit 70b4e6a445715519ae55179dc54f6e961ab30c27 from qemu
This commit is contained in:
Alex Bennée 2018-03-08 22:48:26 -05:00 committed by Lioncash
parent b117df18df
commit 8bbabd7eb3
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -6350,6 +6350,8 @@ static void disas_simd_copy(DisasContext *s, uint32_t insn)
* MVNI - move inverted (shifted) imm into register * MVNI - move inverted (shifted) imm into register
* ORR - bitwise OR of (shifted) imm with register * ORR - bitwise OR of (shifted) imm with register
* BIC - bitwise clear 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) static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
{ {
@ -6365,9 +6367,12 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
uint64_t imm = 0; uint64_t imm = 0;
if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) { if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
/* Check for FMOV (vector, immediate) - half-precision */
if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
unallocated_encoding(s); unallocated_encoding(s);
return; return;
} }
}
if (!fp_access_check(s)) { if (!fp_access_check(s)) {
return; return;
@ -6423,6 +6428,12 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
} else { } else {
imm |= 0x4000000000000000ULL; imm |= 0x4000000000000000ULL;
} }
} else {
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 { } else {
imm = (abcdefgh & 0x3f) << 19; imm = (abcdefgh & 0x3f) << 19;
if (abcdefgh & 0x80) { if (abcdefgh & 0x80) {
@ -6436,7 +6447,11 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
imm |= (imm << 32); imm |= (imm << 32);
} }
} }
}
break; 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) { if (cmode_3_1 != 7 && is_neg) {