From patchwork Mon Apr 11 15:26:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 953 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:47:43 -0000 Delivered-To: patches@linaro.org Received: by 10.68.59.138 with SMTP id z10cs68417pbq; Mon, 11 Apr 2011 08:26:30 -0700 (PDT) Received: by 10.43.55.1 with SMTP id vw1mr8978794icb.204.1302535588822; Mon, 11 Apr 2011 08:26:28 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk [81.2.115.146]) by mx.google.com with ESMTPS id wh1si12427315icb.53.2011.04.11.08.26.27 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 11 Apr 2011 08:26:28 -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 1Q9J0R-00046G-NE; Mon, 11 Apr 2011 16:26:23 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 02/13] target-arm: Handle UNDEF cases for Neon 3-regs-same insns Date: Mon, 11 Apr 2011 16:26:12 +0100 Message-Id: <1302535583-15733-3-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1302535583-15733-1-git-send-email-peter.maydell@linaro.org> References: <1302535583-15733-1-git-send-email-peter.maydell@linaro.org> Correct the handling of UNDEF cases for the NEON "3 registers same size" forms, by adding missing checks and rationalising some others so they are done early enough to avoid leaking TCG temporaries. Signed-off-by: Peter Maydell --- target-arm/translate.c | 54 ++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 43 insertions(+), 11 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 3fa27e1..5ffbace 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -4348,6 +4348,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) if ((neon_3r_sizes[op] & (1 << size)) == 0) { return 1; } + /* All insns of this form UNDEF for either this condition or the + * superset of cases "Q==1"; we catch the latter later. + */ + if (q && ((rd | rn | rm) & 1)) { + return 1; + } if (size == 3 && op != NEON_3R_LOGIC) { /* 64-bit element instructions. */ for (pass = 0; pass < (q ? 2 : 1); pass++) { @@ -4410,6 +4416,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } return 0; } + pairwise = 0; switch (op) { case NEON_3R_VSHL: case NEON_3R_VQSHL: @@ -4421,25 +4428,54 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) rtmp = rn; rn = rm; rm = rtmp; - pairwise = 0; } break; + case NEON_3R_VPADD: + if (u) { + return 1; + } + /* Fall through */ case NEON_3R_VPMAX: case NEON_3R_VPMIN: - case NEON_3R_VPADD: pairwise = 1; break; - case NEON_3R_FLOAT_ARITH: /* VADD, VSUB, VPADD, VABD (float) */ - pairwise = (u && size < 2); + case NEON_3R_FLOAT_ARITH: + pairwise = (u && size < 2); /* if VPADD (float) */ + break; + case NEON_3R_FLOAT_MINMAX: + pairwise = u; /* if VPMIN/VPMAX (float) */ + break; + case NEON_3R_FLOAT_CMP: + if (!u && size) { + /* no encoding for U=0 C=1x */ + return 1; + } + break; + case NEON_3R_FLOAT_ACMP: + if (!u) { + return 1; + } + break; + case NEON_3R_VRECPS_VRSQRTS: + if (u) { + return 1; + } break; - case NEON_3R_FLOAT_MINMAX: /* VPMIN/VPMAX (float) */ - pairwise = u; + case NEON_3R_VMUL: + if (u && (size != 0)) { + /* UNDEF on invalid size for polynomial subcase */ + return 1; + } break; default: - pairwise = 0; break; } + if (pairwise && q) { + /* All the pairwise insns UNDEF if Q is set */ + return 1; + } + for (pass = 0; pass < (q ? 4 : 2); pass++) { if (pairwise) { @@ -4621,8 +4657,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } break; case NEON_3R_VPADD: - if (u) - return 1; switch (size) { case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break; @@ -4671,8 +4705,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } break; case NEON_3R_FLOAT_ACMP: - if (!u) - return 1; if (size == 0) gen_helper_neon_acge_f32(tmp, tmp, tmp2); else