From patchwork Fri Jul 22 10:51:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 3045 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 3337523E52 for ; Fri, 22 Jul 2011 10:51:26 +0000 (UTC) Received: from mail-qw0-f52.google.com (mail-qw0-f52.google.com [209.85.216.52]) by fiordland.canonical.com (Postfix) with ESMTP id E1701A1801E for ; Fri, 22 Jul 2011 10:51:25 +0000 (UTC) Received: by qwb8 with SMTP id 8so1523633qwb.11 for ; Fri, 22 Jul 2011 03:51:25 -0700 (PDT) Received: by 10.229.25.212 with SMTP id a20mr1121297qcc.148.1311331885276; Fri, 22 Jul 2011 03:51:25 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.217.78 with SMTP id hl14cs11339qcb; Fri, 22 Jul 2011 03:51:24 -0700 (PDT) Received: by 10.216.120.130 with SMTP id p2mr1244040weh.2.1311331883677; Fri, 22 Jul 2011 03:51:23 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk [81.2.115.146]) by mx.google.com with ESMTPS id y58si1169583wec.50.2011.07.22.03.51.23 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 22 Jul 2011 03:51:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) client-ip=81.2.115.146; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) smtp.mail=pm215@archaic.org.uk Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1QkDKD-0003Mg-Hr; Fri, 22 Jul 2011 11:51:21 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 1/3] target-arm: Handle UNDEF and UNPREDICTABLE cases for VLDM, VSTM Date: Fri, 22 Jul 2011 11:51:19 +0100 Message-Id: <1311331881-12909-2-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1311331881-12909-1-git-send-email-peter.maydell@linaro.org> References: <1311331881-12909-1-git-send-email-peter.maydell@linaro.org> Handle the UNDEF and UNPREDICTABLE cases for VLDM and VSTM. In particular, we now generate an undef exception for overlarge imm8 values rather than generating 1000+ TCG ops and hitting an assertion. Signed-off-by: Peter Maydell --- target-arm/translate.c | 38 +++++++++++++++++++++++++++++++------- 1 files changed, 31 insertions(+), 7 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 34d5e6e..7bce343 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -3382,17 +3382,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) VFP_DREG_D(rd, insn); else rd = VFP_SREG_D(insn); - if (s->thumb && rn == 15) { - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~2); - } else { - addr = load_reg(s, rn); - } if ((insn & 0x01200000) == 0x01000000) { /* Single load/store */ offset = (insn & 0xff) << 2; if ((insn & (1 << 23)) == 0) offset = -offset; + if (s->thumb && rn == 15) { + /* This is actually UNPREDICTABLE */ + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, s->pc & ~2); + } else { + addr = load_reg(s, rn); + } tcg_gen_addi_i32(addr, addr, offset); if (insn & (1 << 20)) { gen_vfp_ld(s, dp, addr); @@ -3404,11 +3405,34 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_temp_free_i32(addr); } else { /* load/store multiple */ + int w = insn & (1 << 21); if (dp) n = (insn >> 1) & 0x7f; else n = insn & 0xff; + if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) { + /* P == U , W == 1 => UNDEF */ + return 1; + } + if (n == 0 || (rd + n) > 32 || (dp && n > 16)) { + /* UNPREDICTABLE cases for bad immediates: we choose to + * UNDEF to avoid generating huge numbers of TCG ops + */ + return 1; + } + if (rn == 15 && w) { + /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */ + return 1; + } + + if (s->thumb && rn == 15) { + /* This is actually UNPREDICTABLE */ + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, s->pc & ~2); + } else { + addr = load_reg(s, rn); + } if (insn & (1 << 24)) /* pre-decrement */ tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2)); @@ -3428,7 +3452,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) } tcg_gen_addi_i32(addr, addr, offset); } - if (insn & (1 << 21)) { + if (w) { /* writeback */ if (insn & (1 << 24)) offset = -offset * n;