[v3,03/16] target/arm: Refactor disas_simd_indexed size checks

Message ID 20180228193125.20577-4-richard.henderson@linaro.org
State New
Headers show
Series
  • ARM v8.1 simd + v8.3 complex insns
Related show

Commit Message

Richard Henderson Feb. 28, 2018, 7:31 p.m.
The integer size check was already outside of the opcode switch;
move the floating-point size check outside as well.  Unify the
size vs index adjustment between fp and integer paths.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 target/arm/translate-a64.c | 65 +++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 33 deletions(-)

-- 
2.14.3

Comments

Peter Maydell March 1, 2018, 1:19 p.m. | #1
On 28 February 2018 at 19:31, Richard Henderson
<richard.henderson@linaro.org> wrote:
> The integer size check was already outside of the opcode switch;

> move the floating-point size check outside as well.  Unify the

> size vs index adjustment between fp and integer paths.

>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---


Reviewed-by: Peter Maydell <peter.maydell@linaro.org>


thanks
-- PMM

Patch

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index fc928b61f6..cbb4510e3a 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11820,10 +11820,6 @@  static void disas_simd_indexed(DisasContext *s, uint32_t insn)
     case 0x05: /* FMLS */
     case 0x09: /* FMUL */
     case 0x19: /* FMULX */
-        if (size == 1) {
-            unallocated_encoding(s);
-            return;
-        }
         is_fp = true;
         break;
     default:
@@ -11834,45 +11830,48 @@  static void disas_simd_indexed(DisasContext *s, uint32_t insn)
     if (is_fp) {
         /* convert insn encoded size to TCGMemOp size */
         switch (size) {
-        case 2: /* single precision */
-            size = MO_32;
-            index = h << 1 | l;
-            rm |= (m << 4);
-            break;
-        case 3: /* double precision */
-            size = MO_64;
-            if (l || !is_q) {
+        case 0: /* half-precision */
+            if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
                 unallocated_encoding(s);
                 return;
             }
-            index = h;
-            rm |= (m << 4);
-            break;
-        case 0: /* half precision */
             size = MO_16;
-            index = h << 2 | l << 1 | m;
-            is_fp16 = true;
-            if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
-                break;
-            }
-            /* fallthru */
-        default: /* unallocated */
-            unallocated_encoding(s);
-            return;
-        }
-    } else {
-        switch (size) {
-        case 1:
-            index = h << 2 | l << 1 | m;
             break;
-        case 2:
-            index = h << 1 | l;
-            rm |= (m << 4);
+        case MO_32: /* single precision */
+        case MO_64: /* double precision */
             break;
         default:
             unallocated_encoding(s);
             return;
         }
+    } else {
+        switch (size) {
+        case MO_8:
+        case MO_64:
+            unallocated_encoding(s);
+            return;
+        }
+    }
+
+    /* Given TCGMemOp size, adjust register and indexing.  */
+    switch (size) {
+    case MO_16:
+        index = h << 2 | l << 1 | m;
+        break;
+    case MO_32:
+        index = h << 1 | l;
+        rm |= m << 4;
+        break;
+    case MO_64:
+        if (l || !is_q) {
+            unallocated_encoding(s);
+            return;
+        }
+        index = h;
+        rm |= m << 4;
+        break;
+    default:
+        g_assert_not_reached();
     }
 
     if (!fp_access_check(s)) {