diff options
Diffstat (limited to 'arch/sparc64/math-emu/sfp-machine.h')
-rw-r--r-- | arch/sparc64/math-emu/sfp-machine.h | 130 |
1 files changed, 75 insertions, 55 deletions
diff --git a/arch/sparc64/math-emu/sfp-machine.h b/arch/sparc64/math-emu/sfp-machine.h index f15a5ea4a..3846ac4f9 100644 --- a/arch/sparc64/math-emu/sfp-machine.h +++ b/arch/sparc64/math-emu/sfp-machine.h @@ -52,16 +52,6 @@ X##_s = _flo->bits.sign; \ } while (0) -#define __FP_PACK_RAW_1(fs, val, X) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)val; \ - \ - _flo->bits.frac = X##_f; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } while (0) - #define __FP_UNPACK_RAW_2(fs, X, val) \ do { \ union _FP_UNION_##fs *_flo = \ @@ -73,53 +63,80 @@ X##_s = _flo->bits.sign; \ } while (0) -#define __FP_PACK_RAW_2(fs, val, X) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)val; \ - \ - _flo->bits.frac0 = X##_f0; \ - _flo->bits.frac1 = X##_f1; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } while (0) - #define __FP_UNPACK_S(X,val) \ do { \ __FP_UNPACK_RAW_1(S,X,val); \ _FP_UNPACK_CANONICAL(S,1,X); \ } while (0) -#define __FP_PACK_S(val,X) \ - do { \ - _FP_PACK_CANONICAL(S,1,X); \ - __FP_PACK_RAW_1(S,val,X); \ - } while (0) - #define __FP_UNPACK_D(X,val) \ do { \ __FP_UNPACK_RAW_1(D,X,val); \ _FP_UNPACK_CANONICAL(D,1,X); \ } while (0) -#define __FP_PACK_D(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,1,X); \ - __FP_PACK_RAW_1(D,val,X); \ - } while (0) - #define __FP_UNPACK_Q(X,val) \ do { \ __FP_UNPACK_RAW_2(Q,X,val); \ _FP_UNPACK_CANONICAL(Q,2,X); \ } while (0) -#define __FP_PACK_Q(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,2,X); \ - __FP_PACK_RAW_2(Q,val,X); \ +#define __FP_PACK_RAW_1(fs, val, X) \ + do { \ + union _FP_UNION_##fs *_flo = \ + (union _FP_UNION_##fs *)val; \ + \ + _flo->bits.frac = X##_f; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } while (0) + +#define __FP_PACK_RAW_2(fs, val, X) \ + do { \ + union _FP_UNION_##fs *_flo = \ + (union _FP_UNION_##fs *)val; \ + \ + _flo->bits.frac0 = X##_f0; \ + _flo->bits.frac1 = X##_f1; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ } while (0) +#include <linux/kernel.h> +#include <linux/sched.h> + +/* We only actually write to the destination register + * if exceptions signalled (if any) will not trap. + */ +#define __FPU_TEM \ + (((current->tss.xfsr[0])>>23)&0x1f) +#define __FPU_TRAP_P(bits) \ + ((__FPU_TEM & (bits)) != 0) + +#define __FP_PACK_S(val,X) \ +({ int __exc = _FP_PACK_CANONICAL(S,1,X); \ + if(!__exc || !__FPU_TRAP_P(__exc)) \ + __FP_PACK_RAW_1(S,val,X); \ + __exc; \ +}) + +#define __FP_PACK_D(val,X) \ +({ int __exc = _FP_PACK_CANONICAL(D,1,X); \ + if(!__exc || !__FPU_TRAP_P(__exc)) \ + __FP_PACK_RAW_1(D,val,X); \ + __exc; \ +}) + +#define __FP_PACK_Q(val,X) \ +({ int __exc = _FP_PACK_CANONICAL(Q,2,X); \ + if(!__exc || !__FPU_TRAP_P(__exc)) \ + __FP_PACK_RAW_2(Q,val,X); \ + __exc; \ +}) + +/* Obtain the current rounding mode. */ +#define FP_ROUNDMODE ((current->tss.xfsr[0] >> 30) & 0x3) + #include <linux/types.h> #include <asm/byteorder.h> @@ -153,28 +170,24 @@ #define umul_ppmm(wh, wl, u, v) \ do { \ - long tmp1 = 0, tmp2 = 0, tmp3 = 0; \ __asm__ ("mulx %2,%3,%1 - srlx %2,32,%4 - srl %3,0,%5 - mulx %4,%5,%6 - srlx %3,32,%4 - srl %2,0,%5 - mulx %4,%5,%5 - srlx %2,32,%4 - add %5,%6,%6 - srlx %3,32,%5 - mulx %4,%5,%4 - srlx %6,32,%5 - add %4,%5,%0" \ + srlx %2,32,%%g1 + srl %3,0,%%g2 + mulx %%g1,%%g2,%%g3 + srlx %3,32,%%g1 + srl %2,0,%%g2 + mulx %%g1,%%g2,%%g2 + srlx %2,32,%%g1 + add %%g2,%%g3,%%g3 + srlx %3,32,%%g2 + mulx %%g1,%%g2,%%g1 + srlx %%g3,32,%%g2 + add %%g1,%%g2,%0" \ : "=r" ((UDItype)(wh)), \ "=&r" ((UDItype)(wl)) \ : "r" ((UDItype)(u)), \ - "r" ((UDItype)(v)), \ - "r" ((UDItype)(tmp1)), \ - "r" ((UDItype)(tmp2)), \ - "r" ((UDItype)(tmp3)) \ - : "cc"); \ + "r" ((UDItype)(v)) \ + : "g1", "g2", "g3", "cc"); \ } while (0) #define udiv_qrnnd(q, r, n1, n0, d) \ @@ -223,3 +236,10 @@ #else #define __BYTE_ORDER __LITTLE_ENDIAN #endif + +/* Exception flags. */ +#define EFLAG_INVALID (1 << 4) +#define EFLAG_OVERFLOW (1 << 3) +#define EFLAG_UNDERFLOW (1 << 2) +#define EFLAG_DIVZERO (1 << 1) +#define EFLAG_INEXACT (1 << 0) |