Merge convert_xmm_s87.c into fpu.c. It contains only two functions, that
are used only in fpu.c.
This commit is contained in:
parent
2684bf2f4d
commit
488673a3ac
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.amd64,v 1.103 2018/05/22 11:09:57 maxv Exp $
|
||||
# $NetBSD: files.amd64,v 1.104 2018/05/23 07:45:35 maxv Exp $
|
||||
#
|
||||
# new style config file for amd64 architecture
|
||||
#
|
||||
|
@ -56,7 +56,6 @@ file arch/amd64/amd64/process_machdep.c machdep
|
|||
file arch/amd64/amd64/trap.c machdep
|
||||
file arch/x86/x86/fpu.c machdep
|
||||
file arch/x86/x86/dbregs.c machdep
|
||||
file arch/x86/x86/convert_xmm_s87.c machdep
|
||||
file arch/x86/x86/spectre.c machdep
|
||||
file arch/amd64/amd64/lock_stubs.S machdep
|
||||
file dev/cons.c machdep
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.i386,v 1.393 2018/05/22 11:09:57 maxv Exp $
|
||||
# $NetBSD: files.i386,v 1.394 2018/05/23 07:45:35 maxv Exp $
|
||||
#
|
||||
# new style config file for i386 architecture
|
||||
#
|
||||
|
@ -73,7 +73,6 @@ file arch/i386/i386/machdep.c
|
|||
file arch/i386/i386/longrun.c
|
||||
file arch/i386/i386/mtrr_k6.c mtrr
|
||||
file arch/i386/i386/process_machdep.c
|
||||
file arch/x86/x86/convert_xmm_s87.c
|
||||
file arch/i386/i386/trap.c
|
||||
file dev/cons.c
|
||||
file arch/x86/x86/fpu.c
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu.h,v 1.7 2017/11/03 07:14:24 maxv Exp $ */
|
||||
/* $NetBSD: fpu.h,v 1.8 2018/05/23 07:45:35 maxv Exp $ */
|
||||
|
||||
#ifndef _X86_FPU_H_
|
||||
#define _X86_FPU_H_
|
||||
|
@ -21,9 +21,6 @@ void fpu_set_default_cw(struct lwp *, unsigned int);
|
|||
void fputrap(struct trapframe *);
|
||||
void fpudna(struct trapframe *);
|
||||
|
||||
void process_xmm_to_s87(const struct fxsave *, struct save87 *);
|
||||
void process_s87_to_xmm(const struct save87 *, struct fxsave *);
|
||||
|
||||
/* Set all to defaults (eg during exec) */
|
||||
void fpu_save_area_clear(struct lwp *, unsigned int);
|
||||
/* Reset control words only - for signal handlers */
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
/* $NetBSD: convert_xmm_s87.c,v 1.3 2014/02/15 22:20:42 dsl Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2000, 2001, 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Charles M. Hannum; by Jason R. Thorpe of Wasabi Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: convert_xmm_s87.c,v 1.3 2014/02/15 22:20:42 dsl Exp $");
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <x86/fpu.h>
|
||||
|
||||
void
|
||||
process_xmm_to_s87(const struct fxsave *sxmm, struct save87 *s87)
|
||||
{
|
||||
unsigned int tag, ab_tag;
|
||||
const struct fpaccfx *fx_reg;
|
||||
struct fpacc87 *s87_reg;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* For historic reasons core dumps and ptrace all use the old save87
|
||||
* layout. Convert the important parts.
|
||||
* getucontext gets what we give it.
|
||||
* setucontext should return something given by getucontext, but
|
||||
* we are (at the moment) willing to change it.
|
||||
*
|
||||
* It really isn't worth setting the 'tag' bits to 01 (zero) or
|
||||
* 10 (NaN etc) since the processor will set any internal bits
|
||||
* correctly when the value is loaded (the 287 believed them).
|
||||
*
|
||||
* Additionally the s87_tw and s87_tw are 'indexed' by the actual
|
||||
* register numbers, whereas the registers themselves have ST(0)
|
||||
* first. Pairing the values and tags can only be done with
|
||||
* reference to the 'top of stack'.
|
||||
*
|
||||
* If any x87 registers are used, they will typically be from
|
||||
* r7 downwards - so the high bits of the tag register indicate
|
||||
* used registers. The conversions are not optimised for this.
|
||||
*
|
||||
* The ABI we use requires the FP stack to be empty on every
|
||||
* function call. I think this means that the stack isn't expected
|
||||
* to overflow - overflow doesn't drop a core in my testing.
|
||||
*
|
||||
* Note that this code writes to all of the 's87' structure that
|
||||
* actually gets written to userspace.
|
||||
*/
|
||||
|
||||
/* FPU control/status */
|
||||
s87->s87_cw = sxmm->fx_cw;
|
||||
s87->s87_sw = sxmm->fx_sw;
|
||||
/* tag word handled below */
|
||||
s87->s87_ip = sxmm->fx_ip;
|
||||
s87->s87_opcode = sxmm->fx_opcode;
|
||||
s87->s87_dp = sxmm->fx_dp;
|
||||
|
||||
/* FP registers (in stack order) */
|
||||
fx_reg = sxmm->fx_87_ac;
|
||||
s87_reg = s87->s87_ac;
|
||||
for (i = 0; i < 8; fx_reg++, s87_reg++, i++)
|
||||
*s87_reg = fx_reg->r;
|
||||
|
||||
/* Tag word and registers. */
|
||||
ab_tag = sxmm->fx_tw & 0xff; /* Bits set if valid */
|
||||
if (ab_tag == 0) {
|
||||
/* none used */
|
||||
s87->s87_tw = 0xffff;
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
process_s87_to_xmm(const struct save87 *s87, struct fxsave *sxmm)
|
||||
{
|
||||
unsigned int tag, ab_tag;
|
||||
struct fpaccfx *fx_reg;
|
||||
const struct fpacc87 *s87_reg;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* ptrace gives us registers in the save87 format and
|
||||
* we must convert them to the correct format.
|
||||
*
|
||||
* This code is normally used when overwriting the processes
|
||||
* registers (in the pcb), so it musn't change any other fields.
|
||||
*
|
||||
* There is a lot of pad in 'struct fxsave', if the destination
|
||||
* is written to userspace, it must be zeroed first.
|
||||
*/
|
||||
|
||||
/* FPU control/status */
|
||||
sxmm->fx_cw = s87->s87_cw;
|
||||
sxmm->fx_sw = s87->s87_sw;
|
||||
/* tag word handled below */
|
||||
sxmm->fx_ip = s87->s87_ip;
|
||||
sxmm->fx_opcode = s87->s87_opcode;
|
||||
sxmm->fx_dp = s87->s87_dp;
|
||||
|
||||
/* Tag word */
|
||||
tag = s87->s87_tw; /* 0b11 => unused */
|
||||
if (tag == 0xffff) {
|
||||
/* All unused - values don't matter, zero for safety */
|
||||
sxmm->fx_tw = 0;
|
||||
memset(&sxmm->fx_87_ac, 0, sizeof sxmm->fx_87_ac);
|
||||
return;
|
||||
}
|
||||
|
||||
tag ^= 0xffff; /* So 0b00 is unused */
|
||||
tag |= tag >> 1; /* Look at even bits */
|
||||
ab_tag = 0;
|
||||
i = 1;
|
||||
do
|
||||
ab_tag |= tag & i;
|
||||
while ((tag >>= 1) >= (i <<= 1));
|
||||
sxmm->fx_tw = ab_tag;
|
||||
|
||||
/* FP registers (in stack order) */
|
||||
fx_reg = sxmm->fx_87_ac;
|
||||
s87_reg = s87->s87_ac;
|
||||
for (i = 0; i < 8; fx_reg++, s87_reg++, i++)
|
||||
fx_reg->r = *s87_reg;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu.c,v 1.29 2018/05/23 07:34:40 maxv Exp $ */
|
||||
/* $NetBSD: fpu.c,v 1.30 2018/05/23 07:45:35 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc. All
|
||||
|
@ -96,7 +96,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.29 2018/05/23 07:34:40 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.30 2018/05/23 07:45:35 maxv Exp $");
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
|
||||
|
@ -613,6 +613,126 @@ fpu_save_area_fork(struct pcb *pcb2, const struct pcb *pcb1)
|
|||
memcpy(pcb2 + 1, pcb1 + 1, extra);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
process_xmm_to_s87(const struct fxsave *sxmm, struct save87 *s87)
|
||||
{
|
||||
unsigned int tag, ab_tag;
|
||||
const struct fpaccfx *fx_reg;
|
||||
struct fpacc87 *s87_reg;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* For historic reasons core dumps and ptrace all use the old save87
|
||||
* layout. Convert the important parts.
|
||||
* getucontext gets what we give it.
|
||||
* setucontext should return something given by getucontext, but
|
||||
* we are (at the moment) willing to change it.
|
||||
*
|
||||
* It really isn't worth setting the 'tag' bits to 01 (zero) or
|
||||
* 10 (NaN etc) since the processor will set any internal bits
|
||||
* correctly when the value is loaded (the 287 believed them).
|
||||
*
|
||||
* Additionally the s87_tw and s87_tw are 'indexed' by the actual
|
||||
* register numbers, whereas the registers themselves have ST(0)
|
||||
* first. Pairing the values and tags can only be done with
|
||||
* reference to the 'top of stack'.
|
||||
*
|
||||
* If any x87 registers are used, they will typically be from
|
||||
* r7 downwards - so the high bits of the tag register indicate
|
||||
* used registers. The conversions are not optimised for this.
|
||||
*
|
||||
* The ABI we use requires the FP stack to be empty on every
|
||||
* function call. I think this means that the stack isn't expected
|
||||
* to overflow - overflow doesn't drop a core in my testing.
|
||||
*
|
||||
* Note that this code writes to all of the 's87' structure that
|
||||
* actually gets written to userspace.
|
||||
*/
|
||||
|
||||
/* FPU control/status */
|
||||
s87->s87_cw = sxmm->fx_cw;
|
||||
s87->s87_sw = sxmm->fx_sw;
|
||||
/* tag word handled below */
|
||||
s87->s87_ip = sxmm->fx_ip;
|
||||
s87->s87_opcode = sxmm->fx_opcode;
|
||||
s87->s87_dp = sxmm->fx_dp;
|
||||
|
||||
/* FP registers (in stack order) */
|
||||
fx_reg = sxmm->fx_87_ac;
|
||||
s87_reg = s87->s87_ac;
|
||||
for (i = 0; i < 8; fx_reg++, s87_reg++, i++)
|
||||
*s87_reg = fx_reg->r;
|
||||
|
||||
/* Tag word and registers. */
|
||||
ab_tag = sxmm->fx_tw & 0xff; /* Bits set if valid */
|
||||
if (ab_tag == 0) {
|
||||
/* none used */
|
||||
s87->s87_tw = 0xffff;
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
process_s87_to_xmm(const struct save87 *s87, struct fxsave *sxmm)
|
||||
{
|
||||
unsigned int tag, ab_tag;
|
||||
struct fpaccfx *fx_reg;
|
||||
const struct fpacc87 *s87_reg;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* ptrace gives us registers in the save87 format and
|
||||
* we must convert them to the correct format.
|
||||
*
|
||||
* This code is normally used when overwriting the processes
|
||||
* registers (in the pcb), so it musn't change any other fields.
|
||||
*
|
||||
* There is a lot of pad in 'struct fxsave', if the destination
|
||||
* is written to userspace, it must be zeroed first.
|
||||
*/
|
||||
|
||||
/* FPU control/status */
|
||||
sxmm->fx_cw = s87->s87_cw;
|
||||
sxmm->fx_sw = s87->s87_sw;
|
||||
/* tag word handled below */
|
||||
sxmm->fx_ip = s87->s87_ip;
|
||||
sxmm->fx_opcode = s87->s87_opcode;
|
||||
sxmm->fx_dp = s87->s87_dp;
|
||||
|
||||
/* Tag word */
|
||||
tag = s87->s87_tw; /* 0b11 => unused */
|
||||
if (tag == 0xffff) {
|
||||
/* All unused - values don't matter, zero for safety */
|
||||
sxmm->fx_tw = 0;
|
||||
memset(&sxmm->fx_87_ac, 0, sizeof sxmm->fx_87_ac);
|
||||
return;
|
||||
}
|
||||
|
||||
tag ^= 0xffff; /* So 0b00 is unused */
|
||||
tag |= tag >> 1; /* Look at even bits */
|
||||
ab_tag = 0;
|
||||
i = 1;
|
||||
do
|
||||
ab_tag |= tag & i;
|
||||
while ((tag >>= 1) >= (i <<= 1));
|
||||
sxmm->fx_tw = ab_tag;
|
||||
|
||||
/* FP registers (in stack order) */
|
||||
fx_reg = sxmm->fx_87_ac;
|
||||
s87_reg = s87->s87_ac;
|
||||
for (i = 0; i < 8; fx_reg++, s87_reg++, i++)
|
||||
fx_reg->r = *s87_reg;
|
||||
}
|
||||
|
||||
void
|
||||
process_write_fpregs_xmm(struct lwp *l, const struct fxsave *fpregs)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.xen,v 1.168 2018/03/18 00:17:18 christos Exp $
|
||||
# $NetBSD: files.xen,v 1.169 2018/05/23 07:45:35 maxv Exp $
|
||||
# NetBSD: files.x86,v 1.10 2003/10/08 17:30:00 bouyer Exp
|
||||
# NetBSD: files.i386,v 1.254 2004/03/25 23:32:10 jmc Exp
|
||||
|
||||
|
@ -78,7 +78,6 @@ endif
|
|||
|
||||
file kern/subr_disk_mbr.c disk
|
||||
file uvm/pmap/pmap_pvt.c
|
||||
file arch/x86/x86/convert_xmm_s87.c
|
||||
file arch/x86/x86/db_memrw.c ddb | kgdb
|
||||
file arch/x86/x86/db_trace.c ddb
|
||||
file arch/x86/x86/fpu.c
|
||||
|
|
Loading…
Reference in New Issue