From patchwork Mon Nov 11 15:13:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Claudio Fontana X-Patchwork-Id: 21445 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f72.google.com (mail-oa0-f72.google.com [209.85.219.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C5583259D3 for ; Mon, 11 Nov 2013 15:13:48 +0000 (UTC) Received: by mail-oa0-f72.google.com with SMTP id m1sf7711197oag.7 for ; Mon, 11 Nov 2013 07:13:48 -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:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=K3sDjCC+hjHGXz3BHUt6ifvqy61ZjVmCye+/YCZXL6E=; b=RUTkjT6jy4mD/hVOb1/pOfWVuRLvJXhYDJ0q/RZ3TlrXWRlxjBRgnk/ArZBWk412yI IFUynei31r2N+j1TNXvfLveTP32o4eS1oJizJ8DaKxXm2/f8lROqI9hGp2npLg2+9Jt8 8HFkx+7YkfeD8lg+Y5uslWus8PiY7g6IT8uLJiKWPzEssZU13CjCw9HSrBxpHyqotTF4 EeF3YO4LUehif4jPSJVOJ+fZF7YQDgyK3MfLKuVa8G8UxhcMMBG8C4Z5HnkAas56Q20n RWJDqO6ul70jIKOAq64fKCC9E/6nTXH+TSBKoONSM3tNegUGlv7hi7hvL+hkPRPIfNAG jHyA== X-Gm-Message-State: ALoCoQm6/+xTthkHR3w553r+tLn++l/dzsWRJByOsWbWXNjiBVhhvTNQdzO3H/W8hHBHCTELAX/8 X-Received: by 10.50.164.198 with SMTP id ys6mr5960697igb.5.1384182828014; Mon, 11 Nov 2013 07:13:48 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.62.195 with SMTP id a3ls293137qes.14.gmail; Mon, 11 Nov 2013 07:13:47 -0800 (PST) X-Received: by 10.52.33.69 with SMTP id p5mr1921740vdi.28.1384182827802; Mon, 11 Nov 2013 07:13:47 -0800 (PST) Received: from mail-vb0-f41.google.com (mail-vb0-f41.google.com [209.85.212.41]) by mx.google.com with ESMTPS id tq4si9804155vdc.155.2013.11.11.07.13.47 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 11 Nov 2013 07:13:47 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.41 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.41; Received: by mail-vb0-f41.google.com with SMTP id w8so3456589vbj.28 for ; Mon, 11 Nov 2013 07:13:47 -0800 (PST) X-Received: by 10.221.39.195 with SMTP id tn3mr24188719vcb.2.1384182827697; Mon, 11 Nov 2013 07:13:47 -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 u4csp97408vcz; Mon, 11 Nov 2013 07:13:47 -0800 (PST) X-Received: by 10.14.7.71 with SMTP id 47mr309449eeo.122.1384182826663; Mon, 11 Nov 2013 07:13:46 -0800 (PST) Received: from mail-ee0-f50.google.com (mail-ee0-f50.google.com [74.125.83.50]) by mx.google.com with ESMTPS id g2si18337636eeo.115.2013.11.11.07.13.46 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 11 Nov 2013 07:13:46 -0800 (PST) Received-SPF: neutral (google.com: 74.125.83.50 is neither permitted nor denied by best guess record for domain of claudio.fontana@linaro.org) client-ip=74.125.83.50; Received: by mail-ee0-f50.google.com with SMTP id b45so2481501eek.23 for ; Mon, 11 Nov 2013 07:13:46 -0800 (PST) X-Received: by 10.14.88.69 with SMTP id z45mr327943eee.95.1384182826096; Mon, 11 Nov 2013 07:13:46 -0800 (PST) Received: from moosach.csi ([217.111.50.163]) by mx.google.com with ESMTPSA id b42sm63929669eem.9.2013.11.11.07.13.43 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Nov 2013 07:13:45 -0800 (PST) From: Claudio Fontana To: Peter Maydell Cc: Claudio Fontana , Alexander Graf , Alex Bennee , Michael Matz , Richard Henderson , patches@linaro.org, qemu-devel@nongnu.org Subject: [RFC] target-arm: provide skeleton for a64 insn decoding Date: Mon, 11 Nov 2013 16:13:57 +0100 Message-Id: <1384182837-5925-1-git-send-email-claudio.fontana@linaro.org> X-Mailer: git-send-email 1.8.1 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: claudio.fontana@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.41 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: , 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) C3 Signed-off-by: Claudio Fontana Reviewed-by: Alex Bennée --- The following patch has been started during Linaro Connect by me and Alex Bennee. The goal is to provide a decoder that is easy to match against the ARM Architecture Reference Manual. The plan here is a process of cleaning up / refactoring the SuSE patchset. We will be posting actual instruction implementations in the following days and weeks. However, as we currently have between 60-120 patches in the backlog we thought it would be worth getting the basic decoding skeleton agreed (and merged?) first to reduce any patch ordering problems and ease the reviewing burden. The first set of instruction patches will be based on Alexander Graf's 60 patch set after we have applied fixes, review comments and run some instruction testing using Peter Maydell's risu tool patched for aarch64: https://github.com/hw-claudio/risu-aarch64.git (master) We hope from there to quickly progress through the rest of the SUSE patch-set for getting a functional aarch64 linux-user setup before turning our attention to system emulation. target-arm/translate-a64.c | 367 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 359 insertions(+), 8 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index f120088..7105728 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -107,17 +107,345 @@ static void gen_exception_insn(DisasContext *s, int offset, int excp) s->is_jmp = DISAS_JUMP; } -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", \ + __FILE__, __LINE__, insn); \ + 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_sys(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 0x4a: /* 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_sys(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_csel(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_csel(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; + } + 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 */ void disas_a64_insn(CPUARMState *env, DisasContext *s) { uint32_t insn; @@ -126,10 +454,33 @@ 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; } if (unlikely(s->singlestep_enabled) && (s->is_jmp == DISAS_TB_JUMP)) {