diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2003-07-28 19:59:19 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2003-07-28 19:59:19 +0000 |
commit | 689230dab7a5984514a4070c740f06884cc3d96a (patch) | |
tree | 026acc0e3db6fe72774a1d87fcc76d2891614697 /sys/arch/i386 | |
parent | 68ed9b1964d6347d1059cd69a7f5dee36e1451b9 (diff) |
remove the non-licensed i386 math emulation stuff. This only leaves the
gnu stuff as an option until it is replaced RSN. ok deraadt.
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/conf/files.i386 | 3 | ||||
-rw-r--r-- | sys/arch/i386/i386/math_emu.h | 157 | ||||
-rw-r--r-- | sys/arch/i386/i386/math_emulate.c | 1447 | ||||
-rw-r--r-- | sys/arch/i386/i386/trap.c | 6 |
4 files changed, 4 insertions, 1609 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 0d7002baf43..7bf56879892 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $OpenBSD: files.i386,v 1.105 2003/06/24 22:45:33 espie Exp $ +# $OpenBSD: files.i386,v 1.106 2003/07/28 19:59:18 jason Exp $ # $NetBSD: files.i386,v 1.73 1996/05/07 00:58:36 thorpej Exp $ # # new style config file for i386 architecture @@ -25,7 +25,6 @@ file arch/i386/i386/ipx_cksum.c ipx file arch/i386/i386/machdep.c file arch/i386/i386/kgdb_machdep.c kgdb file arch/i386/i386/longrun.c !small_kernel -file arch/i386/i386/math_emulate.c math_emulate file arch/i386/i386/mem.c file arch/i386/i386/i686_mem.c mtrr file arch/i386/i386/k6_mem.c mtrr diff --git a/sys/arch/i386/i386/math_emu.h b/sys/arch/i386/i386/math_emu.h deleted file mode 100644 index a1798df34f3..00000000000 --- a/sys/arch/i386/i386/math_emu.h +++ /dev/null @@ -1,157 +0,0 @@ -/* $OpenBSD: math_emu.h,v 1.2 2001/07/04 08:57:47 niklas Exp $ */ -/* $NetBSD: math_emu.h,v 1.5 1995/05/03 00:17:16 mycroft Exp $ */ - -/* - * linux/include/linux/math_emu.h - * - * (C) 1991 Linus Torvalds - */ -#ifndef _LINUX_MATH_EMU_H -#define _LINUX_MATH_EMU_H - -/*#define math_abort(x,y) \ -(((volatile void (*)(struct info *,unsigned int)) __math_abort)((x),(y)))*/ - -/* - * Gcc forces this stupid alignment problem: I want to use only two longs - * for the temporary real 64-bit mantissa, but then gcc aligns out the - * structure to 12 bytes which breaks things in math_emulate.c. Shit. I - * want some kind of "no-alignt" pragma or something. - */ - -typedef struct { - long a,b; - short exponent; -} temp_real; - -typedef struct { - short m0,m1,m2,m3; - short exponent; -} temp_real_unaligned; - -#define real_to_real(a,b) \ -((*(long long *) (b) = *(long long *) (a)),((b)->exponent = (a)->exponent)) - -typedef struct { - long a,b; -} long_real; - -typedef long short_real; - -typedef struct { - long a,b; - short sign; -} temp_int; - -struct swd { - int ie:1; - int de:1; - int ze:1; - int oe:1; - int ue:1; - int pe:1; - int sf:1; - int ir:1; - int c0:1; - int c1:1; - int c2:1; - int top:3; - int c3:1; - int b:1; -}; -struct i387_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ -}; - -#define I387 (*(struct i387_struct *)&(curpcb->pcb_savefpu)) -#define SWD (*(struct swd *) &I387.swd) -#define ROUNDING ((I387.cwd >> 10) & 3) -#define PRECISION ((I387.cwd >> 8) & 3) - -#define BITS24 0 -#define BITS53 2 -#define BITS64 3 - -#define ROUND_NEAREST 0 -#define ROUND_DOWN 1 -#define ROUND_UP 2 -#define ROUND_0 3 - -#define CONSTZ (temp_real_unaligned) {0x0000,0x0000,0x0000,0x0000,0x0000} -#define CONST1 (temp_real_unaligned) {0x0000,0x0000,0x0000,0x8000,0x3FFF} -#define CONSTPI (temp_real_unaligned) {0xC235,0x2168,0xDAA2,0xC90F,0x4000} -#define CONSTLN2 (temp_real_unaligned) {0x79AC,0xD1CF,0x17F7,0xB172,0x3FFE} -#define CONSTLG2 (temp_real_unaligned) {0xF799,0xFBCF,0x9A84,0x9A20,0x3FFD} -#define CONSTL2E (temp_real_unaligned) {0xF0BC,0x5C17,0x3B29,0xB8AA,0x3FFF} -#define CONSTL2T (temp_real_unaligned) {0x8AFE,0xCD1B,0x784B,0xD49A,0x4000} - -#define set_IE() (I387.swd |= 1) -#define set_DE() (I387.swd |= 2) -#define set_ZE() (I387.swd |= 4) -#define set_OE() (I387.swd |= 8) -#define set_UE() (I387.swd |= 16) -#define set_PE() (I387.swd |= 32) - -#define set_C0() (I387.swd |= 0x0100) -#define set_C1() (I387.swd |= 0x0200) -#define set_C2() (I387.swd |= 0x0400) -#define set_C3() (I387.swd |= 0x4000) - -/* ea.c */ - -char * ea(struct trapframe *, unsigned short); - -/* convert.c */ - -void frndint(const temp_real * __a, temp_real * __b); -void Fscale(const temp_real *, const temp_real *, temp_real *); -void short_to_temp(const short_real * __a, temp_real * __b); -void long_to_temp(const long_real * __a, temp_real * __b); -void temp_to_short(const temp_real * __a, short_real * __b); -void temp_to_long(const temp_real * __a, long_real * __b); -void real_to_int(const temp_real * __a, temp_int * __b); -void int_to_real(const temp_int * __a, temp_real * __b); - -/* get_put.c */ - -void get_short_real(temp_real *, struct trapframe *, unsigned short); -void get_long_real(temp_real *, struct trapframe *, unsigned short); -void get_temp_real(temp_real *, struct trapframe *, unsigned short); -void get_short_int(temp_real *, struct trapframe *, unsigned short); -void get_long_int(temp_real *, struct trapframe *, unsigned short); -void get_longlong_int(temp_real *, struct trapframe *, unsigned short); -void get_BCD(temp_real *, struct trapframe *, unsigned short); -void put_short_real(const temp_real *, struct trapframe *, unsigned short); -void put_long_real(const temp_real *, struct trapframe *, unsigned short); -void put_temp_real(const temp_real *, struct trapframe *, unsigned short); -void put_short_int(const temp_real *, struct trapframe *, unsigned short); -void put_long_int(const temp_real *, struct trapframe *, unsigned short); -void put_longlong_int(const temp_real *, struct trapframe *, unsigned short); -void put_BCD(const temp_real *, struct trapframe *, unsigned short); - -/* add.c */ - -void fadd(const temp_real *, const temp_real *, temp_real *); - -/* mul.c */ - -void fmul(const temp_real *, const temp_real *, temp_real *); - -/* div.c */ - -void fdiv(const temp_real *, const temp_real *, temp_real *); - -/* compare.c */ - -void fcom(const temp_real *, const temp_real *); -void fucom(const temp_real *, const temp_real *); -void ftst(const temp_real *); - -#endif diff --git a/sys/arch/i386/i386/math_emulate.c b/sys/arch/i386/i386/math_emulate.c deleted file mode 100644 index a60b7958015..00000000000 --- a/sys/arch/i386/i386/math_emulate.c +++ /dev/null @@ -1,1447 +0,0 @@ -/* $OpenBSD: math_emulate.c,v 1.6 2003/01/09 22:27:09 miod Exp $ */ -/* $NetBSD: math_emulate.c,v 1.17 1996/05/03 19:42:17 christos Exp $ */ - -/* - * expediant "port" of linux 8087 emulator to 386BSD, with apologies -wfj - */ - -/* - * linux/kernel/math/math_emulate.c - * - * (C) 1991 Linus Torvalds - */ - -/* - * Limited emulation 27.12.91 - mostly loads/stores, which gcc wants - * even for soft-float, unless you use bruce evans' patches. The patches - * are great, but they have to be re-applied for every version, and the - * library is different for soft-float and 80387. So emulation is more - * practical, even though it's slower. - * - * 28.12.91 - loads/stores work, even BCD. I'll have to start thinking - * about add/sub/mul/div. Urgel. I should find some good source, but I'll - * just fake up something. - * - * 30.12.91 - add/sub/mul/div/com seem to work mostly. I should really - * test every possible combination. - */ - -/* - * This file is full of ugly macros etc: one problem was that gcc simply - * didn't want to make the structures as they should be: it has to try to - * align them. Sickening code, but at least I've hidden the ugly things - * in this one file: the other files don't need to know about these things. - * - * The other files also don't care about ST(x) etc - they just get addresses - * to 80-bit temporary reals, and do with them as they please. I wanted to - * hide most of the 387-specific things here. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/user.h> -#include <sys/acct.h> -#include <sys/kernel.h> -#include <sys/signal.h> - -#include <machine/cpu.h> -#include <machine/reg.h> - -#define __ALIGNED_TEMP_REAL 1 -#include <i386/i386/math_emu.h> - -#define ST(x) (*__st((x))) -#define PST(x) ((const temp_real *) __st((x))) -#define math_abort(tfp, signo) tfp->tf_eip = oldeip; return (signo); - -/* - * We don't want these inlined - it gets too messy in the machine-code. - */ -static void fpop(void); -static void fpush(void); -static void fxchg(temp_real_unaligned * a, temp_real_unaligned * b); -static temp_real_unaligned * __st(int i); - -#define fninit() do { \ - I387.cwd = __INITIAL_NPXCW__; \ - I387.swd = 0x0000; \ - I387.twd = 0x0000; \ -} while (0) - -int -math_emulate(info) - struct trapframe *info; -{ - u_short code; - temp_real tmp; - char * address; - u_long oldeip; - - if (!USERMODE(info->tf_cs, info->tf_eflags)) - panic("math emulator called from supervisor mode"); - - /* ever used fp? */ - if ((curproc->p_md.md_flags & MDP_USEDFPU) == 0) { - curproc->p_md.md_flags |= MDP_USEDFPU; - fninit(); - } - - if (I387.cwd & I387.swd & 0x3f) - I387.swd |= 0x8000; - else - I387.swd &= 0x7fff; - - I387.fip = oldeip = info->tf_eip; - info->tf_eip += 2; - if (copyin((u_short *)oldeip, &code, sizeof(u_short)) != 0) - math_abort(info,SIGSEGV); - code = htons(code) & 0x7ff; - *((u_short *) &I387.fcs) = (u_short) info->tf_cs; - *((u_short *) &I387.fcs + 1) = code; - - switch (code) { - case 0x1d0: /* fnop */ - return(0); - case 0x1e0: /* fchs */ - ST(0).exponent ^= 0x8000; - return(0); - case 0x1e1: /* fabs */ - ST(0).exponent &= 0x7fff; - return(0); - case 0x1e4: /* fxtract XXX */ - ftst(PST(0)); - return(0); - case 0x1e8: /* fld1 */ - fpush(); - ST(0) = CONST1; - return(0); - case 0x1e9: /* fld2t */ - fpush(); - ST(0) = CONSTL2T; - return(0); - case 0x1ea: /* fld2e */ - fpush(); - ST(0) = CONSTL2E; - return(0); - case 0x1eb: /* fldpi */ - fpush(); - ST(0) = CONSTPI; - return(0); - case 0x1ec: /* fldlg2 */ - fpush(); - ST(0) = CONSTLG2; - return(0); - case 0x1ed: /* fldln2 */ - fpush(); - ST(0) = CONSTLN2; - return(0); - case 0x1ee: /* fldz */ - fpush(); - ST(0) = CONSTZ; - return(0); - case 0x1fc: /* frndint */ - frndint(PST(0),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 0x1fd: /* fscale */ - /* incomplete and totally inadequate -wfj */ - Fscale(PST(0), PST(1), &tmp); - real_to_real(&tmp,&ST(0)); - return(0); /* 19 Sep 92*/ - case 0x2e9: /* XXX */ - fucom(PST(1),PST(0)); - fpop(); fpop(); - return(0); - case 0x3d0: case 0x3d1: /* XXX */ - return(0); - case 0x3e2: /* fclex */ - I387.swd &= 0x7f00; - return(0); - case 0x3e3: /* fninit */ - fninit(); - return(0); - case 0x3e4: /* XXX */ - return(0); - case 0x6d9: /* fcompp */ - fcom(PST(1),PST(0)); - fpop(); fpop(); - return(0); - case 0x7e0: /* fstsw ax */ - *(u_short *) &info->tf_eax = I387.swd; - return(0); - case 0x1d1: case 0x1d2: case 0x1d3: - case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7: - case 0x1e2: case 0x1e3: - case 0x1e6: case 0x1e7: - case 0x1ef: - math_abort(info,SIGILL); - case 0x1e5: - uprintf("math_emulate: fxam not implemented\n\r"); - math_abort(info,SIGILL); - case 0x1f0: case 0x1f1: case 0x1f2: case 0x1f3: - case 0x1f4: case 0x1f5: case 0x1f6: case 0x1f7: - case 0x1f8: case 0x1f9: case 0x1fa: case 0x1fb: - case 0x1fe: case 0x1ff: - uprintf("math_emulate: 0x%04x not implemented\n", - code + 0xd800); - math_abort(info,SIGILL); - } - switch (code >> 3) { - case 0x18: /* fadd */ - fadd(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 0x19: /* fmul */ - fmul(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 0x1a: /* fcom */ - fcom(PST(code & 7),PST(0)); - return(0); - case 0x1b: /* fcomp */ - fcom(PST(code & 7),PST(0)); - fpop(); - return(0); - case 0x1c: /* fsubr */ - real_to_real(&ST(code & 7),&tmp); - tmp.exponent ^= 0x8000; - fadd(PST(0),&tmp,&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 0x1d: /* fsub */ - ST(0).exponent ^= 0x8000; - fadd(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 0x1e: /* fdivr */ - fdiv(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 0x1f: /* fdiv */ - fdiv(PST(code & 7),PST(0),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 0x38: /* fld */ - fpush(); - ST(0) = ST((code & 7)+1); - return(0); - case 0x39: /* fxch */ - fxchg(&ST(0),&ST(code & 7)); - return(0); - case 0x3b: /* XXX */ - ST(code & 7) = ST(0); - fpop(); - return(0); - case 0x98: /* fadd */ - fadd(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(code & 7)); - return(0); - case 0x99: /* fmul */ - fmul(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(code & 7)); - return(0); - case 0x9a: /* XXX */ - fcom(PST(code & 7),PST(0)); - return(0); - case 0x9b: /* XXX */ - fcom(PST(code & 7),PST(0)); - fpop(); - return(0); - case 0x9c: /* fsubr */ - ST(code & 7).exponent ^= 0x8000; - fadd(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(code & 7)); - return(0); - case 0x9d: /* fsub */ - real_to_real(&ST(0),&tmp); - tmp.exponent ^= 0x8000; - fadd(PST(code & 7),&tmp,&tmp); - real_to_real(&tmp,&ST(code & 7)); - return(0); - case 0x9e: /* fdivr */ - fdiv(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(code & 7)); - return(0); - case 0x9f: /* fdiv */ - fdiv(PST(code & 7),PST(0),&tmp); - real_to_real(&tmp,&ST(code & 7)); - return(0); - case 0xb8: /* ffree */ - printf("ffree not implemented\n\r"); - math_abort(info,SIGILL); - case 0xb9: /* fstp XXX */ - fxchg(&ST(0),&ST(code & 7)); - return(0); - case 0xba: /* fst */ - ST(code & 7) = ST(0); - return(0); - case 0xbb: /* XXX */ - ST(code & 7) = ST(0); - fpop(); - return(0); - case 0xbc: /* fucom */ - fucom(PST(code & 7),PST(0)); - return(0); - case 0xbd: /* fucomp */ - fucom(PST(code & 7),PST(0)); - fpop(); - return(0); - case 0xd8: /* faddp */ - fadd(PST(code & 7),PST(0),&tmp); - real_to_real(&tmp,&ST(code & 7)); - fpop(); - return(0); - case 0xd9: /* fmulp */ - fmul(PST(code & 7),PST(0),&tmp); - real_to_real(&tmp,&ST(code & 7)); - fpop(); - return(0); - case 0xda: /* XXX */ - fcom(PST(code & 7),PST(0)); - fpop(); - return(0); - case 0xdc: /* fsubrp */ - ST(code & 7).exponent ^= 0x8000; - fadd(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(code & 7)); - fpop(); - return(0); - case 0xdd: /* fsubp */ - real_to_real(&ST(0),&tmp); - tmp.exponent ^= 0x8000; - fadd(PST(code & 7),&tmp,&tmp); - real_to_real(&tmp,&ST(code & 7)); - fpop(); - return(0); - case 0xde: /* fdivrp */ - fdiv(PST(0),PST(code & 7),&tmp); - real_to_real(&tmp,&ST(code & 7)); - fpop(); - return(0); - case 0xdf: /* fdivp */ - fdiv(PST(code & 7),PST(0),&tmp); - real_to_real(&tmp,&ST(code & 7)); - fpop(); - return(0); - case 0xf8: /* XXX */ - printf("ffree not implemented\n\r"); - math_abort(info,SIGILL); - fpop(); - return(0); - case 0xf9: /* XXX */ - fxchg(&ST(0),&ST(code & 7)); - return(0); - case 0xfa: /* XXX */ - case 0xfb: /* XXX */ - ST(code & 7) = ST(0); - fpop(); - return(0); - } - switch ((code>>3) & 0xe7) { - case 0x22: - put_short_real(PST(0),info,code); - return(0); - case 0x23: - put_short_real(PST(0),info,code); - fpop(); - return(0); - case 0x24: - address = ea(info,code); - if (copyin((u_long *) address, (u_long *) &I387, 28) != 0) - math_abort(info,SIGSEGV); - return(0); - case 0x25: - address = ea(info,code); - if (copyin((u_short *)address, &I387.cwd, sizeof(u_short)) != 0) - math_abort(info,SIGSEGV); - return(0); - case 0x26: - address = ea(info,code); - if (copyout((u_long *) &I387, (u_long *) address, 28) != 0) - math_abort(info,SIGSEGV); - return(0); - case 0x27: - address = ea(info,code); - if (copyout(&I387.cwd, address, sizeof(int16_t)) != 0) - math_abort(info,SIGSEGV); - return(0); - case 0x62: - put_long_int(PST(0),info,code); - return(0); - case 0x63: - put_long_int(PST(0),info,code); - fpop(); - return(0); - case 0x65: - fpush(); - get_temp_real(&tmp,info,code); - real_to_real(&tmp,&ST(0)); - return(0); - case 0x67: - put_temp_real(PST(0),info,code); - fpop(); - return(0); - case 0xa2: - put_long_real(PST(0),info,code); - return(0); - case 0xa3: - put_long_real(PST(0),info,code); - fpop(); - return(0); - case 0xa4: - address = ea(info,code); - if (copyin((u_long *) address, (u_long *) &I387, 108) != 0) - math_abort(info,SIGSEGV); - return(0); - case 0xa6: - address = ea(info,code); - if (copyout((u_long *) &I387, (u_long *) address, 108) != 0) - math_abort(info,SIGSEGV); - fninit(); - return(0); - case 0xa7: - address = ea(info,code); - if (copyout(&I387.swd, address, sizeof(int16_t)) != 0) - math_abort(info,SIGSEGV); - return(0); - case 0xe2: - put_short_int(PST(0),info,code); - return(0); - case 0xe3: - put_short_int(PST(0),info,code); - fpop(); - return(0); - case 0xe4: - fpush(); - get_BCD(&tmp,info,code); - real_to_real(&tmp,&ST(0)); - return(0); - case 0xe5: - fpush(); - get_longlong_int(&tmp,info,code); - real_to_real(&tmp,&ST(0)); - return(0); - case 0xe6: - put_BCD(PST(0),info,code); - fpop(); - return(0); - case 0xe7: - put_longlong_int(PST(0),info,code); - fpop(); - return(0); - } - switch (code >> 9) { - case 0: - get_short_real(&tmp,info,code); - break; - case 1: - get_long_int(&tmp,info,code); - break; - case 2: - get_long_real(&tmp,info,code); - break; - case 4: - get_short_int(&tmp,info,code); - } - switch ((code>>3) & 0x27) { - case 0: - fadd(&tmp,PST(0),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 1: - fmul(&tmp,PST(0),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 2: - fcom(&tmp,PST(0)); - return(0); - case 3: - fcom(&tmp,PST(0)); - fpop(); - return(0); - case 4: - tmp.exponent ^= 0x8000; - fadd(&tmp,PST(0),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 5: - ST(0).exponent ^= 0x8000; - fadd(&tmp,PST(0),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 6: - fdiv(PST(0),&tmp,&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - case 7: - fdiv(&tmp,PST(0),&tmp); - real_to_real(&tmp,&ST(0)); - return(0); - } - if ((code & 0x138) == 0x100) { - fpush(); - real_to_real(&tmp,&ST(0)); - return(0); - } - printf("Unknown math-insns: %04x:%08x %04x\n\r",(u_short)info->tf_cs, - info->tf_eip,code); - math_abort(info,SIGFPE); -} - -static void fpop(void) -{ - u_long tmp; - - tmp = I387.swd & 0xffffc7ff; - I387.swd += 0x00000800; - I387.swd &= 0x00003800; - I387.swd |= tmp; -} - -static void fpush(void) -{ - u_long tmp; - - tmp = I387.swd & 0xffffc7ff; - I387.swd -= 0x00000800; - I387.swd &= 0x00003800; - I387.swd |= tmp; -} - -static void fxchg(temp_real_unaligned * a, temp_real_unaligned * b) -{ - temp_real_unaligned c; - - c = *a; - *a = *b; - *b = c; -} - -static temp_real_unaligned * __st(int i) -{ - i += I387.swd >> 11; - i &= 7; - return (temp_real_unaligned *) (i*10 + (char *)(I387.st_space)); -} - -/* - * linux/kernel/math/ea.c - * - * (C) 1991 Linus Torvalds - */ - -/* - * Calculate the effective address. - */ - - -static int __regoffset[] = { - tEAX, tECX, tEDX, tEBX, tESP, tEBP, tESI, tEDI -}; - -#define REG(x) (((int *)curproc->p_md.md_regs)[__regoffset[(x)]]) - -static char * sib(struct trapframe * info, int mod) -{ - u_char ss, index, base; - long increment = 0, offset = 0; - - copyin(info->tf_eip++, &base, sizeof(u_char)) - ss = base >> 6; - index = (base >> 3) & 7; - base &= 7; - if (index == 4) - offset = 0; - else - offset = REG(index); - offset <<= ss; - if (mod || base != 5) - offset += REG(base); - if (mod == 1) { - copyin(info->tf_eip++, &increment, sizeof(u_char)); - offset += increment; - } else if (mod == 2 || base == 5) { - copyin(info->tf_eip, &increment, sizeof(u_long)); - offset += increment; - info->tf_eip += 4; - } - I387.foo = offset; - I387.fos = 0x17; - return (char *) offset; -} - -char * ea(struct trapframe * info, u_short code) -{ - u_char mod,rm; - long * tmp; - signed char tmp; - int offset = 0; - - mod = (code >> 6) & 3; - rm = code & 7; - if (rm == 4 && mod != 3) - return sib(info,mod); - if (rm == 5 && !mod) { - copyin(info->tf_eip, &offset, sizeof(u_long)); - info->tf_eip += 4; - I387.foo = offset; - I387.fos = 0x17; - return (char *) offset; - } - tmp = (long *)®(rm); - switch (mod) { - case 0: offset = 0; break; - case 1: - copyin(info->tf_eip++, &tmp, sizeof(char)); - offset = (signed char)tmp; - break; - case 2: - copyin(info->tf_eip, &offset, sizeof(u_long)); - info->tf_eip += 4; - break; -#ifdef notyet - case 3: - math_abort(info,SIGILL); -#endif - } - I387.foo = offset; - I387.fos = 0x17; - return offset + (char *) *tmp; -} -/* - * linux/kernel/math/get_put.c - * - * (C) 1991 Linus Torvalds - */ - -/* - * This file handles all accesses to user memory: getting and putting - * ints/reals/BCD etc. This is the only part that concerns itself with - * other than temporary real format. All other cals are strictly temp_real. - */ - -void get_short_real(temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - short_real sr; - - addr = ea(info,code); - copyin(addr, &sr, sizeof(u_long)); - short_to_temp(&sr,tmp); -} - -void get_long_real(temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - long_real lr; - - addr = ea(info,code); - copyin(addr, &lr.a, sizeof(u_long)); - copyin(addr + sizeof(u_long), &lr.b, sizeof(u_long)); - long_to_temp(&lr,tmp); -} - -void get_temp_real(temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - - addr = ea(info,code); - copyin(addr, &tmp->a, sizeof(u_long)); - copyin(addr + sizeof(u_long), &tmp->b, sizeof(u_long)); - copyin(addr + sizeof(u_long) * 2, &tmp->exponent, sizeof(u_short)); -} - -void get_short_int(temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - temp_int ti; - signed short tmp; - - addr = ea(info,code); - copyin(addr, &tmp, sizeof(signed short)); - ti.a = (signed short)tmp; - ti.b = 0; - if ((ti.sign = (ti.a < 0)) != 0) - ti.a = - ti.a; - int_to_real(&ti,tmp); -} - -void get_long_int(temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - temp_int ti; - - addr = ea(info,code); - copyin(addr, &ti.a, sizeof(u_long)); - ti.b = 0; - if ((ti.sign = (ti.a < 0)) != 0) - ti.a = - ti.a; - int_to_real(&ti,tmp); -} - -void get_longlong_int(temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - temp_int ti; - - addr = ea(info,code); - copyin(addr, &ti.a, sizeof(u_long)); - copyin(addr + sizeof(u_long), &ti.b, sizeof(u_long)); - if ((ti.sign = (ti.b < 0)) != 0) - __asm__("notl %0 ; notl %1\n\t" - "addl $1,%0 ; adcl $0,%1" - :"=r" (ti.a),"=r" (ti.b) - :"0" (ti.a),"1" (ti.b)); - int_to_real(&ti,tmp); -} - -#define MUL10(low,high) \ -__asm__("addl %0,%0 ; adcl %1,%1\n\t" \ -"movl %0,%%ecx ; movl %1,%%ebx\n\t" \ -"addl %0,%0 ; adcl %1,%1\n\t" \ -"addl %0,%0 ; adcl %1,%1\n\t" \ -"addl %%ecx,%0 ; adcl %%ebx,%1" \ -:"=a" (low),"=d" (high) \ -:"0" (low),"1" (high):"cx","bx") - -#define ADD64(val,low,high) \ -__asm__("addl %4,%0 ; adcl $0,%1":"=r" (low),"=r" (high) \ -:"0" (low),"1" (high),"r" ((u_long) (val))) - -void get_BCD(temp_real * tmp, struct trapframe * info, u_short code) -{ - int k; - char * addr; - temp_int i; - u_char c; - - addr = ea(info,code); - addr += 9; - copyin(addr--, &i.sign, sizeof(u_char)); - i.sign &= 0x80; - i.a = i.b = 0; - for (k = 0; k < 9; k++) { - copyin(addr--, &c, sizeof(u_char)); - MUL10(i.a, i.b); - ADD64((c>>4), i.a, i.b); - MUL10(i.a, i.b); - ADD64((c&0xf), i.a, i.b); - } - int_to_real(&i,tmp); -} - -void put_short_real(const temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - short_real sr; - - addr = ea(info,code); - temp_to_short(tmp,&sr); - copyout(&sr, addr, sizeof(int32_t)); -} - -void put_long_real(const temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - long_real lr; - - addr = ea(info,code); - temp_to_long(tmp,&lr); - copyout(&lr.a, (u_long *)addr, sizeof(int32_t)); - copyout(&lr.b, (u_long *)addr + 1, sizeof(int32_t)); -} - -void put_temp_real(const temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - - addr = ea(info,code); - copyout(&tmp->a, (u_long *)addr, sizeof(int32_t)); - copyout(&tmp->b, (u_long *)addr + 1, sizeof(int32_t)); - copyout(&tmp->exponent, (u_short *)addr + 4, sizeof(int16_t)); -} - -void put_short_int(const temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - temp_int ti; - - addr = ea(info,code); - real_to_int(tmp,&ti); - if (ti.sign) - ti.a = -ti.a; - copyout(&ti.a, addr, sizeof(int16_t)); -} - -void put_long_int(const temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - temp_int ti; - - addr = ea(info,code); - real_to_int(tmp,&ti); - if (ti.sign) - ti.a = -ti.a; - copyout(&ti.a, addr, sizeof(int32_t)); -} - -void put_longlong_int(const temp_real * tmp, - struct trapframe * info, u_short code) -{ - char * addr; - temp_int ti; - - addr = ea(info,code); - real_to_int(tmp,&ti); - if (ti.sign) - __asm__("notl %0 ; notl %1\n\t" - "addl $1,%0 ; adcl $0,%1" - :"=r" (ti.a),"=r" (ti.b) - :"0" (ti.a),"1" (ti.b)); - copyout(&ti.a, (u_long *)addr, sizeof(int32_t)); - copyout(&ti.b, (u_long *)addr + 1, sizeof(int32_t)); -} - -#define DIV10(low,high,rem) \ -__asm__("divl %6 ; xchgl %1,%2 ; divl %6" \ - :"=d" (rem),"=a" (low),"=r" (high) \ - :"0" (0),"1" (high),"2" (low),"c" (10)) - -void put_BCD(const temp_real * tmp,struct trapframe * info, u_short code) -{ - int k,rem; - char * addr; - temp_int i; - u_char c; - - addr = ea(info,code); - real_to_int(tmp,&i); - if (i.sign) - c = 0x80; - else - c = 0; - copyout(&c, addr + 9, sizeof(char)); - for (k = 0; k < 9; k++) { - DIV10(i.a,i.b,rem); - c = rem; - DIV10(i.a,i.b,rem); - c += rem<<4; - copyout(&c, addr++, sizeof(char)); - } -} - -/* - * linux/kernel/math/mul.c - * - * (C) 1991 Linus Torvalds - */ - -/* - * temporary real multiplication routine. - */ - - -static void shift(int * c) -{ - __asm__("movl (%0),%%eax ; addl %%eax,(%0)\n\t" - "movl 4(%0),%%eax ; adcl %%eax,4(%0)\n\t" - "movl 8(%0),%%eax ; adcl %%eax,8(%0)\n\t" - "movl 12(%0),%%eax ; adcl %%eax,12(%0)" - ::"r" ((long) c):"ax"); -} - -static void mul64(const temp_real * a, const temp_real * b, int * c) -{ - __asm__("movl (%0),%%eax\n\t" - "mull (%1)\n\t" - "movl %%eax,(%2)\n\t" - "movl %%edx,4(%2)\n\t" - "movl 4(%0),%%eax\n\t" - "mull 4(%1)\n\t" - "movl %%eax,8(%2)\n\t" - "movl %%edx,12(%2)\n\t" - "movl (%0),%%eax\n\t" - "mull 4(%1)\n\t" - "addl %%eax,4(%2)\n\t" - "adcl %%edx,8(%2)\n\t" - "adcl $0,12(%2)\n\t" - "movl 4(%0),%%eax\n\t" - "mull (%1)\n\t" - "addl %%eax,4(%2)\n\t" - "adcl %%edx,8(%2)\n\t" - "adcl $0,12(%2)" - ::"S" ((long) a),"c" ((long) b),"D" ((long) c) - :"ax","dx"); -} - -void fmul(const temp_real * src1, const temp_real * src2, temp_real * result) -{ - int i,sign; - int tmp[4] = {0,0,0,0}; - - sign = (src1->exponent ^ src2->exponent) & 0x8000; - i = (src1->exponent & 0x7fff) + (src2->exponent & 0x7fff) - 16383 + 1; - if (i<0) { - result->exponent = sign; - result->a = result->b = 0; - return; - } - if (i>0x7fff) { - set_OE(); - return; - } - mul64(src1,src2,tmp); - if (tmp[0] || tmp[1] || tmp[2] || tmp[3]) - while (i && tmp[3] >= 0) { - i--; - shift(tmp); - } - else - i = 0; - result->exponent = i | sign; - result->a = tmp[2]; - result->b = tmp[3]; -} - -/* - * linux/kernel/math/div.c - * - * (C) 1991 Linus Torvalds - */ - -/* - * temporary real division routine. - */ - -#include <i386/i386/math_emu.h> - -static void shift_left(int * c) -{ - __asm__ __volatile__("movl (%0),%%eax ; addl %%eax,(%0)\n\t" - "movl 4(%0),%%eax ; adcl %%eax,4(%0)\n\t" - "movl 8(%0),%%eax ; adcl %%eax,8(%0)\n\t" - "movl 12(%0),%%eax ; adcl %%eax,12(%0)" - ::"r" ((long) c):"ax"); -} - -static void shift_right(int * c) -{ - __asm__("shrl $1,12(%0) ; rcrl $1,8(%0) ; rcrl $1,4(%0) ; rcrl $1,(%0)" - ::"r" ((long) c)); -} - -static int try_sub(int * a, int * b) -{ - char ok; - - __asm__ __volatile__("movl (%1),%%eax ; subl %%eax,(%2)\n\t" - "movl 4(%1),%%eax ; sbbl %%eax,4(%2)\n\t" - "movl 8(%1),%%eax ; sbbl %%eax,8(%2)\n\t" - "movl 12(%1),%%eax ; sbbl %%eax,12(%2)\n\t" - "setae %%al":"=a" (ok):"c" ((long) a),"d" ((long) b)); - return ok; -} - -static void div64(int * a, int * b, int * c) -{ - int tmp[4]; - int i; - u_int mask = 0; - - c += 4; - for (i = 0 ; i<64 ; i++) { - if (!(mask >>= 1)) { - c--; - mask = 0x80000000; - } - tmp[0] = a[0]; tmp[1] = a[1]; - tmp[2] = a[2]; tmp[3] = a[3]; - if (try_sub(b,tmp)) { - *c |= mask; - a[0] = tmp[0]; a[1] = tmp[1]; - a[2] = tmp[2]; a[3] = tmp[3]; - } - shift_right(b); - } -} - -void fdiv(const temp_real * src1, const temp_real * src2, temp_real * result) -{ - int i,sign; - int a[4],b[4],tmp[4] = {0,0,0,0}; - - sign = (src1->exponent ^ src2->exponent) & 0x8000; - if (!(src2->a || src2->b)) { - set_ZE(); - return; - } - i = (src1->exponent & 0x7fff) - (src2->exponent & 0x7fff) + 16383; - if (i<0) { - set_UE(); - result->exponent = sign; - result->a = result->b = 0; - return; - } - a[0] = a[1] = 0; - a[2] = src1->a; - a[3] = src1->b; - b[0] = b[1] = 0; - b[2] = src2->a; - b[3] = src2->b; - while (b[3] >= 0) { - i++; - shift_left(b); - } - div64(a,b,tmp); - if (tmp[0] || tmp[1] || tmp[2] || tmp[3]) { - while (i && tmp[3] >= 0) { - i--; - shift_left(tmp); - } - if (tmp[3] >= 0) - set_DE(); - } else - i = 0; - if (i>0x7fff) { - set_OE(); - return; - } - if (tmp[0] || tmp[1]) - set_PE(); - result->exponent = i | sign; - result->a = tmp[2]; - result->b = tmp[3]; -} - -/* - * linux/kernel/math/add.c - * - * (C) 1991 Linus Torvalds - */ - -/* - * temporary real addition routine. - * - * NOTE! These aren't exact: they are only 62 bits wide, and don't do - * correct rounding. Fast hack. The reason is that we shift right the - * values by two, in order not to have overflow (1 bit), and to be able - * to move the sign into the mantissa (1 bit). Much simpler algorithms, - * and 62 bits (61 really - no rounding) accuracy is usually enough. The - * only time you should notice anything weird is when adding 64-bit - * integers together. When using doubles (52 bits accuracy), the - * 61-bit accuracy never shows at all. - */ - -#define NEGINT(a) \ -__asm__("notl %0 ; notl %1 ; addl $1,%0 ; adcl $0,%1" \ - :"=r" (a->a),"=r" (a->b) \ - :"0" (a->a),"1" (a->b)) - -static void signify(temp_real * a) -{ - a->exponent += 2; - __asm__("shrdl $2,%1,%0 ; shrl $2,%1" - :"=r" (a->a),"=r" (a->b) - :"0" (a->a),"1" (a->b)); - if (a->exponent < 0) - NEGINT(a); - a->exponent &= 0x7fff; -} - -static void unsignify(temp_real * a) -{ - if (!(a->a || a->b)) { - a->exponent = 0; - return; - } - a->exponent &= 0x7fff; - if (a->b < 0) { - NEGINT(a); - a->exponent |= 0x8000; - } - while (a->b >= 0) { - a->exponent--; - __asm__("addl %0,%0 ; adcl %1,%1" - :"=r" (a->a),"=r" (a->b) - :"0" (a->a),"1" (a->b)); - } -} - -void fadd(const temp_real * src1, const temp_real * src2, temp_real * result) -{ - temp_real a,b; - int x1,x2,shift; - - x1 = src1->exponent & 0x7fff; - x2 = src2->exponent & 0x7fff; - if (x1 > x2) { - a = *src1; - b = *src2; - shift = x1-x2; - } else { - a = *src2; - b = *src1; - shift = x2-x1; - } - if (shift >= 64) { - *result = a; - return; - } - if (shift >= 32) { - b.a = b.b; - b.b = 0; - shift -= 32; - } - __asm__("shrdl %4,%1,%0 ; shrl %4,%1" - :"=r" (b.a),"=r" (b.b) - :"0" (b.a),"1" (b.b),"c" ((char) shift)); - signify(&a); - signify(&b); - __asm__("addl %4,%0 ; adcl %5,%1" - :"=r" (a.a),"=r" (a.b) - :"0" (a.a),"1" (a.b),"g" (b.a),"g" (b.b)); - unsignify(&a); - *result = a; -} - -/* - * linux/kernel/math/compare.c - * - * (C) 1991 Linus Torvalds - */ - -/* - * temporary real comparison routines - */ - - -#define clear_Cx() (I387.swd &= ~0x4500) - -static void normalize(temp_real * a) -{ - int i = a->exponent & 0x7fff; - int sign = a->exponent & 0x8000; - - if (!(a->a || a->b)) { - a->exponent = 0; - return; - } - while (i && a->b >= 0) { - i--; - __asm__("addl %0,%0 ; adcl %1,%1" - :"=r" (a->a),"=r" (a->b) - :"0" (a->a),"1" (a->b)); - } - a->exponent = i | sign; -} - -void ftst(const temp_real * a) -{ - temp_real b; - - clear_Cx(); - b = *a; - normalize(&b); - if (b.a || b.b || b.exponent) { - if (b.exponent < 0) - set_C0(); - } else - set_C3(); -} - -void fcom(const temp_real * src1, const temp_real * src2) -{ - temp_real a; - - a = *src1; - a.exponent ^= 0x8000; - fadd(&a,src2,&a); - ftst(&a); -} - -void fucom(const temp_real * src1, const temp_real * src2) -{ - fcom(src1,src2); -} - -/* - * linux/kernel/math/convert.c - * - * (C) 1991 Linus Torvalds - */ - - -/* - * NOTE!!! There is some "non-obvious" optimisations in the temp_to_long - * and temp_to_short conversion routines: don't touch them if you don't - * know what's going on. They are the adding of one in the rounding: the - * overflow bit is also used for adding one into the exponent. Thus it - * looks like the overflow would be incorrectly handled, but due to the - * way the IEEE numbers work, things are correct. - * - * There is no checking for total overflow in the conversions, though (ie - * if the temp-real number simply won't fit in a short- or long-real.) - */ - -void short_to_temp(const short_real * a, temp_real * b) -{ - if (!(*a & 0x7fffffff)) { - b->a = b->b = 0; - if (*a) - b->exponent = 0x8000; - else - b->exponent = 0; - return; - } - b->exponent = ((*a>>23) & 0xff)-127+16383; - if (*a<0) - b->exponent |= 0x8000; - b->b = (*a<<8) | 0x80000000; - b->a = 0; -} - -void long_to_temp(const long_real * a, temp_real * b) -{ - if (!a->a && !(a->b & 0x7fffffff)) { - b->a = b->b = 0; - if (a->b) - b->exponent = 0x8000; - else - b->exponent = 0; - return; - } - b->exponent = ((a->b >> 20) & 0x7ff)-1023+16383; - if (a->b<0) - b->exponent |= 0x8000; - b->b = 0x80000000 | (a->b<<11) | (((u_long)a->a)>>21); - b->a = a->a<<11; -} - -void temp_to_short(const temp_real * a, short_real * b) -{ - if (!(a->exponent & 0x7fff)) { - *b = (a->exponent)?0x80000000:0; - return; - } - *b = ((((long) a->exponent)-16383+127) << 23) & 0x7f800000; - if (a->exponent < 0) - *b |= 0x80000000; - *b |= (a->b >> 8) & 0x007fffff; - switch (ROUNDING) { - case ROUND_NEAREST: - if ((a->b & 0xff) > 0x80) - ++*b; - break; - case ROUND_DOWN: - if ((a->exponent & 0x8000) && (a->b & 0xff)) - ++*b; - break; - case ROUND_UP: - if (!(a->exponent & 0x8000) && (a->b & 0xff)) - ++*b; - break; - } -} - -void temp_to_long(const temp_real * a, long_real * b) -{ - if (!(a->exponent & 0x7fff)) { - b->a = 0; - b->b = (a->exponent)?0x80000000:0; - return; - } - b->b = (((0x7fff & (long) a->exponent)-16383+1023) << 20) & 0x7ff00000; - if (a->exponent < 0) - b->b |= 0x80000000; - b->b |= (a->b >> 11) & 0x000fffff; - b->a = a->b << 21; - b->a |= (a->a >> 11) & 0x001fffff; - switch (ROUNDING) { - case ROUND_NEAREST: - if ((a->a & 0x7ff) > 0x400) - __asm__("addl $1,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - break; - case ROUND_DOWN: - if ((a->exponent & 0x8000) && (a->b & 0xff)) - __asm__("addl $1,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - break; - case ROUND_UP: - if (!(a->exponent & 0x8000) && (a->b & 0xff)) - __asm__("addl $1,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - break; - } -} - -void frndint(const temp_real * a, temp_real * b) -{ - int shift = 16383 + 63 - (a->exponent & 0x7fff); - u_long underflow; - - if ((shift < 0) || (shift == 16383+63)) { - *b = *a; - return; - } - b->a = b->b = underflow = 0; - b->exponent = a->exponent; - if (shift < 32) { - b->b = a->b; b->a = a->a; - } else if (shift < 64) { - b->a = a->b; underflow = a->a; - shift -= 32; - b->exponent += 32; - } else if (shift < 96) { - underflow = a->b; - shift -= 64; - b->exponent += 64; - } else { - underflow = 1; - shift = 0; - } - b->exponent += shift; - __asm__("shrdl %2,%1,%0" - :"=r" (underflow),"=r" (b->a) - :"c" ((char) shift),"0" (underflow),"1" (b->a)); - __asm__("shrdl %2,%1,%0" - :"=r" (b->a),"=r" (b->b) - :"c" ((char) shift),"0" (b->a),"1" (b->b)); - __asm__("shrl %1,%0" - :"=r" (b->b) - :"c" ((char) shift),"0" (b->b)); - switch (ROUNDING) { - case ROUND_NEAREST: - __asm__("addl %4,%5 ; adcl $0,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b) - ,"r" (0x7fffffff + (b->a & 1)) - ,"m" (*&underflow)); - break; - case ROUND_UP: - if ((b->exponent >= 0) && underflow) - __asm__("addl $1,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - break; - case ROUND_DOWN: - if ((b->exponent < 0) && underflow) - __asm__("addl $1,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - break; - } - if (b->a || b->b) - while (b->b >= 0) { - b->exponent--; - __asm__("addl %0,%0 ; adcl %1,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - } - else - b->exponent = 0; -} - -void Fscale(const temp_real *a, const temp_real *b, temp_real *c) -{ - temp_int ti; - - *c = *a; - if(!c->a && !c->b) { /* 19 Sep 92*/ - c->exponent = 0; - return; - } - real_to_int(b, &ti); - if(ti.sign) - c->exponent -= ti.a; - else - c->exponent += ti.a; -} - -void real_to_int(const temp_real * a, temp_int * b) -{ - int shift = 16383 + 63 - (a->exponent & 0x7fff); - u_long underflow; - - b->a = b->b = underflow = 0; - b->sign = (a->exponent < 0); - if (shift < 0) { - set_OE(); - return; - } - if (shift < 32) { - b->b = a->b; b->a = a->a; - } else if (shift < 64) { - b->a = a->b; underflow = a->a; - shift -= 32; - } else if (shift < 96) { - underflow = a->b; - shift -= 64; - } else { - underflow = 1; - shift = 0; - } - __asm__("shrdl %2,%1,%0" - :"=r" (underflow),"=r" (b->a) - :"c" ((char) shift),"0" (underflow),"1" (b->a)); - __asm__("shrdl %2,%1,%0" - :"=r" (b->a),"=r" (b->b) - :"c" ((char) shift),"0" (b->a),"1" (b->b)); - __asm__("shrl %1,%0" - :"=r" (b->b) - :"c" ((char) shift),"0" (b->b)); - switch (ROUNDING) { - case ROUND_NEAREST: - __asm__("addl %4,%5 ; adcl $0,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b) - ,"r" (0x7fffffff + (b->a & 1)) - ,"m" (*&underflow)); - break; - case ROUND_UP: - if (!b->sign && underflow) - __asm__("addl $1,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - break; - case ROUND_DOWN: - if (b->sign && underflow) - __asm__("addl $1,%0 ; adcl $0,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - break; - } -} - -void int_to_real(const temp_int * a, temp_real * b) -{ - b->a = a->a; - b->b = a->b; - if (b->a || b->b) - b->exponent = 16383 + 63 + (a->sign? 0x8000:0); - else { - b->exponent = 0; - return; - } - while (b->b >= 0) { - b->exponent--; - __asm__("addl %0,%0 ; adcl %1,%1" - :"=r" (b->a),"=r" (b->b) - :"0" (b->a),"1" (b->b)); - } -} diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c index 16b63c1ad1e..598a3067197 100644 --- a/sys/arch/i386/i386/trap.c +++ b/sys/arch/i386/i386/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.59 2003/06/24 22:45:33 espie Exp $ */ +/* $OpenBSD: trap.c,v 1.60 2003/07/28 19:59:18 jason Exp $ */ /* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */ /*- @@ -368,7 +368,7 @@ trap(frame) goto out; case T_DNA|T_USER: { -#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE) +#if defined(GPL_MATH_EMULATE) int rv; if ((rv = math_emulate(&frame)) == 0) { if (frame.tf_eflags & PSL_T) @@ -503,7 +503,7 @@ trap(frame) trapsignal(p, SIGTRAP, type &~ T_USER, TRAP_BRKPT, sv); break; case T_TRCTRAP|T_USER: /* trace trap */ -#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE) +#if defined(GPL_MATH_EMULATE) trace: #endif sv.sival_int = rcr2(); |