summaryrefslogtreecommitdiffstats
path: root/arch/i386/math-emu
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-03-17 22:05:47 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-03-17 22:05:47 +0000
commit27cfca1ec98e91261b1a5355d10a8996464b63af (patch)
tree8e895a53e372fa682b4c0a585b9377d67ed70d0e /arch/i386/math-emu
parent6a76fb7214c477ccf6582bd79c5b4ccc4f9c41b1 (diff)
Look Ma' what I found on my harddisk ...
o New faster syscalls for 2.1.x, too o Upgrade to 2.1.89. Don't try to run this. It's flaky as hell. But feel free to debug ...
Diffstat (limited to 'arch/i386/math-emu')
-rw-r--r--arch/i386/math-emu/fpu_entry.c6
-rw-r--r--arch/i386/math-emu/get_address.c28
-rw-r--r--arch/i386/math-emu/reg_ld_str.c6
3 files changed, 21 insertions, 19 deletions
diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c
index 36ca90a35..f120bbc49 100644
--- a/arch/i386/math-emu/fpu_entry.c
+++ b/arch/i386/math-emu/fpu_entry.c
@@ -728,11 +728,11 @@ struct _fpstate * save_i387_soft(void *s387, struct _fpstate * buf)
FPU_verify_area(VERIFY_WRITE, d, 7*4 + 8*10);
#ifdef PECULIAR_486
S387->cwd &= ~0xe080;
- /* An 80486 sets all the reserved bits to 1. */
- S387->cwd |= 0xffff0000;
+ /* An 80486 sets nearly all of the reserved bits to 1. */
+ S387->cwd |= 0xffff0040;
S387->swd = sstatus_word() | 0xffff0000;
S387->twd |= 0xffff0000;
- S387->fcs |= 0xf8000000;
+ S387->fcs &= ~0xf8000000;
S387->fos |= 0xffff0000;
#endif PECULIAR_486
__copy_to_user(d, &S387->cwd, 7*4);
diff --git a/arch/i386/math-emu/get_address.c b/arch/i386/math-emu/get_address.c
index 799bc1c41..a4b15ee7f 100644
--- a/arch/i386/math-emu/get_address.c
+++ b/arch/i386/math-emu/get_address.c
@@ -134,8 +134,8 @@ static int sib(int mod, unsigned long *fpu_eip)
static unsigned long vm86_segment(u_char segment,
- unsigned short *selector)
-{
+ struct address *addr)
+{
segment--;
#ifdef PARANOID
if ( segment > PREFIX_SS_ )
@@ -144,14 +144,14 @@ static unsigned long vm86_segment(u_char segment,
math_abort(FPU_info,SIGSEGV);
}
#endif PARANOID
- *selector = VM86_REG_(segment);
+ addr->selector = VM86_REG_(segment);
return (unsigned long)VM86_REG_(segment) << 4;
}
/* This should work for 16 and 32 bit protected mode. */
static long pm_address(u_char FPU_modrm, u_char segment,
- unsigned short *selector, long offset)
+ struct address *addr, long offset)
{
struct desc_struct descriptor;
unsigned long base_address, limit, address, seg_top;
@@ -172,13 +172,17 @@ static long pm_address(u_char FPU_modrm, u_char segment,
/* fs and gs aren't used by the kernel, so they still have their
user-space values. */
case PREFIX_FS_-1:
- __asm__("mov %%fs,%0":"=r" (*selector));
+ /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register
+ in the assembler statement. */
+ __asm__("mov %%fs,%0":"=r" ((unsigned short)addr->selector));
break;
case PREFIX_GS_-1:
- __asm__("mov %%gs,%0":"=r" (*selector));
+ /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register
+ in the assembler statement. */
+ __asm__("mov %%gs,%0":"=r" ((unsigned short)addr->selector));
break;
default:
- *selector = PM_REG_(segment);
+ addr->selector = PM_REG_(segment);
}
descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
@@ -312,13 +316,12 @@ void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
case 0:
break;
case VM86:
- address += vm86_segment(addr_modes.override.segment,
- (unsigned short *)&(addr->selector));
+ address += vm86_segment(addr_modes.override.segment, addr);
break;
case PM16:
case SEG32:
address = pm_address(FPU_modrm, addr_modes.override.segment,
- (unsigned short *)&(addr->selector), address);
+ addr, address);
break;
default:
EXCEPTION(EX_INTERNAL|0x133);
@@ -427,13 +430,12 @@ void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
case 0:
break;
case VM86:
- address += vm86_segment(addr_modes.override.segment,
- (unsigned short *)&(addr->selector));
+ address += vm86_segment(addr_modes.override.segment, addr);
break;
case PM16:
case SEG32:
address = pm_address(FPU_modrm, addr_modes.override.segment,
- (unsigned short *)&(addr->selector), address);
+ addr, address);
break;
default:
EXCEPTION(EX_INTERNAL|0x131);
diff --git a/arch/i386/math-emu/reg_ld_str.c b/arch/i386/math-emu/reg_ld_str.c
index 468e51cc8..b3ed9acbb 100644
--- a/arch/i386/math-emu/reg_ld_str.c
+++ b/arch/i386/math-emu/reg_ld_str.c
@@ -1329,11 +1329,11 @@ u_char *fstenv(fpu_addr_modes addr_modes, u_char *d)
FPU_verify_area(VERIFY_WRITE, d, 7*4);
#ifdef PECULIAR_486
control_word &= ~0xe080;
- /* An 80486 sets all the reserved bits to 1. */
- control_word |= 0xffff0000;
+ /* An 80486 sets nearly all of the reserved bits to 1. */
+ control_word |= 0xffff0040;
partial_status = status_word() | 0xffff0000;
fpu_tag_word |= 0xffff0000;
- I387.soft.fcs |= 0xf8000000;
+ I387.soft.fcs &= ~0xf8000000;
I387.soft.fos |= 0xffff0000;
#endif PECULIAR_486
__copy_to_user(d, &control_word, 7*4);