From nobody Sat Nov 23 19:56:34 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1729641801; cv=none; d=zohomail.com; s=zohoarc; b=bLntV5mE/op6Zhg0cxzJQDc0h8UrxpUI00wLSCpUh8m8gYByyuwBjz9M8PojYCFP9SXL9gOjzLu70FZg5pGrn93p5mY4yJRL/t0pgudwnKOO17lZiHk/pUh7Y1UP+miKA7Hdt1KU69Uep4elAz39c3i/weZ+YIpthV+IaVbS7hQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1729641801; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=DE9fEl2MbyBjyVKLILKN31Xn9Ht7J9RVPieuaoHEzW8=; b=MeN8kuT6wD57rI0poffyyuDzKDh1/1VkBLpC5iB6euv3kfGGCgKBilVXO+nucoarSxUNTB6lwoRMa+nUlCTAhpA6Vmj4AgjwJ51DGIKGubl5Bm106gGrdpex6m9AmSJGHJWnIq4gUPEj6g9RjsuwV4MFWJamyZ7ROQw712UPIag= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 172964180124491.78741417222386; Tue, 22 Oct 2024 17:03:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t3OpN-0004jR-Vo; Tue, 22 Oct 2024 20:02:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t3OpK-0004hk-GL; Tue, 22 Oct 2024 20:02:14 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t3OpH-0004QK-2A; Tue, 22 Oct 2024 20:02:14 -0400 Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 49MLoAxF029973; Wed, 23 Oct 2024 00:01:54 GMT Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 42emafgcqj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 23 Oct 2024 00:01:53 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id 49MM4mGU012603; Wed, 23 Oct 2024 00:01:52 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 42emhf8bje-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 23 Oct 2024 00:01:52 +0000 Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 49N01pot54133056 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 23 Oct 2024 00:01:51 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3188F2004B; Wed, 23 Oct 2024 00:01:51 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C2D3720040; Wed, 23 Oct 2024 00:01:50 +0000 (GMT) Received: from heavy.ibm.com (unknown [9.171.26.72]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Wed, 23 Oct 2024 00:01:50 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=DE9fEl2MbyBjyVKLI LKN31Xn9Ht7J9RVPieuaoHEzW8=; b=GYIEj75HiJt2DO1zLNbavefSruAxxUlQT uPQ52fgtcS/hfsSaZlXivXs5561x8CUFy2IyPd+qrVxOsQ4RXSSmjGBrvtpzRm4k Jv3QUh/TzbZZDoIqJss5bJ+Ts4jWswa9dNrdEtIhTTmshH0tetqWGA78JAUMZTXO GTLnv2l/uRsfQEEkkoOtRbtn4xMTdvLSb1rISvlZksnLzCmt1Ev8DK/lGb0u5ywR myebGPY5iWYXaMykdeI118ud1924BV9q6qyx6d5KGD0oVI2oHtCqFDpb2UGjL/9c shwjttxX36Lod3JdN4OIzOLjZBp2sWS3l32MrJIS2wCnvqiNnLY+Q== From: Ilya Leoshkevich To: Aurelien Jarno , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , David Hildenbrand , Thomas Huth Cc: qemu-devel@nongnu.org, qemu-s390x@nongnu.org, Ilya Leoshkevich Subject: [PATCH 1/2] target/s390x: Fix the floating-point multiply-and-add NaN rules Date: Wed, 23 Oct 2024 01:59:18 +0200 Message-ID: <20241023000147.34035-2-iii@linux.ibm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241023000147.34035-1-iii@linux.ibm.com> References: <20241023000147.34035-1-iii@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: w3SJlgp944AJTwX0UJ1o7nvO48_mO1nC X-Proofpoint-GUID: w3SJlgp944AJTwX0UJ1o7nvO48_mO1nC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1051,Hydra:6.0.680,FMLib:17.12.62.30 definitions=2024-10-15_01,2024-10-11_01,2024-09-30_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 suspectscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 lowpriorityscore=0 malwarescore=0 spamscore=0 phishscore=0 priorityscore=1501 impostorscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2410220154 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=iii@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1729641801656116600 Content-Type: text/plain; charset="utf-8" Order the helper arguments to match the Principles of Operation. Implement the "Results: MULTIPLY AND ADD" table in pickNaNMulAdd(). Reported-by: Peter Maydell Signed-off-by: Ilya Leoshkevich Reviewed-by: Peter Maydell --- fpu/softfloat-specialize.c.inc | 19 +++++++++++++++++++ target/s390x/tcg/fpu_helper.c | 8 ++++---- target/s390x/tcg/vec_fpu_helper.c | 12 ++++++------ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc index 4e279b9bc40..62197373c93 100644 --- a/fpu/softfloat-specialize.c.inc +++ b/fpu/softfloat-specialize.c.inc @@ -635,6 +635,25 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass = b_cls, FloatClass c_cls, float_raise(float_flag_invalid | float_flag_invalid_imz, status); } return 3; /* default NaN */ +#elif defined(TARGET_S390X) + if (infzero) { + float_raise(float_flag_invalid | float_flag_invalid_imz, status); + return 3; + } + + if (is_snan(a_cls)) { + return 0; + } else if (is_snan(b_cls)) { + return 1; + } else if (is_snan(c_cls)) { + return 2; + } else if (is_qnan(a_cls)) { + return 0; + } else if (is_qnan(b_cls)) { + return 1; + } else { + return 2; + } #elif defined(TARGET_SPARC) /* For (inf,0,nan) return c. */ if (infzero) { diff --git a/target/s390x/tcg/fpu_helper.c b/target/s390x/tcg/fpu_helper.c index d8bd5748faf..5041c139627 100644 --- a/target/s390x/tcg/fpu_helper.c +++ b/target/s390x/tcg/fpu_helper.c @@ -780,7 +780,7 @@ uint32_t HELPER(kxb)(CPUS390XState *env, Int128 a, Int1= 28 b) uint64_t HELPER(maeb)(CPUS390XState *env, uint64_t f1, uint64_t f2, uint64_t f3) { - float32 ret =3D float32_muladd(f2, f3, f1, 0, &env->fpu_status); + float32 ret =3D float32_muladd(f3, f2, f1, 0, &env->fpu_status); handle_exceptions(env, false, GETPC()); return ret; } @@ -789,7 +789,7 @@ uint64_t HELPER(maeb)(CPUS390XState *env, uint64_t f1, uint64_t HELPER(madb)(CPUS390XState *env, uint64_t f1, uint64_t f2, uint64_t f3) { - float64 ret =3D float64_muladd(f2, f3, f1, 0, &env->fpu_status); + float64 ret =3D float64_muladd(f3, f2, f1, 0, &env->fpu_status); handle_exceptions(env, false, GETPC()); return ret; } @@ -798,7 +798,7 @@ uint64_t HELPER(madb)(CPUS390XState *env, uint64_t f1, uint64_t HELPER(mseb)(CPUS390XState *env, uint64_t f1, uint64_t f2, uint64_t f3) { - float32 ret =3D float32_muladd(f2, f3, f1, float_muladd_negate_c, + float32 ret =3D float32_muladd(f3, f2, f1, float_muladd_negate_c, &env->fpu_status); handle_exceptions(env, false, GETPC()); return ret; @@ -808,7 +808,7 @@ uint64_t HELPER(mseb)(CPUS390XState *env, uint64_t f1, uint64_t HELPER(msdb)(CPUS390XState *env, uint64_t f1, uint64_t f2, uint64_t f3) { - float64 ret =3D float64_muladd(f2, f3, f1, float_muladd_negate_c, + float64 ret =3D float64_muladd(f3, f2, f1, float_muladd_negate_c, &env->fpu_status); handle_exceptions(env, false, GETPC()); return ret; diff --git a/target/s390x/tcg/vec_fpu_helper.c b/target/s390x/tcg/vec_fpu_h= elper.c index 75cf605b9f4..1bbaa82fe8a 100644 --- a/target/s390x/tcg/vec_fpu_helper.c +++ b/target/s390x/tcg/vec_fpu_helper.c @@ -621,8 +621,8 @@ static void vfma32(S390Vector *v1, const S390Vector *v2= , const S390Vector *v3, int i; =20 for (i =3D 0; i < 4; i++) { - const float32 a =3D s390_vec_read_float32(v2, i); - const float32 b =3D s390_vec_read_float32(v3, i); + const float32 a =3D s390_vec_read_float32(v3, i); + const float32 b =3D s390_vec_read_float32(v2, i); const float32 c =3D s390_vec_read_float32(v4, i); float32 ret =3D float32_muladd(a, b, c, flags, &env->fpu_status); =20 @@ -645,8 +645,8 @@ static void vfma64(S390Vector *v1, const S390Vector *v2= , const S390Vector *v3, int i; =20 for (i =3D 0; i < 2; i++) { - const float64 a =3D s390_vec_read_float64(v2, i); - const float64 b =3D s390_vec_read_float64(v3, i); + const float64 a =3D s390_vec_read_float64(v3, i); + const float64 b =3D s390_vec_read_float64(v2, i); const float64 c =3D s390_vec_read_float64(v4, i); const float64 ret =3D float64_muladd(a, b, c, flags, &env->fpu_sta= tus); =20 @@ -664,8 +664,8 @@ static void vfma128(S390Vector *v1, const S390Vector *v= 2, const S390Vector *v3, const S390Vector *v4, CPUS390XState *env, bool s, int = flags, uintptr_t retaddr) { - const float128 a =3D s390_vec_read_float128(v2); - const float128 b =3D s390_vec_read_float128(v3); + const float128 a =3D s390_vec_read_float128(v3); + const float128 b =3D s390_vec_read_float128(v2); const float128 c =3D s390_vec_read_float128(v4); uint8_t vxc, vec_exc =3D 0; float128 ret; --=20 2.47.0 From nobody Sat Nov 23 19:56:34 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1729641793; cv=none; d=zohomail.com; s=zohoarc; b=mmfislHeEG9xdV3F+5QSmUPJ/oGLa1jWjChwr/ZUGrY9MmKGGmSJe5/ldUIhMIc9ALTMVtqLBZ5hRk2DCwxeuMB8xOouPEPDw1yNCuS9OlWBZIhSYW+baoUZN3GONrfHMCI7rVKfHXNkbXK6Pu0g8NJ+FSvHkvts/+r8Lrxg6yI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1729641793; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=AoXtEQCk+Yi2AwNhrD+UgZmfp1emmOPrZ8YbLtpdo9A=; b=aUmg0jNwXmOzmjxQSYrpkkhFBsb8B8b0ce3k8SgOzJ7GDdeALlcx7ddlQYxIea66971UpP5vxQHiD1wtC550m9XyyMf8eaL2myHPE1qY4pxA/Ntc1TJLvpF9raSn/WzJ6Lxyy2AxCU5wZwTXQ1TNdxNjrBDPN69eH2bqnIAi7yE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 172964179304083.21137914881285; Tue, 22 Oct 2024 17:03:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t3OpO-0004jX-Ia; Tue, 22 Oct 2024 20:02:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t3OpL-0004i8-3Z; Tue, 22 Oct 2024 20:02:15 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t3OpH-0004Qf-Qf; Tue, 22 Oct 2024 20:02:14 -0400 Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 49MLoRB2007731; Wed, 23 Oct 2024 00:01:55 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 42emafrchb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 23 Oct 2024 00:01:55 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id 49MM6qN6006876; Wed, 23 Oct 2024 00:01:54 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 42emjcrayd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 23 Oct 2024 00:01:54 +0000 Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 49N01qL421758580 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 23 Oct 2024 00:01:53 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C5B6D20043; Wed, 23 Oct 2024 00:01:52 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 57B0B20040; Wed, 23 Oct 2024 00:01:52 +0000 (GMT) Received: from heavy.ibm.com (unknown [9.171.26.72]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Wed, 23 Oct 2024 00:01:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=AoXtEQCk+Yi2AwNhr D+UgZmfp1emmOPrZ8YbLtpdo9A=; b=pv/aYtcNXdapWgkQDset2vq2T4Cw1e4VJ YgjNDQfcJeb3bMH2lktyNQQE5IaGWghE/Q2k0axo2LNdhEsAGKMfc1yQwOagy0Eo HWz4V1LvLqMMzVWTR3pZrcaadQjvEGCDz2pENxQC/V+S5qAaynyQu34qvkhbtRCh zt4rRABgZ9eXE2Ln7V/eWqRD3NhTxg2WbCZEFj2pUBA2Bc1FnDuquvYlPzyAucV1 RMtxnWXYYJukN/awRXDRYhpdpxcqG/ddBKyZq0p3Ooml6Aiaknnibi7GtSwKYe78 ytDP3ldRVP/CkmL3HlvS37hnzQmIkp81U/cdeJOTYC6euX91Bj7nA== From: Ilya Leoshkevich To: Aurelien Jarno , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , David Hildenbrand , Thomas Huth Cc: qemu-devel@nongnu.org, qemu-s390x@nongnu.org, Ilya Leoshkevich Subject: [PATCH 2/2] tests/tcg/s390x: Add the floating-point multiply-and-add test Date: Wed, 23 Oct 2024 01:59:19 +0200 Message-ID: <20241023000147.34035-3-iii@linux.ibm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241023000147.34035-1-iii@linux.ibm.com> References: <20241023000147.34035-1-iii@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: pL-ZM2IPZNpcaoQs1_eIvaa2iLYTl-Jd X-Proofpoint-ORIG-GUID: pL-ZM2IPZNpcaoQs1_eIvaa2iLYTl-Jd X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1051,Hydra:6.0.680,FMLib:17.12.62.30 definitions=2024-10-15_01,2024-10-11_01,2024-09-30_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 spamscore=0 priorityscore=1501 bulkscore=0 lowpriorityscore=0 malwarescore=0 mlxscore=0 adultscore=0 mlxlogscore=999 phishscore=0 suspectscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2410220154 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=iii@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1729641793911116600 Content-Type: text/plain; charset="utf-8" Add a test to prevent regressions. Share some useful pieces with the vfminmax test. Remove the duplicates from the floating point class values. Signed-off-by: Ilya Leoshkevich Reviewed-by: Peter Maydell --- tests/tcg/s390x/Makefile.target | 5 +- tests/tcg/s390x/float.h | 104 ++++++++++++++ tests/tcg/s390x/fma.c | 233 ++++++++++++++++++++++++++++++++ tests/tcg/s390x/vfminmax.c | 223 +++++++++++------------------- 4 files changed, 420 insertions(+), 145 deletions(-) create mode 100644 tests/tcg/s390x/float.h create mode 100644 tests/tcg/s390x/fma.c diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.tar= get index 2dab4f45822..da5fe71a407 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -74,8 +74,11 @@ $(Z13_TESTS): CFLAGS+=3D-march=3Dz13 -O2 TESTS+=3D$(Z13_TESTS) =20 ifneq ($(CROSS_CC_HAS_Z14),) -Z14_TESTS=3Dvfminmax +Z14_TESTS=3Dfma vfminmax +fma: float.h +fma: LDFLAGS+=3D-lm vfminmax: LDFLAGS+=3D-lm +vfminmax: float.h $(Z14_TESTS): CFLAGS+=3D-march=3Dz14 -O2 TESTS+=3D$(Z14_TESTS) endif diff --git a/tests/tcg/s390x/float.h b/tests/tcg/s390x/float.h new file mode 100644 index 00000000000..9d1682b8fc5 --- /dev/null +++ b/tests/tcg/s390x/float.h @@ -0,0 +1,104 @@ +/* + * Helpers for floating-point tests. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef FLOAT_H +#define FLOAT_H + +/* + * Floating-point value classes. + */ +#define N_FORMATS 3 +#define CLASS_MINUS_INF 0 +#define CLASS_MINUS_FN 1 +#define CLASS_MINUS_ZERO 2 +#define CLASS_PLUS_ZERO 3 +#define CLASS_PLUS_FN 4 +#define CLASS_PLUS_INF 5 +#define CLASS_QNAN 6 +#define CLASS_SNAN 7 +#define N_SIGNED_CLASSES 8 +static const size_t float_sizes[N_FORMATS] =3D { + /* M4 =3D=3D 2: short */ 4, + /* M4 =3D=3D 3: long */ 8, + /* M4 =3D=3D 4: extended */ 16, +}; +static const size_t e_bits[N_FORMATS] =3D { + /* M4 =3D=3D 2: short */ 8, + /* M4 =3D=3D 3: long */ 11, + /* M4 =3D=3D 4: extended */ 15, +}; +struct float_class { + size_t n; + unsigned char v[2][16]; +}; +static const struct float_class signed_floats[N_FORMATS][N_SIGNED_CLASSES]= =3D { + /* M4 =3D=3D 2: short */ + { + /* -inf */ {1, {{0xff, 0x80, 0x00, 0x00}}}, + /* -Fn */ {2, {{0xc2, 0x28, 0x00, 0x00}, + {0xc2, 0x29, 0x00, 0x00}}}, + /* -0 */ {1, {{0x80, 0x00, 0x00, 0x00}}}, + /* +0 */ {1, {{0x00, 0x00, 0x00, 0x00}}}, + /* +Fn */ {2, {{0x42, 0x28, 0x00, 0x00}, + {0x42, 0x2a, 0x00, 0x00}}}, + /* +inf */ {1, {{0x7f, 0x80, 0x00, 0x00}}}, + /* QNaN */ {2, {{0x7f, 0xff, 0xff, 0xff}, + {0x7f, 0xff, 0xff, 0xfe}}}, + /* SNaN */ {2, {{0x7f, 0xbf, 0xff, 0xff}, + {0x7f, 0xbf, 0xff, 0xfd}}}, + }, + + /* M4 =3D=3D 3: long */ + { + /* -inf */ {1, {{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* -Fn */ {2, {{0xc0, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* -0 */ {1, {{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* +0 */ {1, {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* +Fn */ {2, {{0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x40, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* +inf */ {1, {{0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* QNaN */ {2, {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}}, + /* SNaN */ {2, {{0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd}}}, + }, + + /* M4 =3D=3D 4: extended */ + { + /* -inf */ {1, {{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0= x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* -Fn */ {2, {{0xc0, 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0= x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xc0, 0x04, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0= x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* -0 */ {1, {{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0= x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* +0 */ {1, {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0= x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* +Fn */ {2, {{0x40, 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0= x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x40, 0x04, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0= x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* +inf */ {1, {{0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0= x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, + /* QNaN */ {2, {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0= xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0= xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}}, + /* SNaN */ {2, {{0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0= xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0= xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd}}}, + }, +}; +static const unsigned char default_nans[N_FORMATS][16] =3D { + /* M4 =3D=3D 2: short */ {0x7f, 0xc0, 0x00, 0x00}, + /* M4 =3D=3D 3: long */ {0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00}, + /* M4 =3D=3D 4: extended */ {0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +}; + +static void dump_v(FILE *f, const void *v, size_t n) +{ + for (int i =3D 0; i < n; i++) { + fprintf(f, "%02x", ((const unsigned char *)v)[i]); + } +} + +static void snan_to_qnan(char *v, int fmt) +{ + size_t bit =3D 1 + e_bits[fmt]; + v[bit / 8] |=3D 1 << (7 - (bit % 8)); +} + +#endif diff --git a/tests/tcg/s390x/fma.c b/tests/tcg/s390x/fma.c new file mode 100644 index 00000000000..6872f59a7a6 --- /dev/null +++ b/tests/tcg/s390x/fma.c @@ -0,0 +1,233 @@ +/* + * Test floating-point multiply-and-add instructions. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include +#include +#include +#include +#include +#include "float.h" + +union val { + float e; + double d; + long double x; + char buf[16]; +}; + +/* + * PoP tables as close to the original as possible. + */ +static const char *table1[N_SIGNED_CLASSES][N_SIGNED_CLASSES] =3D { + /* -inf -Fn -0 +0 = +Fn +inf QNaN SNaN */ + {/* -inf */ "P(+inf)", "P(+inf)", "Xi: T(dNaN)", "Xi: T(dNaN)", = "P(-inf)", "P(-inf)", "P(b)", "Xi: T(b*)"}, + {/* -Fn */ "P(+inf)", "P(a*b)", "P(+0)", "P(-0)", = "P(a*b)", "P(-inf)", "P(b)", "Xi: T(b*)"}, + {/* -0 */ "Xi: T(dNaN)", "P(+0)", "P(+0)", "P(-0)", = "P(-0)", "Xi: T(dNaN)", "P(b)", "Xi: T(b*)"}, + {/* +0 */ "Xi: T(dNaN)", "P(-0)", "P(-0)", "P(+0)", = "P(+0)", "Xi: T(dNaN)", "P(b)", "Xi: T(b*)"}, + {/* +Fn */ "P(-inf)", "P(a*b)", "P(-0)", "P(+0)", = "P(a*b)", "P(+inf)", "P(b)", "Xi: T(b*)"}, + {/* +inf */ "P(-inf)", "P(-inf)", "Xi: T(dNaN)", "Xi: T(dNaN)", = "P(+inf)", "P(+inf)", "P(b)", "Xi: T(b*)"}, + {/* QNaN */ "P(a)", "P(a)", "P(a)", "P(a)", = "P(a)", "P(a)", "P(a)", "Xi: T(b*)"}, + {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", = "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"}, +}; + +static const char *table2[N_SIGNED_CLASSES][N_SIGNED_CLASSES] =3D { + /* -inf -Fn -0 +0 +Fn = +inf QNaN SNaN */ + {/* -inf */ "T(-inf)", "T(-inf)", "T(-inf)", "T(-inf)", "T(-inf)",= "Xi: T(dNaN)", "T(c)", "Xi: T(c*)"}, + {/* -Fn */ "T(-inf)", "R(p+c)", "R(p)", "R(p)", "R(p+c)", = "T(+inf)", "T(c)", "Xi: T(c*)"}, + {/* -0 */ "T(-inf)", "R(c)", "T(-0)", "Rezd", "R(c)", = "T(+inf)", "T(c)", "Xi: T(c*)"}, + {/* +0 */ "T(-inf)", "R(c)", "Rezd", "T(+0)", "R(c)", = "T(+inf)", "T(c)", "Xi: T(c*)"}, + {/* +Fn */ "T(-inf)", "R(p+c)", "R(p)", "R(p)", "R(p+c)", = "T(+inf)", "T(c)", "Xi: T(c*)"}, + {/* +inf */ "Xi: T(dNaN)", "T(+inf)", "T(+inf)", "T(+inf)", "T(+inf)",= "T(+inf)", "T(c)", "Xi: T(c*)"}, + {/* QNaN */ "T(p)", "T(p)", "T(p)", "T(p)", "T(p)", = "T(p)", "T(p)", "Xi: T(c*)"}, + /* SNaN: can't happen */ +}; + +static void interpret_tables(union val *r, bool *xi, int fmt, + int cls_a, const union val *a, + int cls_b, const union val *b, + int cls_c, const union val *c) +{ + const char *spec1 =3D table1[cls_a][cls_b]; + const char *spec2; + union val p; + int cls_p; + + *xi =3D false; + + if (strcmp(spec1, "P(-inf)") =3D=3D 0) { + cls_p =3D CLASS_MINUS_INF; + } else if (strcmp(spec1, "P(+inf)") =3D=3D 0) { + cls_p =3D CLASS_PLUS_INF; + } else if (strcmp(spec1, "P(-0)") =3D=3D 0) { + cls_p =3D CLASS_MINUS_ZERO; + } else if (strcmp(spec1, "P(+0)") =3D=3D 0) { + cls_p =3D CLASS_PLUS_ZERO; + } else if (strcmp(spec1, "P(a)") =3D=3D 0) { + cls_p =3D cls_a; + memcpy(&p, a, sizeof(p)); + } else if (strcmp(spec1, "P(b)") =3D=3D 0) { + cls_p =3D cls_b; + memcpy(&p, b, sizeof(p)); + } else if (strcmp(spec1, "P(a*b)") =3D=3D 0) { + /* + * In the general case splitting fma into multiplication and addit= ion + * doesn't work, but this is the case with our test inputs. + */ + cls_p =3D cls_a =3D=3D cls_b ? CLASS_PLUS_FN : CLASS_MINUS_FN; + switch (fmt) { + case 0: + p.e =3D a->e * b->e; + break; + case 1: + p.d =3D a->d * b->d; + break; + case 2: + p.x =3D a->x * b->x; + break; + default: + fprintf(stderr, "Unsupported fmt: %d\n", fmt); + exit(1); + } + } else if (strcmp(spec1, "Xi: T(dNaN)") =3D=3D 0) { + memcpy(r, default_nans[fmt], sizeof(*r)); + *xi =3D true; + return; + } else if (strcmp(spec1, "Xi: T(a*)") =3D=3D 0) { + memcpy(r, a, sizeof(*r)); + snan_to_qnan(r->buf, fmt); + *xi =3D true; + return; + } else if (strcmp(spec1, "Xi: T(b*)") =3D=3D 0) { + memcpy(r, b, sizeof(*r)); + snan_to_qnan(r->buf, fmt); + *xi =3D true; + return; + } else { + fprintf(stderr, "Unsupported spec1: %s\n", spec1); + exit(1); + } + + spec2 =3D table2[cls_p][cls_c]; + if (strcmp(spec2, "T(-inf)") =3D=3D 0) { + memcpy(r, signed_floats[fmt][CLASS_MINUS_INF].v[0], sizeof(*r)); + } else if (strcmp(spec2, "T(+inf)") =3D=3D 0) { + memcpy(r, signed_floats[fmt][CLASS_PLUS_INF].v[0], sizeof(*r)); + } else if (strcmp(spec2, "T(-0)") =3D=3D 0) { + memcpy(r, signed_floats[fmt][CLASS_MINUS_ZERO].v[0], sizeof(*r)); + } else if (strcmp(spec2, "T(+0)") =3D=3D 0 || strcmp(spec2, "Rezd") = =3D=3D 0) { + memcpy(r, signed_floats[fmt][CLASS_PLUS_ZERO].v[0], sizeof(*r)); + } else if (strcmp(spec2, "R(c)") =3D=3D 0 || strcmp(spec2, "T(c)") =3D= =3D 0) { + memcpy(r, c, sizeof(*r)); + } else if (strcmp(spec2, "R(p)") =3D=3D 0 || strcmp(spec2, "T(p)") =3D= =3D 0) { + memcpy(r, &p, sizeof(*r)); + } else if (strcmp(spec2, "R(p+c)") =3D=3D 0 || strcmp(spec2, "T(p+c)")= =3D=3D 0) { + switch (fmt) { + case 0: + r->e =3D p.e + c->e; + break; + case 1: + r->d =3D p.d + c->d; + break; + case 2: + r->x =3D p.x + c->x; + break; + default: + fprintf(stderr, "Unsupported fmt: %d\n", fmt); + exit(1); + } + } else if (strcmp(spec2, "Xi: T(dNaN)") =3D=3D 0) { + memcpy(r, default_nans[fmt], sizeof(*r)); + *xi =3D true; + } else if (strcmp(spec2, "Xi: T(c*)") =3D=3D 0) { + memcpy(r, c, sizeof(*r)); + snan_to_qnan(r->buf, fmt); + *xi =3D true; + } else { + fprintf(stderr, "Unsupported spec2: %s\n", spec2); + exit(1); + } +} + +struct iter { + int fmt; + int cls[3]; + int val[3]; +}; + +static bool iter_next(struct iter *it) +{ + int i; + + for (i =3D 2; i >=3D 0; i--) { + if (++it->val[i] !=3D signed_floats[it->fmt][it->cls[i]].n) { + return true; + } + it->val[i] =3D 0; + + if (++it->cls[i] !=3D N_SIGNED_CLASSES) { + return true; + } + it->cls[i] =3D 0; + } + + return ++it->fmt !=3D N_FORMATS; +} + +int main(void) +{ + int ret =3D EXIT_SUCCESS; + struct iter it =3D {}; + + do { + size_t n =3D float_sizes[it.fmt]; + union val a, b, c, exp, res; + bool xi_exp, xi; + + memcpy(&a, signed_floats[it.fmt][it.cls[0]].v[it.val[0]], sizeof(a= )); + memcpy(&b, signed_floats[it.fmt][it.cls[1]].v[it.val[1]], sizeof(b= )); + memcpy(&c, signed_floats[it.fmt][it.cls[2]].v[it.val[2]], sizeof(c= )); + + interpret_tables(&exp, &xi_exp, it.fmt, + it.cls[1], &b, it.cls[2], &c, it.cls[0], &a); + + memcpy(&res, &a, sizeof(res)); + feclearexcept(FE_ALL_EXCEPT); + switch (it.fmt) { + case 0: + asm("maebr %[a],%[b],%[c]" + : [a] "+f" (res.e) : [b] "f" (b.e), [c] "f" (c.e)); + break; + case 1: + asm("madbr %[a],%[b],%[c]" + : [a] "+f" (res.d) : [b] "f" (b.d), [c] "f" (c.d)); + break; + case 2: + asm("wfmaxb %[a],%[c],%[b],%[a]" + : [a] "+v" (res.x) : [b] "v" (b.x), [c] "v" (c.x)); + break; + default: + fprintf(stderr, "Unsupported fmt: %d\n", it.fmt); + exit(1); + } + xi =3D fetestexcept(FE_ALL_EXCEPT) =3D=3D FE_INVALID; + + if (memcmp(&res, &exp, n) !=3D 0 || xi !=3D xi_exp) { + fprintf(stderr, "[ FAILED ] "); + dump_v(stderr, &b, n); + fprintf(stderr, " * "); + dump_v(stderr, &c, n); + fprintf(stderr, " + "); + dump_v(stderr, &a, n); + fprintf(stderr, ": actual=3D"); + dump_v(stderr, &res, n); + fprintf(stderr, "/%d, expected=3D", (int)xi); + dump_v(stderr, &exp, n); + fprintf(stderr, "/%d\n", (int)xi_exp); + ret =3D EXIT_FAILURE; + } + } while (iter_next(&it)); + + return ret; +} diff --git a/tests/tcg/s390x/vfminmax.c b/tests/tcg/s390x/vfminmax.c index 22629df160e..e66285f7625 100644 --- a/tests/tcg/s390x/vfminmax.c +++ b/tests/tcg/s390x/vfminmax.c @@ -4,6 +4,8 @@ #include #include =20 +#include "float.h" + /* * vfmin/vfmax instruction execution. */ @@ -21,98 +23,21 @@ static void vfminmax(unsigned int op, unsigned int m4, unsigned int m5, unsigned int m6, void *v1, const void *v2, const void *v3) { - insn[3] =3D (m6 << 4) | m5; - insn[4] =3D (m4 << 4) | 0x0e; - insn[5] =3D op; + insn[3] =3D (m6 << 4) | m5; + insn[4] =3D (m4 << 4) | 0x0e; + insn[5] =3D op; =20 asm("vl %%v25,%[v2]\n" "vl %%v26,%[v3]\n" "ex 0,%[insn]\n" "vst %%v24,%[v1]\n" : [v1] "=3Dm" (*(char (*)[16])v1) - : [v2] "m" (*(char (*)[16])v2) - , [v3] "m" (*(char (*)[16])v3) - , [insn] "m"(insn) + : [v2] "m" (*(const char (*)[16])v2) + , [v3] "m" (*(const char (*)[16])v3) + , [insn] "m" (insn) : "v24", "v25", "v26"); } =20 -/* - * Floating-point value classes. - */ -#define N_FORMATS 3 -#define N_SIGNED_CLASSES 8 -static const size_t float_sizes[N_FORMATS] =3D { - /* M4 =3D=3D 2: short */ 4, - /* M4 =3D=3D 3: long */ 8, - /* M4 =3D=3D 4: extended */ 16, -}; -static const size_t e_bits[N_FORMATS] =3D { - /* M4 =3D=3D 2: short */ 8, - /* M4 =3D=3D 3: long */ 11, - /* M4 =3D=3D 4: extended */ 15, -}; -static const unsigned char signed_floats[N_FORMATS][N_SIGNED_CLASSES][2][1= 6] =3D { - /* M4 =3D=3D 2: short */ - { - /* -inf */ {{0xff, 0x80, 0x00, 0x00}, - {0xff, 0x80, 0x00, 0x00}}, - /* -Fn */ {{0xc2, 0x28, 0x00, 0x00}, - {0xc2, 0x29, 0x00, 0x00}}, - /* -0 */ {{0x80, 0x00, 0x00, 0x00}, - {0x80, 0x00, 0x00, 0x00}}, - /* +0 */ {{0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00}}, - /* +Fn */ {{0x42, 0x28, 0x00, 0x00}, - {0x42, 0x2a, 0x00, 0x00}}, - /* +inf */ {{0x7f, 0x80, 0x00, 0x00}, - {0x7f, 0x80, 0x00, 0x00}}, - /* QNaN */ {{0x7f, 0xff, 0xff, 0xff}, - {0x7f, 0xff, 0xff, 0xfe}}, - /* SNaN */ {{0x7f, 0xbf, 0xff, 0xff}, - {0x7f, 0xbf, 0xff, 0xfd}}, - }, - - /* M4 =3D=3D 3: long */ - { - /* -inf */ {{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* -Fn */ {{0xc0, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* -0 */ {{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* +0 */ {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* +Fn */ {{0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x40, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* +inf */ {{0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* QNaN */ {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}, - /* SNaN */ {{0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd}}, - }, - - /* M4 =3D=3D 4: extended */ - { - /* -inf */ {{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* -Fn */ {{0xc0, 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xc0, 0x04, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* -0 */ {{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* +0 */ {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* +Fn */ {{0x40, 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x40, 0x04, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* +inf */ {{0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - /* QNaN */ {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,= 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,= 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}, - /* SNaN */ {{0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,= 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,= 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd}}, - }, -}; - /* * PoP tables as close to the original as possible. */ @@ -285,13 +210,6 @@ struct signed_test { }, }; =20 -static void dump_v(FILE *f, const void *v, size_t n) -{ - for (int i =3D 0; i < n; i++) { - fprintf(f, "%02x", ((const unsigned char *)v)[i]); - } -} - static int signed_test(struct signed_test *test, int m4, int m5, const void *v1_exp, bool xi_exp, const void *v2, const void *v3) @@ -320,10 +238,28 @@ static int signed_test(struct signed_test *test, int = m4, int m5, return 0; } =20 -static void snan_to_qnan(char *v, int m4) +struct iter { + int cls[2]; + int val[2]; +}; + +static bool iter_next(struct iter *it, int fmt) { - size_t bit =3D 1 + e_bits[m4 - 2]; - v[bit / 8] |=3D 1 << (7 - (bit % 8)); + int i; + + for (i =3D 1; i >=3D 0; i--) { + if (++it->val[i] !=3D signed_floats[fmt][it->cls[i]].n) { + return true; + } + it->val[i] =3D 0; + + if (++it->cls[i] !=3D N_SIGNED_CLASSES) { + return true; + } + it->cls[i] =3D 0; + } + + return false; } =20 int main(void) @@ -333,72 +269,71 @@ int main(void) =20 for (i =3D 0; i < sizeof(signed_tests) / sizeof(signed_tests[0]); i++)= { struct signed_test *test =3D &signed_tests[i]; - int m4; + int fmt; =20 - for (m4 =3D 2; m4 <=3D 4; m4++) { - const unsigned char (*floats)[2][16] =3D signed_floats[m4 - 2]; - size_t float_size =3D float_sizes[m4 - 2]; + for (fmt =3D 0; fmt < N_FORMATS; fmt++) { + size_t float_size =3D float_sizes[fmt]; + int m4 =3D fmt + 2; int m5; =20 for (m5 =3D 0; m5 <=3D 8; m5 +=3D 8) { char v1_exp[16], v2[16], v3[16]; bool xi_exp =3D false; + struct iter it =3D {}; int pos =3D 0; - int i2; =20 - for (i2 =3D 0; i2 < N_SIGNED_CLASSES * 2; i2++) { - int i3; + do { + const char *spec =3D test->table[it.cls[0]][it.cls[1]]; =20 - for (i3 =3D 0; i3 < N_SIGNED_CLASSES * 2; i3++) { - const char *spec =3D test->table[i2 / 2][i3 / 2]; + memcpy(&v2[pos], + signed_floats[fmt][it.cls[0]].v[it.val[0]], + float_size); + memcpy(&v3[pos], + signed_floats[fmt][it.cls[1]].v[it.val[1]], + float_size); + if (strcmp(spec, "T(a)") =3D=3D 0 || + strcmp(spec, "Xi: T(a)") =3D=3D 0) { + memcpy(&v1_exp[pos], &v2[pos], float_size); + } else if (strcmp(spec, "T(b)") =3D=3D 0 || + strcmp(spec, "Xi: T(b)") =3D=3D 0) { + memcpy(&v1_exp[pos], &v3[pos], float_size); + } else if (strcmp(spec, "Xi: T(a*)") =3D=3D 0) { + memcpy(&v1_exp[pos], &v2[pos], float_size); + snan_to_qnan(&v1_exp[pos], fmt); + } else if (strcmp(spec, "Xi: T(b*)") =3D=3D 0) { + memcpy(&v1_exp[pos], &v3[pos], float_size); + snan_to_qnan(&v1_exp[pos], fmt); + } else if (strcmp(spec, "T(M(a,b))") =3D=3D 0) { + /* + * Comparing floats is risky, since the compiler m= ight + * generate the same instruction that we are testi= ng. + * Compare ints instead. This works, because we get + * here only for +-Fn, and the corresponding test + * values have identical exponents. + */ + int v2_int =3D *(int *)&v2[pos]; + int v3_int =3D *(int *)&v3[pos]; =20 - memcpy(&v2[pos], floats[i2 / 2][i2 % 2], float_siz= e); - memcpy(&v3[pos], floats[i3 / 2][i3 % 2], float_siz= e); - if (strcmp(spec, "T(a)") =3D=3D 0 || - strcmp(spec, "Xi: T(a)") =3D=3D 0) { + if ((v2_int < v3_int) =3D=3D + ((test->op =3D=3D VFMIN) !=3D (v2_int < 0))) { memcpy(&v1_exp[pos], &v2[pos], float_size); - } else if (strcmp(spec, "T(b)") =3D=3D 0 || - strcmp(spec, "Xi: T(b)") =3D=3D 0) { - memcpy(&v1_exp[pos], &v3[pos], float_size); - } else if (strcmp(spec, "Xi: T(a*)") =3D=3D 0) { - memcpy(&v1_exp[pos], &v2[pos], float_size); - snan_to_qnan(&v1_exp[pos], m4); - } else if (strcmp(spec, "Xi: T(b*)") =3D=3D 0) { - memcpy(&v1_exp[pos], &v3[pos], float_size); - snan_to_qnan(&v1_exp[pos], m4); - } else if (strcmp(spec, "T(M(a,b))") =3D=3D 0) { - /* - * Comparing floats is risky, since the compil= er - * might generate the same instruction that we= are - * testing. Compare ints instead. This works, - * because we get here only for +-Fn, and the - * corresponding test values have identical - * exponents. - */ - int v2_int =3D *(int *)&v2[pos]; - int v3_int =3D *(int *)&v3[pos]; - - if ((v2_int < v3_int) =3D=3D - ((test->op =3D=3D VFMIN) !=3D (v2_int < 0)= )) { - memcpy(&v1_exp[pos], &v2[pos], float_size); - } else { - memcpy(&v1_exp[pos], &v3[pos], float_size); - } } else { - fprintf(stderr, "Unexpected spec: %s\n", spec); - return 1; + memcpy(&v1_exp[pos], &v3[pos], float_size); } - xi_exp |=3D spec[0] =3D=3D 'X'; - pos +=3D float_size; + } else { + fprintf(stderr, "Unexpected spec: %s\n", spec); + return 1; + } + xi_exp |=3D spec[0] =3D=3D 'X'; + pos +=3D float_size; =20 - if ((m5 & 8) || pos =3D=3D 16) { - ret |=3D signed_test(test, m4, m5, - v1_exp, xi_exp, v2, v3); - pos =3D 0; - xi_exp =3D false; - } + if ((m5 & 8) || pos =3D=3D 16) { + ret |=3D signed_test(test, m4, m5, + v1_exp, xi_exp, v2, v3); + pos =3D 0; + xi_exp =3D false; } - } + } while (iter_next(&it, fmt)); =20 if (pos !=3D 0) { ret |=3D signed_test(test, m4, m5, v1_exp, xi_exp, v2,= v3); --=20 2.47.0