From nobody Fri Nov 14 19:27:32 2025 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=1589578043; cv=none; d=zohomail.com; s=zohoarc; b=Z1/vKakqJmzG2PDjVBrDv6iQ9lI+MG5L4/ga5ah+nLkQMNtQEotISmKKoppwXKJVjIE4AAwDplVuEjTveyJ+6mEXPDZWT3aaWMMiMMHh9sgGGwXY3siZc1R+fEFL+Ozf8lOPKmptFVb5vAP6WuBvcESYG7mHBWslXMFYCn9/J3M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589578043; 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=tCgDGawqb1JSqWqmV1OxhVw/LT7QB89aGgKdw3XAjWM=; b=me8wittzeLb+ZzNjkyJop8nnoFomgV0pdKbOfYRNEcusAFHpdp9y22lhoznLGrVpCuA3U3IQ3Yy37SCIvDQVT0QzUMKHGBa/IAPibqNzd8Tq97z+7eCQo5PvjPnz8Hv8RU/XShl866mHD+lQaXlu4MYvMD7PDSlv6fBdnmPjWHo= 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 1589578043215486.15528759861945; Fri, 15 May 2020 14:27:23 -0700 (PDT) Received: from localhost ([::1]:58420 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jZhrW-0000KX-1i for importer@patchew.org; Fri, 15 May 2020 17:27:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43134) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZhkx-0000I8-FG for qemu-devel@nongnu.org; Fri, 15 May 2020 17:20:35 -0400 Received: from esa3.mentor.iphmx.com ([68.232.137.180]:44186) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jZhkw-0007JC-02 for qemu-devel@nongnu.org; Fri, 15 May 2020 17:20:35 -0400 Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 15 May 2020 13:20:31 -0800 IronPort-SDR: Rl6+KdgYmQ8I9/wBEY1zg4JqliBORW/2PECe4uuquxyTCrWFuHU/zmU993dLFUByLkJFKgl9OP EGj1gQPrQG1rZtiUldAToZTkrkqXYRfQYzHkYlcAdmZXfZxftgGdfjf0zMcLp+DopB8yaY24KA UuNCEx0KT0dUp6JY+v20sFRELlRCvWbcKqpetSn1FU0H075ehvIFKrJt6pDzVHOzoqu7wtu8Cp HQlF2i8UYWYvgbn2lBOh58f3FwDPRh/IVTRBvIrqiqDxt7M8ToRXMruem5/dE1V1rvoCHPiYsT Yik= X-IronPort-AV: E=Sophos;i="5.73,396,1583222400"; d="scan'208";a="48901696" IronPort-SDR: I90DriDduXTSbGy1oykAjrBVFEsZOe3NCymQyB/EDsULtTs89ueK4Ic5cMGVF1dGKWK+sQjUJr 2Ucwjm/qV6uVWQgzfSvtXAmEEYllu7ywYZ6IggMcy0/0s1cPmprtVeYYW9yujalM+bgK0XDwW1 vx5MXyMTlf5c31QYBHSlDDfDr8XycimK/SNIJtfN+hQU5izaCHmq5oHRMrB6Vg5gHAabxE99d0 EPhp46EHvd8HyFLveWYu7Sa7EVreLp1TRliZ6msvtJMyXjW6BO3ZeTS69BoenvXgeW+TtMlATh HQU= Date: Fri, 15 May 2020 21:20:25 +0000 From: Joseph Myers X-X-Sender: jsm28@digraph.polyomino.org.uk To: , , , Subject: [PATCH 1/2] target/i386: fix fisttpl, fisttpll 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-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.180; envelope-from=joseph_myers@mentor.com; helo=esa3.mentor.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/15 17:20:32 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 fist / fistt family of instructions should all store the most negative integer in the destination format when the rounded / truncated integer result is out of range or the input is an invalid encoding, infinity or NaN. The fisttpl and fisttpll implementations (32-bit and 64-bit results, truncate towards zero) failed to do this, producing the most positive integer in some cases instead. Fix this by copying the code used to handle this issue for fistpl and fistpll, adjusted to use the _round_to_zero functions for the actual conversion (but without any other changes to that code). Signed-off-by: Joseph Myers --- target/i386/fpu_helper.c | 28 ++++++++- tests/tcg/i386/test-i386-fisttp.c | 100 ++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 tests/tcg/i386/test-i386-fisttp.c diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c index 96c512fedf..8dcc9ddf68 100644 --- a/target/i386/fpu_helper.c +++ b/target/i386/fpu_helper.c @@ -338,12 +338,36 @@ int32_t helper_fistt_ST0(CPUX86State *env) =20 int32_t helper_fisttl_ST0(CPUX86State *env) { - return floatx80_to_int32_round_to_zero(ST0, &env->fp_status); + int32_t val; + signed char old_exp_flags; + + old_exp_flags =3D get_float_exception_flags(&env->fp_status); + set_float_exception_flags(0, &env->fp_status); + + val =3D floatx80_to_int32_round_to_zero(ST0, &env->fp_status); + if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) { + val =3D 0x80000000; + } + set_float_exception_flags(get_float_exception_flags(&env->fp_status) + | old_exp_flags, &env->fp_status); + return val; } =20 int64_t helper_fisttll_ST0(CPUX86State *env) { - return floatx80_to_int64_round_to_zero(ST0, &env->fp_status); + int64_t val; + signed char old_exp_flags; + + old_exp_flags =3D get_float_exception_flags(&env->fp_status); + set_float_exception_flags(0, &env->fp_status); + + val =3D floatx80_to_int64_round_to_zero(ST0, &env->fp_status); + if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) { + val =3D 0x8000000000000000ULL; + } + set_float_exception_flags(get_float_exception_flags(&env->fp_status) + | old_exp_flags, &env->fp_status); + return val; } =20 void helper_fldt_ST0(CPUX86State *env, target_ulong ptr) diff --git a/tests/tcg/i386/test-i386-fisttp.c b/tests/tcg/i386/test-i386-f= isttp.c new file mode 100644 index 0000000000..16af59a774 --- /dev/null +++ b/tests/tcg/i386/test-i386-fisttp.c @@ -0,0 +1,100 @@ +/* Test fisttpl and fisttpll instructions. */ + +#include +#include +#include + +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 } }; + +int main(void) +{ + int ret =3D 0; + int32_t res_32; + int64_t res_64; + __asm__ volatile ("fisttpl %0" : "=3Dm" (res_32) : "t" (0x1p100L) : "s= t"); + if (res_32 !=3D INT32_MIN) { + printf("FAIL: fisttpl 0x1p100\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpl %0" : "=3Dm" (res_32) : "t" (-0x1p100L) : "= st"); + if (res_32 !=3D INT32_MIN) { + printf("FAIL: fisttpl -0x1p100\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpl %0" : "=3Dm" (res_32) : "t" (__builtin_infl= ()) : + "st"); + if (res_32 !=3D INT32_MIN) { + printf("FAIL: fisttpl inf\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpl %0" : "=3Dm" (res_32) : "t" (-__builtin_inf= l()) : + "st"); + if (res_32 !=3D INT32_MIN) { + printf("FAIL: fisttpl -inf\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpl %0" : "=3Dm" (res_32) : "t" (__builtin_nanl= ("")) : + "st"); + if (res_32 !=3D INT32_MIN) { + printf("FAIL: fisttpl nan\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpl %0" : "=3Dm" (res_32) : + "t" (-__builtin_nanl("")) : "st"); + if (res_32 !=3D INT32_MIN) { + printf("FAIL: fisttpl -nan\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpl %0" : "=3Dm" (res_32) : "t" (ld_invalid_1.l= d) : + "st"); + if (res_32 !=3D INT32_MIN) { + printf("FAIL: fisttpl invalid\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpll %0" : "=3Dm" (res_64) : "t" (0x1p100L) : "= st"); + if (res_64 !=3D INT64_MIN) { + printf("FAIL: fisttpll 0x1p100\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpll %0" : "=3Dm" (res_64) : "t" (-0x1p100L) : = "st"); + if (res_64 !=3D INT64_MIN) { + printf("FAIL: fisttpll -0x1p100\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpll %0" : "=3Dm" (res_64) : "t" (__builtin_inf= l()) : + "st"); + if (res_64 !=3D INT64_MIN) { + printf("FAIL: fisttpll inf\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpll %0" : "=3Dm" (res_64) : "t" (-__builtin_in= fl()) : + "st"); + if (res_64 !=3D INT64_MIN) { + printf("FAIL: fisttpll -inf\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpll %0" : "=3Dm" (res_64) : + "t" (__builtin_nanl("")) : "st"); + if (res_64 !=3D INT64_MIN) { + printf("FAIL: fisttpll nan\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpll %0" : "=3Dm" (res_64) : + "t" (-__builtin_nanl("")) : "st"); + if (res_64 !=3D INT64_MIN) { + printf("FAIL: fisttpll -nan\n"); + ret =3D 1; + } + __asm__ volatile ("fisttpll %0" : "=3Dm" (res_64) : "t" (ld_invalid_1.= ld) : + "st"); + if (res_64 !=3D INT64_MIN) { + printf("FAIL: fisttpll invalid\n"); + ret =3D 1; + } + return ret; +} --=20 2.17.1 --=20 Joseph S. Myers joseph@codesourcery.com