qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Cc: patches@linaro.org, Michael Matz <matz@suse.de>,
	Alexander Graf <agraf@suse.de>,
	C Fontana <claudio.fontana@linaro.org>,
	Dirk Mueller <dmueller@suse.de>,
	Laurent Desnogues <laurent.desnogues@gmail.com>,
	kvmarm@lists.cs.columbia.edu, Richard Henderson <rth@twiddle.net>
Subject: [Qemu-devel] [PATCH 06/12] target-arm: A64: provide skeleton for a64 insn decoding
Date: Tue,  3 Dec 2013 21:51:11 +0000	[thread overview]
Message-ID: <1386107477-24165-7-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1386107477-24165-1-git-send-email-peter.maydell@linaro.org>

From: Claudio Fontana <claudio.fontana@linaro.org>

Provide a skeleton for a64 instruction decoding in translate-a64.c,
by dividing instructions into the classes defined by the
ARM Architecture Reference Manual(DDI0487A_a) section C3.

Signed-off-by: Claudio Fontana <claudio.fontana@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate-a64.c |  370 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 362 insertions(+), 8 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index a713137..8e16cb1 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -146,17 +146,348 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
     }
 }
 
-static void real_unallocated_encoding(DisasContext *s)
+static void unallocated_encoding(DisasContext *s)
 {
-    fprintf(stderr, "Unknown instruction: %#x\n", s->insn);
     gen_exception_insn(s, 4, EXCP_UDEF);
 }
 
-#define unallocated_encoding(s) do { \
-    fprintf(stderr, "unallocated encoding at line: %d\n", __LINE__); \
-    real_unallocated_encoding(s); \
-    } while (0)
+#define unsupported_encoding(s, insn)                                    \
+    do {                                                                 \
+        qemu_log_mask(LOG_UNIMP,                                         \
+                      "%s:%d: unsupported instruction encoding 0x%08x "  \
+                      "at pc=%016" PRIx64 "\n",                          \
+                      __FILE__, __LINE__, insn, s->pc - 4);              \
+        unallocated_encoding(s);                                         \
+    } while (0);
 
