Re: [Qemu-devel] [PATCH v3 28/31] arm/translate-a64: add FP16 FMOV to simd_mod_imm

2018-02-23 Thread Richard Henderson
On 02/23/2018 07:36 AM, Alex Bennée wrote:
> 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(-)

Reviewed-by: Richard Henderson 


r~




[Qemu-devel] [PATCH v3 28/31] arm/translate-a64: add FP16 FMOV to simd_mod_imm

2018-02-23 Thread Alex Bennée
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