From patchwork Tue Dec 3 21:51:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 21998 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 ACDA9202DA for ; Tue, 3 Dec 2013 21:51:27 +0000 (UTC) Received: by mail-ob0-f198.google.com with SMTP id wo20sf47956405obc.1 for ; Tue, 03 Dec 2013 13:51:27 -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=6LLy9fkDYkNh35GJF3lpcf1n4bpX8cDmbUv51glhJTA=; b=dg+bAkgszQQoZ/G7BdodgEIE2TlAJQgw9V87jSrWfuPD13+f+Ejm7P5l4hziL7nGUW njiv9En2sDxIYfBpia9yiqbHMv4e8X16n6Ft1sm2keEo2eu54P3bUjN7HPWhBrfo9MHN 6EIY/HyODnYgcipnGyrVyrSz8enLcCP6UrsGNCRvcilbyMb5D3fqTUyTaZoRvCGvtX5q 4xChw5tXn8zIxvHgrAvyw+Au73FNOyqEhZ63sOf5RZXFuYMElw2O+6XE7+WunE68AvGo jLd7ltumQJ/FzxrsiC98BZJaIqzwxsEgG2ZslvVPLpmINSIuwBPXrvoQifabhW9X5Lel hkNw== X-Gm-Message-State: ALoCoQlLw6RTOe4PXvMv27F2LRYIW/J7pIbAqw/mf2Pf3nIRAiJSV0FdXiNIekWA7i1NF+zvaEF4 X-Received: by 10.182.120.198 with SMTP id le6mr434818obb.44.1386107487308; Tue, 03 Dec 2013 13:51:27 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.49.70 with SMTP id s6ls3866qen.34.gmail; Tue, 03 Dec 2013 13:51:26 -0800 (PST) X-Received: by 10.52.0.81 with SMTP id 17mr64597vdc.50.1386107486944; Tue, 03 Dec 2013 13:51:26 -0800 (PST) Received: from mail-ve0-f176.google.com (mail-ve0-f176.google.com [209.85.128.176]) by mx.google.com with ESMTPS id vr9si31872332vcb.126.2013.12.03.13.51.26 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 03 Dec 2013 13:51:26 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.176 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.176; Received: by mail-ve0-f176.google.com with SMTP id oz11so11089895veb.35 for ; Tue, 03 Dec 2013 13:51:26 -0800 (PST) X-Received: by 10.220.74.69 with SMTP id t5mr42436923vcj.18.1386107486722; Tue, 03 Dec 2013 13:51:26 -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 u4csp243285vcz; Tue, 3 Dec 2013 13:51:26 -0800 (PST) X-Received: by 10.194.94.167 with SMTP id dd7mr9289088wjb.43.1386107482760; Tue, 03 Dec 2013 13:51:22 -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 ju4si31706357wjc.29.2013.12.03.13.51.20 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 03 Dec 2013 13:51:22 -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 1VnxsD-0006Ic-Cn; Tue, 03 Dec 2013 21:51:17 +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 06/12] target-arm: A64: provide skeleton for a64 insn decoding Date: Tue, 3 Dec 2013 21:51:11 +0000 Message-Id: <1386107477-24165-7-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1386107477-24165-1-git-send-email-peter.maydell@linaro.org> References: <1386107477-24165-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.128.176 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; } }