Module Name:    src
Committed By:   mgorny
Date:           Thu Oct 15 17:43:09 UTC 2020

Modified Files:
        src/sys/arch/x86/x86: convert_xmm_s87.c
        src/tests/lib/libc/sys: t_ptrace_x86_wait.h

Log Message:
Fix s87_tw reconstruction to correctly indicate register states

Fix the code reconstructing s87_tw (full tag word) from fx_sw (abridged
tag word) to correctly represent all register states.  The previous code
only distinguished between empty/non-empty registers, and assigned
'regular value' to all non-empty registers.  The new code explicitly
distinguishes the two other tag word values: empty and special.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x86/x86/convert_xmm_s87.c
cvs rdiff -u -r1.27 -r1.28 src/tests/lib/libc/sys/t_ptrace_x86_wait.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/x86/convert_xmm_s87.c
diff -u src/sys/arch/x86/x86/convert_xmm_s87.c:1.5 src/sys/arch/x86/x86/convert_xmm_s87.c:1.6
--- src/sys/arch/x86/x86/convert_xmm_s87.c:1.5	Thu Oct 15 17:42:31 2020
+++ src/sys/arch/x86/x86/convert_xmm_s87.c	Thu Oct 15 17:43:08 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: convert_xmm_s87.c,v 1.5 2020/10/15 17:42:31 mgorny Exp $	*/
+/*	$NetBSD: convert_xmm_s87.c,v 1.6 2020/10/15 17:43:08 mgorny Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: convert_xmm_s87.c,v 1.5 2020/10/15 17:42:31 mgorny Exp $");
+__KERNEL_RCSID(0, "$NetBSD: convert_xmm_s87.c,v 1.6 2020/10/15 17:43:08 mgorny Exp $");
 
 
 #include <sys/param.h>
@@ -40,7 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: convert_xmm_
 void
 process_xmm_to_s87(const struct fxsave *sxmm, struct save87 *s87)
 {
-	unsigned int tag, ab_tag;
+	unsigned int tag, ab_tag, st;
 	const struct fpaccfx *fx_reg;
 	struct fpacc87 *s87_reg;
 	int i;
@@ -95,12 +95,28 @@ process_xmm_to_s87(const struct fxsave *
 		return;
 	}
 
+	/* For ST(i), i = fpu_reg - top, we start with fpu_reg=7. */
+	st = 7 - ((sxmm->fx_sw >> 11) & 7);
 	tag = 0;
-	/* Separate bits of abridged tag word with zeros */
-	for (i = 0x80; i != 0; tag <<= 1, i >>= 1)
-		tag |= ab_tag & i;
-	/* Replicate and invert so that 0 => 0b11 and 1 => 0b00 */
-	s87->s87_tw = (tag | tag >> 1) ^ 0xffff;
+	for (i = 0x80; i != 0; i >>= 1) {
+		tag <<= 2;
+		if (ab_tag & i) {
+			unsigned int exp;
+			/* Non-empty - we need to check ST(i) */
+			fx_reg = &sxmm->fx_87_ac[st];
+			exp = fx_reg->r.f87_exp_sign & 0x7fff;
+			if (exp == 0) {
+				if (fx_reg->r.f87_mantissa == 0)
+					tag |= 1; /* Zero */
+				else
+					tag |= 2; /* Denormal */
+			} else if (exp == 0x7fff)
+				tag |= 2; /* Infinity or NaN */
+		} else
+			tag |= 3; /* Empty */
+		st = (st - 1) & 7;
+	}
+	s87->s87_tw = tag;
 }
 
 void

Index: src/tests/lib/libc/sys/t_ptrace_x86_wait.h
diff -u src/tests/lib/libc/sys/t_ptrace_x86_wait.h:1.27 src/tests/lib/libc/sys/t_ptrace_x86_wait.h:1.28
--- src/tests/lib/libc/sys/t_ptrace_x86_wait.h:1.27	Fri Oct  9 17:43:30 2020
+++ src/tests/lib/libc/sys/t_ptrace_x86_wait.h	Thu Oct 15 17:43:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ptrace_x86_wait.h,v 1.27 2020/10/09 17:43:30 mgorny Exp $	*/
+/*	$NetBSD: t_ptrace_x86_wait.h,v 1.28 2020/10/15 17:43:09 mgorny Exp $	*/
 
 /*-
  * Copyright (c) 2016, 2017, 2018, 2019 The NetBSD Foundation, Inc.
@@ -3367,10 +3367,8 @@ x86_register_test(enum x86_test_regset r
 				    expected_fpu.cw);
 				ATF_CHECK_EQ(fpr.fstate.s87_sw,
 				    expected_fpu.sw);
-#if 0 /* TODO: translation from FXSAVE is broken */
 				ATF_CHECK_EQ(fpr.fstate.s87_tw,
 				    expected_fpu.tw);
-#endif
 				ATF_CHECK_EQ(fpr.fstate.s87_opcode,
 				    expected_fpu.opcode);
 				ATF_CHECK_EQ(fpr.fstate.s87_ip.fa_32.fa_off,

Reply via email to