From patchwork Tue Nov 12 13:29:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Claudio Fontana X-Patchwork-Id: 21455 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f70.google.com (mail-oa0-f70.google.com [209.85.219.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 0551223FBB for ; Tue, 12 Nov 2013 13:29:47 +0000 (UTC) Received: by mail-oa0-f70.google.com with SMTP id g12sf12311078oah.5 for ; Tue, 12 Nov 2013 05:29:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :mime-version:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe:content-type:content-transfer-encoding; bh=zRI9Ft5NmBzygHj7Gda3EckrUDUS/Yg/0fgqrXvpcl8=; b=gpXvIdld7eD+BMQNeRL5+7gJJmLXVFa7LHp7EJfX0b/9uwdzLo/TSjImrDDsMMseDo oUDn4fKKx2v19UppPzChXqP2LLg6/PoN9/4fL+AwHIT4YynYSobZsH2lk+lw652D+HTt YTTQ+2IhopFs9pdNU9IQN3Tlzk/0Ve6bVbX9MQ8mias3apJqYgbmQ0sSeZTHQZrTjfhs 9YstskI+PANLGEsAW/AqvjgGxn7Ceoz8Yn3XasNuSQu2SiB/6/IZ/9XZp3chL9u5k+Gg 4sPZd2mJT19Z7l6iagpT9Tp8odnbw92HoQo2GV4a9Gv1zIZv0HPWzLKd5zXVgLsJH6h1 olEw== X-Gm-Message-State: ALoCoQks/BQfU7suQVd1lu/mo1vH5Lc5Rc/L3HzeM2qfUvlzNvBsDYCgZ/brNTs8cCf2ouBl1Jjz X-Received: by 10.182.24.3 with SMTP id q3mr11202656obf.6.1384262987185; Tue, 12 Nov 2013 05:29:47 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.29.6 with SMTP id f6ls99855qeh.3.gmail; Tue, 12 Nov 2013 05:29:47 -0800 (PST) X-Received: by 10.52.169.227 with SMTP id ah3mr37734vdc.45.1384262987104; Tue, 12 Nov 2013 05:29: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 ef6si11996754ved.123.2013.11.12.05.29.47 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 12 Nov 2013 05:29: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 w8so4418969vbj.28 for ; Tue, 12 Nov 2013 05:29:47 -0800 (PST) X-Received: by 10.58.232.228 with SMTP id tr4mr358252vec.34.1384262986969; Tue, 12 Nov 2013 05:29:46 -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 u4csp162812vcz; Tue, 12 Nov 2013 05:29:46 -0800 (PST) X-Received: by 10.14.127.4 with SMTP id c4mr9771eei.144.1384262985809; Tue, 12 Nov 2013 05:29:45 -0800 (PST) Received: from mail-ea0-f171.google.com (mail-ea0-f171.google.com [209.85.215.171]) by mx.google.com with ESMTPS id f8si9807655eep.75.2013.11.12.05.29.45 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 12 Nov 2013 05:29:45 -0800 (PST) Received-SPF: neutral (google.com: 209.85.215.171 is neither permitted nor denied by best guess record for domain of claudio.fontana@linaro.org) client-ip=209.85.215.171; Received: by mail-ea0-f171.google.com with SMTP id h10so1045166eak.2 for ; Tue, 12 Nov 2013 05:29:45 -0800 (PST) X-Received: by 10.14.95.69 with SMTP id o45mr933863eef.107.1384262984901; Tue, 12 Nov 2013 05:29:44 -0800 (PST) Received: from moosach.csi ([217.111.50.163]) by mx.google.com with ESMTPSA id v45sm76037458eef.11.2013.11.12.05.29.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Nov 2013 05:29:44 -0800 (PST) From: Claudio Fontana To: Peter Maydell Cc: Claudio Fontana , Alexander Graf , Michael Matz , Richard Henderson , patches@linaro.org, qemu-devel@nongnu.org, =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [RFC v2] target-arm: provide skeleton for a64 insn decoding Date: Tue, 12 Nov 2013 14:29:47 +0100 Message-Id: <1384262987-3972-1-git-send-email-claudio.fontana@linaro.org> X-Mailer: git-send-email 1.8.1 MIME-Version: 1.0 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 Signed-off-by: Alex Bennée Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Laurent Desnogues --- target-arm/translate-a64.c | 368 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 360 insertions(+), 8 deletions(-) For the rationale, see v1 of the RFC at http://lists.gnu.org/archive/html/qemu-devel/2013-11/msg01312.html diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index f120088..c4b2bb5 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -107,17 +107,346 @@ 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 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_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 +455,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)) {