From patchwork Mon Oct 17 23:08:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 13946 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63CFAC433FE for ; Mon, 17 Oct 2022 23:09:06 +0000 (UTC) Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by mx.groups.io with SMTP id smtpd.web09.677.1666048139626889648 for ; Mon, 17 Oct 2022 16:09:00 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@sakoman-com.20210112.gappssmtp.com header.s=20210112 header.b=lwa8gD1Q; spf=softfail (domain: sakoman.com, ip: 209.85.214.176, mailfrom: steve@sakoman.com) Received: by mail-pl1-f176.google.com with SMTP id l1so12128178pld.13 for ; Mon, 17 Oct 2022 16:08:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=hTDDUTNfLdbfV77W/sBMcnKw9c5GeTYk8061bRgSqOk=; b=lwa8gD1QX+D5hkbw/EsoTnMyIVTFPIlI7RfuEroo80PJAr2oah9EwIV2lzHQrHmicO aJEr4gqAz8kwoVjdjUMwVh03n42grdrvsR7eE3fLJq1YFkyeOJBrM3kab7V0j/3yQC7g pNbibV0xgkgBvusQm2uxpKbLrqx+nH0UtvV8V/iTv8v4FC+RTgPbPzjzAyRZAPmp2nOY b0/d549LnQsmkSJCQaIIk37gTrX3ed2K5wRS2N8kPlsb0B3a9K4hnDVPJrX/736czdrO RqzTK7jbtE/Kx4WEMoi+t2ijY0vt+Y5w62nHlGsjpWP2B2PYuL1G5r/m0bND7d6fPi7R tL9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hTDDUTNfLdbfV77W/sBMcnKw9c5GeTYk8061bRgSqOk=; b=FiTFd06eCSe/e1qRIBFS/UR5t66qsrMOpsqP969x+5t/sXk3pxD3AU4x8vD1jih9jy gdVm+DBmpg1dIR/8J6zR8/xfceHA1GKxhDNb5Lsbz2jz53CvG+EyeGTCr6DCEOZgO5fy 30IH98MnkBnWay9M6yVmxZx5d33UBUeT596YSbHT+H/CTp5VAByeUmv34XtyJvjidOcA ndTPaDrMf9HqzZOR60ZMYPaGAe/YbfT3fVjAimqntg7refPNmXa9NPGICIbPkqV1MJM0 gjLaa5kO9omJwkp/cvboX59t2/ovbAnXsB3l2Gn5bjmJNpjlHXeImqHeTBIgyPB7tHWd 7HZA== X-Gm-Message-State: ACrzQf2gLIUmKD7cEI3SujTHGo6gK0wbv7IdxC6sXew6hydTevJJQcfj oB040QthIK+NM6woUOwOZOpVJJu4T0Em1+/U X-Google-Smtp-Source: AMsMyM5DkNxfbN+Si+dGCHAVS8CgswpF0dGONMH67dbUNi2JxbZ7+4Bl8H0A/NVc7VfM76/NHOV+Uw== X-Received: by 2002:a17:90a:c7cc:b0:20a:c595:16de with SMTP id gf12-20020a17090ac7cc00b0020ac59516demr134116pjb.201.1666048136925; Mon, 17 Oct 2022 16:08:56 -0700 (PDT) Received: from hexa.router0800d9.com (dhcp-72-253-6-214.hawaiiantel.net. [72.253.6.214]) by smtp.gmail.com with ESMTPSA id j6-20020a17090a694600b0020aacde1964sm10119479pjm.32.2022.10.17.16.08.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 16:08:56 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 06/13] qemu: Backport patches from upstream to support float128 on qemu-ppc64 Date: Mon, 17 Oct 2022 13:08:22 -1000 Message-Id: <5ed94b1d155a7d5597358a93c65dfe98ac07ea15.1666047986.git.steve@sakoman.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 17 Oct 2022 23:09:06 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/171924 From: Xiangyu Chen Background: Due to current qemu 6.2 doesn't support float128, this cause some POSIX APIs(e.g. double difftime()..) return a wrong value, this issue can be reproduced by open_posix_testsuit difftime case[1]. The qemu upstream has already supported ppc64 float128, but need to update to qemu 7.0 or later. We backport the commits[2] from upstream to support that in qemu-ppc64 6.2.0. [1] difftime test case: https://github.com/linux-test-project/ltp/tree/master/testcases/open_posix_testsuite/conformance/interfaces/difftime [2] commits link: LINK: https://git.qemu.org/?p=qemu.git;a=commit;h=149a48f6e6ccedfa01307d45884aa480f5bf77c5 https://git.qemu.org/?p=qemu.git;a=commit;h=ba11446c40903b9d97fb75a078d43fee6444d3b6 https://git.qemu.org/?p=qemu.git;a=commit;h=bead3c9b0ff8efd652afb27923d8ab4458b3bbd9 https://git.qemu.org/?p=qemu.git;a=commit;h=10cc964030fca459591d9353571f3b1b4e1b5aec https://git.qemu.org/?p=qemu.git;a=commit;h=e706d4455b8d54252b11fc504c56df060151cb89 https://git.qemu.org/?p=qemu.git;a=commit;h=941298ecd7e3103d3789d2dd87dd0f119e81c69e https://git.qemu.org/?p=qemu.git;a=commit;h=4edf55698fc2ea30903657c63ed95db0d5548943 https://git.qemu.org/?p=qemu.git;a=commit;h=c07f82416cb7973c64d1e21c09957182b4b033dc https://git.qemu.org/?p=qemu.git;a=commit;h=e4052bb773cc829a27786d68caa22f28cff19d39 https://git.qemu.org/?p=qemu.git;a=commit;h=ffdaff8e9c698061f57a6b1827570562c5a1c909 https://git.qemu.org/?p=qemu.git;a=commit;h=201fc774e0e1cc76ec23b595968004a7b14fb6e8 https://git.qemu.org/?p=qemu.git;a=commit;h=c5df1898a147c232f0502cda5dac8df6074070fc https://git.qemu.org/?p=qemu.git;a=commit;h=38d4914c5065e14f0969161274793ded448f067f https://git.qemu.org/?p=qemu.git;a=commit;h=caf6f9b568479bea6f6d97798be670f21641a006 https://git.qemu.org/?p=qemu.git;a=commit;h=25ee608d79c1890c0f4e8c495ec8629d5712de45 https://git.qemu.org/?p=qemu.git;a=commit;h=19f0862dd8fa6510b2f5b3aff4859363602cd0cf https://git.qemu.org/?p=qemu.git;a=commit;h=5f1470b091007f24035d6d33149df49a6dd61682 https://git.qemu.org/?p=qemu.git;a=commit;h=17868d81e0074905b2c1e414af6618570e8059eb https://git.qemu.org/?p=qemu.git;a=commit;h=9193eaa901c54dbff4a91ea0b12a99e0135dbca1 https://git.qemu.org/?p=qemu.git;a=commit;h=e4318ab2e423c4caf9a88a4e99b5e234096b81a9 https://git.qemu.org/?p=qemu.git;a=commit;h=3bb1aed246d7b59ceee625a82628f7369d492a8f Signed-off-by: Xiangyu Chen Signed-off-by: Steve Sakoman --- meta/recipes-devtools/qemu/qemu.inc | 21 ++ ...end-float_exception_flags-to-16-bits.patch | 75 +++++ ...ftfloat-Add-flag-specific-to-Inf-Inf.patch | 59 ++++ ...softfloat-Add-flag-specific-to-Inf-0.patch | 126 +++++++++ ...dd-flags-specific-to-Inf-Inf-and-0-0.patch | 73 +++++ ...-Add-flag-specific-to-signaling-nans.patch | 121 ++++++++ ...e-float_invalid_op_addsub-for-new-fl.patch | 114 ++++++++ ...e-float_invalid_op_mul-for-new-flags.patch | 86 ++++++ ...e-float_invalid_op_div-for-new-flags.patch | 99 +++++++ ...arget-ppc-Update-fmadd-for-new-flags.patch | 102 +++++++ .../0010-target-ppc-Split-out-do_fmadd.patch | 71 +++++ ...s-max-min-cj-dp-to-use-VSX-registers.patch | 93 +++++++ ...-Move-xs-max-min-cj-dp-to-decodetree.patch | 121 ++++++++ ...get-ppc-fix-xscvqpdp-register-access.patch | 41 +++ ...rget-ppc-move-xscvqpdp-to-decodetree.patch | 130 +++++++++ ...tore_fpscr-doesn-t-update-bits-0-to-.patch | 70 +++++ ...get-ppc-Introduce-TRANS-FLAGS-macros.patch | 133 +++++++++ ...get-ppc-Implement-Vector-Expand-Mask.patch | 105 +++++++ ...et-ppc-Implement-Vector-Extract-Mask.patch | 141 ++++++++++ ...ppc-Implement-Vector-Mask-Move-insns.patch | 187 +++++++++++++ ...xs-n-madd-am-ds-p-xs-n-msub-am-ds-p-.patch | 258 ++++++++++++++++++ ...mplement-xs-n-maddqp-o-xs-n-msubqp-o.patch | 174 ++++++++++++ 22 files changed, 2400 insertions(+) create mode 100644 meta/recipes-devtools/qemu/qemu/0001-softfloat-Extend-float_exception_flags-to-16-bits.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0002-softfloat-Add-flag-specific-to-Inf-Inf.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0003-softfloat-Add-flag-specific-to-Inf-0.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0004-softfloat-Add-flags-specific-to-Inf-Inf-and-0-0.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0005-softfloat-Add-flag-specific-to-signaling-nans.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0006-target-ppc-Update-float_invalid_op_addsub-for-new-fl.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0007-target-ppc-Update-float_invalid_op_mul-for-new-flags.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0008-target-ppc-Update-float_invalid_op_div-for-new-flags.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0009-target-ppc-Update-fmadd-for-new-flags.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0010-target-ppc-Split-out-do_fmadd.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0011-target-ppc-Fix-xs-max-min-cj-dp-to-use-VSX-registers.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0012-target-ppc-Move-xs-max-min-cj-dp-to-decodetree.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0013-target-ppc-fix-xscvqpdp-register-access.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0014-target-ppc-move-xscvqpdp-to-decodetree.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0015-target-ppc-ppc_store_fpscr-doesn-t-update-bits-0-to-.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0016-target-ppc-Introduce-TRANS-FLAGS-macros.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0017-target-ppc-Implement-Vector-Expand-Mask.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0018-target-ppc-Implement-Vector-Extract-Mask.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0019-target-ppc-Implement-Vector-Mask-Move-insns.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0020-target-ppc-move-xs-n-madd-am-ds-p-xs-n-msub-am-ds-p-.patch create mode 100644 meta/recipes-devtools/qemu/qemu/0021-target-ppc-implement-xs-n-maddqp-o-xs-n-msubqp-o.patch diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc index 76ae603ee4..14feb4f1e0 100644 --- a/meta/recipes-devtools/qemu/qemu.inc +++ b/meta/recipes-devtools/qemu/qemu.inc @@ -71,6 +71,27 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \ file://CVE-2021-3611_1.patch \ file://CVE-2021-3611_2.patch \ file://0001-net-tulip-Restrict-DMA-engine-to-memories.patch \ + file://0001-softfloat-Extend-float_exception_flags-to-16-bits.patch \ + file://0002-softfloat-Add-flag-specific-to-Inf-Inf.patch \ + file://0003-softfloat-Add-flag-specific-to-Inf-0.patch \ + file://0004-softfloat-Add-flags-specific-to-Inf-Inf-and-0-0.patch \ + file://0005-softfloat-Add-flag-specific-to-signaling-nans.patch \ + file://0006-target-ppc-Update-float_invalid_op_addsub-for-new-fl.patch \ + file://0007-target-ppc-Update-float_invalid_op_mul-for-new-flags.patch \ + file://0008-target-ppc-Update-float_invalid_op_div-for-new-flags.patch \ + file://0009-target-ppc-Update-fmadd-for-new-flags.patch \ + file://0010-target-ppc-Split-out-do_fmadd.patch \ + file://0011-target-ppc-Fix-xs-max-min-cj-dp-to-use-VSX-registers.patch \ + file://0012-target-ppc-Move-xs-max-min-cj-dp-to-decodetree.patch \ + file://0013-target-ppc-fix-xscvqpdp-register-access.patch \ + file://0014-target-ppc-move-xscvqpdp-to-decodetree.patch \ + file://0015-target-ppc-ppc_store_fpscr-doesn-t-update-bits-0-to-.patch \ + file://0016-target-ppc-Introduce-TRANS-FLAGS-macros.patch \ + file://0017-target-ppc-Implement-Vector-Expand-Mask.patch \ + file://0018-target-ppc-Implement-Vector-Extract-Mask.patch \ + file://0019-target-ppc-Implement-Vector-Mask-Move-insns.patch \ + file://0020-target-ppc-move-xs-n-madd-am-ds-p-xs-n-msub-am-ds-p-.patch \ + file://0021-target-ppc-implement-xs-n-maddqp-o-xs-n-msubqp-o.patch \ " UPSTREAM_CHECK_REGEX = "qemu-(?P\d+(\.\d+)+)\.tar" diff --git a/meta/recipes-devtools/qemu/qemu/0001-softfloat-Extend-float_exception_flags-to-16-bits.patch b/meta/recipes-devtools/qemu/qemu/0001-softfloat-Extend-float_exception_flags-to-16-bits.patch new file mode 100644 index 0000000000..e9c47f6901 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0001-softfloat-Extend-float_exception_flags-to-16-bits.patch @@ -0,0 +1,75 @@ +From 0bec1ded33a857f59cf5f3ceca2f72694256e710 Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:14 +0100 +Subject: [PATCH 01/21] softfloat: Extend float_exception_flags to 16 bits +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We will shortly have more than 8 bits of exceptions. +Repack the existing flags into low bits and reformat to hex. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=149a48f6e6ccedfa01307d45884aa480f5bf77c5] + +Signed-off-by: Richard Henderson +Reviewed-by: Philippe Mathieu-Daudé +Message-Id: <20211119160502.17432-2-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + include/fpu/softfloat-types.h | 16 ++++++++-------- + include/fpu/softfloat.h | 2 +- + 2 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h +index 5bcbd041f7..65a43aff59 100644 +--- a/include/fpu/softfloat-types.h ++++ b/include/fpu/softfloat-types.h +@@ -145,13 +145,13 @@ typedef enum __attribute__((__packed__)) { + */ + + enum { +- float_flag_invalid = 1, +- float_flag_divbyzero = 4, +- float_flag_overflow = 8, +- float_flag_underflow = 16, +- float_flag_inexact = 32, +- float_flag_input_denormal = 64, +- float_flag_output_denormal = 128 ++ float_flag_invalid = 0x0001, ++ float_flag_divbyzero = 0x0002, ++ float_flag_overflow = 0x0004, ++ float_flag_underflow = 0x0008, ++ float_flag_inexact = 0x0010, ++ float_flag_input_denormal = 0x0020, ++ float_flag_output_denormal = 0x0040, + }; + + /* +@@ -171,8 +171,8 @@ typedef enum __attribute__((__packed__)) { + */ + + typedef struct float_status { ++ uint16_t float_exception_flags; + FloatRoundMode float_rounding_mode; +- uint8_t float_exception_flags; + FloatX80RoundPrec floatx80_rounding_precision; + bool tininess_before_rounding; + /* should denormalised results go to zero and set the inexact flag? */ +diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h +index a249991e61..0d3b407807 100644 +--- a/include/fpu/softfloat.h ++++ b/include/fpu/softfloat.h +@@ -100,7 +100,7 @@ typedef enum { + | Routine to raise any or all of the software IEC/IEEE floating-point + | exception flags. + *----------------------------------------------------------------------------*/ +-static inline void float_raise(uint8_t flags, float_status *status) ++static inline void float_raise(uint16_t flags, float_status *status) + { + status->float_exception_flags |= flags; + } +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0002-softfloat-Add-flag-specific-to-Inf-Inf.patch b/meta/recipes-devtools/qemu/qemu/0002-softfloat-Add-flag-specific-to-Inf-Inf.patch new file mode 100644 index 0000000000..2713ff370d --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0002-softfloat-Add-flag-specific-to-Inf-Inf.patch @@ -0,0 +1,59 @@ +From 9b0737858b2b68c3a4d1e0611f2732679c997c6d Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:14 +0100 +Subject: [PATCH 02/21] softfloat: Add flag specific to Inf - Inf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PowerPC has this flag, and it's easier to compute it here +than after the fact. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=ba11446c40903b9d97fb75a078d43fee6444d3b6] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-3-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + fpu/softfloat-parts.c.inc | 3 ++- + include/fpu/softfloat-types.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc +index 41d4b17e41..eb2b475ca4 100644 +--- a/fpu/softfloat-parts.c.inc ++++ b/fpu/softfloat-parts.c.inc +@@ -354,7 +354,7 @@ static FloatPartsN *partsN(addsub)(FloatPartsN *a, FloatPartsN *b, + return a; + } + /* Inf - Inf */ +- float_raise(float_flag_invalid, s); ++ float_raise(float_flag_invalid | float_flag_invalid_isi, s); + parts_default_nan(a, s); + return a; + } +@@ -494,6 +494,7 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b, + + if (ab_mask & float_cmask_inf) { + if (c->cls == float_class_inf && a->sign != c->sign) { ++ float_raise(float_flag_invalid | float_flag_invalid_isi, s); + goto d_nan; + } + goto return_inf; +diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h +index 65a43aff59..eaa12e1e00 100644 +--- a/include/fpu/softfloat-types.h ++++ b/include/fpu/softfloat-types.h +@@ -152,6 +152,7 @@ enum { + float_flag_inexact = 0x0010, + float_flag_input_denormal = 0x0020, + float_flag_output_denormal = 0x0040, ++ float_flag_invalid_isi = 0x0080, /* inf - inf */ + }; + + /* +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0003-softfloat-Add-flag-specific-to-Inf-0.patch b/meta/recipes-devtools/qemu/qemu/0003-softfloat-Add-flag-specific-to-Inf-0.patch new file mode 100644 index 0000000000..1b21e3cfeb --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0003-softfloat-Add-flag-specific-to-Inf-0.patch @@ -0,0 +1,126 @@ +From 613f373f0b652ab2fb2572633e7a23807096790b Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:14 +0100 +Subject: [PATCH 03/21] softfloat: Add flag specific to Inf * 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PowerPC has this flag, and it's easier to compute it here +than after the fact. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=bead3c9b0ff8efd652afb27923d8ab4458b3bbd9] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-4-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + fpu/softfloat-parts.c.inc | 4 ++-- + fpu/softfloat-specialize.c.inc | 12 ++++++------ + include/fpu/softfloat-types.h | 1 + + 3 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc +index eb2b475ca4..3ed793347b 100644 +--- a/fpu/softfloat-parts.c.inc ++++ b/fpu/softfloat-parts.c.inc +@@ -423,7 +423,7 @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b, + + /* Inf * Zero == NaN */ + if (unlikely(ab_mask == float_cmask_infzero)) { +- float_raise(float_flag_invalid, s); ++ float_raise(float_flag_invalid | float_flag_invalid_imz, s); + parts_default_nan(a, s); + return a; + } +@@ -489,6 +489,7 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b, + + if (unlikely(ab_mask != float_cmask_normal)) { + if (unlikely(ab_mask == float_cmask_infzero)) { ++ float_raise(float_flag_invalid | float_flag_invalid_imz, s); + goto d_nan; + } + +@@ -567,7 +568,6 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b, + goto finish_sign; + + d_nan: +- float_raise(float_flag_invalid, s); + parts_default_nan(a, s); + return a; + } +diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc +index f2ad0f335e..943e3301d2 100644 +--- a/fpu/softfloat-specialize.c.inc ++++ b/fpu/softfloat-specialize.c.inc +@@ -506,7 +506,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls, + * the default NaN + */ + if (infzero && is_qnan(c_cls)) { +- float_raise(float_flag_invalid, status); ++ float_raise(float_flag_invalid | float_flag_invalid_imz, status); + return 3; + } + +@@ -533,7 +533,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls, + * case sets InvalidOp and returns the default NaN + */ + if (infzero) { +- float_raise(float_flag_invalid, status); ++ float_raise(float_flag_invalid | float_flag_invalid_imz, status); + return 3; + } + /* Prefer sNaN over qNaN, in the a, b, c order. */ +@@ -556,7 +556,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls, + * case sets InvalidOp and returns the input value 'c' + */ + if (infzero) { +- float_raise(float_flag_invalid, status); ++ float_raise(float_flag_invalid | float_flag_invalid_imz, status); + return 2; + } + /* Prefer sNaN over qNaN, in the c, a, b order. */ +@@ -580,7 +580,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls, + * a default NaN + */ + if (infzero) { +- float_raise(float_flag_invalid, status); ++ float_raise(float_flag_invalid | float_flag_invalid_imz, status); + return 2; + } + +@@ -597,7 +597,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls, + #elif defined(TARGET_RISCV) + /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */ + if (infzero) { +- float_raise(float_flag_invalid, status); ++ float_raise(float_flag_invalid | float_flag_invalid_imz, status); + } + return 3; /* default NaN */ + #elif defined(TARGET_XTENSA) +@@ -606,7 +606,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls, + * an input NaN if we have one (ie c). + */ + if (infzero) { +- float_raise(float_flag_invalid, status); ++ float_raise(float_flag_invalid | float_flag_invalid_imz, status); + return 2; + } + if (status->use_first_nan) { +diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h +index eaa12e1e00..56b4cf7835 100644 +--- a/include/fpu/softfloat-types.h ++++ b/include/fpu/softfloat-types.h +@@ -153,6 +153,7 @@ enum { + float_flag_input_denormal = 0x0020, + float_flag_output_denormal = 0x0040, + float_flag_invalid_isi = 0x0080, /* inf - inf */ ++ float_flag_invalid_imz = 0x0100, /* inf * 0 */ + }; + + /* +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0004-softfloat-Add-flags-specific-to-Inf-Inf-and-0-0.patch b/meta/recipes-devtools/qemu/qemu/0004-softfloat-Add-flags-specific-to-Inf-Inf-and-0-0.patch new file mode 100644 index 0000000000..c5377fbe70 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0004-softfloat-Add-flags-specific-to-Inf-Inf-and-0-0.patch @@ -0,0 +1,73 @@ +From 52f1760d2d65e1a61028cb9d8610c8a38aa44cfc Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:14 +0100 +Subject: [PATCH 04/21] softfloat: Add flags specific to Inf / Inf and 0 / 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PowerPC has these flags, and it's easier to compute them here +than after the fact. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=10cc964030fca459591d9353571f3b1b4e1b5aec] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-5-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + fpu/softfloat-parts.c.inc | 16 +++++++++++----- + include/fpu/softfloat-types.h | 2 ++ + 2 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc +index 3ed793347b..b8563cd2df 100644 +--- a/fpu/softfloat-parts.c.inc ++++ b/fpu/softfloat-parts.c.inc +@@ -590,11 +590,13 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b, + } + + /* 0/0 or Inf/Inf => NaN */ +- if (unlikely(ab_mask == float_cmask_zero) || +- unlikely(ab_mask == float_cmask_inf)) { +- float_raise(float_flag_invalid, s); +- parts_default_nan(a, s); +- return a; ++ if (unlikely(ab_mask == float_cmask_zero)) { ++ float_raise(float_flag_invalid | float_flag_invalid_zdz, s); ++ goto d_nan; ++ } ++ if (unlikely(ab_mask == float_cmask_inf)) { ++ float_raise(float_flag_invalid | float_flag_invalid_idi, s); ++ goto d_nan; + } + + /* All the NaN cases */ +@@ -625,6 +627,10 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b, + float_raise(float_flag_divbyzero, s); + a->cls = float_class_inf; + return a; ++ ++ d_nan: ++ parts_default_nan(a, s); ++ return a; + } + + /* +diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h +index 56b4cf7835..5a9671e564 100644 +--- a/include/fpu/softfloat-types.h ++++ b/include/fpu/softfloat-types.h +@@ -154,6 +154,8 @@ enum { + float_flag_output_denormal = 0x0040, + float_flag_invalid_isi = 0x0080, /* inf - inf */ + float_flag_invalid_imz = 0x0100, /* inf * 0 */ ++ float_flag_invalid_idi = 0x0200, /* inf / inf */ ++ float_flag_invalid_zdz = 0x0400, /* 0 / 0 */ + }; + + /* +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0005-softfloat-Add-flag-specific-to-signaling-nans.patch b/meta/recipes-devtools/qemu/qemu/0005-softfloat-Add-flag-specific-to-signaling-nans.patch new file mode 100644 index 0000000000..e4ecb496ae --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0005-softfloat-Add-flag-specific-to-signaling-nans.patch @@ -0,0 +1,121 @@ +From 6bc0b2cffab0ee280ae9730262f162f25c16f6c2 Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:14 +0100 +Subject: [PATCH 05/21] softfloat: Add flag specific to signaling nans +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PowerPC has this flag, and it's easier to compute it here +than after the fact. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=e706d4455b8d54252b11fc504c56df060151cb89] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-8-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + fpu/softfloat-parts.c.inc | 18 ++++++++++++------ + fpu/softfloat.c | 4 +++- + include/fpu/softfloat-types.h | 1 + + 3 files changed, 16 insertions(+), 7 deletions(-) + +diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc +index b8563cd2df..9518f3dc61 100644 +--- a/fpu/softfloat-parts.c.inc ++++ b/fpu/softfloat-parts.c.inc +@@ -19,7 +19,7 @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s) + { + switch (a->cls) { + case float_class_snan: +- float_raise(float_flag_invalid, s); ++ float_raise(float_flag_invalid | float_flag_invalid_snan, s); + if (s->default_nan_mode) { + parts_default_nan(a, s); + } else { +@@ -40,7 +40,7 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b, + float_status *s) + { + if (is_snan(a->cls) || is_snan(b->cls)) { +- float_raise(float_flag_invalid, s); ++ float_raise(float_flag_invalid | float_flag_invalid_snan, s); + } + + if (s->default_nan_mode) { +@@ -68,7 +68,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b, + int which; + + if (unlikely(abc_mask & float_cmask_snan)) { +- float_raise(float_flag_invalid, s); ++ float_raise(float_flag_invalid | float_flag_invalid_snan, s); + } + + which = pickNaNMulAdd(a->cls, b->cls, c->cls, +@@ -1049,8 +1049,10 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode, + + switch (p->cls) { + case float_class_snan: ++ flags |= float_flag_invalid_snan; ++ /* fall through */ + case float_class_qnan: +- flags = float_flag_invalid; ++ flags |= float_flag_invalid; + r = max; + break; + +@@ -1114,8 +1116,10 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode, + + switch (p->cls) { + case float_class_snan: ++ flags |= float_flag_invalid_snan; ++ /* fall through */ + case float_class_qnan: +- flags = float_flag_invalid; ++ flags |= float_flag_invalid; + r = max; + break; + +@@ -1341,7 +1345,9 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b, + } + + if (unlikely(ab_mask & float_cmask_anynan)) { +- if (!is_quiet || (ab_mask & float_cmask_snan)) { ++ if (ab_mask & float_cmask_snan) { ++ float_raise(float_flag_invalid | float_flag_invalid_snan, s); ++ } else if (!is_quiet) { + float_raise(float_flag_invalid, s); + } + return float_relation_unordered; +diff --git a/fpu/softfloat.c b/fpu/softfloat.c +index 9a28720d82..834ed3a054 100644 +--- a/fpu/softfloat.c ++++ b/fpu/softfloat.c +@@ -2543,8 +2543,10 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status) + static void parts_float_to_ahp(FloatParts64 *a, float_status *s) + { + switch (a->cls) { +- case float_class_qnan: + case float_class_snan: ++ float_raise(float_flag_invalid_snan, s); ++ /* fall through */ ++ case float_class_qnan: + /* + * There is no NaN in the destination format. Raise Invalid + * and return a zero with the sign of the input NaN. +diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h +index 5a9671e564..e557b9126b 100644 +--- a/include/fpu/softfloat-types.h ++++ b/include/fpu/softfloat-types.h +@@ -156,6 +156,7 @@ enum { + float_flag_invalid_imz = 0x0100, /* inf * 0 */ + float_flag_invalid_idi = 0x0200, /* inf / inf */ + float_flag_invalid_zdz = 0x0400, /* 0 / 0 */ ++ float_flag_invalid_snan = 0x2000, /* any operand was snan */ + }; + + /* +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0006-target-ppc-Update-float_invalid_op_addsub-for-new-fl.patch b/meta/recipes-devtools/qemu/qemu/0006-target-ppc-Update-float_invalid_op_addsub-for-new-fl.patch new file mode 100644 index 0000000000..5f38c7265f --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0006-target-ppc-Update-float_invalid_op_addsub-for-new-fl.patch @@ -0,0 +1,114 @@ +From ba4a60dd5df31b9fff8b7b8006bf9f15140cc6c5 Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:14 +0100 +Subject: [PATCH 06/21] target/ppc: Update float_invalid_op_addsub for new + flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now that vxisi and vxsnan are computed directly by +softfloat, we don't need to recompute it via classes. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=941298ecd7e3103d3789d2dd87dd0f119e81c69e] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-9-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 38 ++++++++++++++------------------------ + 1 file changed, 14 insertions(+), 24 deletions(-) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index c4896cecc8..f0deada84b 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -450,13 +450,12 @@ void helper_reset_fpstatus(CPUPPCState *env) + set_float_exception_flags(0, &env->fp_status); + } + +-static void float_invalid_op_addsub(CPUPPCState *env, bool set_fpcc, +- uintptr_t retaddr, int classes) ++static void float_invalid_op_addsub(CPUPPCState *env, int flags, ++ bool set_fpcc, uintptr_t retaddr) + { +- if ((classes & ~is_neg) == is_inf) { +- /* Magnitude subtraction of infinities */ ++ if (flags & float_flag_invalid_isi) { + float_invalid_op_vxisi(env, set_fpcc, retaddr); +- } else if (classes & is_snan) { ++ } else if (flags & float_flag_invalid_snan) { + float_invalid_op_vxsnan(env, retaddr); + } + } +@@ -465,12 +464,10 @@ static void float_invalid_op_addsub(CPUPPCState *env, bool set_fpcc, + float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2) + { + float64 ret = float64_add(arg1, arg2, &env->fp_status); +- int status = get_float_exception_flags(&env->fp_status); ++ int flags = get_float_exception_flags(&env->fp_status); + +- if (unlikely(status & float_flag_invalid)) { +- float_invalid_op_addsub(env, 1, GETPC(), +- float64_classify(arg1) | +- float64_classify(arg2)); ++ if (unlikely(flags & float_flag_invalid)) { ++ float_invalid_op_addsub(env, flags, 1, GETPC()); + } + + return ret; +@@ -480,12 +477,10 @@ float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2) + float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2) + { + float64 ret = float64_sub(arg1, arg2, &env->fp_status); +- int status = get_float_exception_flags(&env->fp_status); ++ int flags = get_float_exception_flags(&env->fp_status); + +- if (unlikely(status & float_flag_invalid)) { +- float_invalid_op_addsub(env, 1, GETPC(), +- float64_classify(arg1) | +- float64_classify(arg2)); ++ if (unlikely(flags & float_flag_invalid)) { ++ float_invalid_op_addsub(env, flags, 1, GETPC()); + } + + return ret; +@@ -1616,9 +1611,8 @@ void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \ + env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ + if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ +- float_invalid_op_addsub(env, sfprf, GETPC(), \ +- tp##_classify(xa->fld) | \ +- tp##_classify(xb->fld)); \ ++ float_invalid_op_addsub(env, tstat.float_exception_flags, \ ++ sfprf, GETPC()); \ + } \ + \ + if (r2sp) { \ +@@ -1660,9 +1654,7 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode, + env->fp_status.float_exception_flags |= tstat.float_exception_flags; + + if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { +- float_invalid_op_addsub(env, 1, GETPC(), +- float128_classify(xa->f128) | +- float128_classify(xb->f128)); ++ float_invalid_op_addsub(env, tstat.float_exception_flags, 1, GETPC()); + } + + helper_compute_fprf_float128(env, t.f128); +@@ -3278,9 +3270,7 @@ void helper_xssubqp(CPUPPCState *env, uint32_t opcode, + env->fp_status.float_exception_flags |= tstat.float_exception_flags; + + if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { +- float_invalid_op_addsub(env, 1, GETPC(), +- float128_classify(xa->f128) | +- float128_classify(xb->f128)); ++ float_invalid_op_addsub(env, tstat.float_exception_flags, 1, GETPC()); + } + + helper_compute_fprf_float128(env, t.f128); +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0007-target-ppc-Update-float_invalid_op_mul-for-new-flags.patch b/meta/recipes-devtools/qemu/qemu/0007-target-ppc-Update-float_invalid_op_mul-for-new-flags.patch new file mode 100644 index 0000000000..1cc4e9e35c --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0007-target-ppc-Update-float_invalid_op_mul-for-new-flags.patch @@ -0,0 +1,86 @@ +From ee8ba2dbb046f48457566b64ad95bf0440d2513e Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:14 +0100 +Subject: [PATCH 07/21] target/ppc: Update float_invalid_op_mul for new flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now that vximz and vxsnan are computed directly by +softfloat, we don't need to recompute it via classes. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=4edf55698fc2ea30903657c63ed95db0d5548943] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-10-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 26 ++++++++++---------------- + 1 file changed, 10 insertions(+), 16 deletions(-) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index f0deada84b..23264e6528 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -486,13 +486,12 @@ float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2) + return ret; + } + +-static void float_invalid_op_mul(CPUPPCState *env, bool set_fprc, +- uintptr_t retaddr, int classes) ++static void float_invalid_op_mul(CPUPPCState *env, int flags, ++ bool set_fprc, uintptr_t retaddr) + { +- if ((classes & (is_zero | is_inf)) == (is_zero | is_inf)) { +- /* Multiplication of zero by infinity */ ++ if (flags & float_flag_invalid_imz) { + float_invalid_op_vximz(env, set_fprc, retaddr); +- } else if (classes & is_snan) { ++ } else if (flags & float_flag_invalid_snan) { + float_invalid_op_vxsnan(env, retaddr); + } + } +@@ -501,12 +500,10 @@ static void float_invalid_op_mul(CPUPPCState *env, bool set_fprc, + float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2) + { + float64 ret = float64_mul(arg1, arg2, &env->fp_status); +- int status = get_float_exception_flags(&env->fp_status); ++ int flags = get_float_exception_flags(&env->fp_status); + +- if (unlikely(status & float_flag_invalid)) { +- float_invalid_op_mul(env, 1, GETPC(), +- float64_classify(arg1) | +- float64_classify(arg2)); ++ if (unlikely(flags & float_flag_invalid)) { ++ float_invalid_op_mul(env, flags, 1, GETPC()); + } + + return ret; +@@ -1687,9 +1684,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ + env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ + if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ +- float_invalid_op_mul(env, sfprf, GETPC(), \ +- tp##_classify(xa->fld) | \ +- tp##_classify(xb->fld)); \ ++ float_invalid_op_mul(env, tstat.float_exception_flags, \ ++ sfprf, GETPC()); \ + } \ + \ + if (r2sp) { \ +@@ -1727,9 +1723,7 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode, + env->fp_status.float_exception_flags |= tstat.float_exception_flags; + + if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { +- float_invalid_op_mul(env, 1, GETPC(), +- float128_classify(xa->f128) | +- float128_classify(xb->f128)); ++ float_invalid_op_mul(env, tstat.float_exception_flags, 1, GETPC()); + } + helper_compute_fprf_float128(env, t.f128); + +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0008-target-ppc-Update-float_invalid_op_div-for-new-flags.patch b/meta/recipes-devtools/qemu/qemu/0008-target-ppc-Update-float_invalid_op_div-for-new-flags.patch new file mode 100644 index 0000000000..cb657eefd5 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0008-target-ppc-Update-float_invalid_op_div-for-new-flags.patch @@ -0,0 +1,99 @@ +From a13c0819ef14120a0e30077fcc6a7470409fa732 Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:14 +0100 +Subject: [PATCH 08/21] target/ppc: Update float_invalid_op_div for new flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now that vxidi, vxzdz, and vxsnan are computed directly by +softfloat, we don't need to recompute it via classes. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=c07f82416cb7973c64d1e21c09957182b4b033dc] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-11-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 38 ++++++++++++++------------------------ + 1 file changed, 14 insertions(+), 24 deletions(-) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index 23264e6528..2ab34236a3 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -509,17 +509,14 @@ float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2) + return ret; + } + +-static void float_invalid_op_div(CPUPPCState *env, bool set_fprc, +- uintptr_t retaddr, int classes) ++static void float_invalid_op_div(CPUPPCState *env, int flags, ++ bool set_fprc, uintptr_t retaddr) + { +- classes &= ~is_neg; +- if (classes == is_inf) { +- /* Division of infinity by infinity */ ++ if (flags & float_flag_invalid_idi) { + float_invalid_op_vxidi(env, set_fprc, retaddr); +- } else if (classes == is_zero) { +- /* Division of zero by zero */ ++ } else if (flags & float_flag_invalid_zdz) { + float_invalid_op_vxzdz(env, set_fprc, retaddr); +- } else if (classes & is_snan) { ++ } else if (flags & float_flag_invalid_snan) { + float_invalid_op_vxsnan(env, retaddr); + } + } +@@ -528,17 +525,13 @@ static void float_invalid_op_div(CPUPPCState *env, bool set_fprc, + float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2) + { + float64 ret = float64_div(arg1, arg2, &env->fp_status); +- int status = get_float_exception_flags(&env->fp_status); ++ int flags = get_float_exception_flags(&env->fp_status); + +- if (unlikely(status)) { +- if (status & float_flag_invalid) { +- float_invalid_op_div(env, 1, GETPC(), +- float64_classify(arg1) | +- float64_classify(arg2)); +- } +- if (status & float_flag_divbyzero) { +- float_zero_divide_excp(env, GETPC()); +- } ++ if (unlikely(flags & float_flag_invalid)) { ++ float_invalid_op_div(env, flags, 1, GETPC()); ++ } ++ if (unlikely(flags & float_flag_divbyzero)) { ++ float_zero_divide_excp(env, GETPC()); + } + + return ret; +@@ -1755,9 +1748,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ + env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ + if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ +- float_invalid_op_div(env, sfprf, GETPC(), \ +- tp##_classify(xa->fld) | \ +- tp##_classify(xb->fld)); \ ++ float_invalid_op_div(env, tstat.float_exception_flags, \ ++ sfprf, GETPC()); \ + } \ + if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) { \ + float_zero_divide_excp(env, GETPC()); \ +@@ -1798,9 +1790,7 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode, + env->fp_status.float_exception_flags |= tstat.float_exception_flags; + + if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { +- float_invalid_op_div(env, 1, GETPC(), +- float128_classify(xa->f128) | +- float128_classify(xb->f128)); ++ float_invalid_op_div(env, tstat.float_exception_flags, 1, GETPC()); + } + if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) { + float_zero_divide_excp(env, GETPC()); +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0009-target-ppc-Update-fmadd-for-new-flags.patch b/meta/recipes-devtools/qemu/qemu/0009-target-ppc-Update-fmadd-for-new-flags.patch new file mode 100644 index 0000000000..2e723582b7 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0009-target-ppc-Update-fmadd-for-new-flags.patch @@ -0,0 +1,102 @@ +From ce768160ee1ee9673d60e800389c41b3c707411a Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:15 +0100 +Subject: [PATCH 09/21] target/ppc: Update fmadd for new flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now that vximz, vxisi, and vxsnan are computed directly by +softfloat, we don't need to recompute it. This replaces the +separate float{32,64}_maddsub_update_excp functions with a +single float_invalid_op_madd function. + +Fix VSX_MADD by passing sfprf to float_invalid_op_madd, +whereas the previous *_maddsub_update_excp assumed it true. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=e4052bb773cc829a27786d68caa22f28cff19d39] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-19-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 46 ++++++++++------------------------------- + 1 file changed, 11 insertions(+), 35 deletions(-) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index 2ab34236a3..3b1cb25666 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -639,38 +639,15 @@ uint64_t helper_frim(CPUPPCState *env, uint64_t arg) + return do_fri(env, arg, float_round_down); + } + +-#define FPU_MADDSUB_UPDATE(NAME, TP) \ +-static void NAME(CPUPPCState *env, TP arg1, TP arg2, TP arg3, \ +- unsigned int madd_flags, uintptr_t retaddr) \ +-{ \ +- if (TP##_is_signaling_nan(arg1, &env->fp_status) || \ +- TP##_is_signaling_nan(arg2, &env->fp_status) || \ +- TP##_is_signaling_nan(arg3, &env->fp_status)) { \ +- /* sNaN operation */ \ +- float_invalid_op_vxsnan(env, retaddr); \ +- } \ +- if ((TP##_is_infinity(arg1) && TP##_is_zero(arg2)) || \ +- (TP##_is_zero(arg1) && TP##_is_infinity(arg2))) { \ +- /* Multiplication of zero by infinity */ \ +- float_invalid_op_vximz(env, 1, retaddr); \ +- } \ +- if ((TP##_is_infinity(arg1) || TP##_is_infinity(arg2)) && \ +- TP##_is_infinity(arg3)) { \ +- uint8_t aSign, bSign, cSign; \ +- \ +- aSign = TP##_is_neg(arg1); \ +- bSign = TP##_is_neg(arg2); \ +- cSign = TP##_is_neg(arg3); \ +- if (madd_flags & float_muladd_negate_c) { \ +- cSign ^= 1; \ +- } \ +- if (aSign ^ bSign ^ cSign) { \ +- float_invalid_op_vxisi(env, 1, retaddr); \ +- } \ +- } \ ++static void float_invalid_op_madd(CPUPPCState *env, int flags, ++ bool set_fpcc, uintptr_t retaddr) ++{ ++ if (flags & float_flag_invalid_imz) { ++ float_invalid_op_vximz(env, set_fpcc, retaddr); ++ } else { ++ float_invalid_op_addsub(env, flags, set_fpcc, retaddr); ++ } + } +-FPU_MADDSUB_UPDATE(float32_maddsub_update_excp, float32) +-FPU_MADDSUB_UPDATE(float64_maddsub_update_excp, float64) + + #define FPU_FMADD(op, madd_flags) \ + uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \ +@@ -682,8 +659,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \ + flags = get_float_exception_flags(&env->fp_status); \ + if (flags) { \ + if (flags & float_flag_invalid) { \ +- float64_maddsub_update_excp(env, arg1, arg2, arg3, \ +- madd_flags, GETPC()); \ ++ float_invalid_op_madd(env, flags, 1, GETPC()); \ + } \ + do_float_check_status(env, GETPC()); \ + } \ +@@ -2087,8 +2063,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ + env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ + if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ +- tp##_maddsub_update_excp(env, xa->fld, b->fld, \ +- c->fld, maddflgs, GETPC()); \ ++ float_invalid_op_madd(env, tstat.float_exception_flags, \ ++ sfprf, GETPC()); \ + } \ + \ + if (r2sp) { \ +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0010-target-ppc-Split-out-do_fmadd.patch b/meta/recipes-devtools/qemu/qemu/0010-target-ppc-Split-out-do_fmadd.patch new file mode 100644 index 0000000000..4d19773200 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0010-target-ppc-Split-out-do_fmadd.patch @@ -0,0 +1,71 @@ +From f024b8937d8b614994b94e86d2240fafcc7d2d73 Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 17 Dec 2021 17:57:15 +0100 +Subject: [PATCH 10/21] target/ppc: Split out do_fmadd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Create a common function for all of the madd helpers. +Let the compiler tail call or inline as it chooses. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=ffdaff8e9c698061f57a6b1827570562c5a1c909] + +Signed-off-by: Richard Henderson +Message-Id: <20211119160502.17432-20-richard.henderson@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 33 ++++++++++++++++++--------------- + 1 file changed, 18 insertions(+), 15 deletions(-) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index 3b1cb25666..9a1e7e6244 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -649,23 +649,26 @@ static void float_invalid_op_madd(CPUPPCState *env, int flags, + } + } + +-#define FPU_FMADD(op, madd_flags) \ +-uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \ +- uint64_t arg2, uint64_t arg3) \ +-{ \ +- uint32_t flags; \ +- float64 ret = float64_muladd(arg1, arg2, arg3, madd_flags, \ +- &env->fp_status); \ +- flags = get_float_exception_flags(&env->fp_status); \ +- if (flags) { \ +- if (flags & float_flag_invalid) { \ +- float_invalid_op_madd(env, flags, 1, GETPC()); \ +- } \ +- do_float_check_status(env, GETPC()); \ +- } \ +- return ret; \ ++static float64 do_fmadd(CPUPPCState *env, float64 a, float64 b, ++ float64 c, int madd_flags, uintptr_t retaddr) ++{ ++ float64 ret = float64_muladd(a, b, c, madd_flags, &env->fp_status); ++ int flags = get_float_exception_flags(&env->fp_status); ++ ++ if (flags) { ++ if (flags & float_flag_invalid) { ++ float_invalid_op_madd(env, flags, 1, retaddr); ++ } ++ do_float_check_status(env, retaddr); ++ } ++ return ret; + } + ++#define FPU_FMADD(op, madd_flags) \ ++ uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \ ++ uint64_t arg2, uint64_t arg3) \ ++ { return do_fmadd(env, arg1, arg2, arg3, madd_flags, GETPC()); } ++ + #define MADD_FLGS 0 + #define MSUB_FLGS float_muladd_negate_c + #define NMADD_FLGS float_muladd_negate_result +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0011-target-ppc-Fix-xs-max-min-cj-dp-to-use-VSX-registers.patch b/meta/recipes-devtools/qemu/qemu/0011-target-ppc-Fix-xs-max-min-cj-dp-to-use-VSX-registers.patch new file mode 100644 index 0000000000..0daae55b99 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0011-target-ppc-Fix-xs-max-min-cj-dp-to-use-VSX-registers.patch @@ -0,0 +1,93 @@ +From a1821ad612994b95cb6597efd15e0a888676386c Mon Sep 17 00:00:00 2001 +From: Victor Colombo +Date: Fri, 17 Dec 2021 17:57:18 +0100 +Subject: [PATCH 11/21] target/ppc: Fix xs{max, min}[cj]dp to use VSX registers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PPC instruction xsmaxcdp, xsmincdp, xsmaxjdp, and xsminjdp are using +vector registers when they should be using VSX ones. This happens +because the instructions are using GEN_VSX_HELPER_R3, which adds 32 +to the register numbers, effectively making them vector registers. + +This patch fixes it by changing these instructions to use +GEN_VSX_HELPER_X3. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=201fc774e0e1cc76ec23b595968004a7b14fb6e8] + +Reviewed-by: Richard Henderson +Signed-off-by: Victor Colombo +Message-Id: <20211213120958.24443-2-victor.colombo@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 4 ++-- + target/ppc/helper.h | 8 ++++---- + target/ppc/translate/vsx-impl.c.inc | 8 ++++---- + 3 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index 9a1e7e6244..ecdcd36a11 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -2375,7 +2375,7 @@ VSX_MAX_MIN(xvmindp, minnum, 2, float64, VsrD(i)) + VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i)) + + #define VSX_MAX_MINC(name, max) \ +-void helper_##name(CPUPPCState *env, uint32_t opcode, \ ++void helper_##name(CPUPPCState *env, \ + ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \ + { \ + ppc_vsr_t t = *xt; \ +@@ -2410,7 +2410,7 @@ VSX_MAX_MINC(xsmaxcdp, 1); + VSX_MAX_MINC(xsmincdp, 0); + + #define VSX_MAX_MINJ(name, max) \ +-void helper_##name(CPUPPCState *env, uint32_t opcode, \ ++void helper_##name(CPUPPCState *env, \ + ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \ + { \ + ppc_vsr_t t = *xt; \ +diff --git a/target/ppc/helper.h b/target/ppc/helper.h +index 627811cefc..12a3d5f269 100644 +--- a/target/ppc/helper.h ++++ b/target/ppc/helper.h +@@ -392,10 +392,10 @@ DEF_HELPER_4(xscmpoqp, void, env, i32, vsr, vsr) + DEF_HELPER_4(xscmpuqp, void, env, i32, vsr, vsr) + DEF_HELPER_4(xsmaxdp, void, env, vsr, vsr, vsr) + DEF_HELPER_4(xsmindp, void, env, vsr, vsr, vsr) +-DEF_HELPER_5(xsmaxcdp, void, env, i32, vsr, vsr, vsr) +-DEF_HELPER_5(xsmincdp, void, env, i32, vsr, vsr, vsr) +-DEF_HELPER_5(xsmaxjdp, void, env, i32, vsr, vsr, vsr) +-DEF_HELPER_5(xsminjdp, void, env, i32, vsr, vsr, vsr) ++DEF_HELPER_4(xsmaxcdp, void, env, vsr, vsr, vsr) ++DEF_HELPER_4(xsmincdp, void, env, vsr, vsr, vsr) ++DEF_HELPER_4(xsmaxjdp, void, env, vsr, vsr, vsr) ++DEF_HELPER_4(xsminjdp, void, env, vsr, vsr, vsr) + DEF_HELPER_3(xscvdphp, void, env, vsr, vsr) + DEF_HELPER_4(xscvdpqp, void, env, i32, vsr, vsr) + DEF_HELPER_3(xscvdpsp, void, env, vsr, vsr) +diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc +index c0e38060b4..02df75339e 100644 +--- a/target/ppc/translate/vsx-impl.c.inc ++++ b/target/ppc/translate/vsx-impl.c.inc +@@ -1098,10 +1098,10 @@ GEN_VSX_HELPER_R2_AB(xscmpoqp, 0x04, 0x04, 0, PPC2_VSX) + GEN_VSX_HELPER_R2_AB(xscmpuqp, 0x04, 0x14, 0, PPC2_VSX) + GEN_VSX_HELPER_X3(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX) + GEN_VSX_HELPER_X3(xsmindp, 0x00, 0x15, 0, PPC2_VSX) +-GEN_VSX_HELPER_R3(xsmaxcdp, 0x00, 0x10, 0, PPC2_ISA300) +-GEN_VSX_HELPER_R3(xsmincdp, 0x00, 0x11, 0, PPC2_ISA300) +-GEN_VSX_HELPER_R3(xsmaxjdp, 0x00, 0x12, 0, PPC2_ISA300) +-GEN_VSX_HELPER_R3(xsminjdp, 0x00, 0x12, 0, PPC2_ISA300) ++GEN_VSX_HELPER_X3(xsmaxcdp, 0x00, 0x10, 0, PPC2_ISA300) ++GEN_VSX_HELPER_X3(xsmincdp, 0x00, 0x11, 0, PPC2_ISA300) ++GEN_VSX_HELPER_X3(xsmaxjdp, 0x00, 0x12, 0, PPC2_ISA300) ++GEN_VSX_HELPER_X3(xsminjdp, 0x00, 0x12, 0, PPC2_ISA300) + GEN_VSX_HELPER_X2(xscvdphp, 0x16, 0x15, 0x11, PPC2_ISA300) + GEN_VSX_HELPER_X2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX) + GEN_VSX_HELPER_R2(xscvdpqp, 0x04, 0x1A, 0x16, PPC2_ISA300) +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0012-target-ppc-Move-xs-max-min-cj-dp-to-decodetree.patch b/meta/recipes-devtools/qemu/qemu/0012-target-ppc-Move-xs-max-min-cj-dp-to-decodetree.patch new file mode 100644 index 0000000000..e9b99c9b4e --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0012-target-ppc-Move-xs-max-min-cj-dp-to-decodetree.patch @@ -0,0 +1,121 @@ +From 1cbb2622de34ee034f1dd7196567673c52c84805 Mon Sep 17 00:00:00 2001 +From: Victor Colombo +Date: Fri, 17 Dec 2021 17:57:18 +0100 +Subject: [PATCH 12/21] target/ppc: Move xs{max,min}[cj]dp to decodetree +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=c5df1898a147c232f0502cda5dac8df6074070fc] + +Reviewed-by: Richard Henderson +Signed-off-by: Victor Colombo +Message-Id: <20211213120958.24443-3-victor.colombo@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/insn32.decode | 17 +++++++++++++--- + target/ppc/translate/vsx-impl.c.inc | 30 +++++++++++++++++++++++++---- + target/ppc/translate/vsx-ops.c.inc | 4 ---- + 3 files changed, 40 insertions(+), 11 deletions(-) + +diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode +index e135b8aba4..759b2a9aa5 100644 +--- a/target/ppc/insn32.decode ++++ b/target/ppc/insn32.decode +@@ -123,10 +123,14 @@ + &X_vrt_frbp vrt frbp + @X_vrt_frbp ...... vrt:5 ..... ....0 .......... . &X_vrt_frbp frbp=%x_frbp + ++%xx_xt 0:1 21:5 ++%xx_xb 1:1 11:5 ++%xx_xa 2:1 16:5 + &XX2 xt xb uim:uint8_t +-%xx2_xt 0:1 21:5 +-%xx2_xb 1:1 11:5 +-@XX2 ...... ..... ... uim:2 ..... ......... .. &XX2 xt=%xx2_xt xb=%xx2_xb ++@XX2 ...... ..... ... uim:2 ..... ......... .. &XX2 xt=%xx_xt xb=%xx_xb ++ ++&XX3 xt xa xb ++@XX3 ...... ..... ..... ..... ........ ... &XX3 xt=%xx_xt xa=%xx_xa xb=%xx_xb + + &Z22_bf_fra bf fra dm + @Z22_bf_fra ...... bf:3 .. fra:5 dm:6 ......... . &Z22_bf_fra +@@ -427,3 +431,10 @@ XXSPLTW 111100 ..... ---.. ..... 010100100 . . @XX2 + ## VSX Vector Load Special Value Instruction + + LXVKQ 111100 ..... 11111 ..... 0101101000 . @X_uim5 ++ ++## VSX Comparison Instructions ++ ++XSMAXCDP 111100 ..... ..... ..... 10000000 ... @XX3 ++XSMINCDP 111100 ..... ..... ..... 10001000 ... @XX3 ++XSMAXJDP 111100 ..... ..... ..... 10010000 ... @XX3 ++XSMINJDP 111100 ..... ..... ..... 10011000 ... @XX3 +diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc +index 02df75339e..e2447750dd 100644 +--- a/target/ppc/translate/vsx-impl.c.inc ++++ b/target/ppc/translate/vsx-impl.c.inc +@@ -1098,10 +1098,6 @@ GEN_VSX_HELPER_R2_AB(xscmpoqp, 0x04, 0x04, 0, PPC2_VSX) + GEN_VSX_HELPER_R2_AB(xscmpuqp, 0x04, 0x14, 0, PPC2_VSX) + GEN_VSX_HELPER_X3(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX) + GEN_VSX_HELPER_X3(xsmindp, 0x00, 0x15, 0, PPC2_VSX) +-GEN_VSX_HELPER_X3(xsmaxcdp, 0x00, 0x10, 0, PPC2_ISA300) +-GEN_VSX_HELPER_X3(xsmincdp, 0x00, 0x11, 0, PPC2_ISA300) +-GEN_VSX_HELPER_X3(xsmaxjdp, 0x00, 0x12, 0, PPC2_ISA300) +-GEN_VSX_HELPER_X3(xsminjdp, 0x00, 0x12, 0, PPC2_ISA300) + GEN_VSX_HELPER_X2(xscvdphp, 0x16, 0x15, 0x11, PPC2_ISA300) + GEN_VSX_HELPER_X2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX) + GEN_VSX_HELPER_R2(xscvdpqp, 0x04, 0x1A, 0x16, PPC2_ISA300) +@@ -2185,6 +2181,32 @@ TRANS(XXBLENDVH, do_xxblendv, MO_16) + TRANS(XXBLENDVW, do_xxblendv, MO_32) + TRANS(XXBLENDVD, do_xxblendv, MO_64) + ++static bool do_xsmaxmincjdp(DisasContext *ctx, arg_XX3 *a, ++ void (*helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr)) ++{ ++ TCGv_ptr xt, xa, xb; ++ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA300); ++ REQUIRE_VSX(ctx); ++ ++ xt = gen_vsr_ptr(a->xt); ++ xa = gen_vsr_ptr(a->xa); ++ xb = gen_vsr_ptr(a->xb); ++ ++ helper(cpu_env, xt, xa, xb); ++ ++ tcg_temp_free_ptr(xt); ++ tcg_temp_free_ptr(xa); ++ tcg_temp_free_ptr(xb); ++ ++ return true; ++} ++ ++TRANS(XSMAXCDP, do_xsmaxmincjdp, gen_helper_xsmaxcdp) ++TRANS(XSMINCDP, do_xsmaxmincjdp, gen_helper_xsmincdp) ++TRANS(XSMAXJDP, do_xsmaxmincjdp, gen_helper_xsmaxjdp) ++TRANS(XSMINJDP, do_xsmaxmincjdp, gen_helper_xsminjdp) ++ + #undef GEN_XX2FORM + #undef GEN_XX3FORM + #undef GEN_XX2IFORM +diff --git a/target/ppc/translate/vsx-ops.c.inc b/target/ppc/translate/vsx-ops.c.inc +index 152d1e5c3b..f980bc1bae 100644 +--- a/target/ppc/translate/vsx-ops.c.inc ++++ b/target/ppc/translate/vsx-ops.c.inc +@@ -207,10 +207,6 @@ GEN_VSX_XFORM_300(xscmpoqp, 0x04, 0x04, 0x00600001), + GEN_VSX_XFORM_300(xscmpuqp, 0x04, 0x14, 0x00600001), + GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX), + GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX), +-GEN_XX3FORM(xsmaxcdp, 0x00, 0x10, PPC2_ISA300), +-GEN_XX3FORM(xsmincdp, 0x00, 0x11, PPC2_ISA300), +-GEN_XX3FORM(xsmaxjdp, 0x00, 0x12, PPC2_ISA300), +-GEN_XX3FORM(xsminjdp, 0x00, 0x13, PPC2_ISA300), + GEN_XX2FORM_EO(xscvdphp, 0x16, 0x15, 0x11, PPC2_ISA300), + GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX), + GEN_XX2FORM(xscvdpspn, 0x16, 0x10, PPC2_VSX207), +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0013-target-ppc-fix-xscvqpdp-register-access.patch b/meta/recipes-devtools/qemu/qemu/0013-target-ppc-fix-xscvqpdp-register-access.patch new file mode 100644 index 0000000000..100dcd25bc --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0013-target-ppc-fix-xscvqpdp-register-access.patch @@ -0,0 +1,41 @@ +From 98ff271a4d1a1d60ae53b1f742df7c188b163375 Mon Sep 17 00:00:00 2001 +From: Matheus Ferst +Date: Fri, 17 Dec 2021 17:57:18 +0100 +Subject: [PATCH 13/21] target/ppc: fix xscvqpdp register access +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This instruction has VRT and VRB fields instead of T/TX and B/BX. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=38d4914c5065e14f0969161274793ded448f067f] + +Reviewed-by: Richard Henderson +Signed-off-by: Matheus Ferst +Message-Id: <20211213120958.24443-4-victor.colombo@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/translate/vsx-impl.c.inc | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc +index e2447750dd..ab5cb21f13 100644 +--- a/target/ppc/translate/vsx-impl.c.inc ++++ b/target/ppc/translate/vsx-impl.c.inc +@@ -913,8 +913,9 @@ static void gen_xscvqpdp(DisasContext *ctx) + return; + } + opc = tcg_const_i32(ctx->opcode); +- xt = gen_vsr_ptr(xT(ctx->opcode)); +- xb = gen_vsr_ptr(xB(ctx->opcode)); ++ ++ xt = gen_vsr_ptr(rD(ctx->opcode) + 32); ++ xb = gen_vsr_ptr(rB(ctx->opcode) + 32); + gen_helper_xscvqpdp(cpu_env, opc, xt, xb); + tcg_temp_free_i32(opc); + tcg_temp_free_ptr(xt); +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0014-target-ppc-move-xscvqpdp-to-decodetree.patch b/meta/recipes-devtools/qemu/qemu/0014-target-ppc-move-xscvqpdp-to-decodetree.patch new file mode 100644 index 0000000000..345a49c90c --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0014-target-ppc-move-xscvqpdp-to-decodetree.patch @@ -0,0 +1,130 @@ +From c76ea6322bd70c36c9b396cf356167b36928e811 Mon Sep 17 00:00:00 2001 +From: Matheus Ferst +Date: Fri, 17 Dec 2021 17:57:18 +0100 +Subject: [PATCH 14/21] target/ppc: move xscvqpdp to decodetree +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=caf6f9b568479bea6f6d97798be670f21641a006] + +Reviewed-by: Richard Henderson +Signed-off-by: Matheus Ferst +Message-Id: <20211213120958.24443-5-victor.colombo@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 10 +++------- + target/ppc/helper.h | 2 +- + target/ppc/insn32.decode | 4 ++++ + target/ppc/translate/vsx-impl.c.inc | 24 +++++++++++++----------- + target/ppc/translate/vsx-ops.c.inc | 1 - + 5 files changed, 21 insertions(+), 20 deletions(-) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index ecdcd36a11..5cc7fb1dcb 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -2631,18 +2631,14 @@ VSX_CVT_FP_TO_FP_HP(xscvhpdp, 1, float16, float64, VsrH(3), VsrD(0), 1) + VSX_CVT_FP_TO_FP_HP(xvcvsphp, 4, float32, float16, VsrW(i), VsrH(2 * i + 1), 0) + VSX_CVT_FP_TO_FP_HP(xvcvhpsp, 4, float16, float32, VsrH(2 * i + 1), VsrW(i), 0) + +-/* +- * xscvqpdp isn't using VSX_CVT_FP_TO_FP() because xscvqpdpo will be +- * added to this later. +- */ +-void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode, +- ppc_vsr_t *xt, ppc_vsr_t *xb) ++void helper_XSCVQPDP(CPUPPCState *env, uint32_t ro, ppc_vsr_t *xt, ++ ppc_vsr_t *xb) + { + ppc_vsr_t t = { }; + float_status tstat; + + tstat = env->fp_status; +- if (unlikely(Rc(opcode) != 0)) { ++ if (ro != 0) { + tstat.float_rounding_mode = float_round_to_odd; + } + +diff --git a/target/ppc/helper.h b/target/ppc/helper.h +index 12a3d5f269..ef5bdd38a7 100644 +--- a/target/ppc/helper.h ++++ b/target/ppc/helper.h +@@ -400,7 +400,7 @@ DEF_HELPER_3(xscvdphp, void, env, vsr, vsr) + DEF_HELPER_4(xscvdpqp, void, env, i32, vsr, vsr) + DEF_HELPER_3(xscvdpsp, void, env, vsr, vsr) + DEF_HELPER_2(xscvdpspn, i64, env, i64) +-DEF_HELPER_4(xscvqpdp, void, env, i32, vsr, vsr) ++DEF_HELPER_4(XSCVQPDP, void, env, i32, vsr, vsr) + DEF_HELPER_4(xscvqpsdz, void, env, i32, vsr, vsr) + DEF_HELPER_4(xscvqpswz, void, env, i32, vsr, vsr) + DEF_HELPER_4(xscvqpudz, void, env, i32, vsr, vsr) +diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode +index 759b2a9aa5..fd6bb13fa0 100644 +--- a/target/ppc/insn32.decode ++++ b/target/ppc/insn32.decode +@@ -438,3 +438,7 @@ XSMAXCDP 111100 ..... ..... ..... 10000000 ... @XX3 + XSMINCDP 111100 ..... ..... ..... 10001000 ... @XX3 + XSMAXJDP 111100 ..... ..... ..... 10010000 ... @XX3 + XSMINJDP 111100 ..... ..... ..... 10011000 ... @XX3 ++ ++## VSX Binary Floating-Point Convert Instructions ++ ++XSCVQPDP 111111 ..... 10100 ..... 1101000100 . @X_tb_rc +diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc +index ab5cb21f13..c08185e857 100644 +--- a/target/ppc/translate/vsx-impl.c.inc ++++ b/target/ppc/translate/vsx-impl.c.inc +@@ -904,22 +904,24 @@ VSX_CMP(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX) + VSX_CMP(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX) + VSX_CMP(xvcmpnesp, 0x0C, 0x0B, 0, PPC2_VSX) + +-static void gen_xscvqpdp(DisasContext *ctx) ++static bool trans_XSCVQPDP(DisasContext *ctx, arg_X_tb_rc *a) + { +- TCGv_i32 opc; ++ TCGv_i32 ro; + TCGv_ptr xt, xb; +- if (unlikely(!ctx->vsx_enabled)) { +- gen_exception(ctx, POWERPC_EXCP_VSXU); +- return; +- } +- opc = tcg_const_i32(ctx->opcode); + +- xt = gen_vsr_ptr(rD(ctx->opcode) + 32); +- xb = gen_vsr_ptr(rB(ctx->opcode) + 32); +- gen_helper_xscvqpdp(cpu_env, opc, xt, xb); +- tcg_temp_free_i32(opc); ++ REQUIRE_INSNS_FLAGS2(ctx, ISA300); ++ REQUIRE_VSX(ctx); ++ ++ ro = tcg_const_i32(a->rc); ++ ++ xt = gen_avr_ptr(a->rt); ++ xb = gen_avr_ptr(a->rb); ++ gen_helper_XSCVQPDP(cpu_env, ro, xt, xb); ++ tcg_temp_free_i32(ro); + tcg_temp_free_ptr(xt); + tcg_temp_free_ptr(xb); ++ ++ return true; + } + + #define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \ +diff --git a/target/ppc/translate/vsx-ops.c.inc b/target/ppc/translate/vsx-ops.c.inc +index f980bc1bae..c974324c4c 100644 +--- a/target/ppc/translate/vsx-ops.c.inc ++++ b/target/ppc/translate/vsx-ops.c.inc +@@ -133,7 +133,6 @@ GEN_VSX_XFORM_300_EO(xsnabsqp, 0x04, 0x19, 0x08, 0x00000001), + GEN_VSX_XFORM_300_EO(xsnegqp, 0x04, 0x19, 0x10, 0x00000001), + GEN_VSX_XFORM_300(xscpsgnqp, 0x04, 0x03, 0x00000001), + GEN_VSX_XFORM_300_EO(xscvdpqp, 0x04, 0x1A, 0x16, 0x00000001), +-GEN_VSX_XFORM_300_EO(xscvqpdp, 0x04, 0x1A, 0x14, 0x0), + GEN_VSX_XFORM_300_EO(xscvqpsdz, 0x04, 0x1A, 0x19, 0x00000001), + GEN_VSX_XFORM_300_EO(xscvqpswz, 0x04, 0x1A, 0x09, 0x00000001), + GEN_VSX_XFORM_300_EO(xscvqpudz, 0x04, 0x1A, 0x11, 0x00000001), +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0015-target-ppc-ppc_store_fpscr-doesn-t-update-bits-0-to-.patch b/meta/recipes-devtools/qemu/qemu/0015-target-ppc-ppc_store_fpscr-doesn-t-update-bits-0-to-.patch new file mode 100644 index 0000000000..5c5f972961 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0015-target-ppc-ppc_store_fpscr-doesn-t-update-bits-0-to-.patch @@ -0,0 +1,70 @@ +From 7448ee811d86b18a7f7f59e20853bd852e548f59 Mon Sep 17 00:00:00 2001 +From: "Lucas Mateus Castro (alqotel)" +Date: Fri, 17 Dec 2021 17:57:13 +0100 +Subject: [PATCH 15/21] target/ppc: ppc_store_fpscr doesn't update bits 0 to 28 + and 52 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This commit fixes the difference reported in the bug in the reserved +bit 52, it does this by adding this bit to the mask of bits to not be +directly altered in the ppc_store_fpscr function (the hardware used to +compare to QEMU was a Power9). + +The bits 0 to 27 were also added to the mask, as they are marked as +reserved in the PowerISA and bit 28 is a reserved extension of the DRN +field (bits 29:31) but can't be set using mtfsfi, while the other DRN +bits may be set using mtfsfi instruction, so bit 28 was also added to +the mask. + +Although this is a difference reported in the bug, since it's a reserved +bit it may be a "don't care" case, as put in the bug report. Looking at +the ISA it doesn't explicitly mention this bit can't be set, like it +does for FEX and VX, so I'm unsure if this is necessary. + +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/266 + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=25ee608d79c1890c0f4e8c495ec8629d5712de45] + +Signed-off-by: Lucas Mateus Castro (alqotel) +Message-Id: <20211201163808.440385-4-lucas.araujo@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/cpu.c | 2 +- + target/ppc/cpu.h | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c +index f933d9f2bd..d7b42bae52 100644 +--- a/target/ppc/cpu.c ++++ b/target/ppc/cpu.c +@@ -112,7 +112,7 @@ static inline void fpscr_set_rounding_mode(CPUPPCState *env) + + void ppc_store_fpscr(CPUPPCState *env, target_ulong val) + { +- val &= ~(FP_VX | FP_FEX); ++ val &= FPSCR_MTFS_MASK; + if (val & FPSCR_IX) { + val |= FP_VX; + } +diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h +index e946da5f3a..441d3dce19 100644 +--- a/target/ppc/cpu.h ++++ b/target/ppc/cpu.h +@@ -759,6 +759,10 @@ enum { + FP_VXZDZ | FP_VXIMZ | FP_VXVC | FP_VXSOFT | \ + FP_VXSQRT | FP_VXCVI) + ++/* FPSCR bits that can be set by mtfsf, mtfsfi and mtfsb1 */ ++#define FPSCR_MTFS_MASK (~(MAKE_64BIT_MASK(36, 28) | PPC_BIT(28) | \ ++ FP_FEX | FP_VX | PPC_BIT(52))) ++ + /*****************************************************************************/ + /* Vector status and control register */ + #define VSCR_NJ 16 /* Vector non-java */ +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0016-target-ppc-Introduce-TRANS-FLAGS-macros.patch b/meta/recipes-devtools/qemu/qemu/0016-target-ppc-Introduce-TRANS-FLAGS-macros.patch new file mode 100644 index 0000000000..3b651c0b3e --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0016-target-ppc-Introduce-TRANS-FLAGS-macros.patch @@ -0,0 +1,133 @@ +From 232f979babccd6dfac40a54ee33521e652a0577c Mon Sep 17 00:00:00 2001 +From: Luis Pires +Date: Wed, 2 Mar 2022 06:51:36 +0100 +Subject: [PATCH 16/21] target/ppc: Introduce TRANS*FLAGS macros +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +New macros that add FLAGS and FLAGS2 checking were added for +both TRANS and TRANS64. + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=19f0862dd8fa6510b2f5b3aff4859363602cd0cf] + +Reviewed-by: Richard Henderson +Signed-off-by: Luis Pires +[ferst: - TRANS_FLAGS2 instead of TRANS_FLAGS_E + - Use the new macros in load/store vector insns ] +Signed-off-by: Matheus Ferst +Message-Id: <20220225210936.1749575-2-matheus.ferst@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/translate.c | 19 +++++++++++++++ + target/ppc/translate/vsx-impl.c.inc | 37 ++++++++++------------------- + 2 files changed, 31 insertions(+), 25 deletions(-) + +diff --git a/target/ppc/translate.c b/target/ppc/translate.c +index 9960df6e18..c12abc32f6 100644 +--- a/target/ppc/translate.c ++++ b/target/ppc/translate.c +@@ -7377,10 +7377,29 @@ static int times_16(DisasContext *ctx, int x) + #define TRANS(NAME, FUNC, ...) \ + static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ + { return FUNC(ctx, a, __VA_ARGS__); } ++#define TRANS_FLAGS(FLAGS, NAME, FUNC, ...) \ ++ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ ++ { \ ++ REQUIRE_INSNS_FLAGS(ctx, FLAGS); \ ++ return FUNC(ctx, a, __VA_ARGS__); \ ++ } ++#define TRANS_FLAGS2(FLAGS2, NAME, FUNC, ...) \ ++ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ ++ { \ ++ REQUIRE_INSNS_FLAGS2(ctx, FLAGS2); \ ++ return FUNC(ctx, a, __VA_ARGS__); \ ++ } + + #define TRANS64(NAME, FUNC, ...) \ + static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ + { REQUIRE_64BIT(ctx); return FUNC(ctx, a, __VA_ARGS__); } ++#define TRANS64_FLAGS2(FLAGS2, NAME, FUNC, ...) \ ++ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ ++ { \ ++ REQUIRE_64BIT(ctx); \ ++ REQUIRE_INSNS_FLAGS2(ctx, FLAGS2); \ ++ return FUNC(ctx, a, __VA_ARGS__); \ ++ } + + /* TODO: More TRANS* helpers for extra insn_flags checks. */ + +diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc +index c08185e857..99c8a57e50 100644 +--- a/target/ppc/translate/vsx-impl.c.inc ++++ b/target/ppc/translate/vsx-impl.c.inc +@@ -2070,12 +2070,6 @@ static bool do_lstxv(DisasContext *ctx, int ra, TCGv displ, + + static bool do_lstxv_D(DisasContext *ctx, arg_D *a, bool store, bool paired) + { +- if (paired) { +- REQUIRE_INSNS_FLAGS2(ctx, ISA310); +- } else { +- REQUIRE_INSNS_FLAGS2(ctx, ISA300); +- } +- + if (paired || a->rt >= 32) { + REQUIRE_VSX(ctx); + } else { +@@ -2089,7 +2083,6 @@ static bool do_lstxv_PLS_D(DisasContext *ctx, arg_PLS_D *a, + bool store, bool paired) + { + arg_D d; +- REQUIRE_INSNS_FLAGS2(ctx, ISA310); + REQUIRE_VSX(ctx); + + if (!resolve_PLS_D(ctx, &d, a)) { +@@ -2101,12 +2094,6 @@ static bool do_lstxv_PLS_D(DisasContext *ctx, arg_PLS_D *a, + + static bool do_lstxv_X(DisasContext *ctx, arg_X *a, bool store, bool paired) + { +- if (paired) { +- REQUIRE_INSNS_FLAGS2(ctx, ISA310); +- } else { +- REQUIRE_INSNS_FLAGS2(ctx, ISA300); +- } +- + if (paired || a->rt >= 32) { + REQUIRE_VSX(ctx); + } else { +@@ -2116,18 +2103,18 @@ static bool do_lstxv_X(DisasContext *ctx, arg_X *a, bool store, bool paired) + return do_lstxv(ctx, a->ra, cpu_gpr[a->rb], a->rt, store, paired); + } + +-TRANS(STXV, do_lstxv_D, true, false) +-TRANS(LXV, do_lstxv_D, false, false) +-TRANS(STXVP, do_lstxv_D, true, true) +-TRANS(LXVP, do_lstxv_D, false, true) +-TRANS(STXVX, do_lstxv_X, true, false) +-TRANS(LXVX, do_lstxv_X, false, false) +-TRANS(STXVPX, do_lstxv_X, true, true) +-TRANS(LXVPX, do_lstxv_X, false, true) +-TRANS64(PSTXV, do_lstxv_PLS_D, true, false) +-TRANS64(PLXV, do_lstxv_PLS_D, false, false) +-TRANS64(PSTXVP, do_lstxv_PLS_D, true, true) +-TRANS64(PLXVP, do_lstxv_PLS_D, false, true) ++TRANS_FLAGS2(ISA300, STXV, do_lstxv_D, true, false) ++TRANS_FLAGS2(ISA300, LXV, do_lstxv_D, false, false) ++TRANS_FLAGS2(ISA310, STXVP, do_lstxv_D, true, true) ++TRANS_FLAGS2(ISA310, LXVP, do_lstxv_D, false, true) ++TRANS_FLAGS2(ISA300, STXVX, do_lstxv_X, true, false) ++TRANS_FLAGS2(ISA300, LXVX, do_lstxv_X, false, false) ++TRANS_FLAGS2(ISA310, STXVPX, do_lstxv_X, true, true) ++TRANS_FLAGS2(ISA310, LXVPX, do_lstxv_X, false, true) ++TRANS64_FLAGS2(ISA310, PSTXV, do_lstxv_PLS_D, true, false) ++TRANS64_FLAGS2(ISA310, PLXV, do_lstxv_PLS_D, false, false) ++TRANS64_FLAGS2(ISA310, PSTXVP, do_lstxv_PLS_D, true, true) ++TRANS64_FLAGS2(ISA310, PLXVP, do_lstxv_PLS_D, false, true) + + static void gen_xxblendv_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b, + TCGv_vec c) +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0017-target-ppc-Implement-Vector-Expand-Mask.patch b/meta/recipes-devtools/qemu/qemu/0017-target-ppc-Implement-Vector-Expand-Mask.patch new file mode 100644 index 0000000000..6d6d6b86ed --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0017-target-ppc-Implement-Vector-Expand-Mask.patch @@ -0,0 +1,105 @@ +From 4c6a16c2bcdd14249eef876d3d029c445716fb13 Mon Sep 17 00:00:00 2001 +From: Matheus Ferst +Date: Fri, 17 Dec 2021 17:57:13 +0100 +Subject: [PATCH 17/21] target/ppc: Implement Vector Expand Mask +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement the following PowerISA v3.1 instructions: +vexpandbm: Vector Expand Byte Mask +vexpandhm: Vector Expand Halfword Mask +vexpandwm: Vector Expand Word Mask +vexpanddm: Vector Expand Doubleword Mask +vexpandqm: Vector Expand Quadword Mask + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=5f1470b091007f24035d6d33149df49a6dd61682] + +Reviewed-by: Richard Henderson +Signed-off-by: Matheus Ferst +Message-Id: <20211203194229.746275-2-matheus.ferst@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/insn32.decode | 11 ++++++++++ + target/ppc/translate/vmx-impl.c.inc | 34 +++++++++++++++++++++++++++++ + 2 files changed, 45 insertions(+) + +diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode +index fd6bb13fa0..e032251c74 100644 +--- a/target/ppc/insn32.decode ++++ b/target/ppc/insn32.decode +@@ -56,6 +56,9 @@ + &VX_uim4 vrt uim vrb + @VX_uim4 ...... vrt:5 . uim:4 vrb:5 ........... &VX_uim4 + ++&VX_tb vrt vrb ++@VX_tb ...... vrt:5 ..... vrb:5 ........... &VX_tb ++ + &X rt ra rb + @X ...... rt:5 ra:5 rb:5 .......... . &X + +@@ -412,6 +415,14 @@ VINSWVRX 000100 ..... ..... ..... 00110001111 @VX + VSLDBI 000100 ..... ..... ..... 00 ... 010110 @VN + VSRDBI 000100 ..... ..... ..... 01 ... 010110 @VN + ++## Vector Mask Manipulation Instructions ++ ++VEXPANDBM 000100 ..... 00000 ..... 11001000010 @VX_tb ++VEXPANDHM 000100 ..... 00001 ..... 11001000010 @VX_tb ++VEXPANDWM 000100 ..... 00010 ..... 11001000010 @VX_tb ++VEXPANDDM 000100 ..... 00011 ..... 11001000010 @VX_tb ++VEXPANDQM 000100 ..... 00100 ..... 11001000010 @VX_tb ++ + # VSX Load/Store Instructions + + LXV 111101 ..... ..... ............ . 001 @DQ_TSX +diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc +index 8eb8d3a067..ebb0484323 100644 +--- a/target/ppc/translate/vmx-impl.c.inc ++++ b/target/ppc/translate/vmx-impl.c.inc +@@ -1491,6 +1491,40 @@ static bool trans_VSRDBI(DisasContext *ctx, arg_VN *a) + return true; + } + ++static bool do_vexpand(DisasContext *ctx, arg_VX_tb *a, unsigned vece) ++{ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA310); ++ REQUIRE_VECTOR(ctx); ++ ++ tcg_gen_gvec_sari(vece, avr_full_offset(a->vrt), avr_full_offset(a->vrb), ++ (8 << vece) - 1, 16, 16); ++ ++ return true; ++} ++ ++TRANS(VEXPANDBM, do_vexpand, MO_8) ++TRANS(VEXPANDHM, do_vexpand, MO_16) ++TRANS(VEXPANDWM, do_vexpand, MO_32) ++TRANS(VEXPANDDM, do_vexpand, MO_64) ++ ++static bool trans_VEXPANDQM(DisasContext *ctx, arg_VX_tb *a) ++{ ++ TCGv_i64 tmp; ++ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA310); ++ REQUIRE_VECTOR(ctx); ++ ++ tmp = tcg_temp_new_i64(); ++ ++ get_avr64(tmp, a->vrb, true); ++ tcg_gen_sari_i64(tmp, tmp, 63); ++ set_avr64(a->vrt, tmp, false); ++ set_avr64(a->vrt, tmp, true); ++ ++ tcg_temp_free_i64(tmp); ++ return true; ++} ++ + #define GEN_VAFORM_PAIRED(name0, name1, opc2) \ + static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ + { \ +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0018-target-ppc-Implement-Vector-Extract-Mask.patch b/meta/recipes-devtools/qemu/qemu/0018-target-ppc-Implement-Vector-Extract-Mask.patch new file mode 100644 index 0000000000..57450c6fb7 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0018-target-ppc-Implement-Vector-Extract-Mask.patch @@ -0,0 +1,141 @@ +From 2dc8450e80b82c481904570dce789843b031db13 Mon Sep 17 00:00:00 2001 +From: Matheus Ferst +Date: Fri, 17 Dec 2021 17:57:13 +0100 +Subject: [PATCH 18/21] target/ppc: Implement Vector Extract Mask +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement the following PowerISA v3.1 instructions: +vextractbm: Vector Extract Byte Mask +vextracthm: Vector Extract Halfword Mask +vextractwm: Vector Extract Word Mask +vextractdm: Vector Extract Doubleword Mask +vextractqm: Vector Extract Quadword Mask + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=17868d81e0074905b2c1e414af6618570e8059eb] + +Signed-off-by: Matheus Ferst +Reviewed-by: Richard Henderson +Message-Id: <20211203194229.746275-3-matheus.ferst@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/insn32.decode | 6 +++ + target/ppc/translate/vmx-impl.c.inc | 82 +++++++++++++++++++++++++++++ + 2 files changed, 88 insertions(+) + +diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode +index e032251c74..b0568b1356 100644 +--- a/target/ppc/insn32.decode ++++ b/target/ppc/insn32.decode +@@ -423,6 +423,12 @@ VEXPANDWM 000100 ..... 00010 ..... 11001000010 @VX_tb + VEXPANDDM 000100 ..... 00011 ..... 11001000010 @VX_tb + VEXPANDQM 000100 ..... 00100 ..... 11001000010 @VX_tb + ++VEXTRACTBM 000100 ..... 01000 ..... 11001000010 @VX_tb ++VEXTRACTHM 000100 ..... 01001 ..... 11001000010 @VX_tb ++VEXTRACTWM 000100 ..... 01010 ..... 11001000010 @VX_tb ++VEXTRACTDM 000100 ..... 01011 ..... 11001000010 @VX_tb ++VEXTRACTQM 000100 ..... 01100 ..... 11001000010 @VX_tb ++ + # VSX Load/Store Instructions + + LXV 111101 ..... ..... ............ . 001 @DQ_TSX +diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc +index ebb0484323..96c97bf6e7 100644 +--- a/target/ppc/translate/vmx-impl.c.inc ++++ b/target/ppc/translate/vmx-impl.c.inc +@@ -1525,6 +1525,88 @@ static bool trans_VEXPANDQM(DisasContext *ctx, arg_VX_tb *a) + return true; + } + ++static bool do_vextractm(DisasContext *ctx, arg_VX_tb *a, unsigned vece) ++{ ++ const uint64_t elem_width = 8 << vece, elem_count_half = 8 >> vece, ++ mask = dup_const(vece, 1 << (elem_width - 1)); ++ uint64_t i, j; ++ TCGv_i64 lo, hi, t0, t1; ++ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA310); ++ REQUIRE_VECTOR(ctx); ++ ++ hi = tcg_temp_new_i64(); ++ lo = tcg_temp_new_i64(); ++ t0 = tcg_temp_new_i64(); ++ t1 = tcg_temp_new_i64(); ++ ++ get_avr64(lo, a->vrb, false); ++ get_avr64(hi, a->vrb, true); ++ ++ tcg_gen_andi_i64(lo, lo, mask); ++ tcg_gen_andi_i64(hi, hi, mask); ++ ++ /* ++ * Gather the most significant bit of each element in the highest element ++ * element. E.g. for bytes: ++ * aXXXXXXXbXXXXXXXcXXXXXXXdXXXXXXXeXXXXXXXfXXXXXXXgXXXXXXXhXXXXXXX ++ * & dup(1 << (elem_width - 1)) ++ * a0000000b0000000c0000000d0000000e0000000f0000000g0000000h0000000 ++ * << 32 - 4 ++ * 0000e0000000f0000000g0000000h00000000000000000000000000000000000 ++ * | ++ * a000e000b000f000c000g000d000h000e0000000f0000000g0000000h0000000 ++ * << 16 - 2 ++ * 00c000g000d000h000e0000000f0000000g0000000h000000000000000000000 ++ * | ++ * a0c0e0g0b0d0f0h0c0e0g000d0f0h000e0g00000f0h00000g0000000h0000000 ++ * << 8 - 1 ++ * 0b0d0f0h0c0e0g000d0f0h000e0g00000f0h00000g0000000h00000000000000 ++ * | ++ * abcdefghbcdefgh0cdefgh00defgh000efgh0000fgh00000gh000000h0000000 ++ */ ++ for (i = elem_count_half / 2, j = 32; i > 0; i >>= 1, j >>= 1) { ++ tcg_gen_shli_i64(t0, hi, j - i); ++ tcg_gen_shli_i64(t1, lo, j - i); ++ tcg_gen_or_i64(hi, hi, t0); ++ tcg_gen_or_i64(lo, lo, t1); ++ } ++ ++ tcg_gen_shri_i64(hi, hi, 64 - elem_count_half); ++ tcg_gen_extract2_i64(lo, lo, hi, 64 - elem_count_half); ++ tcg_gen_trunc_i64_tl(cpu_gpr[a->vrt], lo); ++ ++ tcg_temp_free_i64(hi); ++ tcg_temp_free_i64(lo); ++ tcg_temp_free_i64(t0); ++ tcg_temp_free_i64(t1); ++ ++ return true; ++} ++ ++TRANS(VEXTRACTBM, do_vextractm, MO_8) ++TRANS(VEXTRACTHM, do_vextractm, MO_16) ++TRANS(VEXTRACTWM, do_vextractm, MO_32) ++TRANS(VEXTRACTDM, do_vextractm, MO_64) ++ ++static bool trans_VEXTRACTQM(DisasContext *ctx, arg_VX_tb *a) ++{ ++ TCGv_i64 tmp; ++ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA310); ++ REQUIRE_VECTOR(ctx); ++ ++ tmp = tcg_temp_new_i64(); ++ ++ get_avr64(tmp, a->vrb, true); ++ tcg_gen_shri_i64(tmp, tmp, 63); ++ tcg_gen_trunc_i64_tl(cpu_gpr[a->vrt], tmp); ++ ++ tcg_temp_free_i64(tmp); ++ ++ return true; ++} ++ + #define GEN_VAFORM_PAIRED(name0, name1, opc2) \ + static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ + { \ +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0019-target-ppc-Implement-Vector-Mask-Move-insns.patch b/meta/recipes-devtools/qemu/qemu/0019-target-ppc-Implement-Vector-Mask-Move-insns.patch new file mode 100644 index 0000000000..96fda98771 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0019-target-ppc-Implement-Vector-Mask-Move-insns.patch @@ -0,0 +1,187 @@ +From 4d5202aad706fd338646d19aafbf255c3864333c Mon Sep 17 00:00:00 2001 +From: Matheus Ferst +Date: Fri, 17 Dec 2021 17:57:13 +0100 +Subject: [PATCH 19/21] target/ppc: Implement Vector Mask Move insns +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement the following PowerISA v3.1 instructions: +mtvsrbm: Move to VSR Byte Mask +mtvsrhm: Move to VSR Halfword Mask +mtvsrwm: Move to VSR Word Mask +mtvsrdm: Move to VSR Doubleword Mask +mtvsrqm: Move to VSR Quadword Mask +mtvsrbmi: Move to VSR Byte Mask Immediate + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=9193eaa901c54dbff4a91ea0b12a99e0135dbca1] + +Reviewed-by: Richard Henderson +Signed-off-by: Matheus Ferst +Message-Id: <20211203194229.746275-4-matheus.ferst@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/insn32.decode | 11 +++ + target/ppc/translate/vmx-impl.c.inc | 115 ++++++++++++++++++++++++++++ + 2 files changed, 126 insertions(+) + +diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode +index b0568b1356..8bdc059a4c 100644 +--- a/target/ppc/insn32.decode ++++ b/target/ppc/insn32.decode +@@ -40,6 +40,10 @@ + %ds_rtp 22:4 !function=times_2 + @DS_rtp ...... ....0 ra:5 .............. .. &D rt=%ds_rtp si=%ds_si + ++&DX_b vrt b ++%dx_b 6:10 16:5 0:1 ++@DX_b ...... vrt:5 ..... .......... ..... . &DX_b b=%dx_b ++ + &DX rt d + %dx_d 6:s10 16:5 0:1 + @DX ...... rt:5 ..... .......... ..... . &DX d=%dx_d +@@ -417,6 +421,13 @@ VSRDBI 000100 ..... ..... ..... 01 ... 010110 @VN + + ## Vector Mask Manipulation Instructions + ++MTVSRBM 000100 ..... 10000 ..... 11001000010 @VX_tb ++MTVSRHM 000100 ..... 10001 ..... 11001000010 @VX_tb ++MTVSRWM 000100 ..... 10010 ..... 11001000010 @VX_tb ++MTVSRDM 000100 ..... 10011 ..... 11001000010 @VX_tb ++MTVSRQM 000100 ..... 10100 ..... 11001000010 @VX_tb ++MTVSRBMI 000100 ..... ..... .......... 01010 . @DX_b ++ + VEXPANDBM 000100 ..... 00000 ..... 11001000010 @VX_tb + VEXPANDHM 000100 ..... 00001 ..... 11001000010 @VX_tb + VEXPANDWM 000100 ..... 00010 ..... 11001000010 @VX_tb +diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc +index 96c97bf6e7..d5e02fd7f2 100644 +--- a/target/ppc/translate/vmx-impl.c.inc ++++ b/target/ppc/translate/vmx-impl.c.inc +@@ -1607,6 +1607,121 @@ static bool trans_VEXTRACTQM(DisasContext *ctx, arg_VX_tb *a) + return true; + } + ++static bool do_mtvsrm(DisasContext *ctx, arg_VX_tb *a, unsigned vece) ++{ ++ const uint64_t elem_width = 8 << vece, elem_count_half = 8 >> vece; ++ uint64_t c; ++ int i, j; ++ TCGv_i64 hi, lo, t0, t1; ++ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA310); ++ REQUIRE_VECTOR(ctx); ++ ++ hi = tcg_temp_new_i64(); ++ lo = tcg_temp_new_i64(); ++ t0 = tcg_temp_new_i64(); ++ t1 = tcg_temp_new_i64(); ++ ++ tcg_gen_extu_tl_i64(t0, cpu_gpr[a->vrb]); ++ tcg_gen_extract_i64(hi, t0, elem_count_half, elem_count_half); ++ tcg_gen_extract_i64(lo, t0, 0, elem_count_half); ++ ++ /* ++ * Spread the bits into their respective elements. ++ * E.g. for bytes: ++ * 00000000000000000000000000000000000000000000000000000000abcdefgh ++ * << 32 - 4 ++ * 0000000000000000000000000000abcdefgh0000000000000000000000000000 ++ * | ++ * 0000000000000000000000000000abcdefgh00000000000000000000abcdefgh ++ * << 16 - 2 ++ * 00000000000000abcdefgh00000000000000000000abcdefgh00000000000000 ++ * | ++ * 00000000000000abcdefgh000000abcdefgh000000abcdefgh000000abcdefgh ++ * << 8 - 1 ++ * 0000000abcdefgh000000abcdefgh000000abcdefgh000000abcdefgh0000000 ++ * | ++ * 0000000abcdefgXbcdefgXbcdefgXbcdefgXbcdefgXbcdefgXbcdefgXbcdefgh ++ * & dup(1) ++ * 0000000a0000000b0000000c0000000d0000000e0000000f0000000g0000000h ++ * * 0xff ++ * aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh ++ */ ++ for (i = elem_count_half / 2, j = 32; i > 0; i >>= 1, j >>= 1) { ++ tcg_gen_shli_i64(t0, hi, j - i); ++ tcg_gen_shli_i64(t1, lo, j - i); ++ tcg_gen_or_i64(hi, hi, t0); ++ tcg_gen_or_i64(lo, lo, t1); ++ } ++ ++ c = dup_const(vece, 1); ++ tcg_gen_andi_i64(hi, hi, c); ++ tcg_gen_andi_i64(lo, lo, c); ++ ++ c = MAKE_64BIT_MASK(0, elem_width); ++ tcg_gen_muli_i64(hi, hi, c); ++ tcg_gen_muli_i64(lo, lo, c); ++ ++ set_avr64(a->vrt, lo, false); ++ set_avr64(a->vrt, hi, true); ++ ++ tcg_temp_free_i64(hi); ++ tcg_temp_free_i64(lo); ++ tcg_temp_free_i64(t0); ++ tcg_temp_free_i64(t1); ++ ++ return true; ++} ++ ++TRANS(MTVSRBM, do_mtvsrm, MO_8) ++TRANS(MTVSRHM, do_mtvsrm, MO_16) ++TRANS(MTVSRWM, do_mtvsrm, MO_32) ++TRANS(MTVSRDM, do_mtvsrm, MO_64) ++ ++static bool trans_MTVSRQM(DisasContext *ctx, arg_VX_tb *a) ++{ ++ TCGv_i64 tmp; ++ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA310); ++ REQUIRE_VECTOR(ctx); ++ ++ tmp = tcg_temp_new_i64(); ++ ++ tcg_gen_ext_tl_i64(tmp, cpu_gpr[a->vrb]); ++ tcg_gen_sextract_i64(tmp, tmp, 0, 1); ++ set_avr64(a->vrt, tmp, false); ++ set_avr64(a->vrt, tmp, true); ++ ++ tcg_temp_free_i64(tmp); ++ ++ return true; ++} ++ ++static bool trans_MTVSRBMI(DisasContext *ctx, arg_DX_b *a) ++{ ++ const uint64_t mask = dup_const(MO_8, 1); ++ uint64_t hi, lo; ++ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA310); ++ REQUIRE_VECTOR(ctx); ++ ++ hi = extract16(a->b, 8, 8); ++ lo = extract16(a->b, 0, 8); ++ ++ for (int i = 4, j = 32; i > 0; i >>= 1, j >>= 1) { ++ hi |= hi << (j - i); ++ lo |= lo << (j - i); ++ } ++ ++ hi = (hi & mask) * 0xFF; ++ lo = (lo & mask) * 0xFF; ++ ++ set_avr64(a->vrt, tcg_constant_i64(hi), true); ++ set_avr64(a->vrt, tcg_constant_i64(lo), false); ++ ++ return true; ++} ++ + #define GEN_VAFORM_PAIRED(name0, name1, opc2) \ + static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ + { \ +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0020-target-ppc-move-xs-n-madd-am-ds-p-xs-n-msub-am-ds-p-.patch b/meta/recipes-devtools/qemu/qemu/0020-target-ppc-move-xs-n-madd-am-ds-p-xs-n-msub-am-ds-p-.patch new file mode 100644 index 0000000000..7e747298a9 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0020-target-ppc-move-xs-n-madd-am-ds-p-xs-n-msub-am-ds-p-.patch @@ -0,0 +1,258 @@ +From a3c7553efdec661a8f7d7dfc0c0618a35fab005c Mon Sep 17 00:00:00 2001 +From: Matheus Ferst +Date: Wed, 2 Mar 2022 06:51:38 +0100 +Subject: [PATCH 20/21] target/ppc: move xs[n]madd[am][ds]p/xs[n]msub[am][ds]p + to decodetree +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=e4318ab2e423c4caf9a88a4e99b5e234096b81a9] + +Reviewed-by: Richard Henderson +Signed-off-by: Matheus Ferst +Message-Id: <20220225210936.1749575-37-matheus.ferst@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 23 ++++++------ + target/ppc/helper.h | 16 ++++----- + target/ppc/insn32.decode | 22 ++++++++++++ + target/ppc/translate/vsx-impl.c.inc | 56 ++++++++++++++++++++++++----- + target/ppc/translate/vsx-ops.c.inc | 16 --------- + 5 files changed, 90 insertions(+), 43 deletions(-) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index 5cc7fb1dcb..853e5f6029 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -2036,10 +2036,11 @@ VSX_TSQRT(xvtsqrtsp, 4, float32, VsrW(i), -126, 23) + * maddflgs - flags for the float*muladd routine that control the + * various forms (madd, msub, nmadd, nmsub) + * sfprf - set FPRF ++ * r2sp - round intermediate double precision result to single precision + */ + #define VSX_MADD(op, nels, tp, fld, maddflgs, sfprf, r2sp) \ + void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ +- ppc_vsr_t *xa, ppc_vsr_t *b, ppc_vsr_t *c) \ ++ ppc_vsr_t *s1, ppc_vsr_t *s2, ppc_vsr_t *s3) \ + { \ + ppc_vsr_t t = *xt; \ + int i; \ +@@ -2055,12 +2056,12 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ + * result to odd. \ + */ \ + set_float_rounding_mode(float_round_to_zero, &tstat); \ +- t.fld = tp##_muladd(xa->fld, b->fld, c->fld, \ ++ t.fld = tp##_muladd(s1->fld, s3->fld, s2->fld, \ + maddflgs, &tstat); \ + t.fld |= (get_float_exception_flags(&tstat) & \ + float_flag_inexact) != 0; \ + } else { \ +- t.fld = tp##_muladd(xa->fld, b->fld, c->fld, \ ++ t.fld = tp##_muladd(s1->fld, s3->fld, s2->fld, \ + maddflgs, &tstat); \ + } \ + env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ +@@ -2082,14 +2083,14 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ + do_float_check_status(env, GETPC()); \ + } + +-VSX_MADD(xsmadddp, 1, float64, VsrD(0), MADD_FLGS, 1, 0) +-VSX_MADD(xsmsubdp, 1, float64, VsrD(0), MSUB_FLGS, 1, 0) +-VSX_MADD(xsnmadddp, 1, float64, VsrD(0), NMADD_FLGS, 1, 0) +-VSX_MADD(xsnmsubdp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 0) +-VSX_MADD(xsmaddsp, 1, float64, VsrD(0), MADD_FLGS, 1, 1) +-VSX_MADD(xsmsubsp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1) +-VSX_MADD(xsnmaddsp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1) +-VSX_MADD(xsnmsubsp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1) ++VSX_MADD(XSMADDDP, 1, float64, VsrD(0), MADD_FLGS, 1, 0) ++VSX_MADD(XSMSUBDP, 1, float64, VsrD(0), MSUB_FLGS, 1, 0) ++VSX_MADD(XSNMADDDP, 1, float64, VsrD(0), NMADD_FLGS, 1, 0) ++VSX_MADD(XSNMSUBDP, 1, float64, VsrD(0), NMSUB_FLGS, 1, 0) ++VSX_MADD(XSMADDSP, 1, float64, VsrD(0), MADD_FLGS, 1, 1) ++VSX_MADD(XSMSUBSP, 1, float64, VsrD(0), MSUB_FLGS, 1, 1) ++VSX_MADD(XSNMADDSP, 1, float64, VsrD(0), NMADD_FLGS, 1, 1) ++VSX_MADD(XSNMSUBSP, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1) + + VSX_MADD(xvmadddp, 2, float64, VsrD(i), MADD_FLGS, 0, 0) + VSX_MADD(xvmsubdp, 2, float64, VsrD(i), MSUB_FLGS, 0, 0) +diff --git a/target/ppc/helper.h b/target/ppc/helper.h +index ef5bdd38a7..e147b37644 100644 +--- a/target/ppc/helper.h ++++ b/target/ppc/helper.h +@@ -376,10 +376,10 @@ DEF_HELPER_3(xssqrtdp, void, env, vsr, vsr) + DEF_HELPER_3(xsrsqrtedp, void, env, vsr, vsr) + DEF_HELPER_4(xstdivdp, void, env, i32, vsr, vsr) + DEF_HELPER_3(xstsqrtdp, void, env, i32, vsr) +-DEF_HELPER_5(xsmadddp, void, env, vsr, vsr, vsr, vsr) +-DEF_HELPER_5(xsmsubdp, void, env, vsr, vsr, vsr, vsr) +-DEF_HELPER_5(xsnmadddp, void, env, vsr, vsr, vsr, vsr) +-DEF_HELPER_5(xsnmsubdp, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSMADDDP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSMSUBDP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSNMADDDP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSNMSUBDP, void, env, vsr, vsr, vsr, vsr) + DEF_HELPER_4(xscmpeqdp, void, env, vsr, vsr, vsr) + DEF_HELPER_4(xscmpgtdp, void, env, vsr, vsr, vsr) + DEF_HELPER_4(xscmpgedp, void, env, vsr, vsr, vsr) +@@ -439,10 +439,10 @@ DEF_HELPER_3(xsresp, void, env, vsr, vsr) + DEF_HELPER_2(xsrsp, i64, env, i64) + DEF_HELPER_3(xssqrtsp, void, env, vsr, vsr) + DEF_HELPER_3(xsrsqrtesp, void, env, vsr, vsr) +-DEF_HELPER_5(xsmaddsp, void, env, vsr, vsr, vsr, vsr) +-DEF_HELPER_5(xsmsubsp, void, env, vsr, vsr, vsr, vsr) +-DEF_HELPER_5(xsnmaddsp, void, env, vsr, vsr, vsr, vsr) +-DEF_HELPER_5(xsnmsubsp, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSMADDSP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSMSUBSP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSNMADDSP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSNMSUBSP, void, env, vsr, vsr, vsr, vsr) + + DEF_HELPER_4(xvadddp, void, env, vsr, vsr, vsr) + DEF_HELPER_4(xvsubdp, void, env, vsr, vsr, vsr) +diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode +index 8bdc059a4c..0ff8818084 100644 +--- a/target/ppc/insn32.decode ++++ b/target/ppc/insn32.decode +@@ -451,6 +451,28 @@ STXVX 011111 ..... ..... ..... 0110001100 . @X_TSX + LXVPX 011111 ..... ..... ..... 0101001101 - @X_TSXP + STXVPX 011111 ..... ..... ..... 0111001101 - @X_TSXP + ++## VSX Scalar Multiply-Add Instructions ++ ++XSMADDADP 111100 ..... ..... ..... 00100001 . . . @XX3 ++XSMADDMDP 111100 ..... ..... ..... 00101001 . . . @XX3 ++XSMADDASP 111100 ..... ..... ..... 00000001 . . . @XX3 ++XSMADDMSP 111100 ..... ..... ..... 00001001 . . . @XX3 ++ ++XSMSUBADP 111100 ..... ..... ..... 00110001 . . . @XX3 ++XSMSUBMDP 111100 ..... ..... ..... 00111001 . . . @XX3 ++XSMSUBASP 111100 ..... ..... ..... 00010001 . . . @XX3 ++XSMSUBMSP 111100 ..... ..... ..... 00011001 . . . @XX3 ++ ++XSNMADDASP 111100 ..... ..... ..... 10000001 . . . @XX3 ++XSNMADDMSP 111100 ..... ..... ..... 10001001 . . . @XX3 ++XSNMADDADP 111100 ..... ..... ..... 10100001 . . . @XX3 ++XSNMADDMDP 111100 ..... ..... ..... 10101001 . . . @XX3 ++ ++XSNMSUBASP 111100 ..... ..... ..... 10010001 . . . @XX3 ++XSNMSUBMSP 111100 ..... ..... ..... 10011001 . . . @XX3 ++XSNMSUBADP 111100 ..... ..... ..... 10110001 . . . @XX3 ++XSNMSUBMDP 111100 ..... ..... ..... 10111001 . . . @XX3 ++ + ## VSX splat instruction + + XXSPLTIB 111100 ..... 00 ........ 0101101000 . @X_imm8 +diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc +index 99c8a57e50..90d3ac665b 100644 +--- a/target/ppc/translate/vsx-impl.c.inc ++++ b/target/ppc/translate/vsx-impl.c.inc +@@ -1201,6 +1201,54 @@ GEN_VSX_HELPER_2(xvtstdcdp, 0x14, 0x1E, 0, PPC2_VSX) + GEN_VSX_HELPER_X3(xxperm, 0x08, 0x03, 0, PPC2_ISA300) + GEN_VSX_HELPER_X3(xxpermr, 0x08, 0x07, 0, PPC2_ISA300) + ++static bool do_xsmadd(DisasContext *ctx, int tgt, int src1, int src2, int src3, ++ void (*gen_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr)) ++{ ++ TCGv_ptr t, s1, s2, s3; ++ ++ t = gen_vsr_ptr(tgt); ++ s1 = gen_vsr_ptr(src1); ++ s2 = gen_vsr_ptr(src2); ++ s3 = gen_vsr_ptr(src3); ++ ++ gen_helper(cpu_env, t, s1, s2, s3); ++ ++ tcg_temp_free_ptr(t); ++ tcg_temp_free_ptr(s1); ++ tcg_temp_free_ptr(s2); ++ tcg_temp_free_ptr(s3); ++ ++ return true; ++} ++ ++static bool do_xsmadd_XX3(DisasContext *ctx, arg_XX3 *a, bool type_a, ++ void (*gen_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr)) ++{ ++ REQUIRE_VSX(ctx); ++ ++ if (type_a) { ++ return do_xsmadd(ctx, a->xt, a->xa, a->xt, a->xb, gen_helper); ++ } ++ return do_xsmadd(ctx, a->xt, a->xa, a->xb, a->xt, gen_helper); ++} ++ ++TRANS_FLAGS2(VSX, XSMADDADP, do_xsmadd_XX3, true, gen_helper_XSMADDDP) ++TRANS_FLAGS2(VSX, XSMADDMDP, do_xsmadd_XX3, false, gen_helper_XSMADDDP) ++TRANS_FLAGS2(VSX, XSMSUBADP, do_xsmadd_XX3, true, gen_helper_XSMSUBDP) ++TRANS_FLAGS2(VSX, XSMSUBMDP, do_xsmadd_XX3, false, gen_helper_XSMSUBDP) ++TRANS_FLAGS2(VSX, XSNMADDADP, do_xsmadd_XX3, true, gen_helper_XSNMADDDP) ++TRANS_FLAGS2(VSX, XSNMADDMDP, do_xsmadd_XX3, false, gen_helper_XSNMADDDP) ++TRANS_FLAGS2(VSX, XSNMSUBADP, do_xsmadd_XX3, true, gen_helper_XSNMSUBDP) ++TRANS_FLAGS2(VSX, XSNMSUBMDP, do_xsmadd_XX3, false, gen_helper_XSNMSUBDP) ++TRANS_FLAGS2(VSX207, XSMADDASP, do_xsmadd_XX3, true, gen_helper_XSMADDSP) ++TRANS_FLAGS2(VSX207, XSMADDMSP, do_xsmadd_XX3, false, gen_helper_XSMADDSP) ++TRANS_FLAGS2(VSX207, XSMSUBASP, do_xsmadd_XX3, true, gen_helper_XSMSUBSP) ++TRANS_FLAGS2(VSX207, XSMSUBMSP, do_xsmadd_XX3, false, gen_helper_XSMSUBSP) ++TRANS_FLAGS2(VSX207, XSNMADDASP, do_xsmadd_XX3, true, gen_helper_XSNMADDSP) ++TRANS_FLAGS2(VSX207, XSNMADDMSP, do_xsmadd_XX3, false, gen_helper_XSNMADDSP) ++TRANS_FLAGS2(VSX207, XSNMSUBASP, do_xsmadd_XX3, true, gen_helper_XSNMSUBSP) ++TRANS_FLAGS2(VSX207, XSNMSUBMSP, do_xsmadd_XX3, false, gen_helper_XSNMSUBSP) ++ + #define GEN_VSX_HELPER_VSX_MADD(name, op1, aop, mop, inval, type) \ + static void gen_##name(DisasContext *ctx) \ + { \ +@@ -1231,14 +1279,6 @@ static void gen_##name(DisasContext *ctx) \ + tcg_temp_free_ptr(c); \ + } + +-GEN_VSX_HELPER_VSX_MADD(xsmadddp, 0x04, 0x04, 0x05, 0, PPC2_VSX) +-GEN_VSX_HELPER_VSX_MADD(xsmsubdp, 0x04, 0x06, 0x07, 0, PPC2_VSX) +-GEN_VSX_HELPER_VSX_MADD(xsnmadddp, 0x04, 0x14, 0x15, 0, PPC2_VSX) +-GEN_VSX_HELPER_VSX_MADD(xsnmsubdp, 0x04, 0x16, 0x17, 0, PPC2_VSX) +-GEN_VSX_HELPER_VSX_MADD(xsmaddsp, 0x04, 0x00, 0x01, 0, PPC2_VSX207) +-GEN_VSX_HELPER_VSX_MADD(xsmsubsp, 0x04, 0x02, 0x03, 0, PPC2_VSX207) +-GEN_VSX_HELPER_VSX_MADD(xsnmaddsp, 0x04, 0x10, 0x11, 0, PPC2_VSX207) +-GEN_VSX_HELPER_VSX_MADD(xsnmsubsp, 0x04, 0x12, 0x13, 0, PPC2_VSX207) + GEN_VSX_HELPER_VSX_MADD(xvmadddp, 0x04, 0x0C, 0x0D, 0, PPC2_VSX) + GEN_VSX_HELPER_VSX_MADD(xvmsubdp, 0x04, 0x0E, 0x0F, 0, PPC2_VSX) + GEN_VSX_HELPER_VSX_MADD(xvnmadddp, 0x04, 0x1C, 0x1D, 0, PPC2_VSX) +diff --git a/target/ppc/translate/vsx-ops.c.inc b/target/ppc/translate/vsx-ops.c.inc +index c974324c4c..ef0200eead 100644 +--- a/target/ppc/translate/vsx-ops.c.inc ++++ b/target/ppc/translate/vsx-ops.c.inc +@@ -186,14 +186,6 @@ GEN_XX2FORM(xssqrtdp, 0x16, 0x04, PPC2_VSX), + GEN_XX2FORM(xsrsqrtedp, 0x14, 0x04, PPC2_VSX), + GEN_XX3FORM(xstdivdp, 0x14, 0x07, PPC2_VSX), + GEN_XX2FORM(xstsqrtdp, 0x14, 0x06, PPC2_VSX), +-GEN_XX3FORM_NAME(xsmadddp, "xsmaddadp", 0x04, 0x04, PPC2_VSX), +-GEN_XX3FORM_NAME(xsmadddp, "xsmaddmdp", 0x04, 0x05, PPC2_VSX), +-GEN_XX3FORM_NAME(xsmsubdp, "xsmsubadp", 0x04, 0x06, PPC2_VSX), +-GEN_XX3FORM_NAME(xsmsubdp, "xsmsubmdp", 0x04, 0x07, PPC2_VSX), +-GEN_XX3FORM_NAME(xsnmadddp, "xsnmaddadp", 0x04, 0x14, PPC2_VSX), +-GEN_XX3FORM_NAME(xsnmadddp, "xsnmaddmdp", 0x04, 0x15, PPC2_VSX), +-GEN_XX3FORM_NAME(xsnmsubdp, "xsnmsubadp", 0x04, 0x16, PPC2_VSX), +-GEN_XX3FORM_NAME(xsnmsubdp, "xsnmsubmdp", 0x04, 0x17, PPC2_VSX), + GEN_XX3FORM(xscmpeqdp, 0x0C, 0x00, PPC2_ISA300), + GEN_XX3FORM(xscmpgtdp, 0x0C, 0x01, PPC2_ISA300), + GEN_XX3FORM(xscmpgedp, 0x0C, 0x02, PPC2_ISA300), +@@ -235,14 +227,6 @@ GEN_XX2FORM(xsresp, 0x14, 0x01, PPC2_VSX207), + GEN_XX2FORM(xsrsp, 0x12, 0x11, PPC2_VSX207), + GEN_XX2FORM(xssqrtsp, 0x16, 0x00, PPC2_VSX207), + GEN_XX2FORM(xsrsqrtesp, 0x14, 0x00, PPC2_VSX207), +-GEN_XX3FORM_NAME(xsmaddsp, "xsmaddasp", 0x04, 0x00, PPC2_VSX207), +-GEN_XX3FORM_NAME(xsmaddsp, "xsmaddmsp", 0x04, 0x01, PPC2_VSX207), +-GEN_XX3FORM_NAME(xsmsubsp, "xsmsubasp", 0x04, 0x02, PPC2_VSX207), +-GEN_XX3FORM_NAME(xsmsubsp, "xsmsubmsp", 0x04, 0x03, PPC2_VSX207), +-GEN_XX3FORM_NAME(xsnmaddsp, "xsnmaddasp", 0x04, 0x10, PPC2_VSX207), +-GEN_XX3FORM_NAME(xsnmaddsp, "xsnmaddmsp", 0x04, 0x11, PPC2_VSX207), +-GEN_XX3FORM_NAME(xsnmsubsp, "xsnmsubasp", 0x04, 0x12, PPC2_VSX207), +-GEN_XX3FORM_NAME(xsnmsubsp, "xsnmsubmsp", 0x04, 0x13, PPC2_VSX207), + GEN_XX2FORM(xscvsxdsp, 0x10, 0x13, PPC2_VSX207), + GEN_XX2FORM(xscvuxdsp, 0x10, 0x12, PPC2_VSX207), + +-- +2.17.1 + diff --git a/meta/recipes-devtools/qemu/qemu/0021-target-ppc-implement-xs-n-maddqp-o-xs-n-msubqp-o.patch b/meta/recipes-devtools/qemu/qemu/0021-target-ppc-implement-xs-n-maddqp-o-xs-n-msubqp-o.patch new file mode 100644 index 0000000000..11d732ac13 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0021-target-ppc-implement-xs-n-maddqp-o-xs-n-msubqp-o.patch @@ -0,0 +1,174 @@ +From 1c1f82fbf0a434948b041eb35c671137628d5538 Mon Sep 17 00:00:00 2001 +From: Matheus Ferst +Date: Wed, 2 Mar 2022 06:51:38 +0100 +Subject: [PATCH 21/21] target/ppc: implement xs[n]maddqp[o]/xs[n]msubqp[o] +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement the following PowerISA v3.0 instuctions: +xsmaddqp[o]: VSX Scalar Multiply-Add Quad-Precision [using round to Odd] +xsmsubqp[o]: VSX Scalar Multiply-Subtract Quad-Precision [using round + to Odd] +xsnmaddqp[o]: VSX Scalar Negative Multiply-Add Quad-Precision [using + round to Odd] +xsnmsubqp[o]: VSX Scalar Negative Multiply-Subtract Quad-Precision + [using round to Odd] + +Upstream-Status: Backport +[https://git.qemu.org/?p=qemu.git;a=commit;h=3bb1aed246d7b59ceee625a82628f7369d492a8f] + +Reviewed-by: Richard Henderson +Signed-off-by: Matheus Ferst +Message-Id: <20220225210936.1749575-38-matheus.ferst@eldorado.org.br> +Signed-off-by: Cédric Le Goater +Signed-off-by: Xiangyu Chen +--- + target/ppc/fpu_helper.c | 42 +++++++++++++++++++++++++++++ + target/ppc/helper.h | 9 +++++++ + target/ppc/insn32.decode | 4 +++ + target/ppc/translate/vsx-impl.c.inc | 25 +++++++++++++++++ + 4 files changed, 80 insertions(+) + +diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c +index 853e5f6029..bdbbdb3b11 100644 +--- a/target/ppc/fpu_helper.c ++++ b/target/ppc/fpu_helper.c +@@ -2102,6 +2102,48 @@ VSX_MADD(xvmsubsp, 4, float32, VsrW(i), MSUB_FLGS, 0, 0) + VSX_MADD(xvnmaddsp, 4, float32, VsrW(i), NMADD_FLGS, 0, 0) + VSX_MADD(xvnmsubsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0) + ++/* ++ * VSX_MADDQ - VSX floating point quad-precision muliply/add ++ * op - instruction mnemonic ++ * maddflgs - flags for the float*muladd routine that control the ++ * various forms (madd, msub, nmadd, nmsub) ++ * ro - round to odd ++ */ ++#define VSX_MADDQ(op, maddflgs, ro) \ ++void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *s1, ppc_vsr_t *s2,\ ++ ppc_vsr_t *s3) \ ++{ \ ++ ppc_vsr_t t = *xt; \ ++ \ ++ helper_reset_fpstatus(env); \ ++ \ ++ float_status tstat = env->fp_status; \ ++ set_float_exception_flags(0, &tstat); \ ++ if (ro) { \ ++ tstat.float_rounding_mode = float_round_to_odd; \ ++ } \ ++ t.f128 = float128_muladd(s1->f128, s3->f128, s2->f128, maddflgs, &tstat); \ ++ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ ++ \ ++ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ ++ float_invalid_op_madd(env, tstat.float_exception_flags, \ ++ false, GETPC()); \ ++ } \ ++ \ ++ helper_compute_fprf_float128(env, t.f128); \ ++ *xt = t; \ ++ do_float_check_status(env, GETPC()); \ ++} ++ ++VSX_MADDQ(XSMADDQP, MADD_FLGS, 0) ++VSX_MADDQ(XSMADDQPO, MADD_FLGS, 1) ++VSX_MADDQ(XSMSUBQP, MSUB_FLGS, 0) ++VSX_MADDQ(XSMSUBQPO, MSUB_FLGS, 1) ++VSX_MADDQ(XSNMADDQP, NMADD_FLGS, 0) ++VSX_MADDQ(XSNMADDQPO, NMADD_FLGS, 1) ++VSX_MADDQ(XSNMSUBQP, NMSUB_FLGS, 0) ++VSX_MADDQ(XSNMSUBQPO, NMSUB_FLGS, 0) ++ + /* + * VSX_SCALAR_CMP_DP - VSX scalar floating point compare double precision + * op - instruction mnemonic +diff --git a/target/ppc/helper.h b/target/ppc/helper.h +index e147b37644..b5080c4955 100644 +--- a/target/ppc/helper.h ++++ b/target/ppc/helper.h +@@ -444,6 +444,15 @@ DEF_HELPER_5(XSMSUBSP, void, env, vsr, vsr, vsr, vsr) + DEF_HELPER_5(XSNMADDSP, void, env, vsr, vsr, vsr, vsr) + DEF_HELPER_5(XSNMSUBSP, void, env, vsr, vsr, vsr, vsr) + ++DEF_HELPER_5(XSMADDQP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSMADDQPO, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSMSUBQP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSMSUBQPO, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSNMADDQP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSNMADDQPO, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSNMSUBQP, void, env, vsr, vsr, vsr, vsr) ++DEF_HELPER_5(XSNMSUBQPO, void, env, vsr, vsr, vsr, vsr) ++ + DEF_HELPER_4(xvadddp, void, env, vsr, vsr, vsr) + DEF_HELPER_4(xvsubdp, void, env, vsr, vsr, vsr) + DEF_HELPER_4(xvmuldp, void, env, vsr, vsr, vsr) +diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode +index 0ff8818084..6bcb1e6804 100644 +--- a/target/ppc/insn32.decode ++++ b/target/ppc/insn32.decode +@@ -457,21 +457,25 @@ XSMADDADP 111100 ..... ..... ..... 00100001 . . . @XX3 + XSMADDMDP 111100 ..... ..... ..... 00101001 . . . @XX3 + XSMADDASP 111100 ..... ..... ..... 00000001 . . . @XX3 + XSMADDMSP 111100 ..... ..... ..... 00001001 . . . @XX3 ++XSMADDQP 111111 ..... ..... ..... 0110000100 . @X_rc + + XSMSUBADP 111100 ..... ..... ..... 00110001 . . . @XX3 + XSMSUBMDP 111100 ..... ..... ..... 00111001 . . . @XX3 + XSMSUBASP 111100 ..... ..... ..... 00010001 . . . @XX3 + XSMSUBMSP 111100 ..... ..... ..... 00011001 . . . @XX3 ++XSMSUBQP 111111 ..... ..... ..... 0110100100 . @X_rc + + XSNMADDASP 111100 ..... ..... ..... 10000001 . . . @XX3 + XSNMADDMSP 111100 ..... ..... ..... 10001001 . . . @XX3 + XSNMADDADP 111100 ..... ..... ..... 10100001 . . . @XX3 + XSNMADDMDP 111100 ..... ..... ..... 10101001 . . . @XX3 ++XSNMADDQP 111111 ..... ..... ..... 0111000100 . @X_rc + + XSNMSUBASP 111100 ..... ..... ..... 10010001 . . . @XX3 + XSNMSUBMSP 111100 ..... ..... ..... 10011001 . . . @XX3 + XSNMSUBADP 111100 ..... ..... ..... 10110001 . . . @XX3 + XSNMSUBMDP 111100 ..... ..... ..... 10111001 . . . @XX3 ++XSNMSUBQP 111111 ..... ..... ..... 0111100100 . @X_rc + + ## VSX splat instruction + +diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc +index 90d3ac665b..4253f01319 100644 +--- a/target/ppc/translate/vsx-impl.c.inc ++++ b/target/ppc/translate/vsx-impl.c.inc +@@ -1249,6 +1249,31 @@ TRANS_FLAGS2(VSX207, XSNMADDMSP, do_xsmadd_XX3, false, gen_helper_XSNMADDSP) + TRANS_FLAGS2(VSX207, XSNMSUBASP, do_xsmadd_XX3, true, gen_helper_XSNMSUBSP) + TRANS_FLAGS2(VSX207, XSNMSUBMSP, do_xsmadd_XX3, false, gen_helper_XSNMSUBSP) + ++static bool do_xsmadd_X(DisasContext *ctx, arg_X_rc *a, ++ void (*gen_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr), ++ void (*gen_helper_ro)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr)) ++{ ++ int vrt, vra, vrb; ++ ++ REQUIRE_INSNS_FLAGS2(ctx, ISA300); ++ REQUIRE_VSX(ctx); ++ ++ vrt = a->rt + 32; ++ vra = a->ra + 32; ++ vrb = a->rb + 32; ++ ++ if (a->rc) { ++ return do_xsmadd(ctx, vrt, vra, vrt, vrb, gen_helper_ro); ++ } ++ ++ return do_xsmadd(ctx, vrt, vra, vrt, vrb, gen_helper); ++} ++ ++TRANS(XSMADDQP, do_xsmadd_X, gen_helper_XSMADDQP, gen_helper_XSMADDQPO) ++TRANS(XSMSUBQP, do_xsmadd_X, gen_helper_XSMSUBQP, gen_helper_XSMSUBQPO) ++TRANS(XSNMADDQP, do_xsmadd_X, gen_helper_XSNMADDQP, gen_helper_XSNMADDQPO) ++TRANS(XSNMSUBQP, do_xsmadd_X, gen_helper_XSNMSUBQP, gen_helper_XSNMSUBQPO) ++ + #define GEN_VSX_HELPER_VSX_MADD(name, op1, aop, mop, inval, type) \ + static void gen_##name(DisasContext *ctx) \ + { \ +-- +2.17.1 +