From nobody Sat Jun 1 03:52:48 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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 ARC-Seal: i=1; a=rsa-sha256; t=1589413831; cv=none; d=zohomail.com; s=zohoarc; b=kPclloZPl4adXeYps+lc9Unqfo6wAeHt20RctNRhRW89VxTDw0Vq2dAtcDXH+xMOlxp/mDRlxaOgZYxsmJ6MRRNhLK/mBIo/e9ZQ/fCOaXSZxyECFoQqdgsfjgKym5TkV74uO01dKB7lscEypf3/f7N9OUB/wjBeR+Qxyf9tayw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589413831; h=Content-Type:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=h5PxXPxBe1nXWM0PGzkzcXEMr4dEc98d+P4ltcx9r3w=; b=bkQPEHNnE49ojwkrMAL1PcCGJW6dkc7ro61N/pIW1ctSVxRy/kFrncwJqyO7q67a3C16PhVY1jVmSLmWg+A+zv/d0KStzt8C5LbRqgUdzLL0ZJ5WKmtQuhNw061UGLF5K+QZoihZefoVregA62eY/pL8ZYnN5rSsx3MA1veQurI= ARC-Authentication-Results: i=1; mx.zohomail.com; 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1589413831424105.17757229077324; Wed, 13 May 2020 16:50:31 -0700 (PDT) Received: from localhost ([::1]:47732 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jZ18w-0000EL-4L for importer@patchew.org; Wed, 13 May 2020 19:50:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50954) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZ185-0007zo-2S for qemu-devel@nongnu.org; Wed, 13 May 2020 19:49:37 -0400 Received: from esa3.mentor.iphmx.com ([68.232.137.180]:57185) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZ183-0001nb-Ma for qemu-devel@nongnu.org; Wed, 13 May 2020 19:49:36 -0400 Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa3.mentor.iphmx.com with ESMTP; 13 May 2020 15:49:33 -0800 IronPort-SDR: RFcFTjgM5CyrE+T+tNxVvScx2f+vR9dJzuMB9FuLgBCBwCxBRyIdEpURwZXrWwoLkvR43s8F3V lBPlLpWbNTZVuKDUf6nOnW/++3AFmGZ9EKt4fCjzQQPbKU1ikR8Sb+qqYbvfUAa3ZUxd80OlTj 2NqAlkFN8ZgNAitSNKsM6OQo/gXTwjyEFH265d/OvP8UzVmWEv5gDKp4/YC4NUqNhI9A3HjxEY 1eRH9AW226Elxy287R88vWAoFud8xoqB4llLAUt0FNIZNdqhf/vQcFEyvj1Sc+5zQPvi0XJtPA hm8= X-IronPort-AV: E=Sophos;i="5.73,389,1583222400"; d="scan'208";a="48823184" IronPort-SDR: bzphfi7peCmMi8TXG2X/RmTB++nbU4ff5bQuU/baxOMosWKOiP6r/tjjjP1x6PHwlwfctStyCz vUsFkAWf1r76WBnUaZbaUEpbWZg4OjV0OMFNPZT1M/t1yXWj7XrppYres4UPcMYXw0VghbGr61 UDgEoWhNmVnF4hKzx+rz7eBzlsHYTgmVuQx0j9jwqyBvjYHVVpT+oorDmSdi2KtmtkYDojbWNo bQQ+1tb0ZB3mUKams6rSrwbkAMkeDFgGTLjl5uCIyCw8wURqDzODmq3g6WOEUMcfp2j5/W6CST L2o= Date: Wed, 13 May 2020 23:49:27 +0000 From: Joseph Myers X-X-Sender: jsm28@digraph.polyomino.org.uk To: , , , Subject: [PATCH 1/4] target/i386: fix floating-point load-constant rounding In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-04.mgc.mentorg.com (139.181.222.4) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) 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=68.232.137.180; envelope-from=joseph_myers@mentor.com; helo=esa3.mentor.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/13 19:49:34 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 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" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The implementations of the fldl2t, fldl2e, fldpi, fldlg2 and fldln2 instructions load fixed constants independent of the rounding mode. Fix them to load a value correctly rounded for the current rounding mode (but always rounded to 64-bit precision independent of the precision control, and without setting "inexact") as specified. Signed-off-by: Joseph Myers Reviewed-by: Richard Henderson --- target/i386/fpu_helper.c | 54 +++++++- tests/tcg/i386/test-i386-fldcst.c | 199 ++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+), 5 deletions(-) create mode 100644 tests/tcg/i386/test-i386-fldcst.c diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c index 0c3fce933c..38968b2ec7 100644 --- a/target/i386/fpu_helper.c +++ b/target/i386/fpu_helper.c @@ -59,8 +59,13 @@ #define FPUC_EM 0x3f =20 #define floatx80_lg2 make_floatx80(0x3ffd, 0x9a209a84fbcff799LL) +#define floatx80_lg2_d make_floatx80(0x3ffd, 0x9a209a84fbcff798LL) #define floatx80_l2e make_floatx80(0x3fff, 0xb8aa3b295c17f0bcLL) +#define floatx80_l2e_d make_floatx80(0x3fff, 0xb8aa3b295c17f0bbLL) #define floatx80_l2t make_floatx80(0x4000, 0xd49a784bcd1b8afeLL) +#define floatx80_l2t_u make_floatx80(0x4000, 0xd49a784bcd1b8affLL) +#define floatx80_ln2_d make_floatx80(0x3ffe, 0xb17217f7d1cf79abLL) +#define floatx80_pi_d make_floatx80(0x4000, 0xc90fdaa22168c234LL) =20 #if !defined(CONFIG_USER_ONLY) static qemu_irq ferr_irq; @@ -544,27 +549,66 @@ void helper_fld1_ST0(CPUX86State *env) =20 void helper_fldl2t_ST0(CPUX86State *env) { - ST0 =3D floatx80_l2t; + switch (env->fpuc & FPU_RC_MASK) { + case FPU_RC_UP: + ST0 =3D floatx80_l2t_u; + break; + default: + ST0 =3D floatx80_l2t; + break; + } } =20 void helper_fldl2e_ST0(CPUX86State *env) { - ST0 =3D floatx80_l2e; + switch (env->fpuc & FPU_RC_MASK) { + case FPU_RC_DOWN: + case FPU_RC_CHOP: + ST0 =3D floatx80_l2e_d; + break; + default: + ST0 =3D floatx80_l2e; + break; + } } =20 void helper_fldpi_ST0(CPUX86State *env) { - ST0 =3D floatx80_pi; + switch (env->fpuc & FPU_RC_MASK) { + case FPU_RC_DOWN: + case FPU_RC_CHOP: + ST0 =3D floatx80_pi_d; + break; + default: + ST0 =3D floatx80_pi; + break; + } } =20 void helper_fldlg2_ST0(CPUX86State *env) { - ST0 =3D floatx80_lg2; + switch (env->fpuc & FPU_RC_MASK) { + case FPU_RC_DOWN: + case FPU_RC_CHOP: + ST0 =3D floatx80_lg2_d; + break; + default: + ST0 =3D floatx80_lg2; + break; + } } =20 void helper_fldln2_ST0(CPUX86State *env) { - ST0 =3D floatx80_ln2; + switch (env->fpuc & FPU_RC_MASK) { + case FPU_RC_DOWN: + case FPU_RC_CHOP: + ST0 =3D floatx80_ln2_d; + break; + default: + ST0 =3D floatx80_ln2; + break; + } } =20 void helper_fldz_ST0(CPUX86State *env) diff --git a/tests/tcg/i386/test-i386-fldcst.c b/tests/tcg/i386/test-i386-f= ldcst.c new file mode 100644 index 0000000000..e635432ccf --- /dev/null +++ b/tests/tcg/i386/test-i386-fldcst.c @@ -0,0 +1,199 @@ +/* Test instructions loading floating-point constants. */ + +#include +#include + +volatile long double ld_res; + +int main(void) +{ + short cw; + int ret =3D 0; + + /* Round to nearest. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x000; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldl2t" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x3.5269e12f346e2bf8p+0L) { + printf("FAIL: fldl2t N\n"); + ret =3D 1; + } + /* Round downward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x400; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldl2t" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x3.5269e12f346e2bf8p+0L) { + printf("FAIL: fldl2t D\n"); + ret =3D 1; + } + /* Round toward zero. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0xc00; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldl2t" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x3.5269e12f346e2bf8p+0L) { + printf("FAIL: fldl2t Z\n"); + ret =3D 1; + } + /* Round upward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x800; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldl2t" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x3.5269e12f346e2bfcp+0L) { + printf("FAIL: fldl2t U\n"); + ret =3D 1; + } + + /* Round to nearest. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x000; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldl2e" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x1.71547652b82fe178p+0L) { + printf("FAIL: fldl2e N\n"); + ret =3D 1; + } + /* Round downward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x400; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldl2e" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x1.71547652b82fe176p+0L) { + printf("FAIL: fldl2e D\n"); + ret =3D 1; + } + /* Round toward zero. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0xc00; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldl2e" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x1.71547652b82fe176p+0L) { + printf("FAIL: fldl2e Z\n"); + ret =3D 1; + } + /* Round upward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x800; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldl2e" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x1.71547652b82fe178p+0L) { + printf("FAIL: fldl2e U\n"); + ret =3D 1; + } + + /* Round to nearest. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x000; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldpi" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x3.243f6a8885a308d4p+0L) { + printf("FAIL: fldpi N\n"); + ret =3D 1; + } + /* Round downward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x400; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldpi" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x3.243f6a8885a308dp+0L) { + printf("FAIL: fldpi D\n"); + ret =3D 1; + } + /* Round toward zero. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0xc00; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldpi" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x3.243f6a8885a308dp+0L) { + printf("FAIL: fldpi Z\n"); + ret =3D 1; + } + /* Round upward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x800; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldpi" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x3.243f6a8885a308d4p+0L) { + printf("FAIL: fldpi U\n"); + ret =3D 1; + } + + /* Round to nearest. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x000; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldlg2" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x4.d104d427de7fbcc8p-4L) { + printf("FAIL: fldlg2 N\n"); + ret =3D 1; + } + /* Round downward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x400; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldlg2" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x4.d104d427de7fbccp-4L) { + printf("FAIL: fldlg2 D\n"); + ret =3D 1; + } + /* Round toward zero. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0xc00; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldlg2" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x4.d104d427de7fbccp-4L) { + printf("FAIL: fldlg2 Z\n"); + ret =3D 1; + } + /* Round upward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x800; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldlg2" : "=3Dt" (ld_res)); + if (ld_res !=3D 0x4.d104d427de7fbcc8p-4L) { + printf("FAIL: fldlg2 U\n"); + ret =3D 1; + } + + /* Round to nearest. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x000; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldln2" : "=3Dt" (ld_res)); + if (ld_res !=3D 0xb.17217f7d1cf79acp-4L) { + printf("FAIL: fldln2 N\n"); + ret =3D 1; + } + /* Round downward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x400; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldln2" : "=3Dt" (ld_res)); + if (ld_res !=3D 0xb.17217f7d1cf79abp-4L) { + printf("FAIL: fldln2 D\n"); + ret =3D 1; + } + /* Round toward zero. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0xc00; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldln2" : "=3Dt" (ld_res)); + if (ld_res !=3D 0xb.17217f7d1cf79abp-4L) { + printf("FAIL: fldln2 Z\n"); + ret =3D 1; + } + /* Round upward. */ + __asm__ volatile ("fnstcw %0" : "=3Dm" (cw)); + cw =3D (cw & ~0xc00) | 0x800; + __asm__ volatile ("fldcw %0" : : "m" (cw)); + __asm__ volatile ("fldln2" : "=3Dt" (ld_res)); + if (ld_res !=3D 0xb.17217f7d1cf79acp-4L) { + printf("FAIL: fldln2 U\n"); + ret =3D 1; + } + + return ret; +} --=20 2.17.1 --=20 Joseph S. Myers joseph@codesourcery.com From nobody Sat Jun 1 03:52:48 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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 ARC-Seal: i=1; a=rsa-sha256; t=1589413913; cv=none; d=zohomail.com; s=zohoarc; b=IueTZ2MT1OoToYGHA9pV6YR9P5tYaEPeP4+KLPFYkXt3C/AS1iXkt0JuyfadmOECE6kKC52e6tBF4oRB4h1sHpmRfX/4qabZEIKenY1ehVDpGVCvjwEoFnnY8Ru2gUR/BHLevg5oYqdDJ2uIxqy8X9YEqh5TGtFl19JvWKdss0M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589413913; h=Content-Type:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=NotaAwVAD/oDcZ7kBc+p0vcqAs5oyjn3DLlP4aYWVeI=; b=N30OU1E8cLIMibSOQa/NcStyJCOXCFXWjgkjB6LpvPWe4ptlMrCuXed/i01qRzCHC8ajqxkVQpGo2IkrtLk3pfw0pi8NgYBD1xRceGtV7uRQSrX7P9nRXkYgObu4tuXfNZvNdG3PaA9ey1G/kxETXE2WCqazRXVibchVrpexQEc= ARC-Authentication-Results: i=1; mx.zohomail.com; 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1589413913139645.0335545766355; Wed, 13 May 2020 16:51:53 -0700 (PDT) Received: from localhost ([::1]:53164 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jZ1AF-0002Vw-SA for importer@patchew.org; Wed, 13 May 2020 19:51:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51098) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZ18w-0000XK-Ev for qemu-devel@nongnu.org; Wed, 13 May 2020 19:50:31 -0400 Received: from esa4.mentor.iphmx.com ([68.232.137.252]:33527) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZ18u-0002Dd-8N for qemu-devel@nongnu.org; Wed, 13 May 2020 19:50:30 -0400 Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa4.mentor.iphmx.com with ESMTP; 13 May 2020 15:50:25 -0800 IronPort-SDR: sr+sogIJb3AScauu8Jvdc5p66eZYbHCT4jQdVYvrmrX0PCZ5XqxkZ+bVabrci/4WoW/3ddtQd8 +e/eyyOR8kdp2oUfAYkUkGBmOjFeHDjPcCjQcYbXZiWUXGQz+D6LFqjw1obBZatE3P1mG7hKKO SO4pT1neqwvTj8IY9HZA5ft0z8zi8d8ptEIZYrHxr0bYA+YeAJe7UHWxsQkfAAhjcjnAuZx5PO D67X3+jqpPwuf5japWlVHiGeNfNKp1AdXTYSAz6YKb09PGy80fUOpnw/nxRxAHf6XTZR65iUZC Zr8= X-IronPort-AV: E=Sophos;i="5.73,389,1583222400"; d="scan'208";a="48881470" IronPort-SDR: LQAqwsLc4016YQ+jGIoBGs9Ak+1jGZdZcT591EXgne5645yH1WtslJexXN+/EYOvgmF8uOQ4DS X8dhfMOtErWLN7jlhcJBkWubO1apbwoydC4IpMNfd/GRfIUz6utAUtU4gdp6Le7TkfTSkmveb7 TG9VvNPD/Zh4VFCurgtuFqusxRFoEExDQeNh1BiNY9sS5SUzfX39OLiXCwRfEdUaZIKNp00HGc B1jQc1smojsgvds7z++WQcIQIFXSktHEKaYkJEYVB0SL9zLTCpD6S2ytx1qTnsm+gDskuyg94Y 2zg= Date: Wed, 13 May 2020 23:50:19 +0000 From: Joseph Myers X-X-Sender: jsm28@digraph.polyomino.org.uk To: , , , Subject: [PATCH 2/4] target/i386: fix fxam handling of invalid encodings In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-06.mgc.mentorg.com (139.181.222.6) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) 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=68.232.137.252; envelope-from=joseph_myers@mentor.com; helo=esa4.mentor.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/13 19:48:30 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 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" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The fxam implementation does not check for invalid encodings, instead treating them like NaN or normal numbers depending on the exponent. Fix it to check that the high bit of the significand is set before treating an encoding as NaN or normal, thus resulting in correct handling (all of C0, C2 and C3 cleared) for invalid encodings. Signed-off-by: Joseph Myers --- target/i386/fpu_helper.c | 4 +- tests/tcg/i386/test-i386-fxam.c | 143 ++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 tests/tcg/i386/test-i386-fxam.c diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c index 38968b2ec7..51372c371b 100644 --- a/target/i386/fpu_helper.c +++ b/target/i386/fpu_helper.c @@ -1099,7 +1099,7 @@ void helper_fxam_ST0(CPUX86State *env) if (expdif =3D=3D MAXEXPD) { if (MANTD(temp) =3D=3D 0x8000000000000000ULL) { env->fpus |=3D 0x500; /* Infinity */ - } else { + } else if (MANTD(temp) & 0x8000000000000000ULL) { env->fpus |=3D 0x100; /* NaN */ } } else if (expdif =3D=3D 0) { @@ -1108,7 +1108,7 @@ void helper_fxam_ST0(CPUX86State *env) } else { env->fpus |=3D 0x4400; /* Denormal */ } - } else { + } else if (MANTD(temp) & 0x8000000000000000ULL) { env->fpus |=3D 0x400; } } diff --git a/tests/tcg/i386/test-i386-fxam.c b/tests/tcg/i386/test-i386-fxa= m.c new file mode 100644 index 0000000000..ddd76ca42d --- /dev/null +++ b/tests/tcg/i386/test-i386-fxam.c @@ -0,0 +1,143 @@ +/* Test fxam instruction. */ + +#include +#include + +union u { + struct { uint64_t sig; uint16_t sign_exp; } s; + long double ld; +}; + +volatile union u ld_pseudo_m16382 =3D { .s =3D { UINT64_C(1) << 63, 0 } }; +volatile union u ld_pseudo_nm16382 =3D { .s =3D { UINT64_C(1) << 63, 0x800= 0 } }; +volatile union u ld_invalid_1 =3D { .s =3D { 1, 1234 } }; +volatile union u ld_invalid_2 =3D { .s =3D { 0, 1234 } }; +volatile union u ld_invalid_3 =3D { .s =3D { 0, 0x7fff } }; +volatile union u ld_invalid_4 =3D { .s =3D { (UINT64_C(1) << 63) - 1, 0x7f= ff } }; +volatile union u ld_invalid_n1 =3D { .s =3D { 1, 0x8123 } }; +volatile union u ld_invalid_n2 =3D { .s =3D { 0, 0x8123 } }; +volatile union u ld_invalid_n3 =3D { .s =3D { 0, 0xffff } }; +volatile union u ld_invalid_n4 =3D { .s =3D { (UINT64_C(1) << 63) - 1, 0xf= fff } }; + +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) +#define FLAGS (C0 | C1 | C2 | C3) + +int main(void) +{ + short sw; + int ret =3D 0; + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (0.0L)); + if ((sw & FLAGS) !=3D C3) { + printf("FAIL: +0\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (-0.0L)); + if ((sw & FLAGS) !=3D (C3 | C1)) { + printf("FAIL: -0\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (1.0L)); + if ((sw & FLAGS) !=3D C2) { + printf("FAIL: +normal\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (-1.0L)); + if ((sw & FLAGS) !=3D (C2 | C1)) { + printf("FAIL: -normal\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (__builtin_infl()= )); + if ((sw & FLAGS) !=3D (C2 | C0)) { + printf("FAIL: +inf\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (-__builtin_infl(= ))); + if ((sw & FLAGS) !=3D (C2 | C1 | C0)) { + printf("FAIL: -inf\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (__builtin_nanl("= "))); + if ((sw & FLAGS) !=3D C0) { + printf("FAIL: +nan\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (-__builtin_nanl(= ""))); + if ((sw & FLAGS) !=3D (C1 | C0)) { + printf("FAIL: -nan\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (__builtin_nansl(= ""))); + if ((sw & FLAGS) !=3D C0) { + printf("FAIL: +snan\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (-__builtin_nansl= (""))); + if ((sw & FLAGS) !=3D (C1 | C0)) { + printf("FAIL: -snan\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (0x1p-16445L)); + if ((sw & FLAGS) !=3D (C3 | C2)) { + printf("FAIL: +denormal\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (-0x1p-16445L)); + if ((sw & FLAGS) !=3D (C3 | C2 | C1)) { + printf("FAIL: -denormal\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_pseudo_m16382= .ld)); + if ((sw & FLAGS) !=3D (C3 | C2)) { + printf("FAIL: +pseudo-denormal\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_pseudo_nm1638= 2.ld)); + if ((sw & FLAGS) !=3D (C3 | C2 | C1)) { + printf("FAIL: -pseudo-denormal\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_invalid_1.ld)= ); + if ((sw & FLAGS) !=3D 0) { + printf("FAIL: +invalid 1\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_invalid_n1.ld= )); + if ((sw & FLAGS) !=3D C1) { + printf("FAIL: -invalid 1\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_invalid_2.ld)= ); + if ((sw & FLAGS) !=3D 0) { + printf("FAIL: +invalid 2\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_invalid_n2.ld= )); + if ((sw & FLAGS) !=3D C1) { + printf("FAIL: -invalid 2\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_invalid_3.ld)= ); + if ((sw & FLAGS) !=3D 0) { + printf("FAIL: +invalid 3\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_invalid_n3.ld= )); + if ((sw & FLAGS) !=3D C1) { + printf("FAIL: -invalid 3\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_invalid_4.ld)= ); + if ((sw & FLAGS) !=3D 0) { + printf("FAIL: +invalid 4\n"); + ret =3D 1; + } + __asm__ volatile ("fxam\nfnstsw" : "=3Da" (sw) : "t" (ld_invalid_n4.ld= )); + if ((sw & FLAGS) !=3D C1) { + printf("FAIL: -invalid 4\n"); + ret =3D 1; + } + return ret; +} --=20 2.17.1 --=20 Joseph S. Myers joseph@codesourcery.com From nobody Sat Jun 1 03:52:48 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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 ARC-Seal: i=1; a=rsa-sha256; t=1589413930; cv=none; d=zohomail.com; s=zohoarc; b=eDW95XdZPS8ecRzpjA0Zrvq6UdQuk4159ulMrwHhBQ9Q74IIYJP7SMbytauL9RRGf3uwot5uqBYtoty3dfFfhToTkwasEXa0ZukDZo0AE54Y2ppGefRbQGpE1vzjdztD/OIhJ9k2THV4kCFbRbdqRVxB9VV3PFW+ROM5XkBfeds= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589413930; h=Content-Type:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=r1qaFSSJ1EoaEOBoTLYe7+MdijC6iyKdazeT7drZa7o=; b=PgaWVwoe5GppN33H0TVckX2kxbSyuWTcORhua+Puf7hjZXZoSEJ8ONY9Fmxvlc/ph1nLH7dDAxmxZV6EihA2EDdFlv8rH3AElyrIz5bgTCwS6KWaJxT2mBfY2niQC5zNaQrq65H8H61gZuewCRXQGHFw3PxOMcMb2mprAyVTbWU= ARC-Authentication-Results: i=1; mx.zohomail.com; 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1589413930030657.8535599912543; Wed, 13 May 2020 16:52:10 -0700 (PDT) Received: from localhost ([::1]:54724 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jZ1AW-00037x-SM for importer@patchew.org; Wed, 13 May 2020 19:52:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51276) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZ19i-0001sL-EG for qemu-devel@nongnu.org; Wed, 13 May 2020 19:51:18 -0400 Received: from esa2.mentor.iphmx.com ([68.232.141.98]:62985) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZ19h-0002RL-9d for qemu-devel@nongnu.org; Wed, 13 May 2020 19:51:18 -0400 Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 13 May 2020 15:51:14 -0800 IronPort-SDR: GV2QDaaxGtPX+rus/4DwNvqmWrDrWz/K/3lyc76KOXKx20VotUqHHbizKjxux5mkcGOr9ztx7b 4SkI5JUyHWXINa2DL1Q5b8xoUfoijXlpfQx+upXFLXGUzurOn/wfY0YKb8wtjVpZ3f3XJX+cFH i9ELBMu2ypnFbcx4MJxE7urdlIqhhigeu4x5Sz4fZ3vjvu1Q4Vqy+jBrRVSFxhAwmjs9fEHir6 QaPLLNl39T/Ov43sMoj9N0+hQMoyMSQIT7xqNg84KfPuSQC7g4tAivG+fzseRoVXjQtNP7pF2n 1gc= X-IronPort-AV: E=Sophos;i="5.73,389,1583222400"; d="scan'208";a="48761597" IronPort-SDR: sZrkrfRRXT+HpjaJ/WnrolmPGH3vAO+4jzWccM4+xG5lEn1ZfXOGpfSfdP9P++ovTKUfpu/uBZ UWso7jMJXWBkM9WyO+vVb5WOQyQ3J1eSUx5uBNVQHX+B/4sJjeha4Zh8YlvuvgJpRh+P8gqkvu FQ5ty12w28YeAj6nEIwKa2vBowcSxl28B2QX7jXLLvFpIuwvxp0tE/WxY2mMHwU1GCbCZr9cV9 lUIpb/Ykw9mmi3Q3NvmxbcP0gEG6d24E+kJKVQh0XJZb8Q0XlYic4YxAF5tlOaEkthV2YHq5KM GGQ= Date: Wed, 13 May 2020 23:51:09 +0000 From: Joseph Myers X-X-Sender: jsm28@digraph.polyomino.org.uk To: , , , Subject: [PATCH 3/4] target/i386: fix fbstp handling of negative zero In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-03.mgc.mentorg.com (139.181.222.3) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) 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=68.232.141.98; envelope-from=joseph_myers@mentor.com; helo=esa2.mentor.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/13 19:51:15 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 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" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The fbstp implementation stores +0 when the rounded result should be -0 because it compares an integer value with 0 to determine the sign. Fix this by checking the sign bit of the operand instead. Signed-off-by: Joseph Myers --- target/i386/fpu_helper.c | 5 ++++- tests/tcg/i386/test-i386-fbstp.c | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/i386/test-i386-fbstp.c diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c index 51372c371b..e1872b3fc0 100644 --- a/target/i386/fpu_helper.c +++ b/target/i386/fpu_helper.c @@ -726,11 +726,14 @@ void helper_fbst_ST0(CPUX86State *env, target_ulong p= tr) int v; target_ulong mem_ref, mem_end; int64_t val; + CPU_LDoubleU temp; + + temp.d =3D ST0; =20 val =3D floatx80_to_int64(ST0, &env->fp_status); mem_ref =3D ptr; mem_end =3D mem_ref + 9; - if (val < 0) { + if (SIGND(temp)) { cpu_stb_data_ra(env, mem_end, 0x80, GETPC()); val =3D -val; } else { diff --git a/tests/tcg/i386/test-i386-fbstp.c b/tests/tcg/i386/test-i386-fb= stp.c new file mode 100644 index 0000000000..d368949188 --- /dev/null +++ b/tests/tcg/i386/test-i386-fbstp.c @@ -0,0 +1,25 @@ +/* Test fbstp instruction. */ + +#include +#include + +int main(void) +{ + int ret =3D 0; + unsigned char out[10]; + memset(out, 0xfe, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (-0.0L) : "st"); + out[9] &=3D 0x80; + if (memcmp(out, "\0\0\0\0\0\0\0\0\0\x80", sizeof out) !=3D 0) { + printf("FAIL: fbstp -0\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (-0.1L) : "st"); + out[9] &=3D 0x80; + if (memcmp(out, "\0\0\0\0\0\0\0\0\0\x80", sizeof out) !=3D 0) { + printf("FAIL: fbstp -0.1\n"); + ret =3D 1; + } + return ret; +} --=20 2.17.1 --=20 Joseph S. Myers joseph@codesourcery.com From nobody Sat Jun 1 03:52:48 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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 ARC-Seal: i=1; a=rsa-sha256; t=1589414000; cv=none; d=zohomail.com; s=zohoarc; b=L169mZrS1RH3ogtF4T4MiJV26ia2LHeo9msCdHYdf+tS696jiwnQGue6K5l6Kv8rKC3WakGaLn8qr1VmVQpZ2rpOoTkyZSASGCPjBoqP+qp4dkYFhT6xu/AhhUzmv3SRg4g4ml5FQ4lY6akwMgMqjPCUMZrtu7iLMd8XvIjWqU8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589414000; h=Content-Type:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=nJecKtHbcFShgnnBilST8lk4vvT250w8GMx/bAszlcM=; b=OUdjlHZ3aRVDwz7AKY8rk8ac6Rac+xM9kdlFfjsXegjIWFV1fja+DVThSBKBvtJyzbtzfqnA+LKEWAoxxztBl6XFu1nCFgshVE0npao2gosYN4k1tn5Sot5TivOeQALxwZYI/ADixswxQWmB9An2s8xyErOLa/xni5yBnwoPFoQ= ARC-Authentication-Results: i=1; mx.zohomail.com; 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1589414000895151.12676404747572; Wed, 13 May 2020 16:53:20 -0700 (PDT) Received: from localhost ([::1]:59210 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jZ1Bf-0005De-Mj for importer@patchew.org; Wed, 13 May 2020 19:53:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51432) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZ1AF-00031s-N9 for qemu-devel@nongnu.org; Wed, 13 May 2020 19:51:51 -0400 Received: from esa1.mentor.iphmx.com ([68.232.129.153]:18313) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZ1AE-0002aq-E1 for qemu-devel@nongnu.org; Wed, 13 May 2020 19:51:51 -0400 Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa1.mentor.iphmx.com with ESMTP; 13 May 2020 15:51:48 -0800 IronPort-SDR: CNbcyX4cbEDzFv5IPZTvzmktUl8MLdhjGyPZ+1wHeMemq7IxKLvQFCZW5+TK/2IK6tWbGB8ako 3E7RAeUqTzP8xcnxHH8Rb8PgX1uXtGi1EUjOe6uIddT9MZevszkWAMAU+0w2+vVVMcfH+MeQfo jnNdspZZdxFQgI/ulZ27RQVc+vm6LgI/8cTGRDARgB/00+No5prL6WH62Og5ewkN5YTn5Iyc5m KRMDUWZPCK5dW1wTUqnLes2p4MB/yLCJgb+ERUF66WkkJZYuhVJS4qN/73SzJ7vQ6EQK5yMUs6 xOw= X-IronPort-AV: E=Sophos;i="5.73,389,1583222400"; d="scan'208";a="50854627" IronPort-SDR: D6XNl6saNuL/Xenub0mNfIVTa5boTUOTiIoLVHr+63M5YCHPVcHRLuC9AF6R5EvmWTRXI5omFM NB+idXVPgpR6dGuntX3SL7fuR0bt7TcHvU5LgEytp97PoUkb1W3MG5UFAi+WvmB07JzNq8AUmd wmpaZNBxhrUlReLIfqOBycsqkWwq8Sl94dz8QoHwaQaY4UoOr8PtaVBtrmiRTnaqg6fnhUoLyS 9Ve1c+2c3JWcT5CBlg96THHXlSX9VMd74xgtk9Etpig86E57XpgKNxDFruTI1wyG+iA51r5mhT gy0= Date: Wed, 13 May 2020 23:51:42 +0000 From: Joseph Myers X-X-Sender: jsm28@digraph.polyomino.org.uk To: , , , Subject: [PATCH 4/4] target/i386: fix fbstp handling of out-of-range values In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) 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=68.232.129.153; envelope-from=joseph_myers@mentor.com; helo=esa1.mentor.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/13 19:51:48 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 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" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The fbstp implementation fails to check for out-of-range and invalid values, instead just taking the result of conversion to int64_t and storing its sign and low 18 decimal digits. Fix this by checking for an out-of-range result (invalid conversions always result in INT64_MAX or INT64_MIN from the softfloat code, which are large enough to be considered as out-of-range by this code) and storing the packed BCD indefinite encoding in that case. Signed-off-by: Joseph Myers --- target/i386/fpu_helper.c | 10 +++ tests/tcg/i386/test-i386-fbstp.c | 115 +++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c index e1872b3fc0..96c512fedf 100644 --- a/target/i386/fpu_helper.c +++ b/target/i386/fpu_helper.c @@ -732,6 +732,16 @@ void helper_fbst_ST0(CPUX86State *env, target_ulong pt= r) =20 val =3D floatx80_to_int64(ST0, &env->fp_status); mem_ref =3D ptr; + if (val >=3D 1000000000000000000LL || val <=3D -1000000000000000000LL)= { + float_raise(float_flag_invalid, &env->fp_status); + while (mem_ref < ptr + 7) { + cpu_stb_data_ra(env, mem_ref++, 0, GETPC()); + } + cpu_stb_data_ra(env, mem_ref++, 0xc0, GETPC()); + cpu_stb_data_ra(env, mem_ref++, 0xff, GETPC()); + cpu_stb_data_ra(env, mem_ref++, 0xff, GETPC()); + return; + } mem_end =3D mem_ref + 9; if (SIGND(temp)) { cpu_stb_data_ra(env, mem_end, 0x80, GETPC()); diff --git a/tests/tcg/i386/test-i386-fbstp.c b/tests/tcg/i386/test-i386-fb= stp.c index d368949188..73bf56b9dc 100644 --- a/tests/tcg/i386/test-i386-fbstp.c +++ b/tests/tcg/i386/test-i386-fbstp.c @@ -1,8 +1,19 @@ /* Test fbstp instruction. */ =20 +#include #include #include =20 +union u { + struct { uint64_t sig; uint16_t sign_exp; } s; + long double ld; +}; + +volatile union u ld_invalid_1 =3D { .s =3D { 1, 1234 } }; +volatile union u ld_invalid_2 =3D { .s =3D { 0, 1234 } }; +volatile union u ld_invalid_3 =3D { .s =3D { 0, 0x7fff } }; +volatile union u ld_invalid_4 =3D { .s =3D { (UINT64_C(1) << 63) - 1, 0x7f= ff } }; + int main(void) { int ret =3D 0; @@ -21,5 +32,109 @@ int main(void) printf("FAIL: fbstp -0.1\n"); ret =3D 1; } + memset(out, 0x1f, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (-987654321987654321= .0L) : + "st"); + out[9] &=3D 0x80; + if (memcmp(out, "\x21\x43\x65\x87\x19\x32\x54\x76\x98\x80", + sizeof out) !=3D 0) { + printf("FAIL: fbstp -987654321987654321\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (999999999999999999.= 5L) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp 999999999999999999.5\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (1000000000000000000= .0L) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp 1000000000000000000\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (1e30L) : "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp 1e30\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (-999999999999999999= .5L) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp -999999999999999999.5\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (-100000000000000000= 0.0L) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp -1000000000000000000\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (-1e30L) : "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp -1e30\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (__builtin_infl()) := "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp inf\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (-__builtin_infl()) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp -inf\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (__builtin_nanl(""))= : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp nan\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (-__builtin_nanl("")= ) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp -nan\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (ld_invalid_1.ld) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp invalid 1\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (ld_invalid_2.ld) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp invalid 2\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (ld_invalid_3.ld) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp invalid 3\n"); + ret =3D 1; + } + memset(out, 0x12, sizeof out); + __asm__ volatile ("fbstp %0" : "=3Dm" (out) : "t" (ld_invalid_4.ld) : + "st"); + if (memcmp(out, "\0\0\0\0\0\0\0\xc0\xff\xff", sizeof out) !=3D 0) { + printf("FAIL: fbstp invalid 4\n"); + ret =3D 1; + } return ret; } --=20 2.17.1 --=20 Joseph S. Myers joseph@codesourcery.com