From owner-svn-src-stable-12@freebsd.org Wed Oct 28 21:01:01 2020 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 4AE8E4504BE; Wed, 28 Oct 2020 21:01:01 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CM1FT1LGbz4ZGr; Wed, 28 Oct 2020 21:01:01 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 12907221D8; Wed, 28 Oct 2020 21:01:01 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 09SL10Nq033226; Wed, 28 Oct 2020 21:01:00 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 09SL107L033224; Wed, 28 Oct 2020 21:01:00 GMT (envelope-from kib@FreeBSD.org) Message-Id: <202010282101.09SL107L033224@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 28 Oct 2020 21:01:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r367115 - in stable/12/sys: amd64/ia32 i386/i386 X-SVN-Group: stable-12 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in stable/12/sys: amd64/ia32 i386/i386 X-SVN-Commit-Revision: 367115 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Oct 2020 21:01:01 -0000 Author: kib Date: Wed Oct 28 21:01:00 2020 New Revision: 367115 URL: https://svnweb.freebsd.org/changeset/base/367115 Log: MFC r366904: Improve FPU Tag Word reconstruction on i386 to indicate register states. PR: 250454 Modified: stable/12/sys/amd64/ia32/ia32_reg.c stable/12/sys/i386/i386/npx.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/amd64/ia32/ia32_reg.c ============================================================================== --- stable/12/sys/amd64/ia32/ia32_reg.c Wed Oct 28 20:22:20 2020 (r367114) +++ stable/12/sys/amd64/ia32/ia32_reg.c Wed Oct 28 21:01:00 2020 (r367115) @@ -146,7 +146,11 @@ fill_fpregs32(struct thread *td, struct fpreg32 *regs) struct save87 *sv_87; struct env87 *penv_87; struct envxmm *penv_xmm; - int i; + struct fpacc87 *fx_reg; + int i, st; + uint64_t mantissa; + uint16_t tw, exp; + uint8_t ab_tw; bzero(regs, sizeof(*regs)); sv_87 = (struct save87 *)regs; @@ -172,13 +176,39 @@ fill_fpregs32(struct thread *td, struct fpreg32 *regs) /* Entry into the kernel always sets TF_HASSEGS */ penv_87->en_fos = td->td_frame->tf_ds; - /* FPU registers and tags */ - penv_87->en_tw = 0xffff; - for (i = 0; i < 8; ++i) { - sv_87->sv_ac[i] = sv_fpu->sv_fp[i].fp_acc; - if ((penv_xmm->en_tw & (1 << i)) != 0) - penv_87->en_tw &= ~(3 << i * 2); + /* + * FPU registers and tags. + * For ST(i), i = fpu_reg - top; we start with fpu_reg=7. + */ + st = 7 - ((penv_xmm->en_sw >> 11) & 7); + ab_tw = penv_xmm->en_tw; + tw = 0; + for (i = 0x80; i != 0; i >>= 1) { + sv_87->sv_ac[st] = sv_fpu->sv_fp[st].fp_acc; + tw <<= 2; + if ((ab_tw & i) != 0) { + /* Non-empty - we need to check ST(i) */ + fx_reg = &sv_fpu->sv_fp[st].fp_acc; + /* The first 64 bits contain the mantissa. */ + mantissa = *((uint64_t *)fx_reg->fp_bytes); + /* + * The final 16 bits contain the sign bit and the exponent. + * Mask the sign bit since it is of no consequence to these + * tests. + */ + exp = *((uint16_t *)&fx_reg->fp_bytes[8]) & 0x7fff; + if (exp == 0) { + if (mantissa == 0) + tw |= 1; /* Zero */ + else + tw |= 2; /* Denormal */ + } else if (exp == 0x7fff) + tw |= 2; /* Infinity or NaN */ + } else + tw |= 3; /* Empty */ + st = (st - 1) & 7; } + penv_87->en_tw = tw; return (0); } Modified: stable/12/sys/i386/i386/npx.c ============================================================================== --- stable/12/sys/i386/i386/npx.c Wed Oct 28 20:22:20 2020 (r367114) +++ stable/12/sys/i386/i386/npx.c Wed Oct 28 21:01:00 2020 (r367115) @@ -1149,7 +1149,11 @@ npx_fill_fpregs_xmm1(struct savexmm *sv_xmm, struct sa { struct env87 *penv_87; struct envxmm *penv_xmm; - int i; + struct fpacc87 *fx_reg; + int i, st; + uint64_t mantissa; + uint16_t tw, exp; + uint8_t ab_tw; penv_87 = &sv_87->sv_env; penv_xmm = &sv_xmm->sv_env; @@ -1163,14 +1167,39 @@ npx_fill_fpregs_xmm1(struct savexmm *sv_xmm, struct sa penv_87->en_foo = penv_xmm->en_foo; penv_87->en_fos = penv_xmm->en_fos; - /* FPU registers and tags */ - penv_87->en_tw = 0xffff; - for (i = 0; i < 8; ++i) { - sv_87->sv_ac[i] = sv_xmm->sv_fp[i].fp_acc; - if ((penv_xmm->en_tw & (1 << i)) != 0) - /* zero and special are set as valid */ - penv_87->en_tw &= ~(3 << i * 2); + /* + * FPU registers and tags. + * For ST(i), i = fpu_reg - top; we start with fpu_reg=7. + */ + st = 7 - ((penv_xmm->en_sw >> 11) & 7); + ab_tw = penv_xmm->en_tw; + tw = 0; + for (i = 0x80; i != 0; i >>= 1) { + sv_87->sv_ac[st] = sv_xmm->sv_fp[st].fp_acc; + tw <<= 2; + if (ab_tw & i) { + /* Non-empty - we need to check ST(i) */ + fx_reg = &sv_xmm->sv_fp[st].fp_acc; + /* The first 64 bits contain the mantissa. */ + mantissa = *((uint64_t *)fx_reg->fp_bytes); + /* + * The final 16 bits contain the sign bit and the exponent. + * Mask the sign bit since it is of no consequence to these + * tests. + */ + exp = *((uint16_t *)&fx_reg->fp_bytes[8]) & 0x7fff; + if (exp == 0) { + if (mantissa == 0) + tw |= 1; /* Zero */ + else + tw |= 2; /* Denormal */ + } else if (exp == 0x7fff) + tw |= 2; /* Infinity or NaN */ + } else + tw |= 3; /* Empty */ + st = (st - 1) & 7; } + penv_87->en_tw = tw; } void