From patchwork Thu Feb 14 21:21:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 158452 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1880160jaa; Thu, 14 Feb 2019 13:28:42 -0800 (PST) X-Google-Smtp-Source: AHgI3Ib1aI0zACgfFuiSyO1ZWvnDp4DsqJhwHWewhHCob4VRuepxMqLs7c0vBa/mYogsIJ0io2Uo X-Received: by 2002:a81:8455:: with SMTP id u82mr4752132ywf.415.1550179722019; Thu, 14 Feb 2019 13:28:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550179722; cv=none; d=google.com; s=arc-20160816; b=OCNKQHF9vjCaa4zQjJuA5bt69V3XGaqa4CatBZhYJ6fn2JcM+L4i2ZYpuYNNoge6O5 jbJhzuJI1UPgfGE8YFzNEF0hrkjSrKrGnIx+MaqRa3D97DA5H5WnJcWQCTB8BoTNITRL qNw1z54lkfeJWGo9rxqzkN3bCwPNgBZP/GDgD6hG7PnNK9L1BsdAQ3wwM85LfZAEBWwq fzDtHvSCSRUc3WJJpeEb6cEqOw8Db/VKHywSf6pgs3SSSYYPCN3rscyctsTj2hK4AWlz ESbnahez2G5Y3e1IZj7fKcd0Sxh7snhVzJtj6HJ62MrZP4e7KfmQYVJbwiHfBZQgMMBj jK4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=51gyUTatbU7IQN+lMo9A7UI7Kfsg4nJW3Mx9lUPNAFU=; b=HGKfNncJPq34EJXUzaprPm5FQO4DhYo4nnx/5SlQa9EKcws3uSdp3ems0Ii9CS0J/T yBLefmCqL746vPGIB+gZemiqyy/PhJZwzZjiT3w1pJcoiBl43kfTgiGrYisi80glD1yJ sy0Nti/3On/YcW/KzG8dylK+isqjEw2uEwIk4J6wMnqU57wOK5rsyFSmJcIZMvwxbu4Q Ujv96AD/cU0XrPIWZ03V9Ap5LlInZ1U8C4XpggVQKiwlgsBri4kfghhD0PuSRF478Fni YMNARcNObWs/mPv7FQXTT0zGs5e93FAyH//reBYesycBNruJy740J0GrVim/XktAyx5p sf4g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=eNV5eJyl; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id u15si1989127ybc.298.2019.02.14.13.28.41 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 14 Feb 2019 13:28:42 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=eNV5eJyl; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:55214 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guOYj-0004mo-GC for patch@linaro.org; Thu, 14 Feb 2019 16:28:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57203) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guOVD-00034z-Jf for qemu-devel@nongnu.org; Thu, 14 Feb 2019 16:25:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1guOSO-0002h3-0B for qemu-devel@nongnu.org; Thu, 14 Feb 2019 16:22:11 -0500 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]:45297) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1guOSN-0002Ic-Jk for qemu-devel@nongnu.org; Thu, 14 Feb 2019 16:22:07 -0500 Received: by mail-pl1-x642.google.com with SMTP id r14so3784318pls.12 for ; Thu, 14 Feb 2019 13:21:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=51gyUTatbU7IQN+lMo9A7UI7Kfsg4nJW3Mx9lUPNAFU=; b=eNV5eJyljp17EEPpvLOA/vDaldlSZIfxCGS8lPrdqNPiNcypZ/yCOGtojtimXWNxyy enHPPVe8ZTW+B7puTUGbMkV930Q6Gr6DnwCAUW1QiJMJ5yR2H9eQDtdN119d4Mse5zHE qMANy9QDGK1X3oDKwm+7DgXiuBpNwr1mhbV+/L7sMzmBE/WNukjxx5SA9QEZ9Shu3wjg cL9T8dNlk6w+ZUlAJj6XQXMSt54eq97DUeIvx5lU9sK51Xmhh7zq4kOmCAGv9aMOJQKf y3l8mgbyvb0BCdIh4BnQ848yCI5hFJHYSnKuBmon9VSIuzA/Av6axSI1Pq0Zh+M9otqy kjQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=51gyUTatbU7IQN+lMo9A7UI7Kfsg4nJW3Mx9lUPNAFU=; b=e9MbYdYy20wUw805Ss5o3g/4J72ei/Gen3Zj08d3E0mQZBFuhD51zxc8sMbnpgrdPw QqwYfvwwUl+tPjXptbbm4hQ07R3TRgQfVqB6TFq4PAn9zpF0fLqVr1HZENeI3LoZTkh4 nQ66nk4h9yot24pJF+/uMRsAGeSxdsM6wA/hhI74bujdOzqgqr35jtQBjWnVZukQO7Dz 6up1bRhnHwVJmyo9G/dNrANjC37WF/ttQpN3DHxUF2wIMXl+8fv5VOoHB5zbApYG51Rv 4QQSi1063ZUC9mCSaCbq0nTsbBlG5G/YMJBKf5HAX+ndEz34/5nCFGXNqSYwyr5J7bnB eXqw== X-Gm-Message-State: AHQUAuYIfxL30Wn5Z3wEdYXmN/7ez31JCyxZ5sgTq2Pd0ua4tL2OR9ul 3TQ0fHf0lHK5aRyFP6WKvy2pRShiw38= X-Received: by 2002:a17:902:bc89:: with SMTP id bb9mr6439978plb.212.1550179309069; Thu, 14 Feb 2019 13:21:49 -0800 (PST) Received: from cloudburst.twiddle.net (97-113-188-82.tukw.qwest.net. [97.113.188.82]) by smtp.gmail.com with ESMTPSA id l87sm10896441pfj.35.2019.02.14.13.21.48 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 14 Feb 2019 13:21:48 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 14 Feb 2019 13:21:43 -0800 Message-Id: <20190214212144.12784-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190214212144.12784-1-richard.henderson@linaro.org> References: <20190214212144.12784-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::642 Subject: [Qemu-devel] [PATCH v3 2/3] target/arm: Rearrange decode of Floating-point data-processing (2 regs) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" There are lots of special cases within these insns. Split the major argument decode/loading/saving into no_output (compares), rd_is_dp, and rm_is_dp. We still need to special case argument load for compare (rd as input, rm as zero) and vcvt fixed (rd as input+output), but lots of special cases do disappear. Now that we have a full switch at the beginning, hoist the ISA checks from the code generation. Signed-off-by: Richard Henderson --- target/arm/translate.c | 227 ++++++++++++++++++++--------------------- 1 file changed, 111 insertions(+), 116 deletions(-) -- 2.17.2 diff --git a/target/arm/translate.c b/target/arm/translate.c index dac737f6ca..64c5fe0df3 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -3639,52 +3639,108 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) } } else { /* data processing */ + bool rd_is_dp = dp; + bool rm_is_dp = dp; + bool no_output = false; + /* The opcode is in bits 23, 21, 20 and 6. */ op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1); - if (dp) { - if (op == 15) { - /* rn is opcode */ - rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1); - } else { - /* rn is register number */ - VFP_DREG_N(rn, insn); - } + rn = VFP_SREG_N(insn); - if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) || - ((rn & 0x1e) == 0x6))) { - /* Integer or single/half precision destination. */ - rd = VFP_SREG_D(insn); - } else { - VFP_DREG_D(rd, insn); - } - if (op == 15 && - (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) || - ((rn & 0x1e) == 0x4))) { - /* VCVT from int or half precision is always from S reg - * regardless of dp bit. VCVT with immediate frac_bits - * has same format as SREG_M. + if (op == 15) { + /* rn is opcode, encoded as per VFP_SREG_N. */ + switch (rn) { + case 0x00: /* vmov */ + case 0x01: /* vabs */ + case 0x02: /* vneg */ + case 0x03: /* vsqrt */ + break; + + case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */ + case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */ + /* + * VCVTB, VCVTT: only present with the halfprec extension + * UNPREDICTABLE if bit 8 is set prior to ARMv8 + * (we choose to UNDEF) */ - rm = VFP_SREG_M(insn); - } else { - VFP_DREG_M(rm, insn); + if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) || + !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) { + return 1; + } + rm_is_dp = false; + break; + case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */ + case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */ + if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) || + !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) { + return 1; + } + rd_is_dp = false; + break; + + case 0x08: case 0x0a: /* vcmp, vcmpz */ + case 0x09: case 0x0b: /* vcmpe, vcmpez */ + no_output = true; + break; + + case 0x0c: /* vrintr */ + case 0x0d: /* vrintz */ + case 0x0e: /* vrintx */ + break; + + case 0x0f: /* vcvt double<->single */ + rd_is_dp = !dp; + break; + + case 0x10: /* vcvt.fxx.u32 */ + case 0x11: /* vcvt.fxx.s32 */ + rm_is_dp = false; + break; + case 0x18: /* vcvtr.u32.fxx */ + case 0x19: /* vcvtz.u32.fxx */ + case 0x1a: /* vcvtr.s32.fxx */ + case 0x1b: /* vcvtz.s32.fxx */ + rd_is_dp = false; + break; + + case 0x14: /* vcvt fp <-> fixed */ + case 0x15: + case 0x16: + case 0x17: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + /* Immediate frac_bits has same format as SREG_M. */ + rm_is_dp = false; + break; + + default: + return 1; } + } else if (dp) { + /* rn is register number */ + VFP_DREG_N(rn, insn); + } + + if (rd_is_dp) { + VFP_DREG_D(rd, insn); + } else { + rd = VFP_SREG_D(insn); + } + if (rm_is_dp) { + VFP_DREG_M(rm, insn); } else { - rn = VFP_SREG_N(insn); - if (op == 15 && rn == 15) { - /* Double precision destination. */ - VFP_DREG_D(rd, insn); - } else { - rd = VFP_SREG_D(insn); - } - /* NB that we implicitly rely on the encoding for the frac_bits - * in VCVT of fixed to float being the same as that of an SREG_M - */ rm = VFP_SREG_M(insn); } veclen = s->vec_len; - if (op == 15 && rn > 3) + if (op == 15 && rn > 3) { veclen = 0; + } /* Shut up compiler warnings. */ delta_m = 0; @@ -3720,55 +3776,28 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) /* Load the initial operands. */ if (op == 15) { switch (rn) { - case 16: - case 17: - /* Integer source */ - gen_mov_F0_vreg(0, rm); - break; - case 8: - case 9: - /* Compare */ + case 0x08: case 0x09: /* Compare */ gen_mov_F0_vreg(dp, rd); gen_mov_F1_vreg(dp, rm); break; - case 10: - case 11: - /* Compare with zero */ + case 0x0a: case 0x0b: /* Compare with zero */ gen_mov_F0_vreg(dp, rd); gen_vfp_F1_ld0(dp); break; - case 20: - case 21: - case 22: - case 23: - case 28: - case 29: - case 30: - case 31: + case 0x14: /* vcvt fp <-> fixed */ + case 0x15: + case 0x16: + case 0x17: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: /* Source and destination the same. */ gen_mov_F0_vreg(dp, rd); break; - case 4: - case 5: - case 6: - case 7: - /* VCVTB, VCVTT: only present with the halfprec extension - * UNPREDICTABLE if bit 8 is set prior to ARMv8 - * (we choose to UNDEF) - */ - if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) || - !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) { - return 1; - } - if (!extract32(rn, 1, 1)) { - /* Half precision source. */ - gen_mov_F0_vreg(0, rm); - break; - } - /* Otherwise fall through */ default: /* One source operand. */ - gen_mov_F0_vreg(dp, rm); + gen_mov_F0_vreg(rm_is_dp, rm); break; } } else { @@ -4047,10 +4076,11 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) break; } case 15: /* single<->double conversion */ - if (dp) + if (dp) { gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); - else + } else { gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env); + } break; case 16: /* fuito */ gen_vfp_uito(dp, 0); @@ -4059,27 +4089,15 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) gen_vfp_sito(dp, 0); break; case 20: /* fshto */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } gen_vfp_shto(dp, 16 - rm, 0); break; case 21: /* fslto */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } gen_vfp_slto(dp, 32 - rm, 0); break; case 22: /* fuhto */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } gen_vfp_uhto(dp, 16 - rm, 0); break; case 23: /* fulto */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } gen_vfp_ulto(dp, 32 - rm, 0); break; case 24: /* ftoui */ @@ -4095,57 +4113,34 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn) gen_vfp_tosiz(dp, 0); break; case 28: /* ftosh */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } gen_vfp_tosh(dp, 16 - rm, 0); break; case 29: /* ftosl */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } gen_vfp_tosl(dp, 32 - rm, 0); break; case 30: /* ftouh */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } gen_vfp_touh(dp, 16 - rm, 0); break; case 31: /* ftoul */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } gen_vfp_toul(dp, 32 - rm, 0); break; default: /* undefined */ - return 1; + g_assert_not_reached(); } break; default: /* undefined */ return 1; } - /* Write back the result. */ - if (op == 15 && (rn >= 8 && rn <= 11)) { - /* Comparison, do nothing. */ - } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 || - (rn & 0x1e) == 0x6)) { - /* VCVT double to int: always integer result. - * VCVT double to half precision is always a single - * precision result. - */ - gen_mov_vreg_F0(0, rd); - } else if (op == 15 && rn == 15) { - /* conversion */ - gen_mov_vreg_F0(!dp, rd); - } else { - gen_mov_vreg_F0(dp, rd); + /* Write back the result, if any. */ + if (!no_output) { + gen_mov_vreg_F0(rd_is_dp, rd); } /* break out of the loop if we have finished */ - if (veclen == 0) + if (veclen == 0) { break; + } if (op == 15 && delta_m == 0) { /* single source one-many */