From patchwork Wed Dec 4 19:33:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 22030 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f198.google.com (mail-ob0-f198.google.com [209.85.214.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id F15982401F for ; Wed, 4 Dec 2013 19:33:36 +0000 (UTC) Received: by mail-ob0-f198.google.com with SMTP id wo20sf52185665obc.9 for ; Wed, 04 Dec 2013 11:33:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=t/oLyVoNdyNye/CVt1m6ZZfcuv5kt+R/HE1Nq8MaSHw=; b=fZR1IDpvBduxvFxGr2BPkiOsEOxZgVnEpFrk5T7jYWSz7h4o1mlKp5M8bzjHCqLKWh 9CG/thYlbiv2KuZ9wCvuhRRnlBxd1yANQU058l6AYrWIX8IVLUPhktmuVCTs1Kkl2sqb FImETC/EFC2oelo7dHrW0F912+O2j7GcsLWxP134AFX8Vat8xbmOcHlWP8SnS1drmJkz SwcsIZhN6H3fkLkHbCVmK284tyzRwtEG3fhqln/qZsXh6mxF8MJ/aaRttgg56iqyFMq/ JLjRiJFI0HCMCYQ+YgpEyIEV7xbVTdtN7fDDrRHdwp2Kue/fl9X8AkCPHIY0UOiQftFH Ct1A== X-Gm-Message-State: ALoCoQlF1DQ+Fsnmq7OxVLnqdPpNndiT/iDDTd0QUbxwrfjvthoW6BZSX2G+bL0WwE6jvps52czO X-Received: by 10.50.41.101 with SMTP id e5mr1010124igl.0.1386185616577; Wed, 04 Dec 2013 11:33:36 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.129.131 with SMTP id nw3ls519273qeb.86.gmail; Wed, 04 Dec 2013 11:33:36 -0800 (PST) X-Received: by 10.220.244.132 with SMTP id lq4mr1913906vcb.31.1386185616430; Wed, 04 Dec 2013 11:33:36 -0800 (PST) Received: from mail-vc0-f179.google.com (mail-vc0-f179.google.com [209.85.220.179]) by mx.google.com with ESMTPS id s4si33258409vcy.61.2013.12.04.11.33.36 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 04 Dec 2013 11:33:36 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.179 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.179; Received: by mail-vc0-f179.google.com with SMTP id ie18so12108898vcb.10 for ; Wed, 04 Dec 2013 11:33:36 -0800 (PST) X-Received: by 10.58.207.15 with SMTP id ls15mr60514712vec.17.1386185616205; Wed, 04 Dec 2013 11:33:36 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp318430vcz; Wed, 4 Dec 2013 11:33:35 -0800 (PST) X-Received: by 10.205.38.199 with SMTP id tj7mr248793bkb.134.1386185613886; Wed, 04 Dec 2013 11:33:33 -0800 (PST) Received: from mnementh.archaic.org.uk (1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id kw6si3881518bkb.335.2013.12.04.11.33.32 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 04 Dec 2013 11:33:33 -0800 (PST) Received-SPF: neutral (google.com: 2001:8b0:1d0::1 is neither permitted nor denied by best guess record for domain of pm215@archaic.org.uk) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1VoICP-0006eE-DO; Wed, 04 Dec 2013 19:33:29 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Alexander Graf , C Fontana , Dirk Mueller , Michael Matz , Laurent Desnogues , Richard Henderson , kvmarm@lists.cs.columbia.edu Subject: [PATCH v2 06/12] target-arm: A64: provide skeleton for a64 insn decoding Date: Wed, 4 Dec 2013 19:33:23 +0000 Message-Id: <1386185609-25505-7-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1386185609-25505-1-git-send-email-peter.maydell@linaro.org> References: <1386185609-25505-1-git-send-email-peter.maydell@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.179 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Claudio Fontana 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 Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- 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; } }