summaryrefslogtreecommitdiffstats
path: root/arch/i386/math-emu
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /arch/i386/math-emu
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'arch/i386/math-emu')
-rw-r--r--arch/i386/math-emu/Makefile34
-rw-r--r--arch/i386/math-emu/README10
-rw-r--r--arch/i386/math-emu/control_w.h2
-rw-r--r--arch/i386/math-emu/div_Xsig.S12
-rw-r--r--arch/i386/math-emu/div_small.S13
-rw-r--r--arch/i386/math-emu/errors.c60
-rw-r--r--arch/i386/math-emu/exception.h10
-rw-r--r--arch/i386/math-emu/fpu_asm.h9
-rw-r--r--arch/i386/math-emu/fpu_emu.h22
-rw-r--r--arch/i386/math-emu/fpu_entry.c59
-rw-r--r--arch/i386/math-emu/fpu_proto.h2
-rw-r--r--arch/i386/math-emu/get_address.c48
-rw-r--r--arch/i386/math-emu/load_store.c8
-rw-r--r--arch/i386/math-emu/mul_Xsig.S18
-rw-r--r--arch/i386/math-emu/polynom_Xsig.S10
-rw-r--r--arch/i386/math-emu/reg_constant.c51
-rw-r--r--arch/i386/math-emu/reg_div.S35
-rw-r--r--arch/i386/math-emu/reg_ld_str.c198
-rw-r--r--arch/i386/math-emu/reg_norm.S25
-rw-r--r--arch/i386/math-emu/reg_round.S22
-rw-r--r--arch/i386/math-emu/reg_u_add.S14
-rw-r--r--arch/i386/math-emu/reg_u_div.S20
-rw-r--r--arch/i386/math-emu/reg_u_mul.S15
-rw-r--r--arch/i386/math-emu/reg_u_sub.S14
-rw-r--r--arch/i386/math-emu/round_Xsig.S17
-rw-r--r--arch/i386/math-emu/shr_Xsig.S11
-rw-r--r--arch/i386/math-emu/status_w.h6
-rw-r--r--arch/i386/math-emu/version.h8
-rw-r--r--arch/i386/math-emu/wm_shrx.S16
-rw-r--r--arch/i386/math-emu/wm_sqrt.S11
30 files changed, 370 insertions, 410 deletions
diff --git a/arch/i386/math-emu/Makefile b/arch/i386/math-emu/Makefile
index 2d391a9e6..1bd2cb40d 100644
--- a/arch/i386/math-emu/Makefile
+++ b/arch/i386/math-emu/Makefile
@@ -2,21 +2,17 @@
# Makefile for wm-FPU-emu
#
+L_TARGET := math.a
+
#DEBUG = -DDEBUGGING
DEBUG =
PARANOID = -DPARANOID
-CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin
-
-.c.o:
- $(CC) $(CFLAGS) $(MATH_EMULATION) -c $<
+CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION)
.S.o:
- $(CC) -D__ASSEMBLER__ $(PARANOID) -c $<
-
-.s.o:
- $(CC) -c $<
+ $(CC) -D__ASSEMBLY__ $(PARANOID) -c $<
-OBJS = fpu_entry.o div_small.o errors.o \
+L_OBJS =fpu_entry.o div_small.o errors.o \
fpu_arith.o fpu_aux.o fpu_etc.o fpu_trig.o \
load_store.o get_address.o \
poly_atan.o poly_l2.o poly_2xm1.o poly_sin.o poly_tan.o \
@@ -28,25 +24,7 @@ OBJS = fpu_entry.o div_small.o errors.o \
div_Xsig.o polynom_Xsig.o round_Xsig.o \
shr_Xsig.o mul_Xsig.o
-math.a: $(OBJS)
- rm -f math.a
- $(AR) rcs math.a $(OBJS)
- sync
-
-dep:
- $(CPP) -M *.c > .depend
- $(CPP) -D__ASSEMBLER__ -M *.S >> .depend
+include $(TOPDIR)/Rules.make
proto:
cproto -e -DMAKING_PROTO *.c >fpu_proto.h
-
-modules:
-
-dummy:
-
-#
-# include a dependency file if one exists
-#
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
diff --git a/arch/i386/math-emu/README b/arch/i386/math-emu/README
index 2c0acb423..5158b4b81 100644
--- a/arch/i386/math-emu/README
+++ b/arch/i386/math-emu/README
@@ -1,9 +1,9 @@
+---------------------------------------------------------------------------+
| wm-FPU-emu an FPU emulator for 80386 and 80486SX microprocessors. |
| |
- | Copyright (C) 1992,1993,1994 |
+ | Copyright (C) 1992,1993,1994,1995,1996 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@suburbia.net |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License version 2 as |
@@ -42,13 +42,11 @@ but is very close. See "Limitations" later in this file for a list of
some differences.
Please report bugs, etc to me at:
- billm@vaxc.cc.monash.edu.au
- or at:
- billm@jacobi.maths.monash.edu.au
+ billm@suburbia.net
--Bill Metzenthen
- August 1994
+ October 1996
----------------------- Internals of wm-FPU-emu -----------------------
diff --git a/arch/i386/math-emu/control_w.h b/arch/i386/math-emu/control_w.h
index ef5fced39..6bd7654b7 100644
--- a/arch/i386/math-emu/control_w.h
+++ b/arch/i386/math-emu/control_w.h
@@ -10,7 +10,7 @@
#ifndef _CONTROLW_H_
#define _CONTROLW_H_
-#ifdef __ASSEMBLER__
+#ifdef __ASSEMBLY__
#define _Const_(x) $##x
#else
#define _Const_(x) x
diff --git a/arch/i386/math-emu/div_Xsig.S b/arch/i386/math-emu/div_Xsig.S
index 67d8be964..fd83732fc 100644
--- a/arch/i386/math-emu/div_Xsig.S
+++ b/arch/i386/math-emu/div_Xsig.S
@@ -4,9 +4,9 @@
| |
| Division subroutine for 96 bit quantities |
| |
- | Copyright (C) 1994 |
+ | Copyright (C) 1994,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -28,7 +28,7 @@
+---------------------------------------------------------------------------*/
#include "exception.h"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
#define XsigLL(x) (x)
@@ -74,11 +74,7 @@ FPU_result_1:
.text
- .align 2,144
-
-.globl _div_Xsig
-
-_div_Xsig:
+ENTRY(div_Xsig)
pushl %ebp
movl %esp,%ebp
#ifndef NON_REENTRANT_FPU
diff --git a/arch/i386/math-emu/div_small.S b/arch/i386/math-emu/div_small.S
index 0225a96d4..13ab2b7ae 100644
--- a/arch/i386/math-emu/div_small.S
+++ b/arch/i386/math-emu/div_small.S
@@ -4,8 +4,9 @@
| |
| Divide a 64 bit integer by a 32 bit integer & return remainder. |
| |
- | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -14,14 +15,10 @@
| unsigned long div_small(unsigned long long *x, unsigned long y) |
+---------------------------------------------------------------------------*/
-#include "fpu_asm.h"
+#include "fpu_emu.h"
.text
- .align 2,144
-
-.globl _div_small
-
-_div_small:
+ENTRY(div_small)
pushl %ebp
movl %esp,%ebp
diff --git a/arch/i386/math-emu/errors.c b/arch/i386/math-emu/errors.c
index e34eec942..f76020d1f 100644
--- a/arch/i386/math-emu/errors.c
+++ b/arch/i386/math-emu/errors.c
@@ -3,9 +3,9 @@
| |
| The error handling functions for wm-FPU-emu |
| |
- | Copyright (C) 1992,1993,1994 |
- | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1993,1994,1996 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@jacobi.maths.monash.edu.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -19,7 +19,7 @@
#include <linux/signal.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include "fpu_system.h"
#include "exception.h"
@@ -46,13 +46,13 @@ void Un_impl(void)
{
while ( 1 )
{
- byte1 = get_fs_byte((unsigned char *) address);
+ get_user(byte1, (unsigned char *) address);
if ( (byte1 & 0xf8) == 0xd8 ) break;
printk("[%02x]", byte1);
address++;
}
printk("%02x ", byte1);
- FPU_modrm = get_fs_byte(1 + (unsigned char *) address);
+ get_user(FPU_modrm, 1 + (unsigned char *) address);
if (FPU_modrm >= 0300)
printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
@@ -82,10 +82,10 @@ void FPU_illegal(void)
-void emu_printall()
+void emu_printall(void)
{
int i;
- static char *tag_desc[] = { "Valid", "Zero", "ERROR", "ERROR",
+ static const char *tag_desc[] = { "Valid", "Zero", "ERROR", "ERROR",
"DeNorm", "Inf", "NaN", "Empty" };
unsigned char byte1, FPU_modrm;
unsigned long address = FPU_ORIG_EIP;
@@ -98,7 +98,7 @@ void emu_printall()
#define MAX_PRINTED_BYTES 20
for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
{
- byte1 = get_fs_byte((unsigned char *) address);
+ get_user(byte1, (unsigned char *) address);
if ( (byte1 & 0xf8) == 0xd8 )
{
printk(" %02x", byte1);
@@ -111,7 +111,7 @@ void emu_printall()
printk(" [more..]\n");
else
{
- FPU_modrm = get_fs_byte(1 + (unsigned char *) address);
+ get_user(FPU_modrm, 1 + (unsigned char *) address);
if (FPU_modrm >= 0300)
printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
@@ -166,7 +166,8 @@ printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n",
for ( i = 0; i < 8; i++ )
{
FPU_REG *r = &st(i);
- switch (r->tag)
+ char tagi = r->tag;
+ switch (tagi)
{
case TW_Empty:
continue;
@@ -190,29 +191,20 @@ printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n",
r->exp - EXP_BIAS + 1);
break;
default:
- printk("Whoops! Error in errors.c ");
+ printk("Whoops! Error in errors.c: tag%d is %d ", i, tagi);
+ continue;
break;
}
- printk("%s\n", tag_desc[(int) (unsigned) r->tag]);
+ printk("%s\n", tag_desc[(int) (unsigned) tagi]);
}
-#ifdef OBSOLETE
- printk("[data] %c .%04lx %04lx %04lx %04lx e%+-6ld ",
- FPU_loaded_data.sign ? '-' : '+',
- (long)(FPU_loaded_data.sigh >> 16),
- (long)(FPU_loaded_data.sigh & 0xFFFF),
- (long)(FPU_loaded_data.sigl >> 16),
- (long)(FPU_loaded_data.sigl & 0xFFFF),
- FPU_loaded_data.exp - EXP_BIAS + 1);
- printk("%s\n", tag_desc[(int) (unsigned) FPU_loaded_data.tag]);
-#endif OBSOLETE
RE_ENTRANT_CHECK_ON;
}
static struct {
int type;
- char *name;
+ const char *name;
} exception_names[] = {
{ EX_StackOver, "stack overflow" },
{ EX_StackUnder, "stack underflow" },
@@ -300,7 +292,7 @@ static struct {
0x242 in div_Xsig.S
*/
-void exception(int n)
+void FPU_exception(int n)
{
int i, int_type;
@@ -365,12 +357,8 @@ void exception(int n)
/*
* The 80486 generates an interrupt on the next non-control FPU
* instruction. So we need some means of flagging it.
- * We use the ES (Error Summary) bit for this, assuming that
- * this is the way a real FPU does it (until I can check it out),
- * if not, then some method such as the following kludge might
- * be needed.
+ * We use the ES (Error Summary) bit for this.
*/
-/* regs[0].tag |= TW_FPU_Interrupt; */
}
RE_ENTRANT_CHECK_ON;
@@ -494,7 +482,7 @@ int set_precision_flag(int flags)
}
else
{
- exception(flags);
+ EXCEPTION(flags);
return 1;
}
}
@@ -506,7 +494,7 @@ asmlinkage void set_precision_flag_up(void)
if ( control_word & CW_Precision )
partial_status |= (SW_Precision | SW_C1); /* The masked response */
else
- exception(EX_Precision | SW_C1);
+ EXCEPTION(EX_Precision | SW_C1);
}
@@ -520,7 +508,7 @@ asmlinkage void set_precision_flag_down(void)
partial_status |= SW_Precision;
}
else
- exception(EX_Precision);
+ EXCEPTION(EX_Precision);
}
@@ -533,7 +521,7 @@ asmlinkage int denormal_operand(void)
}
else
{
- exception(EX_Denormal);
+ EXCEPTION(EX_Denormal);
return 1;
}
}
@@ -568,7 +556,7 @@ asmlinkage int arith_overflow(FPU_REG *dest)
return !(control_word & CW_Precision);
}
- return !(control_word & CW_Overflow);
+ return 0;
}
@@ -599,7 +587,7 @@ asmlinkage int arith_underflow(FPU_REG *dest)
return !(control_word & CW_Precision);
}
- return !(control_word & CW_Underflow);
+ return 0;
}
diff --git a/arch/i386/math-emu/exception.h b/arch/i386/math-emu/exception.h
index 2e629a30c..b90e5e9c3 100644
--- a/arch/i386/math-emu/exception.h
+++ b/arch/i386/math-emu/exception.h
@@ -10,7 +10,7 @@
#define _EXCEPTION_H_
-#ifdef __ASSEMBLER__
+#ifdef __ASSEMBLY__
#define Const_(x) $##x
#else
#define Const_(x) x
@@ -39,15 +39,15 @@
#define PRECISION_LOST_DOWN Const_(EX_Precision)
-#ifndef __ASSEMBLER__
+#ifndef __ASSEMBLY__
#ifdef DEBUG
#define EXCEPTION(x) { printk("exception in %s at line %d\n", \
- __FILE__, __LINE__); exception(x); }
+ __FILE__, __LINE__); FPU_exception(x); }
#else
-#define EXCEPTION(x) exception(x)
+#define EXCEPTION(x) FPU_exception(x)
#endif
-#endif __ASSEMBLER__
+#endif __ASSEMBLY__
#endif _EXCEPTION_H_
diff --git a/arch/i386/math-emu/fpu_asm.h b/arch/i386/math-emu/fpu_asm.h
index 8eb60148d..d08fbc874 100644
--- a/arch/i386/math-emu/fpu_asm.h
+++ b/arch/i386/math-emu/fpu_asm.h
@@ -1,17 +1,18 @@
/*---------------------------------------------------------------------------+
| fpu_asm.h |
| |
- | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
+---------------------------------------------------------------------------*/
#ifndef _FPU_ASM_H_
#define _FPU_ASM_H_
-#include "fpu_emu.h"
+#include <linux/linkage.h>
-#define EXCEPTION _exception
+#define EXCEPTION SYMBOL_NAME(FPU_exception)
#define PARAM1 8(%ebp)
diff --git a/arch/i386/math-emu/fpu_emu.h b/arch/i386/math-emu/fpu_emu.h
index 9d2c5dd13..b8385db1f 100644
--- a/arch/i386/math-emu/fpu_emu.h
+++ b/arch/i386/math-emu/fpu_emu.h
@@ -28,7 +28,7 @@
*/
#define PECULIAR_486
-#ifdef __ASSEMBLER__
+#ifdef __ASSEMBLY__
#include "fpu_asm.h"
#define Const(x) $##x
#else
@@ -55,9 +55,11 @@
#define TW_Empty Const(7) /* empty */
-#ifndef __ASSEMBLER__
+#ifndef __ASSEMBLY__
+
+#include <asm/sigcontext.h> /* for struct _fpstate */
+#include <asm/math_emu.h>
-#include <linux/math_emu.h>
#include <linux/linkage.h>
/*
@@ -95,9 +97,9 @@ extern char emulating;
struct address {
unsigned int offset;
- unsigned int selector:16;
- unsigned int opcode:11;
- unsigned int empty:5;
+ unsigned short selector;
+ unsigned short opcode:11,
+ empty:5;
};
typedef void (*FUNC)(void);
typedef struct fpu_reg FPU_REG;
@@ -133,9 +135,9 @@ extern unsigned char const data_sizes_16[32];
#define reg_move(x, y) { \
- *(short *)&((y)->sign) = *(short *)&((x)->sign); \
- *(long *)&((y)->exp) = *(long *)&((x)->exp); \
- *(long long *)&((y)->sigl) = *(long long *)&((x)->sigl); }
+ *(short *)&((y)->sign) = *(const short *)&((x)->sign); \
+ *(long *)&((y)->exp) = *(const long *)&((x)->exp); \
+ *(long long *)&((y)->sigl) = *(const long long *)&((x)->sigl); }
#define significand(x) ( ((unsigned long long *)&((x)->sigl))[0] )
@@ -166,6 +168,6 @@ asmlinkage void round_reg(FPU_REG *arg, unsigned int extent,
#include "fpu_proto.h"
#endif
-#endif __ASSEMBLER__
+#endif __ASSEMBLY__
#endif _FPU_EMU_H_
diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c
index b2777a722..07c32db9a 100644
--- a/arch/i386/math-emu/fpu_entry.c
+++ b/arch/i386/math-emu/fpu_entry.c
@@ -1,11 +1,11 @@
/*---------------------------------------------------------------------------+
| fpu_entry.c |
| |
- | The entry function for wm-FPU-emu |
+ | The entry functions for wm-FPU-emu |
| |
- | Copyright (C) 1992,1993,1994 |
- | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1993,1994,1996 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@jacobi.maths.monash.edu.au |
| |
| See the files "README" and "COPYING" for further copyright and warranty |
| information. |
@@ -20,12 +20,13 @@
+---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------+
- | math_emulate() is the sole entry point for wm-FPU-emu |
+ | math_emulate(), restore_i387_soft() and save_i387_soft() are the only |
+ | entry points for wm-FPU-emu. |
+---------------------------------------------------------------------------*/
#include <linux/signal.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include "fpu_system.h"
#include "fpu_emu.h"
@@ -159,8 +160,9 @@ asmlinkage void math_emulate(long arg)
{
/* Make sure that the registers are compatible
with the assumptions of the emulator. */
- regs[i].exp = 0;
- regs[i].sigh = 0x80000000;
+ if ( !((regs[i].exp == EXP_UNDER) && (regs[i].sigh == 0)
+ && (regs[i].sigl == 0)) )
+ regs[i].sigh |= 0x80000000;
}
finit();
current->used_math = 1;
@@ -262,7 +264,7 @@ do_another_FPU_instruction:
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- FPU_modrm = get_fs_byte((unsigned char *) FPU_EIP);
+ get_user(FPU_modrm, (unsigned char *) FPU_EIP);
RE_ENTRANT_CHECK_ON;
FPU_EIP++;
@@ -283,24 +285,8 @@ do_another_FPU_instruction:
/*
* We need to simulate the action of the kernel to FPU
* interrupts here.
- * Currently, the "real FPU" part of the kernel (0.99.10)
- * clears the exception flags, sets the registers to empty,
- * and passes information back to the interrupted process
- * via the cs selector and operand selector, so we do the same.
*/
do_the_FPU_interrupt:
- instruction_address.selector = status_word();
- operand_address.selector = tag_word();
- partial_status = 0;
- top = 0;
- {
- int r;
- for (r = 0; r < 8; r++)
- {
- regs[r].tag = TW_Empty;
- }
- }
-
FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */
RE_ENTRANT_CHECK_OFF;
@@ -605,7 +591,7 @@ static int valid_prefix(unsigned char *Byte, unsigned char **fpu_eip,
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- byte = get_fs_byte(ip);
+ get_user(byte, ip);
RE_ENTRANT_CHECK_ON;
while ( 1 )
@@ -651,7 +637,7 @@ static int valid_prefix(unsigned char *Byte, unsigned char **fpu_eip,
ip++;
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- byte = get_fs_byte(ip);
+ get_user(byte, ip);
RE_ENTRANT_CHECK_ON;
break;
case FWAIT_OPCODE:
@@ -688,3 +674,22 @@ void math_abort(struct info * info, unsigned int signal)
printk("ERROR: wm-FPU-emu math_abort failed!\n");
#endif PARANOID
}
+
+
+
+void restore_i387_soft(struct _fpstate *buf)
+{
+ fpu_addr_modes addr_modes = {{ 0, 0, PREFIX_DEFAULT }, 0};
+
+ frstor(addr_modes, (char *)buf);
+}
+
+
+struct _fpstate * save_i387_soft(struct _fpstate * buf)
+{
+ fpu_addr_modes addr_modes = {{ 0, 0, PREFIX_DEFAULT }, 0};
+
+ fsave(addr_modes, (char *)buf);
+
+ return buf;
+}
diff --git a/arch/i386/math-emu/fpu_proto.h b/arch/i386/math-emu/fpu_proto.h
index b4392fe57..d0e58ed0e 100644
--- a/arch/i386/math-emu/fpu_proto.h
+++ b/arch/i386/math-emu/fpu_proto.h
@@ -7,7 +7,7 @@ extern void stack_underflow(void);
extern void stack_underflow_i(int i);
extern void stack_underflow_pop(int i);
extern int set_precision_flag(int flags);
-asmlinkage void exception(int n);
+asmlinkage void FPU_exception(int n);
asmlinkage int real_2op_NaN(FPU_REG const *a, FPU_REG const *b, FPU_REG *dest);
asmlinkage int arith_invalid(FPU_REG *dest);
asmlinkage int divide_by_zero(int sign, FPU_REG *dest);
diff --git a/arch/i386/math-emu/get_address.c b/arch/i386/math-emu/get_address.c
index 6f3270ae3..0749cdc70 100644
--- a/arch/i386/math-emu/get_address.c
+++ b/arch/i386/math-emu/get_address.c
@@ -21,7 +21,7 @@
#include <linux/stddef.h>
#include <linux/head.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include "fpu_system.h"
#include "exception.h"
@@ -56,12 +56,16 @@ static int reg_offset_vm86[] = {
#define VM86_REG_(x) (*(unsigned short *) \
(reg_offset_vm86[((unsigned)x)]+(char *) FPU_info))
+/* These are dummy, fs and gs are not saved on the stack. */
+#define ___FS ___ds
+#define ___GS ___ds
+
static int reg_offset_pm[] = {
offsetof(struct info,___cs),
offsetof(struct info,___ds),
offsetof(struct info,___es),
- offsetof(struct info,___fs),
- offsetof(struct info,___gs),
+ offsetof(struct info,___FS),
+ offsetof(struct info,___GS),
offsetof(struct info,___ss),
offsetof(struct info,___ds)
};
@@ -78,7 +82,7 @@ static int sib(int mod, unsigned long *fpu_eip)
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- base = get_fs_byte((char *) (*fpu_eip)); /* The SIB byte */
+ get_user(base, (unsigned char *) (*fpu_eip)); /* The SIB byte */
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
ss = base >> 6;
@@ -105,18 +109,22 @@ static int sib(int mod, unsigned long *fpu_eip)
if (mod == 1)
{
/* 8 bit signed displacement */
+ long displacement;
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- offset += (signed char) get_fs_byte((char *) (*fpu_eip));
+ get_user(displacement, (signed char *) (*fpu_eip));
+ offset += displacement;
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
}
else if (mod == 2 || base == 5) /* The second condition also has mod==0 */
{
/* 32 bit displacement */
+ long displacement;
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- offset += (signed) get_fs_long((unsigned long *) (*fpu_eip));
+ get_user(displacement, (signed long *) (*fpu_eip));
+ offset += displacement;
RE_ENTRANT_CHECK_ON;
(*fpu_eip) += 4;
}
@@ -149,7 +157,9 @@ static long pm_address(unsigned char FPU_modrm, unsigned char segment,
unsigned long base_address, limit, address, seg_top;
segment--;
+
#ifdef PARANOID
+ /* segment is unsigned, so this also detects if segment was 0: */
if ( segment > PREFIX_SS_ )
{
EXCEPTION(EX_INTERNAL|0x132);
@@ -157,7 +167,19 @@ static long pm_address(unsigned char FPU_modrm, unsigned char segment,
}
#endif PARANOID
- *selector = PM_REG_(segment);
+ switch ( 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));
+ break;
+ case PREFIX_GS_-1:
+ __asm__("mov %%gs,%0":"=r" (*selector));
+ break;
+ default:
+ *selector = PM_REG_(segment);
+ }
descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
base_address = SEG_BASE_ADDR(descriptor);
@@ -248,7 +270,7 @@ void *get_address(unsigned char FPU_modrm, unsigned long *fpu_eip,
/* Special case: disp32 */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- address = get_fs_long((unsigned long *) (*fpu_eip));
+ get_user(address, (unsigned long *) (*fpu_eip));
(*fpu_eip) += 4;
RE_ENTRANT_CHECK_ON;
addr->offset = address;
@@ -265,7 +287,7 @@ void *get_address(unsigned char FPU_modrm, unsigned long *fpu_eip,
/* 8 bit signed displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- address = (signed char) get_fs_byte((char *) (*fpu_eip));
+ get_user(address, (signed char *) (*fpu_eip));
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
break;
@@ -273,7 +295,7 @@ void *get_address(unsigned char FPU_modrm, unsigned long *fpu_eip,
/* 32 bit displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- address = (signed) get_fs_long((unsigned long *) (*fpu_eip));
+ get_user(address, (long *) (*fpu_eip));
(*fpu_eip) += 4;
RE_ENTRANT_CHECK_ON;
break;
@@ -336,7 +358,7 @@ void *get_address_16(unsigned char FPU_modrm, unsigned long *fpu_eip,
/* Special case: disp16 */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(2);
- address = (unsigned short)get_fs_word((unsigned short *) (*fpu_eip));
+ get_user(address, (unsigned short *) (*fpu_eip));
(*fpu_eip) += 2;
RE_ENTRANT_CHECK_ON;
goto add_segment;
@@ -346,7 +368,7 @@ void *get_address_16(unsigned char FPU_modrm, unsigned long *fpu_eip,
/* 8 bit signed displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- address = (signed char) get_fs_byte((signed char *) (*fpu_eip));
+ get_user(address, (signed char *) (*fpu_eip));
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
break;
@@ -354,7 +376,7 @@ void *get_address_16(unsigned char FPU_modrm, unsigned long *fpu_eip,
/* 16 bit displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(2);
- address = (unsigned) get_fs_word((unsigned short *) (*fpu_eip));
+ get_user(address, (unsigned short *) (*fpu_eip));
(*fpu_eip) += 2;
RE_ENTRANT_CHECK_ON;
break;
diff --git a/arch/i386/math-emu/load_store.c b/arch/i386/math-emu/load_store.c
index 6f0e167d6..cc288a9ab 100644
--- a/arch/i386/math-emu/load_store.c
+++ b/arch/i386/math-emu/load_store.c
@@ -18,7 +18,7 @@
| other processes using the emulator while swapping is in progress. |
+---------------------------------------------------------------------------*/
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include "fpu_system.h"
#include "exception.h"
@@ -201,7 +201,7 @@ int load_store_instr(unsigned char type, fpu_addr_modes addr_modes,
case 024: /* fldcw */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, data_address, 2);
- control_word = get_fs_word((unsigned short *) data_address);
+ get_user(control_word, (unsigned short *) data_address);
RE_ENTRANT_CHECK_ON;
if ( partial_status & ~control_word & CW_Exceptions )
partial_status |= (SW_Summary | SW_Backward);
@@ -234,7 +234,7 @@ int load_store_instr(unsigned char type, fpu_addr_modes addr_modes,
case 034: /* fstcw m16int */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,data_address,2);
- put_fs_word(control_word, (short *) data_address);
+ put_user(control_word, (unsigned short *) data_address);
RE_ENTRANT_CHECK_ON;
return 1;
case 035: /* fstp m80real */
@@ -246,7 +246,7 @@ int load_store_instr(unsigned char type, fpu_addr_modes addr_modes,
case 036: /* fstsw m2byte */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,data_address,2);
- put_fs_word(status_word(),(short *) data_address);
+ put_user(status_word(),(unsigned short *) data_address);
RE_ENTRANT_CHECK_ON;
return 1;
case 037: /* fistp m64int */
diff --git a/arch/i386/math-emu/mul_Xsig.S b/arch/i386/math-emu/mul_Xsig.S
index 1d88d4466..717785a53 100644
--- a/arch/i386/math-emu/mul_Xsig.S
+++ b/arch/i386/math-emu/mul_Xsig.S
@@ -3,9 +3,9 @@
| |
| Multiply a 12 byte fixed point number by another fixed point number. |
| |
- | Copyright (C) 1992,1994 |
+ | Copyright (C) 1992,1994,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Call from C as: |
| void mul32_Xsig(Xsig *x, unsigned b) |
@@ -21,12 +21,10 @@
.file "mul_Xsig.S"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
.text
- .align 2,144
-.globl _mul32_Xsig
-_mul32_Xsig:
+ENTRY(mul32_Xsig)
pushl %ebp
movl %esp,%ebp
subl $16,%esp
@@ -66,9 +64,7 @@ _mul32_Xsig:
ret
- .align 2,144
-.globl _mul64_Xsig
-_mul64_Xsig:
+ENTRY(mul64_Xsig)
pushl %ebp
movl %esp,%ebp
subl $16,%esp
@@ -121,9 +117,7 @@ _mul64_Xsig:
- .align 2,144
-.globl _mul_Xsig_Xsig
-_mul_Xsig_Xsig:
+ENTRY(mul_Xsig_Xsig)
pushl %ebp
movl %esp,%ebp
subl $16,%esp
diff --git a/arch/i386/math-emu/polynom_Xsig.S b/arch/i386/math-emu/polynom_Xsig.S
index 585221f96..17315c89f 100644
--- a/arch/i386/math-emu/polynom_Xsig.S
+++ b/arch/i386/math-emu/polynom_Xsig.S
@@ -3,9 +3,9 @@
| |
| Fixed point arithmetic polynomial evaluation. |
| |
- | Copyright (C) 1992,1993,1994 |
+ | Copyright (C) 1992,1993,1994,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Call from C as: |
| void polynomial_Xsig(Xsig *accum, unsigned long long x, |
@@ -23,7 +23,7 @@
+---------------------------------------------------------------------------*/
.file "polynomial_Xsig.S"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
#define TERM_SIZE $8
@@ -36,9 +36,7 @@
#define OVERFLOWED -16(%ebp) /* addition overflow flag */
.text
- .align 2,144
-.globl _polynomial_Xsig
-_polynomial_Xsig:
+ENTRY(polynomial_Xsig)
pushl %ebp
movl %esp,%ebp
subl $32,%esp
diff --git a/arch/i386/math-emu/reg_constant.c b/arch/i386/math-emu/reg_constant.c
index c1981ce24..1b2458eea 100644
--- a/arch/i386/math-emu/reg_constant.c
+++ b/arch/i386/math-emu/reg_constant.c
@@ -3,9 +3,9 @@
| |
| All of the constant FPU_REGs |
| |
- | Copyright (C) 1992,1993,1994 |
- | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1993,1994,1996 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -14,6 +14,7 @@
#include "fpu_emu.h"
#include "status_w.h"
#include "reg_constant.h"
+#include "control_w.h"
FPU_REG const CONST_1 = { SIGN_POS, TW_Valid, EXP_BIAS,
@@ -56,7 +57,7 @@ FPU_REG const CONST_INF = { SIGN_POS, TW_Infinity, EXP_OVER, 0x00000000, 0x8000
-static void fld_const(FPU_REG const *c)
+static void fld_const(FPU_REG const *c, int adj)
{
FPU_REG *st_new_ptr;
@@ -67,50 +68,58 @@ static void fld_const(FPU_REG const *c)
}
push();
reg_move(c, st_new_ptr);
+ st_new_ptr->sigl += adj; /* For all our fldxxx constants, we don't need to
+ borrow or carry. */
clear_C1();
}
+/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP
+ (and not one of RC_RND or RC_UP).
+ */
+#define DOWN_OR_CHOP(x) (x & RC_DOWN)
-static void fld1(void)
+static void fld1(int rc)
{
- fld_const(&CONST_1);
+ fld_const(&CONST_1, 0);
}
-static void fldl2t(void)
+static void fldl2t(int rc)
{
- fld_const(&CONST_L2T);
+ fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0);
}
-static void fldl2e(void)
+static void fldl2e(int rc)
{
- fld_const(&CONST_L2E);
+ fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0);
}
-static void fldpi(void)
+static void fldpi(int rc)
{
- fld_const(&CONST_PI);
+ fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0);
}
-static void fldlg2(void)
+static void fldlg2(int rc)
{
- fld_const(&CONST_LG2);
+ fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0);
}
-static void fldln2(void)
+static void fldln2(int rc)
{
- fld_const(&CONST_LN2);
+ fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0);
}
-static void fldz(void)
+static void fldz(int rc)
{
- fld_const(&CONST_Z);
+ fld_const(&CONST_Z, 0);
}
-static FUNC constants_table[] = {
- fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, FPU_illegal
+typedef void (*FUNC_RC)(int);
+
+static FUNC_RC constants_table[] = {
+ fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC)FPU_illegal
};
void fconst(void)
{
- (constants_table[FPU_rm])();
+ (constants_table[FPU_rm])(control_word & CW_RC);
}
diff --git a/arch/i386/math-emu/reg_div.S b/arch/i386/math-emu/reg_div.S
index 2fbc5f7c4..24d44ac6c 100644
--- a/arch/i386/math-emu/reg_div.S
+++ b/arch/i386/math-emu/reg_div.S
@@ -4,9 +4,9 @@
| |
| Divide one FPU_REG by another and put the result in a destination FPU_REG.|
| |
- | Copyright (C) 1992,1993,1994 |
+ | Copyright (C) 1992,1993,1994,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Call from C as: |
| void reg_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest, |
@@ -15,14 +15,11 @@
+---------------------------------------------------------------------------*/
#include "exception.h"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
.text
- .align 2
-
-.globl _reg_div
-_reg_div:
+ENTRY(reg_div)
pushl %ebp
movl %esp,%ebp
#ifndef NON_REENTRANT_FPU
@@ -47,7 +44,7 @@ _reg_div:
cmpl EXP_UNDER,EXP(%esi)
jg xL_arg1_not_denormal
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
@@ -55,7 +52,7 @@ xL_arg1_not_denormal:
cmpl EXP_UNDER,EXP(%ebx)
jg xL_arg2_not_denormal
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
@@ -75,7 +72,7 @@ xL_arg2_not_denormal:
addl EXP_BIAS,%edx
movl %edx,EXP(%edi)
- jmp _divide_kernel
+ jmp SYMBOL_NAME(divide_kernel)
/*-----------------------------------------------------------------------*/
@@ -92,14 +89,14 @@ L_arg2_NaN:
pushl %edi /* Destination */
pushl %esi
pushl %ebx /* Ordering is important here */
- call _real_2op_NaN
+ call SYMBOL_NAME(real_2op_NaN)
jmp LDiv_exit
/* Invalid operations */
L_zero_zero:
L_inf_inf:
pushl %edi /* Destination */
- call _arith_invalid /* 0/0 or Infinity/Infinity */
+ call SYMBOL_NAME(arith_invalid) /* 0/0 or Infinity/Infinity */
jmp LDiv_exit
L_no_NaN_arg:
@@ -126,7 +123,7 @@ L_inf_valid:
cmpl EXP_UNDER,EXP(%ebx)
jg L_copy_arg1 /* Answer is Inf */
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
#endif DENORM_OPERAND
@@ -151,7 +148,7 @@ L_arg1_not_inf:
movb SIGN(%esi),%al
xorb SIGN(%ebx),%al
pushl %eax /* lower 8 bits have the sign */
- call _divide_by_zero
+ call SYMBOL_NAME(divide_by_zero)
jmp LDiv_exit
L_arg2_not_zero:
@@ -165,7 +162,7 @@ L_arg2_not_zero:
cmpl EXP_UNDER,EXP(%esi)
jg L_return_zero /* Answer is zero */
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
#endif DENORM_OPERAND
@@ -185,7 +182,7 @@ L_arg2_not_inf:
cmpl EXP_UNDER,EXP(%ebx)
jg L_copy_arg1 /* Answer is zero */
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
#endif DENORM_OPERAND
@@ -241,11 +238,11 @@ L_unknown_tags:
call EXCEPTION
/* Generate a NaN for unknown tags */
- movl _CONST_QNaN,%eax
+ movl SYMBOL_NAME(CONST_QNaN),%eax
movl %eax,(%edi)
- movl _CONST_QNaN+4,%eax
+ movl SYMBOL_NAME(CONST_QNaN)+4,%eax
movl %eax,SIGL(%edi)
- movl _CONST_QNaN+8,%eax
+ movl SYMBOL_NAME(CONST_QNaN)+8,%eax
movl %eax,SIGH(%edi)
jmp LDiv_exit /* %eax is nz */
#endif PARANOID
diff --git a/arch/i386/math-emu/reg_ld_str.c b/arch/i386/math-emu/reg_ld_str.c
index efec9e010..3e258a0c6 100644
--- a/arch/i386/math-emu/reg_ld_str.c
+++ b/arch/i386/math-emu/reg_ld_str.c
@@ -3,9 +3,9 @@
| |
| All of the functions which transfer data between user memory and FPU_REGs.|
| |
- | Copyright (C) 1992,1993,1994 |
- | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1993,1994,1996 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@jacobi.maths.monash.edu.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -17,7 +17,7 @@
| other processes using the emulator while swapping is in progress. |
+---------------------------------------------------------------------------*/
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include "fpu_system.h"
#include "exception.h"
@@ -48,9 +48,9 @@ int reg_load_extended(long double *s, FPU_REG *loaded_data)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 10);
- sigl = get_fs_long((unsigned long *) s);
- sigh = get_fs_long(1 + (unsigned long *) s);
- exp = get_fs_word(4 + (unsigned short *) s);
+ get_user(sigl, (unsigned long *) s);
+ get_user(sigh, 1 + (unsigned long *) s);
+ get_user(exp, 4 + (unsigned short *) s);
RE_ENTRANT_CHECK_ON;
loaded_data->tag = TW_Valid; /* Default */
@@ -144,8 +144,8 @@ int reg_load_double(double *dfloat, FPU_REG *loaded_data)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, dfloat, 8);
- m64 = get_fs_long(1 + (unsigned long *) dfloat);
- l64 = get_fs_long((unsigned long *) dfloat);
+ get_user(m64, 1 + (unsigned long *) dfloat);
+ get_user(l64, (unsigned long *) dfloat);
RE_ENTRANT_CHECK_ON;
if (m64 & 0x80000000)
@@ -221,7 +221,7 @@ int reg_load_single(float *single, FPU_REG *loaded_data)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, single, 4);
- m32 = get_fs_long((unsigned long *) single);
+ get_user(m32, (unsigned long *) single);
RE_ENTRANT_CHECK_ON;
if (m32 & 0x80000000)
@@ -289,8 +289,7 @@ void reg_load_int64(long long *_s, FPU_REG *loaded_data)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, _s, 8);
- ((unsigned long *)&s)[0] = get_fs_long((unsigned long *) _s);
- ((unsigned long *)&s)[1] = get_fs_long(1 + (unsigned long *) _s);
+ copy_from_user(&s,_s,8);
RE_ENTRANT_CHECK_ON;
if (s == 0)
@@ -320,7 +319,7 @@ void reg_load_int32(long *_s, FPU_REG *loaded_data)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, _s, 4);
- s = (long)get_fs_long((unsigned long *) _s);
+ get_user(s, _s);
RE_ENTRANT_CHECK_ON;
if (s == 0)
@@ -351,7 +350,7 @@ void reg_load_int16(short *_s, FPU_REG *loaded_data)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, _s, 2);
/* Cast as short to get the sign extended. */
- s = (short)get_fs_word((unsigned short *) _s);
+ get_user(s, _s);
RE_ENTRANT_CHECK_ON;
if (s == 0)
@@ -389,7 +388,7 @@ void reg_load_bcd(char *s, FPU_REG *loaded_data)
{
l *= 10;
RE_ENTRANT_CHECK_OFF;
- bcd = (unsigned char)get_fs_byte((unsigned char *) s+pos);
+ get_user(bcd, (unsigned char *) s+pos);
RE_ENTRANT_CHECK_ON;
l += bcd >> 4;
l *= 10;
@@ -397,9 +396,11 @@ void reg_load_bcd(char *s, FPU_REG *loaded_data)
}
RE_ENTRANT_CHECK_OFF;
- loaded_data->sign =
- ((unsigned char)get_fs_byte((unsigned char *) s+9)) & 0x80 ?
- SIGN_NEG : SIGN_POS;
+ {
+ unsigned char sign;
+ get_user(sign, (unsigned char *) s+9);
+ loaded_data->sign = (sign & 0x80) ? SIGN_NEG : SIGN_POS;
+ }
RE_ENTRANT_CHECK_ON;
if (l == 0)
@@ -445,9 +446,9 @@ int reg_store_extended(long double *d, FPU_REG *st0_ptr)
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,10);
- put_fs_long(0, (unsigned long *) d);
- put_fs_long(0xc0000000, 1 + (unsigned long *) d);
- put_fs_word(0xffff, 4 + (short *) d);
+ put_user(0, (unsigned long *) d);
+ put_user(0xc0000000, 1 + (unsigned long *) d);
+ put_user(0xffff, 4 + (short *) d);
RE_ENTRANT_CHECK_ON;
return 1;
}
@@ -466,6 +467,7 @@ int reg_store_double(double *dfloat, FPU_REG *st0_ptr)
if (st0_tag == TW_Valid)
{
+ int precision_loss;
int exp;
FPU_REG tmp;
@@ -474,8 +476,6 @@ int reg_store_double(double *dfloat, FPU_REG *st0_ptr)
if ( exp < DOUBLE_Emin ) /* It may be a denormal */
{
- int precision_loss;
-
/* A denormal will always underflow. */
#ifndef PECULIAR_486
/* An 80486 is supposed to be able to generate
@@ -518,6 +518,7 @@ int reg_store_double(double *dfloat, FPU_REG *st0_ptr)
{
if ( tmp.sigl & 0x000007ff )
{
+ precision_loss = 1;
switch (control_word & CW_RC)
{
case RC_RND:
@@ -541,8 +542,6 @@ int reg_store_double(double *dfloat, FPU_REG *st0_ptr)
if ( increment )
{
- set_precision_flag_up();
-
if ( tmp.sigl >= 0xfffff800 )
{
/* the sigl part overflows */
@@ -566,9 +565,9 @@ int reg_store_double(double *dfloat, FPU_REG *st0_ptr)
tmp.sigl += 0x00000800;
}
}
- else
- set_precision_flag_down();
}
+ else
+ precision_loss = 0;
l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
l[1] = ((tmp.sigh >> 11) & 0xfffff);
@@ -590,6 +589,13 @@ int reg_store_double(double *dfloat, FPU_REG *st0_ptr)
}
else
{
+ if ( precision_loss )
+ {
+ if ( increment )
+ set_precision_flag_up();
+ else
+ set_precision_flag_down();
+ }
/* Add the exponent */
l[1] |= (((exp+DOUBLE_Ebias) & 0x7ff) << 20);
}
@@ -631,8 +637,8 @@ int reg_store_double(double *dfloat, FPU_REG *st0_ptr)
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
- put_fs_long(0, (unsigned long *) dfloat);
- put_fs_long(0xfff80000, 1 + (unsigned long *) dfloat);
+ put_user(0, (unsigned long *) dfloat);
+ put_user(0xfff80000, 1 + (unsigned long *) dfloat);
RE_ENTRANT_CHECK_ON;
return 1;
}
@@ -644,8 +650,8 @@ int reg_store_double(double *dfloat, FPU_REG *st0_ptr)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
- put_fs_long(l[0], (unsigned long *)dfloat);
- put_fs_long(l[1], 1 + (unsigned long *)dfloat);
+ put_user(l[0], (unsigned long *)dfloat);
+ put_user(l[1], 1 + (unsigned long *)dfloat);
RE_ENTRANT_CHECK_ON;
return 1;
@@ -661,6 +667,7 @@ int reg_store_single(float *single, FPU_REG *st0_ptr)
if (st0_tag == TW_Valid)
{
+ int precision_loss;
int exp;
FPU_REG tmp;
@@ -669,8 +676,6 @@ int reg_store_single(float *single, FPU_REG *st0_ptr)
if ( exp < SINGLE_Emin )
{
- int precision_loss;
-
/* A denormal will always underflow. */
#ifndef PECULIAR_486
/* An 80486 is supposed to be able to generate
@@ -715,6 +720,7 @@ int reg_store_single(float *single, FPU_REG *st0_ptr)
unsigned long sigh = tmp.sigh;
unsigned long sigl = tmp.sigl;
+ precision_loss = 1;
switch (control_word & CW_RC)
{
case RC_RND:
@@ -740,8 +746,6 @@ int reg_store_single(float *single, FPU_REG *st0_ptr)
if (increment)
{
- set_precision_flag_up();
-
if ( sigh >= 0xffffff00 )
{
/* The sigh part overflows */
@@ -758,10 +762,11 @@ int reg_store_single(float *single, FPU_REG *st0_ptr)
}
else
{
- set_precision_flag_down();
tmp.sigh &= 0xffffff00; /* Finish the truncation */
}
}
+ else
+ precision_loss = 0;
templ = (tmp.sigh >> 8) & 0x007fffff;
@@ -780,7 +785,17 @@ int reg_store_single(float *single, FPU_REG *st0_ptr)
templ = 0x7f800000;
}
else
- templ |= ((exp+SINGLE_Ebias) & 0xff) << 23;
+ {
+ if ( precision_loss )
+ {
+ if ( increment )
+ set_precision_flag_up();
+ else
+ set_precision_flag_down();
+ }
+ /* Add the exponent */
+ templ |= ((exp+SINGLE_Ebias) & 0xff) << 23;
+ }
}
}
else if (st0_tag == TW_Zero)
@@ -815,7 +830,7 @@ int reg_store_single(float *single, FPU_REG *st0_ptr)
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,(void *)single,4);
- put_fs_long(0xffc00000, (unsigned long *) single);
+ put_user(0xffc00000, (unsigned long *) single);
RE_ENTRANT_CHECK_ON;
return 1;
}
@@ -834,7 +849,7 @@ int reg_store_single(float *single, FPU_REG *st0_ptr)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,(void *)single,4);
- put_fs_long(templ,(unsigned long *) single);
+ put_user(templ,(unsigned long *) single);
RE_ENTRANT_CHECK_ON;
return 1;
@@ -892,8 +907,7 @@ int reg_store_int64(long long *d, FPU_REG *st0_ptr)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,(void *)d,8);
- put_fs_long(((long *)&tll)[0],(unsigned long *) d);
- put_fs_long(((long *)&tll)[1],1 + (unsigned long *) d);
+ copy_to_user(d, &tll, 8);
RE_ENTRANT_CHECK_ON;
return 1;
@@ -947,7 +961,7 @@ int reg_store_int32(long *d, FPU_REG *st0_ptr)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,4);
- put_fs_long(t.sigl, (unsigned long *) d);
+ put_user(t.sigl, (unsigned long *) d);
RE_ENTRANT_CHECK_ON;
return 1;
@@ -1001,7 +1015,7 @@ int reg_store_int16(short *d, FPU_REG *st0_ptr)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,2);
- put_fs_word((short)t.sigl,(short *) d);
+ put_user((short)t.sigl,(short *) d);
RE_ENTRANT_CHECK_ON;
return 1;
@@ -1042,10 +1056,10 @@ int reg_store_bcd(char *d, FPU_REG *st0_ptr)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,10);
for ( i = 0; i < 7; i++)
- put_fs_byte(0, (unsigned char *) d+i); /* These bytes "undefined" */
- put_fs_byte(0xc0, (unsigned char *) d+7); /* This byte "undefined" */
- put_fs_byte(0xff, (unsigned char *) d+8);
- put_fs_byte(0xff, (unsigned char *) d+9);
+ put_user(0, (unsigned char *) d+i); /* These bytes "undefined" */
+ put_user(0xc0, (unsigned char *) d+7); /* This byte "undefined" */
+ put_user(0xff, (unsigned char *) d+8);
+ put_user(0xff, (unsigned char *) d+9);
RE_ENTRANT_CHECK_ON;
return 1;
}
@@ -1066,11 +1080,11 @@ int reg_store_bcd(char *d, FPU_REG *st0_ptr)
b = div_small(&ll, 10);
b |= (div_small(&ll, 10)) << 4;
RE_ENTRANT_CHECK_OFF;
- put_fs_byte(b,(unsigned char *) d+i);
+ put_user(b,(unsigned char *) d+i);
RE_ENTRANT_CHECK_ON;
}
RE_ENTRANT_CHECK_OFF;
- put_fs_byte(sign,(unsigned char *) d+9);
+ put_user(sign,(unsigned char *) d+9);
RE_ENTRANT_CHECK_ON;
return 1;
@@ -1158,13 +1172,13 @@ char *fldenv(fpu_addr_modes addr_modes, char *s)
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 0x0e);
- control_word = get_fs_word((unsigned short *) s);
- partial_status = get_fs_word((unsigned short *) (s+2));
- tag_word = get_fs_word((unsigned short *) (s+4));
- instruction_address.offset = get_fs_word((unsigned short *) (s+6));
- instruction_address.selector = get_fs_word((unsigned short *) (s+8));
- operand_address.offset = get_fs_word((unsigned short *) (s+0x0a));
- operand_address.selector = get_fs_word((unsigned short *) (s+0x0c));
+ get_user(control_word, (unsigned short *) s);
+ get_user(partial_status, (unsigned short *) (s+2));
+ get_user(tag_word, (unsigned short *) (s+4));
+ get_user(instruction_address.offset, (unsigned short *) (s+6));
+ get_user(instruction_address.selector, (unsigned short *) (s+8));
+ get_user(operand_address.offset, (unsigned short *) (s+0x0a));
+ get_user(operand_address.selector, (unsigned short *) (s+0x0c));
RE_ENTRANT_CHECK_ON;
s += 0x0e;
if ( addr_modes.default_mode == VM86 )
@@ -1178,14 +1192,14 @@ char *fldenv(fpu_addr_modes addr_modes, char *s)
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 0x1c);
- control_word = get_fs_word((unsigned short *) s);
- partial_status = get_fs_word((unsigned short *) (s+4));
- tag_word = get_fs_word((unsigned short *) (s+8));
- instruction_address.offset = get_fs_long((unsigned long *) (s+0x0c));
- instruction_address.selector = get_fs_word((unsigned short *) (s+0x10));
- instruction_address.opcode = get_fs_word((unsigned short *) (s+0x12));
- operand_address.offset = get_fs_long((unsigned long *) (s+0x14));
- operand_address.selector = get_fs_long((unsigned long *) (s+0x18));
+ get_user(control_word, (unsigned short *) s);
+ get_user(partial_status, (unsigned short *) (s+4));
+ get_user(tag_word, (unsigned short *) (s+8));
+ get_user(instruction_address.offset, (unsigned long *) (s+0x0c));
+ get_user(instruction_address.selector, (unsigned short *) (s+0x10));
+ get_user(instruction_address.opcode, (unsigned short *) (s+0x12));
+ get_user(operand_address.offset, (unsigned long *) (s+0x14));
+ get_user(operand_address.selector, (unsigned long *) (s+0x18));
RE_ENTRANT_CHECK_ON;
s += 0x1c;
}
@@ -1296,25 +1310,25 @@ char *fstenv(fpu_addr_modes addr_modes, char *d)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,14);
#ifdef PECULIAR_486
- put_fs_long(control_word & ~0xe080, (unsigned short *) d);
+ put_user(control_word & ~0xe080, (unsigned long *) d);
#else
- put_fs_word(control_word, (unsigned short *) d);
+ put_user(control_word, (unsigned short *) d);
#endif PECULIAR_486
- put_fs_word(status_word(), (unsigned short *) (d+2));
- put_fs_word(tag_word(), (unsigned short *) (d+4));
- put_fs_word(instruction_address.offset, (unsigned short *) (d+6));
- put_fs_word(operand_address.offset, (unsigned short *) (d+0x0a));
+ put_user(status_word(), (unsigned short *) (d+2));
+ put_user(tag_word(), (unsigned short *) (d+4));
+ put_user(instruction_address.offset, (unsigned short *) (d+6));
+ put_user(operand_address.offset, (unsigned short *) (d+0x0a));
if ( addr_modes.default_mode == VM86 )
{
- put_fs_word((instruction_address.offset & 0xf0000) >> 4,
+ put_user((instruction_address.offset & 0xf0000) >> 4,
(unsigned short *) (d+8));
- put_fs_word((operand_address.offset & 0xf0000) >> 4,
+ put_user((operand_address.offset & 0xf0000) >> 4,
(unsigned short *) (d+0x0c));
}
else
{
- put_fs_word(instruction_address.selector, (unsigned short *) (d+8));
- put_fs_word(operand_address.selector, (unsigned short *) (d+0x0c));
+ put_user(instruction_address.selector, (unsigned short *) (d+8));
+ put_user(operand_address.selector, (unsigned short *) (d+0x0c));
}
RE_ENTRANT_CHECK_ON;
d += 0x0e;
@@ -1325,24 +1339,24 @@ char *fstenv(fpu_addr_modes addr_modes, char *d)
FPU_verify_area(VERIFY_WRITE,d,28);
#ifdef PECULIAR_486
/* An 80486 sets all the reserved bits to 1. */
- put_fs_long(0xffff0040 | (control_word & ~0xe080), (unsigned long *) d);
- put_fs_long(0xffff0000 | status_word(), (unsigned long *) (d+4));
- put_fs_long(0xffff0000 | tag_word(), (unsigned long *) (d+8));
+ put_user(0xffff0040 | (control_word & ~0xe080), (unsigned long *) d);
+ put_user(0xffff0000 | status_word(), (unsigned long *) (d+4));
+ put_user(0xffff0000 | tag_word(), (unsigned long *) (d+8));
#else
- put_fs_word(control_word, (unsigned short *) d);
- put_fs_word(status_word(), (unsigned short *) (d+4));
- put_fs_word(tag_word(), (unsigned short *) (d+8));
+ put_user(control_word, (unsigned short *) d);
+ put_user(status_word(), (unsigned short *) (d+4));
+ put_user(tag_word(), (unsigned short *) (d+8));
#endif PECULIAR_486
- put_fs_long(instruction_address.offset, (unsigned long *) (d+0x0c));
- put_fs_word(instruction_address.selector, (unsigned short *) (d+0x10));
- put_fs_word(instruction_address.opcode, (unsigned short *) (d+0x12));
- put_fs_long(operand_address.offset, (unsigned long *) (d+0x14));
+ put_user(instruction_address.offset, (unsigned long *) (d+0x0c));
+ put_user(instruction_address.selector, (unsigned short *) (d+0x10));
+ put_user(instruction_address.opcode, (unsigned short *) (d+0x12));
+ put_user(operand_address.offset, (unsigned long *) (d+0x14));
#ifdef PECULIAR_486
/* An 80486 sets all the reserved bits to 1. */
- put_fs_word(operand_address.selector, (unsigned short *) (d+0x18));
- put_fs_word(0xffff, (unsigned short *) (d+0x1a));
+ put_user(operand_address.selector, (unsigned short *) (d+0x18));
+ put_user(0xffff, (unsigned short *) (d+0x1a));
#else
- put_fs_long(operand_address.selector, (unsigned long *) (d+0x18));
+ put_user(operand_address.selector, (unsigned long *) (d+0x18));
#endif PECULIAR_486
RE_ENTRANT_CHECK_ON;
d += 0x1c;
@@ -1411,8 +1425,8 @@ static void write_to_extended(FPU_REG *rp, char *d)
{
/* just copy the reg */
RE_ENTRANT_CHECK_OFF;
- put_fs_long(rp->sigl, (unsigned long *) d);
- put_fs_long(rp->sigh, (unsigned long *) (d + 4));
+ put_user(rp->sigl, (unsigned long *) d);
+ put_user(rp->sigh, (unsigned long *) (d + 4));
RE_ENTRANT_CHECK_ON;
}
else
@@ -1427,12 +1441,12 @@ static void write_to_extended(FPU_REG *rp, char *d)
round_to_int(&tmp);
e = 0;
RE_ENTRANT_CHECK_OFF;
- put_fs_long(tmp.sigl, (unsigned long *) d);
- put_fs_long(tmp.sigh, (unsigned long *) (d + 4));
+ put_user(tmp.sigl, (unsigned long *) d);
+ put_user(tmp.sigh, (unsigned long *) (d + 4));
RE_ENTRANT_CHECK_ON;
}
e |= rp->sign == SIGN_POS ? 0 : 0x8000;
RE_ENTRANT_CHECK_OFF;
- put_fs_word(e, (unsigned short *) (d + 8));
+ put_user(e, (unsigned short *) (d + 8));
RE_ENTRANT_CHECK_ON;
}
diff --git a/arch/i386/math-emu/reg_norm.S b/arch/i386/math-emu/reg_norm.S
index 9b7a9d77d..781a2d466 100644
--- a/arch/i386/math-emu/reg_norm.S
+++ b/arch/i386/math-emu/reg_norm.S
@@ -1,9 +1,9 @@
/*---------------------------------------------------------------------------+
| reg_norm.S |
| |
- | Copyright (C) 1992,1993,1994 |
+ | Copyright (C) 1992,1993,1994,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Normalize the value in a FPU_REG. |
| |
@@ -14,15 +14,11 @@
| |
+---------------------------------------------------------------------------*/
-#include "fpu_asm.h"
+#include "fpu_emu.h"
.text
-
- .align 2,144
-.globl _normalize
-
-_normalize:
+ENTRY(normalize)
pushl %ebp
movl %esp,%ebp
pushl %ebx
@@ -34,7 +30,7 @@ _normalize:
je L_ok
pushl $0x220
- call _exception
+ call SYMBOL_NAME(FPU_exception)
addl $4,%esp
L_ok:
@@ -86,23 +82,20 @@ L_zero:
L_underflow:
push %ebx
- call _arith_underflow
+ call SYMBOL_NAME(arith_underflow)
pop %ebx
jmp L_exit
L_overflow:
push %ebx
- call _arith_overflow
+ call SYMBOL_NAME(arith_overflow)
pop %ebx
jmp L_exit
/* Normalise without reporting underflow or overflow */
- .align 2,144
-.globl _normalize_nuo
-
-_normalize_nuo:
+ENTRY(normalize_nuo)
pushl %ebp
movl %esp,%ebp
pushl %ebx
@@ -114,7 +107,7 @@ _normalize_nuo:
je L_ok_nuo
pushl $0x221
- call _exception
+ call SYMBOL_NAME(FPU_exception)
addl $4,%esp
L_ok_nuo:
diff --git a/arch/i386/math-emu/reg_round.S b/arch/i386/math-emu/reg_round.S
index bd8a40dc4..4aac507a1 100644
--- a/arch/i386/math-emu/reg_round.S
+++ b/arch/i386/math-emu/reg_round.S
@@ -4,9 +4,9 @@
| |
| Rounding/truncation/etc for FPU basic arithmetic functions. |
| |
- | Copyright (C) 1993 |
+ | Copyright (C) 1993,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| This code has four possible entry points. |
| The following must be entered by a jmp instruction: |
@@ -69,7 +69,7 @@
+---------------------------------------------------------------------------*/
-#include "fpu_asm.h"
+#include "fpu_emu.h"
#include "exception.h"
#include "control_w.h"
@@ -101,14 +101,12 @@ FPU_denormal:
.text
- .align 2,144
.globl fpu_reg_round
.globl fpu_reg_round_sqrt
.globl fpu_Arith_exit
-.globl _round_reg
/* Entry point when called from C */
-_round_reg:
+ENTRY(round_reg)
pushl %ebp
movl %esp,%ebp
pushl %esi
@@ -435,7 +433,7 @@ fpu_Arith_exit:
*/
xL_precision_lost_up:
push %eax
- call _set_precision_flag_up
+ call SYMBOL_NAME(set_precision_flag_up)
popl %eax
jmp xL_no_precision_loss
@@ -445,7 +443,7 @@ xL_precision_lost_up:
*/
xL_precision_lost_down:
push %eax
- call _set_precision_flag_down
+ call SYMBOL_NAME(set_precision_flag_down)
popl %eax
jmp xL_no_precision_loss
@@ -598,7 +596,7 @@ LNormalise_shift_done:
/* There must be a masked underflow */
push %eax
pushl EX_Underflow
- call _exception
+ call SYMBOL_NAME(FPU_exception)
popl %eax
popl %eax
jmp xL_Normalised
@@ -610,12 +608,12 @@ LNormalise_shift_done:
*/
L_underflow_to_zero:
push %eax
- call _set_precision_flag_down
+ call SYMBOL_NAME(set_precision_flag_down)
popl %eax
push %eax
pushl EX_Underflow
- call _exception
+ call SYMBOL_NAME(FPU_exception)
popl %eax
popl %eax
@@ -628,7 +626,7 @@ L_underflow_to_zero:
/* The operations resulted in a number too large to represent. */
L_overflow:
push %edi
- call _arith_overflow
+ call SYMBOL_NAME(arith_overflow)
pop %edi
jmp fpu_reg_round_exit
diff --git a/arch/i386/math-emu/reg_u_add.S b/arch/i386/math-emu/reg_u_add.S
index 4410f8fd4..1dc0d41df 100644
--- a/arch/i386/math-emu/reg_u_add.S
+++ b/arch/i386/math-emu/reg_u_add.S
@@ -5,9 +5,9 @@
| Add two valid (TW_Valid) FPU_REG numbers, of the same sign, and put the |
| result in a destination FPU_REG. |
| |
- | Copyright (C) 1992,1993 |
+ | Copyright (C) 1992,1993,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Call from C as: |
| void reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ, |
@@ -25,13 +25,11 @@
*/
#include "exception.h"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
#include "control_w.h"
.text
- .align 2,144
-.globl _reg_u_add
-_reg_u_add:
+ENTRY(reg_u_add)
pushl %ebp
movl %esp,%ebp
pushl %esi
@@ -45,7 +43,7 @@ _reg_u_add:
cmpl EXP_UNDER,EXP(%esi)
jg xOp1_not_denorm
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
@@ -53,7 +51,7 @@ xOp1_not_denorm:
cmpl EXP_UNDER,EXP(%edi)
jg xOp2_not_denorm
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
diff --git a/arch/i386/math-emu/reg_u_div.S b/arch/i386/math-emu/reg_u_div.S
index 328e9116e..5bba98dd8 100644
--- a/arch/i386/math-emu/reg_u_div.S
+++ b/arch/i386/math-emu/reg_u_div.S
@@ -4,9 +4,9 @@
| |
| Core division routines |
| |
- | Copyright (C) 1992,1993 |
+ | Copyright (C) 1992,1993,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -21,7 +21,7 @@
+---------------------------------------------------------------------------*/
#include "exception.h"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
#include "control_w.h"
@@ -69,13 +69,7 @@ FPU_ovfl_flag:
.text
- .align 2,144
-
-.globl _reg_u_div
-
-.globl _divide_kernel
-
-_reg_u_div:
+ENTRY(reg_u_div)
pushl %ebp
movl %esp,%ebp
#ifndef NON_REENTRANT_FPU
@@ -95,7 +89,7 @@ _reg_u_div:
cmpl EXP_UNDER,%eax
jg xOp1_not_denorm
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
@@ -104,14 +98,14 @@ xOp1_not_denorm:
cmpl EXP_UNDER,%eax
jg xOp2_not_denorm
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
xOp2_not_denorm:
#endif DENORM_OPERAND
-_divide_kernel:
+ENTRY(divide_kernel)
#ifdef PARANOID
/* testl $0x80000000, SIGH(%esi) // Dividend */
/* je L_bugged */
diff --git a/arch/i386/math-emu/reg_u_mul.S b/arch/i386/math-emu/reg_u_mul.S
index 8250666bd..682fbec15 100644
--- a/arch/i386/math-emu/reg_u_mul.S
+++ b/arch/i386/math-emu/reg_u_mul.S
@@ -4,9 +4,9 @@
| |
| Core multiplication routine |
| |
- | Copyright (C) 1992,1993 |
+ | Copyright (C) 1992,1993,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -22,7 +22,7 @@
+---------------------------------------------------------------------------*/
#include "exception.h"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
#include "control_w.h"
@@ -44,10 +44,7 @@ FPU_accum_1:
.text
- .align 2,144
-
-.globl _reg_u_mul
-_reg_u_mul:
+ENTRY(reg_u_mul)
pushl %ebp
movl %esp,%ebp
#ifndef NON_REENTRANT_FPU
@@ -73,7 +70,7 @@ _reg_u_mul:
cmpl EXP_UNDER,%eax
jg xOp1_not_denorm
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
@@ -82,7 +79,7 @@ xOp1_not_denorm:
cmpl EXP_UNDER,%eax
jg xOp2_not_denorm
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
diff --git a/arch/i386/math-emu/reg_u_sub.S b/arch/i386/math-emu/reg_u_sub.S
index fbec17dfb..891670260 100644
--- a/arch/i386/math-emu/reg_u_sub.S
+++ b/arch/i386/math-emu/reg_u_sub.S
@@ -4,9 +4,9 @@
| |
| Core floating point subtraction routine. |
| |
- | Copyright (C) 1992,1993 |
+ | Copyright (C) 1992,1993,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Call from C as: |
| void reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ, |
@@ -26,13 +26,11 @@
*/
#include "exception.h"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
#include "control_w.h"
.text
- .align 2,144
-.globl _reg_u_sub
-_reg_u_sub:
+ENTRY(reg_u_sub)
pushl %ebp
movl %esp,%ebp
pushl %esi
@@ -46,7 +44,7 @@ _reg_u_sub:
cmpl EXP_UNDER,EXP(%esi)
jg xOp1_not_denorm
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
@@ -54,7 +52,7 @@ xOp1_not_denorm:
cmpl EXP_UNDER,EXP(%edi)
jg xOp2_not_denorm
- call _denormal_operand
+ call SYMBOL_NAME(denormal_operand)
orl %eax,%eax
jnz fpu_Arith_exit
diff --git a/arch/i386/math-emu/round_Xsig.S b/arch/i386/math-emu/round_Xsig.S
index 163755878..bbe0e8771 100644
--- a/arch/i386/math-emu/round_Xsig.S
+++ b/arch/i386/math-emu/round_Xsig.S
@@ -1,9 +1,9 @@
/*---------------------------------------------------------------------------+
| round_Xsig.S |
| |
- | Copyright (C) 1992,1993,1994 |
+ | Copyright (C) 1992,1993,1994,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Normalize and round a 12 byte quantity. |
| Call from C as: |
@@ -18,15 +18,11 @@
+---------------------------------------------------------------------------*/
.file "round_Xsig.S"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
.text
-
- .align 2,144
-.globl _round_Xsig
-
-_round_Xsig:
+ENTRY(round_Xsig)
pushl %ebp
movl %esp,%ebp
pushl %ebx /* Reserve some space */
@@ -86,10 +82,7 @@ L_exit:
- .align 2,144
-.globl _norm_Xsig
-
-_norm_Xsig:
+ENTRY(norm_Xsig)
pushl %ebp
movl %esp,%ebp
pushl %ebx /* Reserve some space */
diff --git a/arch/i386/math-emu/shr_Xsig.S b/arch/i386/math-emu/shr_Xsig.S
index d6724a204..31cdd118e 100644
--- a/arch/i386/math-emu/shr_Xsig.S
+++ b/arch/i386/math-emu/shr_Xsig.S
@@ -4,9 +4,9 @@
| |
| 12 byte right shift function |
| |
- | Copyright (C) 1992,1994 |
+ | Copyright (C) 1992,1994,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Call from C as: |
| void shr_Xsig(Xsig *arg, unsigned nr) |
@@ -18,13 +18,10 @@
| |
+---------------------------------------------------------------------------*/
-#include "fpu_asm.h"
+#include "fpu_emu.h"
.text
- .align 2,144
-
- .globl _shr_Xsig
-_shr_Xsig:
+ENTRY(shr_Xsig)
push %ebp
movl %esp,%ebp
pushl %esi
diff --git a/arch/i386/math-emu/status_w.h b/arch/i386/math-emu/status_w.h
index 96607d0e1..57d1ae6bb 100644
--- a/arch/i386/math-emu/status_w.h
+++ b/arch/i386/math-emu/status_w.h
@@ -12,7 +12,7 @@
#include "fpu_emu.h" /* for definition of PECULIAR_486 */
-#ifdef __ASSEMBLER__
+#ifdef __ASSEMBLY__
#define Const__(x) $##x
#else
#define Const__(x) x
@@ -36,7 +36,7 @@
#define SW_Exc_Mask Const__(0x27f) /* Status word exception bit mask */
-#ifndef __ASSEMBLER__
+#ifndef __ASSEMBLY__
#define COMP_A_gt_B 1
#define COMP_A_eq_B 2
@@ -60,6 +60,6 @@
# define clear_C1()
#endif PECULIAR_486
-#endif __ASSEMBLER__
+#endif __ASSEMBLY__
#endif _STATUS_H_
diff --git a/arch/i386/math-emu/version.h b/arch/i386/math-emu/version.h
index 4c75a4792..d966ab193 100644
--- a/arch/i386/math-emu/version.h
+++ b/arch/i386/math-emu/version.h
@@ -2,11 +2,11 @@
| version.h |
| |
| |
- | Copyright (C) 1992,1993,1994 |
- | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1993,1994,1996 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@jacobi.maths.monash.edu.au |
| |
| |
+---------------------------------------------------------------------------*/
-#define FPU_VERSION "wm-FPU-emu version 1.20"
+#define FPU_VERSION "wm-FPU-emu version 1.22"
diff --git a/arch/i386/math-emu/wm_shrx.S b/arch/i386/math-emu/wm_shrx.S
index bef0e1963..1ea7ff7da 100644
--- a/arch/i386/math-emu/wm_shrx.S
+++ b/arch/i386/math-emu/wm_shrx.S
@@ -4,8 +4,9 @@
| |
| 64 bit right shift functions |
| |
- | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Call from C as: |
| unsigned shrx(void *arg1, unsigned arg2) |
@@ -14,11 +15,9 @@
| |
+---------------------------------------------------------------------------*/
-#include "fpu_asm.h"
+#include "fpu_emu.h"
.text
- .align 2,144
-
/*---------------------------------------------------------------------------+
| unsigned shrx(void *arg1, unsigned arg2) |
| |
@@ -33,9 +32,7 @@
| Results returned in the 64 bit arg and eax. |
+---------------------------------------------------------------------------*/
- .globl _shrx
-
-_shrx:
+ENTRY(shrx)
push %ebp
movl %esp,%ebp
pushl %esi
@@ -113,8 +110,7 @@ L_more_than_95:
| part which has been shifted out of the arg. |
| Results returned in the 64 bit arg and eax. |
+---------------------------------------------------------------------------*/
- .globl _shrxs
-_shrxs:
+ENTRY(shrxs)
push %ebp
movl %esp,%ebp
pushl %esi
diff --git a/arch/i386/math-emu/wm_sqrt.S b/arch/i386/math-emu/wm_sqrt.S
index 4e028cb80..848796188 100644
--- a/arch/i386/math-emu/wm_sqrt.S
+++ b/arch/i386/math-emu/wm_sqrt.S
@@ -4,9 +4,9 @@
| |
| Fixed point arithmetic square root evaluation. |
| |
- | Copyright (C) 1992,1993 |
+ | Copyright (C) 1992,1993,1995 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
| |
| Call from C as: |
| void wm_sqrt(FPU_REG *n, unsigned int control_word) |
@@ -26,7 +26,7 @@
+---------------------------------------------------------------------------*/
#include "exception.h"
-#include "fpu_asm.h"
+#include "fpu_emu.h"
#ifndef NON_REENTRANT_FPU
@@ -74,10 +74,7 @@ FPU_fsqrt_arg_0:
.text
- .align 2,144
-
-.globl _wm_sqrt
-_wm_sqrt:
+ENTRY(wm_sqrt)
pushl %ebp
movl %esp,%ebp
#ifndef NON_REENTRANT_FPU