+/*
+ * the instruction disassembly implemented here matches
+ * the instruction encoding classifications in chapter 3 (C3)
+ * of the ARM Architecture Reference Manual (DDI0487A_a)
+ */
+
+/* Unconditional branch (immediate) */
+static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Compare & branch (immediate) */
+static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Test & branch (immediate) */
+static void disas_test_b_imm(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Conditional branch (immediate) */
+static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* System */
+static void disas_system(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Exception generation */
+static void disas_exc(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Unconditional branch (register) */
+static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* C3.2 Branches, exception generating and system instructions */
+static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
+{
+    switch (extract32(insn, 25, 7)) {
+    case 0x0a: case 0x0b:
+    case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
+        disas_uncond_b_imm(s, insn);
+        break;
+    case 0x1a: case 0x5a: /* Compare & branch (immediate) */
+        disas_comp_b_imm(s, insn);
+        break;
+    case 0x1b: case 0x5b: /* Test & branch (immediate) */
+        disas_test_b_imm(s, insn);
+        break;
+    case 0x2a: /* Conditional branch (immediate) */
+        disas_cond_b_imm(s, insn);
+        break;
+    case 0x6a: /* Exception generation / System */
+        if (insn & (1 << 24)) {
+            disas_system(s, insn);
+        } else {
+            disas_exc(s, insn);
+        }
+        break;
+    case 0x6b: /* Unconditional branch (register) */
+        disas_uncond_b_reg(s, insn);
+        break;
+    default:
+        unallocated_encoding(s);
+        break;
+    }
+}
+
+/* Load/store exclusive */
+static void disas_ldst_excl(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Load register (literal) */
+static void disas_ld_lit(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Load/store pair (all forms) */
+static void disas_ldst_pair(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Load/store register (all forms) */
+static void disas_ldst_reg(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* AdvSIMD load/store multiple structures */
+static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* AdvSIMD load/store single structure */
+static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* C3.3 Loads and stores */
+static void disas_ldst(DisasContext *s, uint32_t insn)
+{
+    switch (extract32(insn, 24, 6)) {
+    case 0x08: /* Load/store exclusive */
+        disas_ldst_excl(s, insn);
+        break;
+    case 0x18: case 0x1c: /* Load register (literal) */
+        disas_ld_lit(s, insn);
+        break;
+    case 0x28: case 0x29:
+    case 0x2c: case 0x2d: /* Load/store pair (all forms) */
+        disas_ldst_pair(s, insn);
+        break;
+    case 0x38: case 0x39:
+    case 0x3c: case 0x3d: /* Load/store register (all forms) */
+        disas_ldst_reg(s, insn);
+        break;
+    case 0x0c: /* AdvSIMD load/store multiple structures */
+        disas_ldst_multiple_struct(s, insn);
+        break;
+    case 0x0d: /* AdvSIMD load/store single structure */
+        disas_ldst_single_struct(s, insn);
+        break;
+    default:
+        unallocated_encoding(s);
+        break;
+    }
+}
+
+/* PC-rel. addressing */
+static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Add/subtract (immediate) */
+static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Logical (immediate) */
+static void disas_logic_imm(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Move wide (immediate) */
+static void disas_movw_imm(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Bitfield */
+static void disas_bitfield(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Extract */
+static void disas_extract(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* C3.4 Data processing - immediate */
+static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
+{
+    switch (extract32(insn, 23, 6)) {
+    case 0x20: case 0x21: /* PC-rel. addressing */
+        disas_pc_rel_adr(s, insn);
+        break;
+    case 0x22: case 0x23: /* Add/subtract (immediate) */
+        disas_add_sub_imm(s, insn);
+        break;
+    case 0x24: /* Logical (immediate) */
+        disas_logic_imm(s, insn);
+        break;
+    case 0x25: /* Move wide (immediate) */
+        disas_movw_imm(s, insn);
+        break;
+    case 0x26: /* Bitfield */
+        disas_bitfield(s, insn);
+        break;
+    case 0x27: /* Extract */
+        disas_extract(s, insn);
+        break;
+    default:
+        unallocated_encoding(s);
+        break;
+    }
+}
+
+/* Logical (shifted register) */
+static void disas_logic_reg(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Add/subtract (extended register) */
+static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Add/subtract (shifted register) */
+static void disas_add_sub_reg(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Data-processing (3 source) */
+static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Add/subtract (with carry) */
+static void disas_adc_sbc(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Conditional compare (immediate) */
+static void disas_cc_imm(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Conditional compare (register) */
+static void disas_cc_reg(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Conditional select */
+static void disas_cond_select(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Data-processing (1 source) */
+static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* Data-processing (2 source) */
+static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* C3.5 Data processing - register */
+static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
+{
+    switch (extract32(insn, 24, 5)) {
+    case 0x0a: /* Logical (shifted register) */
+        disas_logic_reg(s, insn);
+        break;
+    case 0x0b: /* Add/subtract */
+        if (insn & (1 << 21)) { /* (extended register) */
+            disas_add_sub_ext_reg(s, insn);
+        } else {
+            disas_add_sub_reg(s, insn);
+        }
+        break;
+    case 0x1b: /* Data-processing (3 source) */
+        disas_data_proc_3src(s, insn);
+        break;
+    case 0x1a:
+        switch (extract32(insn, 21, 3)) {
+        case 0x0: /* Add/subtract (with carry) */
+            disas_adc_sbc(s, insn);
+            break;
+        case 0x2: /* Conditional compare */
+            if (insn & (1 << 11)) { /* (immediate) */
+                disas_cc_imm(s, insn);
+            } else {            /* (register) */
+                disas_cc_reg(s, insn);
+            }
+            break;
+        case 0x4: /* Conditional select */
+            disas_cond_select(s, insn);
+            break;
+        case 0x6: /* Data-processing */
+            if (insn & (1 << 30)) { /* (1 source) */
+                disas_data_proc_1src(s, insn);
+            } else {            /* (2 source) */
+                disas_data_proc_2src(s, insn);
+            }
+            break;
+        default:
+            unallocated_encoding(s);
+            break;
+        }
+        break;
+    default:
+        unallocated_encoding(s);
+        break;
+    }
+}
+
+/* C3.6 Data processing - SIMD and floating point */
+static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
+{
+    unsupported_encoding(s, insn);
+}
+
+/* C3.1 A64 instruction index by encoding */
 static void disas_a64_insn(CPUARMState *env, DisasContext *s)
 {
     uint32_t insn;
@@ -165,10 +496,33 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
     s->insn = insn;
     s->pc += 4;
 
-    switch ((insn >> 24) & 0x1f) {
-    default:
+    switch (extract32(insn, 25, 4)) {
+    case 0x0: case 0x1: case 0x2: case 0x3: /* UNALLOCATED */
         unallocated_encoding(s);
         break;
+    case 0x8: case 0x9: /* Data processing - immediate */
+        disas_data_proc_imm(s, insn);
+        break;
+    case 0xa: case 0xb: /* Branch, exception generation and system insns */
+        disas_b_exc_sys(s, insn);
+        break;
+    case 0x4:
+    case 0x6:
+    case 0xc:
+    case 0xe:      /* Loads and stores */
+        disas_ldst(s, insn);
+        break;
+    case 0x5:
+    case 0xd:      /* Data processing - register */
+        disas_data_proc_reg(s, insn);
+        break;
+    case 0x7:
+    case 0xf:      /* Data processing - SIMD and floating point */
+        disas_data_proc_simd_fp(s, insn);
+        break;
+    default:
+        assert(FALSE); /* all 15 cases should be handled above */
+        break;
     }
 }
 
-- 
1.7.9.5

  parent reply	other threads:[~2013-12-03 21:52 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-03 21:51 [Qemu-devel] [PATCH 00/12] target-arm: A64 decoder, foundation plus branches Peter Maydell
2013-12-03 21:51 ` [Qemu-devel] [PATCH 01/12] target-arm: Split A64 from A32/T32 gen_intermediate_code_internal() Peter Maydell
2013-12-03 23:34   ` Richard Henderson
2013-12-03 21:51 ` [Qemu-devel] [PATCH 02/12] target-arm: A64: add set_pc cpu method Peter Maydell
2013-12-03 23:35   ` Richard Henderson
2013-12-03 21:51 ` [Qemu-devel] [PATCH 03/12] target-arm: A64: provide functions for accessing FPCR and FPSR Peter Maydell
2013-12-03 23:39   ` Richard Henderson
2013-12-03 21:51 ` [Qemu-devel] [PATCH 04/12] target-arm: Support fp registers in gdb stub Peter Maydell
2013-12-03 23:40   ` Richard Henderson
2013-12-03 21:51 ` [Qemu-devel] [PATCH 05/12] target-arm: A64: add stubs for a64 specific helpers Peter Maydell
2013-12-03 23:41   ` Richard Henderson
2013-12-03 21:51 ` Peter Maydell [this message]
2013-12-03 23:41   ` [Qemu-devel] [PATCH 06/12] target-arm: A64: provide skeleton for a64 insn decoding Richard Henderson
2013-12-03 21:51 ` [Qemu-devel] [PATCH 07/12] target-arm: A64: expand decoding skeleton for system instructions Peter Maydell
2013-12-03 23:15   ` Christopher Covington
2013-12-04  0:21     ` Peter Maydell
2013-12-03 23:49   ` Richard Henderson
2013-12-03 21:51 ` [Qemu-devel] [PATCH 08/12] target-arm: A64: add support for B and BL insns Peter Maydell
2013-12-03 21:51 ` [Qemu-devel] [PATCH 09/12] target-arm: A64: add support for BR, BLR and RET insns Peter Maydell
2013-12-04  0:00   ` Richard Henderson
2013-12-03 21:51 ` [Qemu-devel] [PATCH 10/12] target-arm: A64: add support for conditional branches Peter Maydell
2013-12-04  0:03   ` Richard Henderson
2013-12-04  0:22     ` Peter Maydell
2013-12-03 21:51 ` [Qemu-devel] [PATCH 11/12] target-arm: A64: add support for 'test and branch' imm Peter Maydell
2013-12-04  0:07   ` Richard Henderson
2013-12-04  0:22     ` Peter Maydell
2013-12-03 21:51 ` [Qemu-devel] [PATCH 12/12] target-arm: A64: add support for compare and branch imm Peter Maydell
2013-12-04  0:10   ` Richard Henderson
2013-12-04  0:32     ` Peter Maydell
2013-12-04  0:48       ` Richard Henderson
2013-12-04 11:05         ` Peter Maydell
2013-12-04 17:02         ` Peter Maydell
2013-12-04 17:31           ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1386107477-24165-7-git-send-email-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=agraf@suse.de \
    --cc=claudio.fontana@linaro.org \
    --cc=dmueller@suse.de \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=laurent.desnogues@gmail.com \
    --cc=matz@suse.de \
    --cc=patches@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).