From patchwork Mon Apr 11 15:26:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 949 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:42 -0000 Delivered-To: patches@linaro.org Received: by 10.68.59.138 with SMTP id z10cs68412pbq; Mon, 11 Apr 2011 08:26:28 -0700 (PDT) Received: by 10.213.15.11 with SMTP id i11mr398249eba.66.1302535586708; Mon, 11 Apr 2011 08:26:26 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk [81.2.115.146]) by mx.google.com with ESMTPS id p50si13371478eei.98.2011.04.11.08.26.25 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 11 Apr 2011 08:26:26 -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-00046K-PG; Mon, 11 Apr 2011 16:26:23 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 04/13] target-arm: Handle UNDEF cases for Neon "2 regs and shift" insns Date: Mon, 11 Apr 2011 16:26:14 +0100 Message-Id: <1302535583-15733-5-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> Correctly handle all the UNDEF cases for Neon instructions of the "2 registers and shift" form, and make sure that we check for these cases early enough not to leak TCG temporaries. Signed-off-by: Peter Maydell --- target-arm/translate.c | 41 ++++++++++++++++++++++------------------- 1 files changed, 22 insertions(+), 19 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 0cf933d..c0ffa9f 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -4744,7 +4744,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) /* Two registers and shift. */ op = (insn >> 8) & 0xf; if (insn & (1 << 7)) { - /* 64-bit shift. */ + /* 64-bit shift. */ + if (op > 7) { + return 1; + } size = 3; } else { size = 2; @@ -4757,6 +4760,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) if (op < 8) { /* Shift by immediate: VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */ + if (q && ((rd | rm) & 1)) { + return 1; + } + if (!u && (op == 4 || op == 6)) { + return 1; + } /* Right shifts are encoded as N - shift, where N is the element size in bits. */ if (op <= 4) @@ -4804,20 +4813,13 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1); break; case 4: /* VSRI */ - if (!u) - return 1; gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); break; case 5: /* VSHL, VSLI */ gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); break; case 6: /* VQSHLU */ - if (u) { - gen_helper_neon_qshlu_s64(cpu_V0, - cpu_V0, cpu_V1); - } else { - return 1; - } + gen_helper_neon_qshlu_s64(cpu_V0, cpu_V0, cpu_V1); break; case 7: /* VQSHL */ if (u) { @@ -4865,8 +4867,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) GEN_NEON_INTEGER_OP(rshl); break; case 4: /* VSRI */ - if (!u) - return 1; GEN_NEON_INTEGER_OP(shl); break; case 5: /* VSHL, VSLI */ @@ -4874,13 +4874,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } break; case 6: /* VQSHLU */ - if (!u) { - return 1; - } switch (size) { case 0: gen_helper_neon_qshlu_s8(tmp, tmp, tmp2); @@ -4892,7 +4889,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_helper_neon_qshlu_s32(tmp, tmp, tmp2); break; default: - return 1; + abort(); } break; case 7: /* VQSHL */ @@ -4950,7 +4947,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) /* Shift by immediate and narrow: VSHRN, VRSHRN, VQSHRN, VQRSHRN. */ int input_unsigned = (op == 8) ? !u : u; - + if (rm & 1) { + return 1; + } shift = shift - (1 << (size + 3)); size++; if (size == 3) { @@ -5018,9 +5017,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_temp_free_i32(tmp2); } } else if (op == 10) { - /* VSHLL */ - if (q || size == 3) + /* VSHLL, VMOVL */ + if (q || (rd & 1)) { return 1; + } tmp = neon_load_reg(rm, 0); tmp2 = neon_load_reg(rm, 1); for (pass = 0; pass < 2; pass++) { @@ -5061,6 +5061,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } } else if (op >= 14) { /* VCVT fixed-point. */ + if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) { + return 1; + } /* We have already masked out the must-be-1 top bit of imm6, * hence this 32-shift where the ARM ARM has 64-imm6. */