From patchwork Thu Feb 21 18:57:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 158943 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp845221jaa; Thu, 21 Feb 2019 11:10:27 -0800 (PST) X-Google-Smtp-Source: AHgI3IYQXALAOC7knh0eeRR/KSmXLU0pZ40+49SLzUxqWXmSFdBZg73t9biyBcTRpQmrhYQWgCPK X-Received: by 2002:a81:ac4f:: with SMTP id z15mr54175ywj.59.1550776227644; Thu, 21 Feb 2019 11:10:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550776227; cv=none; d=google.com; s=arc-20160816; b=vILI3AmY0Htm6vjHJRipPgAolrA9kqolixRARKe5EG5bqDoKUsWmeiPBFtIyc1706s UrkR0Xresi9Yiz3+gnoKrOCAF4j4s9AfbNLodcJL5pndBv12X0eeSeFaum9mbaIJiLhd j6rXzki1uycQFTJuBfWg6wQobiyD33tgs5coXPEO03L9xjTDX63zTIWfppilECofB1PU 5CwuOaAkDo1SqQuIOhTNAu0dXqPrABF1+q+QdzlQ3fzjHy9AG+AHJNdKgDWF++IplLtm Mh0KmkceQoBC2M6lXoJl1U3a6W4SPgTlB4Vvpkq2VMvsyd0DKkKdaXNweQFK7hfHJwhd tDVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=3CsNdTiJxLpeHZhvA80SvJ6O1mfkLZ6Sw2B47rZsEE4=; b=P9P2Z9Dpf9n+JRgosFUbe0FSB+VOT7SL6cAnOgW2BzNpf51X8seMmEY0yghq5gauSl JQeYbiGvtebSOFQ2bPGLQ1wqrA116Z5m5tnJzNoImlyf+72lld1wRruLN4wvVxK+Qqu8 Or7CS9GBNwrAfTcY5YrJ8BOWWe2mCNrSbpratotHrE7UtxBPhuf1M/iUqsuqxq8r0oZC W9Q7hDQpzVprdSWbAwtiD2ahUWq6ftyUINz8LLCRmWMu8uxcA1ocRK6KBUgWgdvYuBBN 51uW9714Jvu/z9sKKvYl310jJEvOHOvN6cBUE1P+DvDZw+7/PIuvGj4ScsGoKFHnFABU Jw2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=mQ5QzCBV; 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 x130si13703082ywc.459.2019.02.21.11.10.27 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 21 Feb 2019 11:10:27 -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=mQ5QzCBV; 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]:37014 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gwtjn-0001jB-1y for patch@linaro.org; Thu, 21 Feb 2019 14:10:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:52233) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gwtXs-00004r-Us for qemu-devel@nongnu.org; Thu, 21 Feb 2019 13:58:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gwtXp-0007T7-HO for qemu-devel@nongnu.org; Thu, 21 Feb 2019 13:58:08 -0500 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]:42059) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gwtXp-0007JN-4U for qemu-devel@nongnu.org; Thu, 21 Feb 2019 13:58:05 -0500 Received: by mail-wr1-x432.google.com with SMTP id r5so18445207wrg.9 for ; Thu, 21 Feb 2019 10:57:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=3CsNdTiJxLpeHZhvA80SvJ6O1mfkLZ6Sw2B47rZsEE4=; b=mQ5QzCBVZIWw04gvq+KwiT0GQijOBZYnjCKpxrn0/x1KoQQsz6b/gZJDCaokw4V8qZ 7bA1hXtwgsBk6Vn3v/LE5ujLSdr9vHeQc/7XESNFwl7dNPfrY4lPJ3CjJmIsxWQzDm/g +WQaRtQFmjBKkyX9js81PvKqm4sxS/tnTDCcPIyDFzYmJSrpU8nUfKe+WpkHjZJugUXs 6uP7IXNyhvY+reFv03iXnp8OUr+p3vUNm1wq3n8P1pSH6o0aI+VWbqst1bZkjIJlFNzs 6QKhgQg2IhY4Vrs0mKzWCWaZAmGXo2OiTReYg+OOTdWA0zhOE4J8mZquyoYcgVLXSH8n Jr2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3CsNdTiJxLpeHZhvA80SvJ6O1mfkLZ6Sw2B47rZsEE4=; b=GurDXZYuPhchrqdoIYfnpBy5Oqj0ZxQ6/52WnC149voBEWwc2i78rLAVG+OfuXhfgA njCDZKg733JSmK4fTl0iWlDPyiJk99TLQIzoisCGAFXy537GlzOs/vRkIPlUesm3iFn4 MLXjTuP8ovYDyPsqREgvLb0I5+O7uBq7uzkuIMIydbcToNSW4TYALDx4tiDN2cFX6ARx qXizWEj55cIrFmgR+7D91/rl3BpCUb678aIxx9hFWXkAzcTd1bCnMNOhYo8ATPSxpJ/I wWj9bhEQ0dmc7zQTgjqPs0KM0oCVdAawuQKrATqn3krUEzNYiPvyY3dnZtvzADrsrr5t pxMQ== X-Gm-Message-State: AHQUAub1vT3yfNhYePKLGHgK+x/DcBJyc3255zkjlTGBgI3/hZFiFdnV KmeBBSE052k4Shi5EXArXokHaP8jIOE= X-Received: by 2002:adf:9123:: with SMTP id j32mr21557wrj.122.1550775470899; Thu, 21 Feb 2019 10:57:50 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id c18sm29065085wre.32.2019.02.21.10.57.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 21 Feb 2019 10:57:50 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 21 Feb 2019 18:57:24 +0000 Message-Id: <20190221185739.25362-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190221185739.25362-1-peter.maydell@linaro.org> References: <20190221185739.25362-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::432 Subject: [Qemu-devel] [PULL 06/21] target/arm: Rearrange 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: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson 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 Message-id: 20190215192302.27855-4-richard.henderson@linaro.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/translate.c | 227 ++++++++++++++++++++--------------------- 1 file changed, 111 insertions(+), 116 deletions(-) -- 2.20.1 diff --git a/target/arm/translate.c b/target/arm/translate.c index dac737f6cac..64c5fe0df3e 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 */