summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/hppa/spmath/cnv_float.h419
-rw-r--r--sys/arch/hppa/spmath/dbl_float.h552
-rw-r--r--sys/arch/hppa/spmath/dfadd.c524
-rw-r--r--sys/arch/hppa/spmath/dfcmp.c181
-rw-r--r--sys/arch/hppa/spmath/dfdiv.c404
-rw-r--r--sys/arch/hppa/spmath/dfmpy.c395
-rw-r--r--sys/arch/hppa/spmath/dfrem.c301
-rw-r--r--sys/arch/hppa/spmath/dfsqrt.c196
-rw-r--r--sys/arch/hppa/spmath/dfsub.c526
-rw-r--r--sys/arch/hppa/spmath/divsfm.c110
-rw-r--r--sys/arch/hppa/spmath/divsfr.c105
-rw-r--r--sys/arch/hppa/spmath/divsim.c112
-rw-r--r--sys/arch/hppa/spmath/divsir.c104
-rw-r--r--sys/arch/hppa/spmath/divu.S181
-rw-r--r--sys/arch/hppa/spmath/divufr.c69
-rw-r--r--sys/arch/hppa/spmath/divuir.c63
-rw-r--r--sys/arch/hppa/spmath/fcnvff.c308
-rw-r--r--sys/arch/hppa/spmath/fcnvfx.c462
-rw-r--r--sys/arch/hppa/spmath/fcnvfxt.c294
-rw-r--r--sys/arch/hppa/spmath/fcnvxf.c379
-rw-r--r--sys/arch/hppa/spmath/float.h547
-rw-r--r--sys/arch/hppa/spmath/fpbits.h82
-rw-r--r--sys/arch/hppa/spmath/frnd.c266
-rw-r--r--sys/arch/hppa/spmath/hppa.h58
-rw-r--r--sys/arch/hppa/spmath/impys.S323
-rw-r--r--sys/arch/hppa/spmath/impyu.S322
-rw-r--r--sys/arch/hppa/spmath/md.h93
-rw-r--r--sys/arch/hppa/spmath/mpyaccs.c69
-rw-r--r--sys/arch/hppa/spmath/mpyaccu.c68
-rw-r--r--sys/arch/hppa/spmath/mpys.c60
-rw-r--r--sys/arch/hppa/spmath/mpyscv.c56
-rw-r--r--sys/arch/hppa/spmath/mpyu.c58
-rw-r--r--sys/arch/hppa/spmath/mpyucv.c56
-rw-r--r--sys/arch/hppa/spmath/quad_float.h102
-rw-r--r--sys/arch/hppa/spmath/setovfl.c118
-rw-r--r--sys/arch/hppa/spmath/sfadd.c518
-rw-r--r--sys/arch/hppa/spmath/sfcmp.c155
-rw-r--r--sys/arch/hppa/spmath/sfdiv.c396
-rw-r--r--sys/arch/hppa/spmath/sfmpy.c381
-rw-r--r--sys/arch/hppa/spmath/sfrem.c294
-rw-r--r--sys/arch/hppa/spmath/sfsqrt.c187
-rw-r--r--sys/arch/hppa/spmath/sfsub.c521
-rw-r--r--sys/arch/hppa/spmath/sgl_float.h334
43 files changed, 10749 insertions, 0 deletions
diff --git a/sys/arch/hppa/spmath/cnv_float.h b/sys/arch/hppa/spmath/cnv_float.h
new file mode 100644
index 00000000000..adf7b6bc5e6
--- /dev/null
+++ b/sys/arch/hppa/spmath/cnv_float.h
@@ -0,0 +1,419 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/*
+ * @(#)cnv_float.h: $Revision: 1.1 $ $Date: 1998/06/23 20:33:50 $
+ * $Locker: $
+ *
+ */
+
+/*
+ * Some more constants
+ */
+#define SGL_FX_MAX_EXP 30
+#define DBL_FX_MAX_EXP 62
+#define QUAD_FX_MAX_EXP 126
+
+
+#define Dintp1(object) (object)
+#define Dintp2(object) (object)
+
+#define Qintp0(object) (object)
+#define Qintp1(object) (object)
+#define Qintp2(object) (object)
+#define Qintp3(object) (object)
+
+
+/*
+ * These macros will be used specifically by the convert instructions.
+ *
+ *
+ * Single format macros
+ */
+
+#define Sgl_to_dbl_exponent(src_exponent,dest) \
+ Deposit_dexponent(dest,src_exponent+(DBL_BIAS-SGL_BIAS))
+
+#define Sgl_to_dbl_mantissa(src_mantissa,destA,destB) \
+ Deposit_dmantissap1(destA,src_mantissa>>3); \
+ Dmantissap2(destB) = src_mantissa << 29
+
+#define Sgl_isinexact_to_fix(sgl_value,exponent) \
+ ((exponent < (SGL_P - 1)) ? \
+ (Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) : FALSE)
+
+#define Int_isinexact_to_sgl(int_value) (int_value << 33 - SGL_EXP_LENGTH)
+
+#define Sgl_roundnearest_from_int(int_value,sgl_value) \
+ if (int_value & 1<<(SGL_EXP_LENGTH - 2)) /* round bit */ \
+ if ((int_value << 34 - SGL_EXP_LENGTH) || Slow(sgl_value)) \
+ Sall(sgl_value)++
+
+#define Dint_isinexact_to_sgl(dint_valueA,dint_valueB) \
+ ((Dintp1(dint_valueA) << 33 - SGL_EXP_LENGTH) || Dintp2(dint_valueB))
+
+#define Sgl_roundnearest_from_dint(dint_valueA,dint_valueB,sgl_value) \
+ if (Dintp1(dint_valueA) & 1<<(SGL_EXP_LENGTH - 2)) \
+ if ((Dintp1(dint_valueA) << 34 - SGL_EXP_LENGTH) || \
+ Dintp2(dint_valueB) || Slow(sgl_value)) Sall(sgl_value)++
+
+#define Dint_isinexact_to_dbl(dint_value) \
+ (Dintp2(dint_value) << 33 - DBL_EXP_LENGTH)
+
+#define Dbl_roundnearest_from_dint(dint_opndB,dbl_opndA,dbl_opndB) \
+ if (Dintp2(dint_opndB) & 1<<(DBL_EXP_LENGTH - 2)) \
+ if ((Dintp2(dint_opndB) << 34 - DBL_EXP_LENGTH) || Dlowp2(dbl_opndB)) \
+ if ((++Dallp2(dbl_opndB))==0) Dallp1(dbl_opndA)++
+
+#define Sgl_isone_roundbit(sgl_value,exponent) \
+ ((Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) >> 31)
+
+#define Sgl_isone_stickybit(sgl_value,exponent) \
+ (exponent < (SGL_P - 2) ? \
+ Sall(sgl_value) << (SGL_EXP_LENGTH + 2 + exponent) : FALSE)
+
+
+/*
+ * Double format macros
+ */
+
+#define Dbl_to_sgl_exponent(src_exponent,dest) \
+ dest = src_exponent + (SGL_BIAS - DBL_BIAS)
+
+#define Dbl_to_sgl_mantissa(srcA,srcB,dest,inexact,guard,sticky,odd) \
+ Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest); \
+ guard = Dbit3p2(srcB); \
+ sticky = Dallp2(srcB)<<4; \
+ inexact = guard | sticky; \
+ odd = Dbit2p2(srcB)
+
+#define Dbl_to_sgl_denormalized(srcA,srcB,exp,dest,inexact,guard,sticky,odd,tiny) \
+ Deposit_dexponent(srcA,1); \
+ tiny = TRUE; \
+ if (exp >= -2) { \
+ if (exp == 0) { \
+ inexact = Dallp2(srcB) << 3; \
+ guard = inexact >> 31; \
+ sticky = inexact << 1; \
+ Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest); \
+ odd = dest << 31; \
+ if (inexact) { \
+ switch(Rounding_mode()) { \
+ case ROUNDPLUS: \
+ if (Dbl_iszero_sign(srcA)) { \
+ dest++; \
+ if (Sgl_isone_hidden(dest)) \
+ tiny = FALSE; \
+ dest--; \
+ } \
+ break; \
+ case ROUNDMINUS: \
+ if (Dbl_isone_sign(srcA)) { \
+ dest++; \
+ if (Sgl_isone_hidden(dest)) \
+ tiny = FALSE; \
+ dest--; \
+ } \
+ break; \
+ case ROUNDNEAREST: \
+ if (guard && (sticky || odd)) { \
+ dest++; \
+ if (Sgl_isone_hidden(dest)) \
+ tiny = FALSE; \
+ dest--; \
+ } \
+ break; \
+ } \
+ } \
+ /* shift right by one to get correct result */ \
+ guard = odd; \
+ sticky = inexact; \
+ inexact |= guard; \
+ dest >>= 1; \
+ Deposit_dsign(srcA,0); \
+ Shiftdouble(Dallp1(srcA),Dallp2(srcB),30,dest); \
+ odd = dest << 31; \
+ } \
+ else { \
+ inexact = Dallp2(srcB) << (2 + exp); \
+ guard = inexact >> 31; \
+ sticky = inexact << 1; \
+ Deposit_dsign(srcA,0); \
+ if (exp == -2) dest = Dallp1(srcA); \
+ else Variable_shift_double(Dallp1(srcA),Dallp2(srcB),30-exp,dest); \
+ odd = dest << 31; \
+ } \
+ } \
+ else { \
+ Deposit_dsign(srcA,0); \
+ if (exp > (1 - SGL_P)) { \
+ dest = Dallp1(srcA) >> (- 2 - exp); \
+ inexact = Dallp1(srcA) << (34 + exp); \
+ guard = inexact >> 31; \
+ sticky = (inexact << 1) | Dallp2(srcB); \
+ inexact |= Dallp2(srcB); \
+ odd = dest << 31; \
+ } \
+ else { \
+ dest = 0; \
+ inexact = Dallp1(srcA) | Dallp2(srcB); \
+ if (exp == (1 - SGL_P)) { \
+ guard = Dhidden(srcA); \
+ sticky = Dmantissap1(srcA) | Dallp2(srcB); \
+ } \
+ else { \
+ guard = 0; \
+ sticky = inexact; \
+ } \
+ odd = 0; \
+ } \
+ } \
+ exp = 0
+
+#define Dbl_isinexact_to_fix(dbl_valueA,dbl_valueB,exponent) \
+ (exponent < (DBL_P-33) ? \
+ Dallp2(dbl_valueB) || Dallp1(dbl_valueA) << (DBL_EXP_LENGTH+1+exponent) : \
+ (exponent < (DBL_P-1) ? Dallp2(dbl_valueB) << (exponent + (33-DBL_P)) : \
+ FALSE))
+
+#define Dbl_isoverflow_to_int(exponent,dbl_valueA,dbl_valueB) \
+ ((exponent > SGL_FX_MAX_EXP + 1) || Dsign(dbl_valueA)==0 || \
+ Dmantissap1(dbl_valueA)!=0 || (Dallp2(dbl_valueB)>>21)!=0 )
+
+#define Dbl_isone_roundbit(dbl_valueA,dbl_valueB,exponent) \
+ ((exponent < (DBL_P - 33) ? \
+ Dallp1(dbl_valueA) >> ((30 - DBL_EXP_LENGTH) - exponent) : \
+ Dallp2(dbl_valueB) >> ((DBL_P - 2) - exponent)) & 1)
+
+#define Dbl_isone_stickybit(dbl_valueA,dbl_valueB,exponent) \
+ (exponent < (DBL_P-34) ? \
+ (Dallp2(dbl_valueB) || Dallp1(dbl_valueA)<<(DBL_EXP_LENGTH+2+exponent)) : \
+ (exponent<(DBL_P-2) ? (Dallp2(dbl_valueB) << (exponent + (34-DBL_P))) : \
+ FALSE))
+
+
+/* Int macros */
+
+#define Int_from_sgl_mantissa(sgl_value,exponent) \
+ Sall(sgl_value) = \
+ (unsigned)(Sall(sgl_value) << SGL_EXP_LENGTH)>>(31 - exponent)
+
+#define Int_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),22,Dallp1(dbl_valueA)); \
+ if (exponent < 31) Dallp1(dbl_valueA) >>= 30 - exponent; \
+ else Dallp1(dbl_valueA) <<= 1
+
+#define Int_negate(int_value) int_value = -int_value
+
+
+/* Dint macros */
+
+#define Dint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \
+ {Sall(sgl_value) <<= SGL_EXP_LENGTH; /* left-justify */ \
+ if (exponent <= 31) { \
+ Dintp1(dresultA) = 0; \
+ Dintp2(dresultB) = (unsigned)Sall(sgl_value) >> (31 - exponent); \
+ } \
+ else { \
+ Dintp1(dresultA) = Sall(sgl_value) >> (63 - exponent); \
+ Dintp2(dresultB) = Sall(sgl_value) << (exponent - 31); \
+ }}
+
+
+#define Dint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB) \
+ {if (exponent < 32) { \
+ Dintp1(destA) = 0; \
+ if (exponent <= 20) \
+ Dintp2(destB) = Dallp1(dbl_valueA) >> 20-exponent; \
+ else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
+ 52-exponent,Dintp2(destB)); \
+ } \
+ else { \
+ if (exponent <= 52) { \
+ Dintp1(destA) = Dallp1(dbl_valueA) >> 52-exponent; \
+ if (exponent == 52) Dintp2(destB) = Dallp2(dbl_valueB); \
+ else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
+ 52-exponent,Dintp2(destB)); \
+ } \
+ else { \
+ Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
+ 84-exponent,Dintp1(destA)); \
+ Dintp2(destB) = Dallp2(dbl_valueB) << exponent-52; \
+ } \
+ }}
+
+#define Dint_setzero(dresultA,dresultB) \
+ Dintp1(dresultA) = 0; \
+ Dintp2(dresultB) = 0
+
+#define Dint_setone_sign(dresultA,dresultB) \
+ Dintp1(dresultA) = ~Dintp1(dresultA); \
+ if ((Dintp2(dresultB) = -Dintp2(dresultB)) == 0) Dintp1(dresultA)++
+
+#define Dint_set_minint(dresultA,dresultB) \
+ Dintp1(dresultA) = 1<<31; \
+ Dintp2(dresultB) = 0
+
+#define Dint_isone_lowp2(dresultB) (Dintp2(dresultB) & 01)
+
+#define Dint_increment(dresultA,dresultB) \
+ if ((++Dintp2(dresultB))==0) Dintp1(dresultA)++
+
+#define Dint_decrement(dresultA,dresultB) \
+ if ((Dintp2(dresultB)--)==0) Dintp1(dresultA)--
+
+#define Dint_negate(dresultA,dresultB) \
+ Dintp1(dresultA) = ~Dintp1(dresultA); \
+ if ((Dintp2(dresultB) = -Dintp2(dresultB))==0) Dintp1(dresultA)++
+
+#define Dint_copyfromptr(src,destA,destB) \
+ Dintp1(destA) = src->wd0; \
+ Dintp2(destB) = src->wd1
+#define Dint_copytoptr(srcA,srcB,dest) \
+ dest->wd0 = Dintp1(srcA); \
+ dest->wd1 = Dintp2(srcB)
+
+
+/* other macros */
+
+#define Find_ms_one_bit(value, position) \
+ { \
+ int var; \
+ for (var=8; var >=1; var >>= 1) { \
+ if (value >> 32 - position) \
+ position -= var; \
+ else position += var; \
+ } \
+ if ((value >> 32 - position) == 0) \
+ position--; \
+ else position -= 2; \
+ }
+
+/*
+ * The following 4 functions handle the assignment of a floating point
+ * number to a 32-bit integer in cases where the floating point number
+ * is too large (or small) to fit in the integer field.
+ *
+ * In all these cases, HP-UX would return an UNIMPLEMENTEDEXCEPTION
+ * resulting in a SIGFPE being sent to the process. For BSD's math
+ * library (and various other applications), this was unacceptable.
+ * As a result, we now return maxint/minint (like most other OS's)
+ * and either return an INEXACTEXCEPTION (SIGFPE) or set the inexact
+ * flag (so that the program may continue execution).
+ *
+ * After discussing this with Jerry Huck @ HP, the one case where we
+ * differ from BSD is for programs that try to convert a NaN to an
+ * integer; in this case, we will return an UNIMPLEMENTEDEXCEPTION
+ * since doing anything else would be completely unreasonable.
+ *
+ * jef
+ */
+
+#define Dbl_return_overflow(srcp1, srcp2, resultp) \
+ { \
+ if (Dbl_isnan(srcp1, srcp2)) \
+ return(UNIMPLEMENTEDEXCEPTION); \
+ if (Dbl_iszero_sign(srcp1)) \
+ *resultp = 0x7fffffff; \
+ else \
+ *resultp = 0x80000000; \
+ if (Is_overflowtrap_enabled()) { \
+ if (Is_inexacttrap_enabled()) \
+ return(OVERFLOWEXCEPTION|INEXACTEXCEPTION); \
+ else \
+ Set_inexactflag(); \
+ return(OVERFLOWEXCEPTION); \
+ } \
+ return(NOEXCEPTION); \
+ }
+
+#define Dbl_return_overflow_dbl(srcp1, srcp2, resultp) \
+ { \
+ if (Dbl_isnan(srcp1, srcp2)) \
+ return(UNIMPLEMENTEDEXCEPTION); \
+ if (Dbl_iszero_sign(srcp1)) { \
+ Dint_copytoptr(0x7fffffff,0xffffffff,resultp); \
+ } else { \
+ Dint_copytoptr(0x80000000,0x00000000,resultp); \
+ } \
+ if (Is_overflowtrap_enabled()) { \
+ if (Is_inexacttrap_enabled()) \
+ return(OVERFLOWEXCEPTION|INEXACTEXCEPTION); \
+ else \
+ Set_inexactflag(); \
+ return(OVERFLOWEXCEPTION); \
+ } \
+ return(NOEXCEPTION); \
+ }
+
+#define Sgl_return_overflow(src, resultp) \
+ { \
+ if (Sgl_isnan(src)) \
+ return(UNIMPLEMENTEDEXCEPTION); \
+ if (Sgl_iszero_sign(src)) \
+ *resultp = 0x7fffffff; \
+ else \
+ *resultp = 0x80000000; \
+ if (Is_overflowtrap_enabled()) { \
+ if (Is_inexacttrap_enabled()) \
+ return(OVERFLOWEXCEPTION|INEXACTEXCEPTION); \
+ else \
+ Set_inexactflag(); \
+ return(OVERFLOWEXCEPTION); \
+ } \
+ return(NOEXCEPTION); \
+ }
+
+#define Sgl_return_overflow_dbl(src, resultp) \
+ { \
+ if (Sgl_isnan(src)) \
+ return(UNIMPLEMENTEDEXCEPTION); \
+ if (Sgl_iszero_sign(src)) { \
+ Dint_copytoptr(0x7fffffff,0xffffffff,resultp); \
+ } else { \
+ Dint_copytoptr(0x80000000,0x00000000,resultp); \
+ } \
+ if (Is_overflowtrap_enabled()) { \
+ if (Is_inexacttrap_enabled()) \
+ return(OVERFLOWEXCEPTION|INEXACTEXCEPTION); \
+ else \
+ Set_inexactflag(); \
+ return(OVERFLOWEXCEPTION); \
+ } \
+ return(NOEXCEPTION); \
+ }
+
diff --git a/sys/arch/hppa/spmath/dbl_float.h b/sys/arch/hppa/spmath/dbl_float.h
new file mode 100644
index 00000000000..0ad4531a02e
--- /dev/null
+++ b/sys/arch/hppa/spmath/dbl_float.h
@@ -0,0 +1,552 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/*
+ * @(#)dbl_float.h: $Revision: 1.1 $ $Date: 1998/06/23 20:33:51 $
+ * $Locker: $
+ *
+ */
+/**************************************
+ * Declare double precision functions *
+ **************************************/
+
+/* 32-bit word grabing functions */
+#define Dbl_firstword(value) Dallp1(value)
+#define Dbl_secondword(value) Dallp2(value)
+#define Dbl_thirdword(value) dummy_location
+#define Dbl_fourthword(value) dummy_location
+
+#define Dbl_sign(object) Dsign(object)
+#define Dbl_exponent(object) Dexponent(object)
+#define Dbl_signexponent(object) Dsignexponent(object)
+#define Dbl_mantissap1(object) Dmantissap1(object)
+#define Dbl_mantissap2(object) Dmantissap2(object)
+#define Dbl_exponentmantissap1(object) Dexponentmantissap1(object)
+#define Dbl_allp1(object) Dallp1(object)
+#define Dbl_allp2(object) Dallp2(object)
+
+/* dbl_and_signs ands the sign bits of each argument and puts the result
+ * into the first argument. dbl_or_signs ors those same sign bits */
+#define Dbl_and_signs( src1dst, src2) \
+ Dallp1(src1dst) = (Dallp1(src2)|~(1<<31)) & Dallp1(src1dst)
+#define Dbl_or_signs( src1dst, src2) \
+ Dallp1(src1dst) = (Dallp1(src2)&(1<<31)) | Dallp1(src1dst)
+
+/* The hidden bit is always the low bit of the exponent */
+#define Dbl_clear_exponent_set_hidden(srcdst) Deposit_dexponent(srcdst,1)
+#define Dbl_clear_signexponent_set_hidden(srcdst) \
+ Deposit_dsignexponent(srcdst,1)
+#define Dbl_clear_sign(srcdst) Dallp1(srcdst) &= ~(1<<31)
+#define Dbl_clear_signexponent(srcdst) \
+ Dallp1(srcdst) &= Dmantissap1((unsigned)-1)
+
+/* Exponent field for doubles has already been cleared and may be
+ * included in the shift. Here we need to generate two double width
+ * variable shifts. The insignificant bits can be ignored.
+ * MTSAR f(varamount)
+ * VSHD srcdst.high,srcdst.low => srcdst.low
+ * VSHD 0,srcdst.high => srcdst.high
+ * This is very difficult to model with C expressions since the shift amount
+ * could exceed 32. */
+/* varamount must be less than 64 */
+#define Dbl_rightshift(srcdstA, srcdstB, varamount) \
+ {if((varamount) >= 32) { \
+ Dallp2(srcdstB) = Dallp1(srcdstA) >> (varamount-32); \
+ Dallp1(srcdstA)=0; \
+ } \
+ else if(varamount > 0) { \
+ Variable_shift_double(Dallp1(srcdstA), Dallp2(srcdstB), \
+ (varamount), Dallp2(srcdstB)); \
+ Dallp1(srcdstA) >>= varamount; \
+ } }
+/* varamount must be less than 64 */
+#define Dbl_rightshift_exponentmantissa(srcdstA, srcdstB, varamount) \
+ {if((varamount) >= 32) { \
+ Dallp2(srcdstB) = Dexponentmantissap1(srcdstA) >> (varamount-32); \
+ Dallp1(srcdstA) &= (1<<31); /* clear exponentmantissa field */ \
+ } \
+ else if(varamount > 0) { \
+ Variable_shift_double(Dexponentmantissap1(srcdstA), Dallp2(srcdstB), \
+ (varamount), Dallp2(srcdstB)); \
+ Deposit_dexponentmantissap1(srcdstA, \
+ (Dexponentmantissap1(srcdstA)>>varamount)); \
+ } }
+/* varamount must be less than 64 */
+#define Dbl_leftshift(srcdstA, srcdstB, varamount) \
+ {if((varamount) >= 32) { \
+ Dallp1(srcdstA) = Dallp2(srcdstB) << (varamount-32); \
+ Dallp2(srcdstB)=0; \
+ } \
+ else { \
+ if ((varamount) > 0) { \
+ Dallp1(srcdstA) = (Dallp1(srcdstA) << (varamount)) | \
+ (Dallp2(srcdstB) >> (32-(varamount))); \
+ Dallp2(srcdstB) <<= varamount; \
+ } \
+ } }
+#define Dbl_leftshiftby1_withextent(lefta,leftb,right,resulta,resultb) \
+ Shiftdouble(Dallp1(lefta), Dallp2(leftb), 31, Dallp1(resulta)); \
+ Shiftdouble(Dallp2(leftb), Extall(right), 31, Dallp2(resultb))
+
+#define Dbl_rightshiftby1_withextent(leftb,right,dst) \
+ Extall(dst) = (Dallp2(leftb) << 31) | ((unsigned)Extall(right) >> 1) | \
+ Extlow(right)
+
+#define Dbl_arithrightshiftby1(srcdstA,srcdstB) \
+ Shiftdouble(Dallp1(srcdstA),Dallp2(srcdstB),1,Dallp2(srcdstB));\
+ Dallp1(srcdstA) = (int)Dallp1(srcdstA) >> 1
+
+/* Sign extend the sign bit with an integer destination */
+#define Dbl_signextendedsign(value) Dsignedsign(value)
+
+#define Dbl_isone_hidden(dbl_value) (Is_dhidden(dbl_value)!=0)
+/* Singles and doubles may include the sign and exponent fields. The
+ * hidden bit and the hidden overflow must be included. */
+#define Dbl_increment(dbl_valueA,dbl_valueB) \
+ if( (Dallp2(dbl_valueB) += 1) == 0 ) Dallp1(dbl_valueA) += 1
+#define Dbl_increment_mantissa(dbl_valueA,dbl_valueB) \
+ if( (Dmantissap2(dbl_valueB) += 1) == 0 ) \
+ Deposit_dmantissap1(dbl_valueA,dbl_valueA+1)
+#define Dbl_decrement(dbl_valueA,dbl_valueB) \
+ if( Dallp2(dbl_valueB) == 0 ) Dallp1(dbl_valueA) -= 1; \
+ Dallp2(dbl_valueB) -= 1
+
+#define Dbl_isone_sign(dbl_value) (Is_dsign(dbl_value)!=0)
+#define Dbl_isone_hiddenoverflow(dbl_value) (Is_dhiddenoverflow(dbl_value)!=0)
+#define Dbl_isone_lowmantissap1(dbl_valueA) (Is_dlowp1(dbl_valueA)!=0)
+#define Dbl_isone_lowmantissap2(dbl_valueB) (Is_dlowp2(dbl_valueB)!=0)
+#define Dbl_isone_signaling(dbl_value) (Is_dsignaling(dbl_value)!=0)
+#define Dbl_is_signalingnan(dbl_value) (Dsignalingnan(dbl_value)==0xfff)
+#define Dbl_isnotzero(dbl_valueA,dbl_valueB) \
+ (Dallp1(dbl_valueA) || Dallp2(dbl_valueB))
+#define Dbl_isnotzero_hiddenhigh7mantissa(dbl_value) \
+ (Dhiddenhigh7mantissa(dbl_value)!=0)
+#define Dbl_isnotzero_exponent(dbl_value) (Dexponent(dbl_value)!=0)
+#define Dbl_isnotzero_mantissa(dbl_valueA,dbl_valueB) \
+ (Dmantissap1(dbl_valueA) || Dmantissap2(dbl_valueB))
+#define Dbl_isnotzero_mantissap1(dbl_valueA) (Dmantissap1(dbl_valueA)!=0)
+#define Dbl_isnotzero_mantissap2(dbl_valueB) (Dmantissap2(dbl_valueB)!=0)
+#define Dbl_isnotzero_exponentmantissa(dbl_valueA,dbl_valueB) \
+ (Dexponentmantissap1(dbl_valueA) || Dmantissap2(dbl_valueB))
+#define Dbl_isnotzero_low4p2(dbl_value) (Dlow4p2(dbl_value)!=0)
+#define Dbl_iszero(dbl_valueA,dbl_valueB) (Dallp1(dbl_valueA)==0 && \
+ Dallp2(dbl_valueB)==0)
+#define Dbl_iszero_allp1(dbl_value) (Dallp1(dbl_value)==0)
+#define Dbl_iszero_allp2(dbl_value) (Dallp2(dbl_value)==0)
+#define Dbl_iszero_hidden(dbl_value) (Is_dhidden(dbl_value)==0)
+#define Dbl_iszero_hiddenoverflow(dbl_value) (Is_dhiddenoverflow(dbl_value)==0)
+#define Dbl_iszero_hiddenhigh3mantissa(dbl_value) \
+ (Dhiddenhigh3mantissa(dbl_value)==0)
+#define Dbl_iszero_hiddenhigh7mantissa(dbl_value) \
+ (Dhiddenhigh7mantissa(dbl_value)==0)
+#define Dbl_iszero_sign(dbl_value) (Is_dsign(dbl_value)==0)
+#define Dbl_iszero_exponent(dbl_value) (Dexponent(dbl_value)==0)
+#define Dbl_iszero_mantissa(dbl_valueA,dbl_valueB) \
+ (Dmantissap1(dbl_valueA)==0 && Dmantissap2(dbl_valueB)==0)
+#define Dbl_iszero_exponentmantissa(dbl_valueA,dbl_valueB) \
+ (Dexponentmantissap1(dbl_valueA)==0 && Dmantissap2(dbl_valueB)==0)
+#define Dbl_isinfinity_exponent(dbl_value) \
+ (Dexponent(dbl_value)==DBL_INFINITY_EXPONENT)
+#define Dbl_isnotinfinity_exponent(dbl_value) \
+ (Dexponent(dbl_value)!=DBL_INFINITY_EXPONENT)
+#define Dbl_isinfinity(dbl_valueA,dbl_valueB) \
+ (Dexponent(dbl_valueA)==DBL_INFINITY_EXPONENT && \
+ Dmantissap1(dbl_valueA)==0 && Dmantissap2(dbl_valueB)==0)
+#define Dbl_isnan(dbl_valueA,dbl_valueB) \
+ (Dexponent(dbl_valueA)==DBL_INFINITY_EXPONENT && \
+ (Dmantissap1(dbl_valueA)!=0 || Dmantissap2(dbl_valueB)!=0))
+#define Dbl_isnotnan(dbl_valueA,dbl_valueB) \
+ (Dexponent(dbl_valueA)!=DBL_INFINITY_EXPONENT || \
+ (Dmantissap1(dbl_valueA)==0 && Dmantissap2(dbl_valueB)==0))
+
+#define Dbl_islessthan(dbl_op1a,dbl_op1b,dbl_op2a,dbl_op2b) \
+ (Dallp1(dbl_op1a) < Dallp1(dbl_op2a) || \
+ (Dallp1(dbl_op1a) == Dallp1(dbl_op2a) && \
+ Dallp2(dbl_op1b) < Dallp2(dbl_op2b)))
+#define Dbl_isgreaterthan(dbl_op1a,dbl_op1b,dbl_op2a,dbl_op2b) \
+ (Dallp1(dbl_op1a) > Dallp1(dbl_op2a) || \
+ (Dallp1(dbl_op1a) == Dallp1(dbl_op2a) && \
+ Dallp2(dbl_op1b) > Dallp2(dbl_op2b)))
+#define Dbl_isnotlessthan(dbl_op1a,dbl_op1b,dbl_op2a,dbl_op2b) \
+ (Dallp1(dbl_op1a) > Dallp1(dbl_op2a) || \
+ (Dallp1(dbl_op1a) == Dallp1(dbl_op2a) && \
+ Dallp2(dbl_op1b) >= Dallp2(dbl_op2b)))
+#define Dbl_isnotgreaterthan(dbl_op1a,dbl_op1b,dbl_op2a,dbl_op2b) \
+ (Dallp1(dbl_op1a) < Dallp1(dbl_op2a) || \
+ (Dallp1(dbl_op1a) == Dallp1(dbl_op2a) && \
+ Dallp2(dbl_op1b) <= Dallp2(dbl_op2b)))
+#define Dbl_isequal(dbl_op1a,dbl_op1b,dbl_op2a,dbl_op2b) \
+ ((Dallp1(dbl_op1a) == Dallp1(dbl_op2a)) && \
+ (Dallp2(dbl_op1b) == Dallp2(dbl_op2b)))
+
+#define Dbl_leftshiftby8(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),24,Dallp1(dbl_valueA)); \
+ Dallp2(dbl_valueB) <<= 8
+#define Dbl_leftshiftby7(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),25,Dallp1(dbl_valueA)); \
+ Dallp2(dbl_valueB) <<= 7
+#define Dbl_leftshiftby4(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),28,Dallp1(dbl_valueA)); \
+ Dallp2(dbl_valueB) <<= 4
+#define Dbl_leftshiftby3(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),29,Dallp1(dbl_valueA)); \
+ Dallp2(dbl_valueB) <<= 3
+#define Dbl_leftshiftby2(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),30,Dallp1(dbl_valueA)); \
+ Dallp2(dbl_valueB) <<= 2
+#define Dbl_leftshiftby1(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),31,Dallp1(dbl_valueA)); \
+ Dallp2(dbl_valueB) <<= 1
+
+#define Dbl_rightshiftby8(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),8,Dallp2(dbl_valueB)); \
+ Dallp1(dbl_valueA) >>= 8
+#define Dbl_rightshiftby4(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),4,Dallp2(dbl_valueB)); \
+ Dallp1(dbl_valueA) >>= 4
+#define Dbl_rightshiftby2(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),2,Dallp2(dbl_valueB)); \
+ Dallp1(dbl_valueA) >>= 2
+#define Dbl_rightshiftby1(dbl_valueA,dbl_valueB) \
+ Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),1,Dallp2(dbl_valueB)); \
+ Dallp1(dbl_valueA) >>= 1
+
+/* This magnitude comparison uses the signless first words and
+ * the regular part2 words. The comparison is graphically:
+ *
+ * 1st greater? -------------
+ * |
+ * 1st less?-----------------+---------
+ * | |
+ * 2nd greater or equal----->| |
+ * False True
+ */
+#define Dbl_ismagnitudeless(leftB,rightB,signlessleft,signlessright) \
+ ((signlessleft <= signlessright) && \
+ ( (signlessleft < signlessright) || (Dallp2(leftB)<Dallp2(rightB)) ))
+
+#define Dbl_copytoint_exponentmantissap1(src,dest) \
+ dest = Dexponentmantissap1(src)
+
+/* A quiet NaN has the high mantissa bit clear and at least on other (in this
+ * case the adjacent bit) bit set. */
+#define Dbl_set_quiet(dbl_value) Deposit_dhigh2mantissa(dbl_value,1)
+#define Dbl_set_exponent(dbl_value, exp) Deposit_dexponent(dbl_value,exp)
+
+#define Dbl_set_mantissa(desta,destb,valuea,valueb) \
+ Deposit_dmantissap1(desta,valuea); \
+ Dmantissap2(destb) = Dmantissap2(valueb)
+#define Dbl_set_mantissap1(desta,valuea) \
+ Deposit_dmantissap1(desta,valuea)
+#define Dbl_set_mantissap2(destb,valueb) \
+ Dmantissap2(destb) = Dmantissap2(valueb)
+
+#define Dbl_set_exponentmantissa(desta,destb,valuea,valueb) \
+ Deposit_dexponentmantissap1(desta,valuea); \
+ Dmantissap2(destb) = Dmantissap2(valueb)
+#define Dbl_set_exponentmantissap1(dest,value) \
+ Deposit_dexponentmantissap1(dest,value)
+
+#define Dbl_copyfromptr(src,desta,destb) \
+ Dallp1(desta) = src->wd0; \
+ Dallp2(destb) = src->wd1
+#define Dbl_copytoptr(srca,srcb,dest) \
+ dest->wd0 = Dallp1(srca); \
+ dest->wd1 = Dallp2(srcb)
+
+/* An infinity is represented with the max exponent and a zero mantissa */
+#define Dbl_setinfinity_exponent(dbl_value) \
+ Deposit_dexponent(dbl_value,DBL_INFINITY_EXPONENT)
+#define Dbl_setinfinity_exponentmantissa(dbl_valueA,dbl_valueB) \
+ Deposit_dexponentmantissap1(dbl_valueA, \
+ (DBL_INFINITY_EXPONENT << (32-(1+DBL_EXP_LENGTH)))); \
+ Dmantissap2(dbl_valueB) = 0
+#define Dbl_setinfinitypositive(dbl_valueA,dbl_valueB) \
+ Dallp1(dbl_valueA) \
+ = (DBL_INFINITY_EXPONENT << (32-(1+DBL_EXP_LENGTH))); \
+ Dmantissap2(dbl_valueB) = 0
+#define Dbl_setinfinitynegative(dbl_valueA,dbl_valueB) \
+ Dallp1(dbl_valueA) = (1<<31) | \
+ (DBL_INFINITY_EXPONENT << (32-(1+DBL_EXP_LENGTH))); \
+ Dmantissap2(dbl_valueB) = 0
+#define Dbl_setinfinity(dbl_valueA,dbl_valueB,sign) \
+ Dallp1(dbl_valueA) = (sign << 31) | \
+ (DBL_INFINITY_EXPONENT << (32-(1+DBL_EXP_LENGTH))); \
+ Dmantissap2(dbl_valueB) = 0
+
+#define Dbl_sethigh4bits(dbl_value, extsign) Deposit_dhigh4p1(dbl_value,extsign)
+#define Dbl_set_sign(dbl_value,sign) Deposit_dsign(dbl_value,sign)
+#define Dbl_invert_sign(dbl_value) Deposit_dsign(dbl_value,~Dsign(dbl_value))
+#define Dbl_setone_sign(dbl_value) Deposit_dsign(dbl_value,1)
+#define Dbl_setone_lowmantissap2(dbl_value) Deposit_dlowp2(dbl_value,1)
+#define Dbl_setzero_sign(dbl_value) Dallp1(dbl_value) &= 0x7fffffff
+#define Dbl_setzero_exponent(dbl_value) \
+ Dallp1(dbl_value) &= 0x800fffff
+#define Dbl_setzero_mantissa(dbl_valueA,dbl_valueB) \
+ Dallp1(dbl_valueA) &= 0xfff00000; \
+ Dallp2(dbl_valueB) = 0
+#define Dbl_setzero_mantissap1(dbl_value) Dallp1(dbl_value) &= 0xfff00000
+#define Dbl_setzero_mantissap2(dbl_value) Dallp2(dbl_value) = 0
+#define Dbl_setzero_exponentmantissa(dbl_valueA,dbl_valueB) \
+ Dallp1(dbl_valueA) &= 0x80000000; \
+ Dallp2(dbl_valueB) = 0
+#define Dbl_setzero_exponentmantissap1(dbl_valueA) \
+ Dallp1(dbl_valueA) &= 0x80000000
+#define Dbl_setzero(dbl_valueA,dbl_valueB) \
+ Dallp1(dbl_valueA) = 0; Dallp2(dbl_valueB) = 0
+#define Dbl_setzerop1(dbl_value) Dallp1(dbl_value) = 0
+#define Dbl_setzerop2(dbl_value) Dallp2(dbl_value) = 0
+#define Dbl_setnegativezero(dbl_value) \
+ Dallp1(dbl_value) = 1 << 31; Dallp2(dbl_value) = 0
+#define Dbl_setnegativezerop1(dbl_value) Dallp1(dbl_value) = 1 << 31
+
+/* Use the following macro for both overflow & underflow conditions */
+#define ovfl -
+#define unfl +
+#define Dbl_setwrapped_exponent(dbl_value,exponent,op) \
+ Deposit_dexponent(dbl_value,(exponent op DBL_WRAP))
+
+#define Dbl_setlargestpositive(dbl_valueA,dbl_valueB) \
+ Dallp1(dbl_valueA) = ((DBL_EMAX+DBL_BIAS) << (32-(1+DBL_EXP_LENGTH))) \
+ | ((1<<(32-(1+DBL_EXP_LENGTH))) - 1 ); \
+ Dallp2(dbl_valueB) = 0xFFFFFFFF
+#define Dbl_setlargestnegative(dbl_valueA,dbl_valueB) \
+ Dallp1(dbl_valueA) = ((DBL_EMAX+DBL_BIAS) << (32-(1+DBL_EXP_LENGTH))) \
+ | ((1<<(32-(1+DBL_EXP_LENGTH))) - 1 ) | (1<<31); \
+ Dallp2(dbl_valueB) = 0xFFFFFFFF
+#define Dbl_setlargest_exponentmantissa(dbl_valueA,dbl_valueB) \
+ Deposit_dexponentmantissap1(dbl_valueA, \
+ (((DBL_EMAX+DBL_BIAS) << (32-(1+DBL_EXP_LENGTH))) \
+ | ((1<<(32-(1+DBL_EXP_LENGTH))) - 1 ))); \
+ Dallp2(dbl_valueB) = 0xFFFFFFFF
+
+#define Dbl_setnegativeinfinity(dbl_valueA,dbl_valueB) \
+ Dallp1(dbl_valueA) = ((1<<DBL_EXP_LENGTH) | DBL_INFINITY_EXPONENT) \
+ << (32-(1+DBL_EXP_LENGTH)) ; \
+ Dallp2(dbl_valueB) = 0
+#define Dbl_setlargest(dbl_valueA,dbl_valueB,sign) \
+ Dallp1(dbl_valueA) = (sign << 31) | \
+ ((DBL_EMAX+DBL_BIAS) << (32-(1+DBL_EXP_LENGTH))) | \
+ ((1 << (32-(1+DBL_EXP_LENGTH))) - 1 ); \
+ Dallp2(dbl_valueB) = 0xFFFFFFFF
+
+
+/* The high bit is always zero so arithmetic or logical shifts will work. */
+#define Dbl_right_align(srcdstA,srcdstB,shift,extent) \
+ if( shift >= 32 ) \
+ { \
+ /* Big shift requires examining the portion shift off \
+ the end to properly set inexact. */ \
+ if(shift < 64) \
+ { \
+ if(shift > 32) \
+ { \
+ Variable_shift_double(Dallp1(srcdstA),Dallp2(srcdstB), \
+ shift-32, Extall(extent)); \
+ if(Dallp2(srcdstB) << 64 - (shift)) Ext_setone_low(extent); \
+ } \
+ else Extall(extent) = Dallp2(srcdstB); \
+ Dallp2(srcdstB) = Dallp1(srcdstA) >> (shift - 32); \
+ } \
+ else \
+ { \
+ Extall(extent) = Dallp1(srcdstA); \
+ if(Dallp2(srcdstB)) Ext_setone_low(extent); \
+ Dallp2(srcdstB) = 0; \
+ } \
+ Dallp1(srcdstA) = 0; \
+ } \
+ else \
+ { \
+ /* Small alignment is simpler. Extension is easily set. */ \
+ if (shift > 0) \
+ { \
+ Extall(extent) = Dallp2(srcdstB) << 32 - (shift); \
+ Variable_shift_double(Dallp1(srcdstA),Dallp2(srcdstB),shift, \
+ Dallp2(srcdstB)); \
+ Dallp1(srcdstA) >>= shift; \
+ } \
+ else Extall(extent) = 0; \
+ }
+
+/*
+ * Here we need to shift the result right to correct for an overshift
+ * (due to the exponent becoming negative) during normalization.
+ */
+#define Dbl_fix_overshift(srcdstA,srcdstB,shift,extent) \
+ Extall(extent) = Dallp2(srcdstB) << 32 - (shift); \
+ Dallp2(srcdstB) = (Dallp1(srcdstA) << 32 - (shift)) | \
+ (Dallp2(srcdstB) >> (shift)); \
+ Dallp1(srcdstA) = Dallp1(srcdstA) >> shift
+
+#define Dbl_hiddenhigh3mantissa(dbl_value) Dhiddenhigh3mantissa(dbl_value)
+#define Dbl_hidden(dbl_value) Dhidden(dbl_value)
+#define Dbl_lowmantissap2(dbl_value) Dlowp2(dbl_value)
+
+/* The left argument is never smaller than the right argument */
+#define Dbl_subtract(lefta,leftb,righta,rightb,resulta,resultb) \
+ if( Dallp2(rightb) > Dallp2(leftb) ) Dallp1(lefta)--; \
+ Dallp2(resultb) = Dallp2(leftb) - Dallp2(rightb); \
+ Dallp1(resulta) = Dallp1(lefta) - Dallp1(righta)
+
+/* Subtract right augmented with extension from left augmented with zeros and
+ * store into result and extension. */
+#define Dbl_subtract_withextension(lefta,leftb,righta,rightb,extent,resulta,resultb) \
+ Dbl_subtract(lefta,leftb,righta,rightb,resulta,resultb); \
+ if( (Extall(extent) = 0-Extall(extent)) ) \
+ { \
+ if((Dallp2(resultb)--) == 0) Dallp1(resulta)--; \
+ }
+
+#define Dbl_addition(lefta,leftb,righta,rightb,resulta,resultb) \
+ /* If the sum of the low words is less than either source, then \
+ * an overflow into the next word occurred. */ \
+ Dallp1(resulta) = Dallp1(lefta) + Dallp1(righta); \
+ if((Dallp2(resultb) = Dallp2(leftb) + Dallp2(rightb)) < Dallp2(rightb)) \
+ Dallp1(resulta)++
+
+#define Dbl_xortointp1(left,right,result) \
+ result = Dallp1(left) XOR Dallp1(right)
+
+#define Dbl_xorfromintp1(left,right,result) \
+ Dallp1(result) = left XOR Dallp1(right)
+
+#define Dbl_swap_lower(left,right) \
+ Dallp2(left) = Dallp2(left) XOR Dallp2(right); \
+ Dallp2(right) = Dallp2(left) XOR Dallp2(right); \
+ Dallp2(left) = Dallp2(left) XOR Dallp2(right)
+
+/* Need to Initialize */
+#define Dbl_makequietnan(desta,destb) \
+ Dallp1(desta) = ((DBL_EMAX+DBL_BIAS)+1)<< (32-(1+DBL_EXP_LENGTH)) \
+ | (1<<(32-(1+DBL_EXP_LENGTH+2))); \
+ Dallp2(destb) = 0
+#define Dbl_makesignalingnan(desta,destb) \
+ Dallp1(desta) = ((DBL_EMAX+DBL_BIAS)+1)<< (32-(1+DBL_EXP_LENGTH)) \
+ | (1<<(32-(1+DBL_EXP_LENGTH+1))); \
+ Dallp2(destb) = 0
+
+#define Dbl_normalize(dbl_opndA,dbl_opndB,exponent) \
+ while(Dbl_iszero_hiddenhigh7mantissa(dbl_opndA)) { \
+ Dbl_leftshiftby8(dbl_opndA,dbl_opndB); \
+ exponent -= 8; \
+ } \
+ if(Dbl_iszero_hiddenhigh3mantissa(dbl_opndA)) { \
+ Dbl_leftshiftby4(dbl_opndA,dbl_opndB); \
+ exponent -= 4; \
+ } \
+ while(Dbl_iszero_hidden(dbl_opndA)) { \
+ Dbl_leftshiftby1(dbl_opndA,dbl_opndB); \
+ exponent -= 1; \
+ }
+
+#define Twoword_add(src1dstA,src1dstB,src2A,src2B) \
+ /* \
+ * want this macro to generate: \
+ * ADD src1dstB,src2B,src1dstB; \
+ * ADDC src1dstA,src2A,src1dstA; \
+ */ \
+ if ((src1dstB) + (src2B) < (src1dstB)) Dallp1(src1dstA)++; \
+ Dallp1(src1dstA) += (src2A); \
+ Dallp2(src1dstB) += (src2B)
+
+#define Twoword_subtract(src1dstA,src1dstB,src2A,src2B) \
+ /* \
+ * want this macro to generate: \
+ * SUB src1dstB,src2B,src1dstB; \
+ * SUBB src1dstA,src2A,src1dstA; \
+ */ \
+ if ((src1dstB) < (src2B)) Dallp1(src1dstA)--; \
+ Dallp1(src1dstA) -= (src2A); \
+ Dallp2(src1dstB) -= (src2B)
+
+#define Dbl_setoverflow(resultA,resultB) \
+ /* set result to infinity or largest number */ \
+ switch (Rounding_mode()) { \
+ case ROUNDPLUS: \
+ if (Dbl_isone_sign(resultA)) { \
+ Dbl_setlargestnegative(resultA,resultB); \
+ } \
+ else { \
+ Dbl_setinfinitypositive(resultA,resultB); \
+ } \
+ break; \
+ case ROUNDMINUS: \
+ if (Dbl_iszero_sign(resultA)) { \
+ Dbl_setlargestpositive(resultA,resultB); \
+ } \
+ else { \
+ Dbl_setinfinitynegative(resultA,resultB); \
+ } \
+ break; \
+ case ROUNDNEAREST: \
+ Dbl_setinfinity_exponentmantissa(resultA,resultB); \
+ break; \
+ case ROUNDZERO: \
+ Dbl_setlargest_exponentmantissa(resultA,resultB); \
+ }
+
+#define Dbl_denormalize(opndp1,opndp2,exponent,guard,sticky,inexact) \
+ Dbl_clear_signexponent_set_hidden(opndp1); \
+ if (exponent >= (1-DBL_P)) { \
+ if (exponent >= -31) { \
+ guard = (Dallp2(opndp2) >> -exponent) & 1; \
+ if (exponent < 0) sticky |= Dallp2(opndp2) << (32+exponent); \
+ if (exponent > -31) { \
+ Variable_shift_double(opndp1,opndp2,1-exponent,opndp2); \
+ Dallp1(opndp1) >>= 1-exponent; \
+ } \
+ else { \
+ Dallp2(opndp2) = Dallp1(opndp1); \
+ Dbl_setzerop1(opndp1); \
+ } \
+ } \
+ else { \
+ guard = (Dallp1(opndp1) >> -32-exponent) & 1; \
+ if (exponent == -32) sticky |= Dallp2(opndp2); \
+ else sticky |= (Dallp2(opndp2) | Dallp1(opndp1) << 64+exponent); \
+ Dallp2(opndp2) = Dallp1(opndp1) >> -31-exponent; \
+ Dbl_setzerop1(opndp1); \
+ } \
+ inexact = guard | sticky; \
+ } \
+ else { \
+ guard = 0; \
+ sticky |= (Dallp1(opndp1) | Dallp2(opndp2)); \
+ Dbl_setzero(opndp1,opndp2); \
+ inexact = sticky; \
+ }
diff --git a/sys/arch/hppa/spmath/dfadd.c b/sys/arch/hppa/spmath/dfadd.c
new file mode 100644
index 00000000000..a6a28f88457
--- /dev/null
+++ b/sys/arch/hppa/spmath/dfadd.c
@@ -0,0 +1,524 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/dfadd.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:51 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/dbl_float.h"
+
+/*
+ * Double_add: add two double precision values.
+ */
+dbl_fadd(leftptr, rightptr, dstptr, status)
+ dbl_floating_point *leftptr, *rightptr, *dstptr;
+ unsigned int *status;
+ {
+ register unsigned int signless_upper_left, signless_upper_right, save;
+ register unsigned int leftp1, leftp2, rightp1, rightp2, extent;
+ register unsigned int resultp1 = 0, resultp2 = 0;
+
+ register int result_exponent, right_exponent, diff_exponent;
+ register int sign_save, jumpsize;
+ register boolean inexact = FALSE;
+ register boolean underflowtrap;
+
+ /* Create local copies of the numbers */
+ Dbl_copyfromptr(leftptr,leftp1,leftp2);
+ Dbl_copyfromptr(rightptr,rightp1,rightp2);
+
+ /* A zero "save" helps discover equal operands (for later), *
+ * and is used in swapping operands (if needed). */
+ Dbl_xortointp1(leftp1,rightp1,/*to*/save);
+
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if ((result_exponent = Dbl_exponent(leftp1)) == DBL_INFINITY_EXPONENT)
+ {
+ if (Dbl_iszero_mantissa(leftp1,leftp2))
+ {
+ if (Dbl_isnotnan(rightp1,rightp2))
+ {
+ if (Dbl_isinfinity(rightp1,rightp2) && save!=0)
+ {
+ /*
+ * invalid since operands are opposite signed infinity's
+ */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Dbl_makequietnan(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ Dbl_copytoptr(leftp1,leftp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ else
+ {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(leftp1))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(leftp1);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Dbl_is_signalingnan(rightp1))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(rightp1);
+ Dbl_copytoptr(rightp1,rightp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(leftp1,leftp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ } /* End left NaN or Infinity processing */
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if (Dbl_isinfinity_exponent(rightp1))
+ {
+ if (Dbl_iszero_mantissa(rightp1,rightp2))
+ {
+ /* return infinity */
+ Dbl_copytoptr(rightp1,rightp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(rightp1))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(rightp1);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(rightp1,rightp2,dstptr);
+ return(NOEXCEPTION);
+ } /* End right NaN or Infinity processing */
+
+ /* Invariant: Must be dealing with finite numbers */
+
+ /* Compare operands by removing the sign */
+ Dbl_copytoint_exponentmantissap1(leftp1,signless_upper_left);
+ Dbl_copytoint_exponentmantissap1(rightp1,signless_upper_right);
+
+ /* sign difference selects add or sub operation. */
+ if(Dbl_ismagnitudeless(leftp2,rightp2,signless_upper_left,signless_upper_right))
+ {
+ /* Set the left operand to the larger one by XOR swap *
+ * First finish the first word using "save" */
+ Dbl_xorfromintp1(save,rightp1,/*to*/rightp1);
+ Dbl_xorfromintp1(save,leftp1,/*to*/leftp1);
+ Dbl_swap_lower(leftp2,rightp2);
+ result_exponent = Dbl_exponent(leftp1);
+ }
+ /* Invariant: left is not smaller than right. */
+
+ if((right_exponent = Dbl_exponent(rightp1)) == 0)
+ {
+ /* Denormalized operands. First look for zeroes */
+ if(Dbl_iszero_mantissa(rightp1,rightp2))
+ {
+ /* right is zero */
+ if(Dbl_iszero_exponentmantissa(leftp1,leftp2))
+ {
+ /* Both operands are zeros */
+ if(Is_rounding_mode(ROUNDMINUS))
+ {
+ Dbl_or_signs(leftp1,/*with*/rightp1);
+ }
+ else
+ {
+ Dbl_and_signs(leftp1,/*with*/rightp1);
+ }
+ }
+ else
+ {
+ /* Left is not a zero and must be the result. Trapped
+ * underflows are signaled if left is denormalized. Result
+ * is always exact. */
+ if( (result_exponent == 0) && Is_underflowtrap_enabled() )
+ {
+ /* need to normalize results mantissa */
+ sign_save = Dbl_signextendedsign(leftp1);
+ Dbl_leftshiftby1(leftp1,leftp2);
+ Dbl_normalize(leftp1,leftp2,result_exponent);
+ Dbl_set_sign(leftp1,/*using*/sign_save);
+ Dbl_setwrapped_exponent(leftp1,result_exponent,unfl);
+ Dbl_copytoptr(leftp1,leftp2,dstptr);
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ }
+ Dbl_copytoptr(leftp1,leftp2,dstptr);
+ return(NOEXCEPTION);
+ }
+
+ /* Neither are zeroes */
+ Dbl_clear_sign(rightp1); /* Exponent is already cleared */
+ if(result_exponent == 0 )
+ {
+ /* Both operands are denormalized. The result must be exact
+ * and is simply calculated. A sum could become normalized and a
+ * difference could cancel to a true zero. */
+ if( (/*signed*/int) save < 0 )
+ {
+ Dbl_subtract(leftp1,leftp2,/*minus*/rightp1,rightp2,
+ /*into*/resultp1,resultp2);
+ if(Dbl_iszero_mantissa(resultp1,resultp2))
+ {
+ if(Is_rounding_mode(ROUNDMINUS))
+ {
+ Dbl_setone_sign(resultp1);
+ }
+ else
+ {
+ Dbl_setzero_sign(resultp1);
+ }
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ else
+ {
+ Dbl_addition(leftp1,leftp2,rightp1,rightp2,
+ /*into*/resultp1,resultp2);
+ if(Dbl_isone_hidden(resultp1))
+ {
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ if(Is_underflowtrap_enabled())
+ {
+ /* need to normalize result */
+ sign_save = Dbl_signextendedsign(resultp1);
+ Dbl_leftshiftby1(resultp1,resultp2);
+ Dbl_normalize(resultp1,resultp2,result_exponent);
+ Dbl_set_sign(resultp1,/*using*/sign_save);
+ Dbl_setwrapped_exponent(resultp1,result_exponent,unfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ right_exponent = 1; /* Set exponent to reflect different bias
+ * with denomalized numbers. */
+ }
+ else
+ {
+ Dbl_clear_signexponent_set_hidden(rightp1);
+ }
+ Dbl_clear_exponent_set_hidden(leftp1);
+ diff_exponent = result_exponent - right_exponent;
+
+ /*
+ * Special case alignment of operands that would force alignment
+ * beyond the extent of the extension. A further optimization
+ * could special case this but only reduces the path length for this
+ * infrequent case.
+ */
+ if(diff_exponent > DBL_THRESHOLD)
+ {
+ diff_exponent = DBL_THRESHOLD;
+ }
+
+ /* Align right operand by shifting to right */
+ Dbl_right_align(/*operand*/rightp1,rightp2,/*shifted by*/diff_exponent,
+ /*and lower to*/extent);
+
+ /* Treat sum and difference of the operands separately. */
+ if( (/*signed*/int) save < 0 )
+ {
+ /*
+ * Difference of the two operands. Their can be no overflow. A
+ * borrow can occur out of the hidden bit and force a post
+ * normalization phase.
+ */
+ Dbl_subtract_withextension(leftp1,leftp2,/*minus*/rightp1,rightp2,
+ /*with*/extent,/*into*/resultp1,resultp2);
+ if(Dbl_iszero_hidden(resultp1))
+ {
+ /* Handle normalization */
+ /* A straight foward algorithm would now shift the result
+ * and extension left until the hidden bit becomes one. Not
+ * all of the extension bits need participate in the shift.
+ * Only the two most significant bits (round and guard) are
+ * needed. If only a single shift is needed then the guard
+ * bit becomes a significant low order bit and the extension
+ * must participate in the rounding. If more than a single
+ * shift is needed, then all bits to the right of the guard
+ * bit are zeros, and the guard bit may or may not be zero. */
+ sign_save = Dbl_signextendedsign(resultp1);
+ Dbl_leftshiftby1_withextent(resultp1,resultp2,extent,resultp1,resultp2);
+
+ /* Need to check for a zero result. The sign and exponent
+ * fields have already been zeroed. The more efficient test
+ * of the full object can be used.
+ */
+ if(Dbl_iszero(resultp1,resultp2))
+ /* Must have been "x-x" or "x+(-x)". */
+ {
+ if(Is_rounding_mode(ROUNDMINUS)) Dbl_setone_sign(resultp1);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ result_exponent--;
+ /* Look to see if normalization is finished. */
+ if(Dbl_isone_hidden(resultp1))
+ {
+ if(result_exponent==0)
+ {
+ /* Denormalized, exponent should be zero. Left operand *
+ * was normalized, so extent (guard, round) was zero */
+ goto underflow;
+ }
+ else
+ {
+ /* No further normalization is needed. */
+ Dbl_set_sign(resultp1,/*using*/sign_save);
+ Ext_leftshiftby1(extent);
+ goto round;
+ }
+ }
+
+ /* Check for denormalized, exponent should be zero. Left *
+ * operand was normalized, so extent (guard, round) was zero */
+ if(!(underflowtrap = Is_underflowtrap_enabled()) &&
+ result_exponent==0) goto underflow;
+
+ /* Shift extension to complete one bit of normalization and
+ * update exponent. */
+ Ext_leftshiftby1(extent);
+
+ /* Discover first one bit to determine shift amount. Use a
+ * modified binary search. We have already shifted the result
+ * one position right and still not found a one so the remainder
+ * of the extension must be zero and simplifies rounding. */
+ /* Scan bytes */
+ while(Dbl_iszero_hiddenhigh7mantissa(resultp1))
+ {
+ Dbl_leftshiftby8(resultp1,resultp2);
+ if((result_exponent -= 8) <= 0 && !underflowtrap)
+ goto underflow;
+ }
+ /* Now narrow it down to the nibble */
+ if(Dbl_iszero_hiddenhigh3mantissa(resultp1))
+ {
+ /* The lower nibble contains the normalizing one */
+ Dbl_leftshiftby4(resultp1,resultp2);
+ if((result_exponent -= 4) <= 0 && !underflowtrap)
+ goto underflow;
+ }
+ /* Select case were first bit is set (already normalized)
+ * otherwise select the proper shift. */
+ if((jumpsize = Dbl_hiddenhigh3mantissa(resultp1)) > 7)
+ {
+ /* Already normalized */
+ if(result_exponent <= 0) goto underflow;
+ Dbl_set_sign(resultp1,/*using*/sign_save);
+ Dbl_set_exponent(resultp1,/*using*/result_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ Dbl_sethigh4bits(resultp1,/*using*/sign_save);
+ switch(jumpsize)
+ {
+ case 1:
+ {
+ Dbl_leftshiftby3(resultp1,resultp2);
+ result_exponent -= 3;
+ break;
+ }
+ case 2:
+ case 3:
+ {
+ Dbl_leftshiftby2(resultp1,resultp2);
+ result_exponent -= 2;
+ break;
+ }
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ {
+ Dbl_leftshiftby1(resultp1,resultp2);
+ result_exponent -= 1;
+ break;
+ }
+ }
+ if(result_exponent > 0)
+ {
+ Dbl_set_exponent(resultp1,/*using*/result_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION); /* Sign bit is already set */
+ }
+ /* Fixup potential underflows */
+ underflow:
+ if(Is_underflowtrap_enabled())
+ {
+ Dbl_set_sign(resultp1,sign_save);
+ Dbl_setwrapped_exponent(resultp1,result_exponent,unfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ /*
+ * Since we cannot get an inexact denormalized result,
+ * we can now return.
+ */
+ Dbl_fix_overshift(resultp1,resultp2,(1-result_exponent),extent);
+ Dbl_clear_signexponent(resultp1);
+ Dbl_set_sign(resultp1,sign_save);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ } /* end if(hidden...)... */
+ /* Fall through and round */
+ } /* end if(save < 0)... */
+ else
+ {
+ /* Add magnitudes */
+ Dbl_addition(leftp1,leftp2,rightp1,rightp2,/*to*/resultp1,resultp2);
+ if(Dbl_isone_hiddenoverflow(resultp1))
+ {
+ /* Prenormalization required. */
+ Dbl_rightshiftby1_withextent(resultp2,extent,extent);
+ Dbl_arithrightshiftby1(resultp1,resultp2);
+ result_exponent++;
+ } /* end if hiddenoverflow... */
+ } /* end else ...add magnitudes... */
+
+ /* Round the result. If the extension is all zeros,then the result is
+ * exact. Otherwise round in the correct direction. No underflow is
+ * possible. If a postnormalization is necessary, then the mantissa is
+ * all zeros so no shift is needed. */
+ round:
+ if(Ext_isnotzero(extent))
+ {
+ inexact = TRUE;
+ switch(Rounding_mode())
+ {
+ case ROUNDNEAREST: /* The default. */
+ if(Ext_isone_sign(extent))
+ {
+ /* at least 1/2 ulp */
+ if(Ext_isnotzero_lower(extent) ||
+ Dbl_isone_lowmantissap2(resultp2))
+ {
+ /* either exactly half way and odd or more than 1/2ulp */
+ Dbl_increment(resultp1,resultp2);
+ }
+ }
+ break;
+
+ case ROUNDPLUS:
+ if(Dbl_iszero_sign(resultp1))
+ {
+ /* Round up positive results */
+ Dbl_increment(resultp1,resultp2);
+ }
+ break;
+
+ case ROUNDMINUS:
+ if(Dbl_isone_sign(resultp1))
+ {
+ /* Round down negative results */
+ Dbl_increment(resultp1,resultp2);
+ }
+
+ case ROUNDZERO:;
+ /* truncate is simple */
+ } /* end switch... */
+ if(Dbl_isone_hiddenoverflow(resultp1)) result_exponent++;
+ }
+ if(result_exponent == DBL_INFINITY_EXPONENT)
+ {
+ /* Overflow */
+ if(Is_overflowtrap_enabled())
+ {
+ Dbl_setwrapped_exponent(resultp1,result_exponent,ovfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(OVERFLOWEXCEPTION);
+ }
+ else
+ {
+ inexact = TRUE;
+ Set_overflowflag();
+ Dbl_setoverflow(resultp1,resultp2);
+ }
+ }
+ else Dbl_set_exponent(resultp1,result_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if(inexact)
+ if(Is_inexacttrap_enabled())
+ return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(NOEXCEPTION);
+ }
diff --git a/sys/arch/hppa/spmath/dfcmp.c b/sys/arch/hppa/spmath/dfcmp.c
new file mode 100644
index 00000000000..070010eba01
--- /dev/null
+++ b/sys/arch/hppa/spmath/dfcmp.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/dfcmp.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:52 $
+ */
+
+
+#include "../spmath/float.h"
+#include "../spmath/dbl_float.h"
+
+/*
+ * dbl_cmp: compare two values
+ */
+dbl_fcmp(leftptr, rightptr, cond, status)
+ dbl_floating_point *leftptr, *rightptr;
+ unsigned int cond; /* The predicate to be tested */
+ unsigned int *status;
+ {
+ register unsigned int leftp1, leftp2, rightp1, rightp2;
+ register int xorresult;
+
+ /* Create local copies of the numbers */
+ Dbl_copyfromptr(leftptr,leftp1,leftp2);
+ Dbl_copyfromptr(rightptr,rightp1,rightp2);
+ /*
+ * Test for NaN
+ */
+ if( (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
+ || (Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) )
+ {
+ /* Check if a NaN is involved. Signal an invalid exception when
+ * comparing a signaling NaN or when comparing quiet NaNs and the
+ * low bit of the condition is set */
+ if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
+ && Dbl_isnotzero_mantissa(leftp1,leftp2)
+ && (Exception(cond) || Dbl_isone_signaling(leftp1)))
+ ||
+ ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
+ && Dbl_isnotzero_mantissa(rightp1,rightp2)
+ && (Exception(cond) || Dbl_isone_signaling(rightp1))) )
+ {
+ if( Is_invalidtrap_enabled() ) {
+ Set_status_cbit(Unordered(cond));
+ return(INVALIDEXCEPTION);
+ }
+ else Set_invalidflag();
+ Set_status_cbit(Unordered(cond));
+ return(NOEXCEPTION);
+ }
+ /* All the exceptional conditions are handled, now special case
+ NaN compares */
+ else if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
+ && Dbl_isnotzero_mantissa(leftp1,leftp2))
+ ||
+ ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
+ && Dbl_isnotzero_mantissa(rightp1,rightp2)) )
+ {
+ /* NaNs always compare unordered. */
+ Set_status_cbit(Unordered(cond));
+ return(NOEXCEPTION);
+ }
+ /* infinities will drop down to the normal compare mechanisms */
+ }
+ /* First compare for unequal signs => less or greater or
+ * special equal case */
+ Dbl_xortointp1(leftp1,rightp1,xorresult);
+ if( xorresult < 0 )
+ {
+ /* left negative => less, left positive => greater.
+ * equal is possible if both operands are zeros. */
+ if( Dbl_iszero_exponentmantissa(leftp1,leftp2)
+ && Dbl_iszero_exponentmantissa(rightp1,rightp2) )
+ {
+ Set_status_cbit(Equal(cond));
+ }
+ else if( Dbl_isone_sign(leftp1) )
+ {
+ Set_status_cbit(Lessthan(cond));
+ }
+ else
+ {
+ Set_status_cbit(Greaterthan(cond));
+ }
+ }
+ /* Signs are the same. Treat negative numbers separately
+ * from the positives because of the reversed sense. */
+ else if(Dbl_isequal(leftp1,leftp2,rightp1,rightp2))
+ {
+ Set_status_cbit(Equal(cond));
+ }
+ else if( Dbl_iszero_sign(leftp1) )
+ {
+ /* Positive compare */
+ if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
+ {
+ Set_status_cbit(Lessthan(cond));
+ }
+ else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
+ {
+ Set_status_cbit(Greaterthan(cond));
+ }
+ else
+ {
+ /* Equal first parts. Now we must use unsigned compares to
+ * resolve the two possibilities. */
+ if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) )
+ {
+ Set_status_cbit(Lessthan(cond));
+ }
+ else
+ {
+ Set_status_cbit(Greaterthan(cond));
+ }
+ }
+ }
+ else
+ {
+ /* Negative compare. Signed or unsigned compares
+ * both work the same. That distinction is only
+ * important when the sign bits differ. */
+ if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
+ {
+ Set_status_cbit(Lessthan(cond));
+ }
+ else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
+ {
+ Set_status_cbit(Greaterthan(cond));
+ }
+ else
+ {
+ /* Equal first parts. Now we must use unsigned compares to
+ * resolve the two possibilities. */
+ if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) )
+ {
+ Set_status_cbit(Lessthan(cond));
+ }
+ else
+ {
+ Set_status_cbit(Greaterthan(cond));
+ }
+ }
+ }
+ return(NOEXCEPTION);
+ }
diff --git a/sys/arch/hppa/spmath/dfdiv.c b/sys/arch/hppa/spmath/dfdiv.c
new file mode 100644
index 00000000000..8f331698431
--- /dev/null
+++ b/sys/arch/hppa/spmath/dfdiv.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/dfdiv.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:52 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/dbl_float.h"
+
+/*
+ * Double Precision Floating-point Divide
+ */
+
+dbl_fdiv(srcptr1,srcptr2,dstptr,status)
+
+dbl_floating_point *srcptr1, *srcptr2, *dstptr;
+unsigned int *status;
+{
+ register unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2;
+ register unsigned int opnd3p1, opnd3p2, resultp1, resultp2;
+ register int dest_exponent, count;
+ register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
+ boolean is_tiny;
+
+ Dbl_copyfromptr(srcptr1,opnd1p1,opnd1p2);
+ Dbl_copyfromptr(srcptr2,opnd2p1,opnd2p2);
+ /*
+ * set sign bit of result
+ */
+ if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1))
+ Dbl_setnegativezerop1(resultp1);
+ else Dbl_setzerop1(resultp1);
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if (Dbl_isinfinity_exponent(opnd1p1)) {
+ if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
+ if (Dbl_isnotnan(opnd2p1,opnd2p2)) {
+ if (Dbl_isinfinity(opnd2p1,opnd2p2)) {
+ /*
+ * invalid since both operands
+ * are infinity
+ */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Dbl_makequietnan(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ else {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(opnd1p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd1p1);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Dbl_is_signalingnan(opnd2p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd2p1);
+ Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if (Dbl_isinfinity_exponent(opnd2p1)) {
+ if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
+ /*
+ * return zero
+ */
+ Dbl_setzero_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(opnd2p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd2p1);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * check for division by zero
+ */
+ if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
+ if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) {
+ /* invalid since both operands are zero */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Dbl_makequietnan(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ if (Is_divisionbyzerotrap_enabled())
+ return(DIVISIONBYZEROEXCEPTION);
+ Set_divisionbyzeroflag();
+ Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate exponent
+ */
+ dest_exponent = Dbl_exponent(opnd1p1) - Dbl_exponent(opnd2p1) + DBL_BIAS;
+
+ /*
+ * Generate mantissa
+ */
+ if (Dbl_isnotzero_exponent(opnd1p1)) {
+ /* set hidden bit */
+ Dbl_clear_signexponent_set_hidden(opnd1p1);
+ }
+ else {
+ /* check for zero */
+ if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
+ Dbl_setzero_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /* is denormalized, want to normalize */
+ Dbl_clear_signexponent(opnd1p1);
+ Dbl_leftshiftby1(opnd1p1,opnd1p2);
+ Dbl_normalize(opnd1p1,opnd1p2,dest_exponent);
+ }
+ /* opnd2 needs to have hidden bit set with msb in hidden bit */
+ if (Dbl_isnotzero_exponent(opnd2p1)) {
+ Dbl_clear_signexponent_set_hidden(opnd2p1);
+ }
+ else {
+ /* is denormalized; want to normalize */
+ Dbl_clear_signexponent(opnd2p1);
+ Dbl_leftshiftby1(opnd2p1,opnd2p2);
+ while (Dbl_iszero_hiddenhigh7mantissa(opnd2p1)) {
+ dest_exponent+=8;
+ Dbl_leftshiftby8(opnd2p1,opnd2p2);
+ }
+ if (Dbl_iszero_hiddenhigh3mantissa(opnd2p1)) {
+ dest_exponent+=4;
+ Dbl_leftshiftby4(opnd2p1,opnd2p2);
+ }
+ while (Dbl_iszero_hidden(opnd2p1)) {
+ dest_exponent++;
+ Dbl_leftshiftby1(opnd2p1,opnd2p2);
+ }
+ }
+
+ /* Divide the source mantissas */
+
+ /*
+ * A non-restoring divide algorithm is used.
+ */
+ Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2);
+ Dbl_setzero(opnd3p1,opnd3p2);
+ for (count=1; count <= DBL_P && (opnd1p1 || opnd1p2); count++) {
+ Dbl_leftshiftby1(opnd1p1,opnd1p2);
+ Dbl_leftshiftby1(opnd3p1,opnd3p2);
+ if (Dbl_iszero_sign(opnd1p1)) {
+ Dbl_setone_lowmantissap2(opnd3p2);
+ Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2);
+ }
+ else {
+ Twoword_add(opnd1p1, opnd1p2, opnd2p1, opnd2p2);
+ }
+ }
+ if (count <= DBL_P) {
+ Dbl_leftshiftby1(opnd3p1,opnd3p2);
+ Dbl_setone_lowmantissap2(opnd3p2);
+ Dbl_leftshift(opnd3p1,opnd3p2,(DBL_P-count));
+ if (Dbl_iszero_hidden(opnd3p1)) {
+ Dbl_leftshiftby1(opnd3p1,opnd3p2);
+ dest_exponent--;
+ }
+ }
+ else {
+ if (Dbl_iszero_hidden(opnd3p1)) {
+ /* need to get one more bit of result */
+ Dbl_leftshiftby1(opnd1p1,opnd1p2);
+ Dbl_leftshiftby1(opnd3p1,opnd3p2);
+ if (Dbl_iszero_sign(opnd1p1)) {
+ Dbl_setone_lowmantissap2(opnd3p2);
+ Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2);
+ }
+ else {
+ Twoword_add(opnd1p1,opnd1p2,opnd2p1,opnd2p2);
+ }
+ dest_exponent--;
+ }
+ if (Dbl_iszero_sign(opnd1p1)) guardbit = TRUE;
+ stickybit = Dbl_allp1(opnd1p1) || Dbl_allp2(opnd1p2);
+ }
+ inexact = guardbit | stickybit;
+
+ /*
+ * round result
+ */
+ if (inexact && (dest_exponent > 0 || Is_underflowtrap_enabled())) {
+ Dbl_clear_signexponent(opnd3p1);
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(resultp1))
+ Dbl_increment(opnd3p1,opnd3p2);
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(resultp1))
+ Dbl_increment(opnd3p1,opnd3p2);
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Dbl_isone_lowmantissap2(opnd3p2))) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ }
+ }
+ if (Dbl_isone_hidden(opnd3p1)) dest_exponent++;
+ }
+ Dbl_set_mantissa(resultp1,resultp2,opnd3p1,opnd3p2);
+
+ /*
+ * Test for overflow
+ */
+ if (dest_exponent >= DBL_INFINITY_EXPONENT) {
+ /* trap if OVERFLOWTRAP enabled */
+ if (Is_overflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Dbl_setwrapped_exponent(resultp1,dest_exponent,ovfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(OVERFLOWEXCEPTION);
+ }
+ Set_overflowflag();
+ /* set result to infinity or largest number */
+ Dbl_setoverflow(resultp1,resultp2);
+ inexact = TRUE;
+ }
+ /*
+ * Test for underflow
+ */
+ else if (dest_exponent <= 0) {
+ /* trap if UNDERFLOWTRAP enabled */
+ if (Is_underflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Dbl_setwrapped_exponent(resultp1,dest_exponent,unfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(UNDERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(UNDERFLOWEXCEPTION);
+ }
+
+ /* Determine if should set underflow flag */
+ is_tiny = TRUE;
+ if (dest_exponent == 0 && inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(resultp1)) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ if (Dbl_isone_hiddenoverflow(opnd3p1))
+ is_tiny = FALSE;
+ Dbl_decrement(opnd3p1,opnd3p2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(resultp1)) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ if (Dbl_isone_hiddenoverflow(opnd3p1))
+ is_tiny = FALSE;
+ Dbl_decrement(opnd3p1,opnd3p2);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Dbl_isone_lowmantissap2(opnd3p2))) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ if (Dbl_isone_hiddenoverflow(opnd3p1))
+ is_tiny = FALSE;
+ Dbl_decrement(opnd3p1,opnd3p2);
+ }
+ break;
+ }
+ }
+
+ /*
+ * denormalize result or set to signed zero
+ */
+ stickybit = inexact;
+ Dbl_denormalize(opnd3p1,opnd3p2,dest_exponent,guardbit,
+ stickybit,inexact);
+
+ /* return rounded number */
+ if (inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(resultp1)) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(resultp1)) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Dbl_isone_lowmantissap2(opnd3p2))) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ }
+ break;
+ }
+ if (is_tiny) Set_underflowflag();
+ }
+ Dbl_set_exponentmantissa(resultp1,resultp2,opnd3p1,opnd3p2);
+ }
+ else Dbl_set_exponent(resultp1,dest_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+
+ /* check for inexact */
+ if (inexact) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/dfmpy.c b/sys/arch/hppa/spmath/dfmpy.c
new file mode 100644
index 00000000000..77e56a024b6
--- /dev/null
+++ b/sys/arch/hppa/spmath/dfmpy.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/dfmpy.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:53 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/dbl_float.h"
+
+/*
+ * Double Precision Floating-point Multiply
+ */
+
+dbl_fmpy(srcptr1,srcptr2,dstptr,status)
+
+dbl_floating_point *srcptr1, *srcptr2, *dstptr;
+unsigned int *status;
+{
+ register unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2;
+ register unsigned int opnd3p1, opnd3p2, resultp1, resultp2;
+ register int dest_exponent, count;
+ register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
+ boolean is_tiny;
+
+ Dbl_copyfromptr(srcptr1,opnd1p1,opnd1p2);
+ Dbl_copyfromptr(srcptr2,opnd2p1,opnd2p2);
+
+ /*
+ * set sign bit of result
+ */
+ if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1))
+ Dbl_setnegativezerop1(resultp1);
+ else Dbl_setzerop1(resultp1);
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if (Dbl_isinfinity_exponent(opnd1p1)) {
+ if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
+ if (Dbl_isnotnan(opnd2p1,opnd2p2)) {
+ if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
+ /*
+ * invalid since operands are infinity
+ * and zero
+ */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Dbl_makequietnan(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ else {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(opnd1p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd1p1);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Dbl_is_signalingnan(opnd2p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd2p1);
+ Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if (Dbl_isinfinity_exponent(opnd2p1)) {
+ if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
+ if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) {
+ /* invalid since operands are zero & infinity */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Dbl_makequietnan(opnd2p1,opnd2p2);
+ Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(opnd2p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd2p1);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate exponent
+ */
+ dest_exponent = Dbl_exponent(opnd1p1) + Dbl_exponent(opnd2p1) -DBL_BIAS;
+
+ /*
+ * Generate mantissa
+ */
+ if (Dbl_isnotzero_exponent(opnd1p1)) {
+ /* set hidden bit */
+ Dbl_clear_signexponent_set_hidden(opnd1p1);
+ }
+ else {
+ /* check for zero */
+ if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
+ Dbl_setzero_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /* is denormalized, adjust exponent */
+ Dbl_clear_signexponent(opnd1p1);
+ Dbl_leftshiftby1(opnd1p1,opnd1p2);
+ Dbl_normalize(opnd1p1,opnd1p2,dest_exponent);
+ }
+ /* opnd2 needs to have hidden bit set with msb in hidden bit */
+ if (Dbl_isnotzero_exponent(opnd2p1)) {
+ Dbl_clear_signexponent_set_hidden(opnd2p1);
+ }
+ else {
+ /* check for zero */
+ if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
+ Dbl_setzero_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /* is denormalized; want to normalize */
+ Dbl_clear_signexponent(opnd2p1);
+ Dbl_leftshiftby1(opnd2p1,opnd2p2);
+ Dbl_normalize(opnd2p1,opnd2p2,dest_exponent);
+ }
+
+ /* Multiply two source mantissas together */
+
+ /* make room for guard bits */
+ Dbl_leftshiftby7(opnd2p1,opnd2p2);
+ Dbl_setzero(opnd3p1,opnd3p2);
+ /*
+ * Four bits at a time are inspected in each loop, and a
+ * simple shift and add multiply algorithm is used.
+ */
+ for (count=1;count<=DBL_P;count+=4) {
+ stickybit |= Dlow4p2(opnd3p2);
+ Dbl_rightshiftby4(opnd3p1,opnd3p2);
+ if (Dbit28p2(opnd1p2)) {
+ /* Twoword_add should be an ADDC followed by an ADD. */
+ Twoword_add(opnd3p1, opnd3p2, opnd2p1<<3 | opnd2p2>>29,
+ opnd2p2<<3);
+ }
+ if (Dbit29p2(opnd1p2)) {
+ Twoword_add(opnd3p1, opnd3p2, opnd2p1<<2 | opnd2p2>>30,
+ opnd2p2<<2);
+ }
+ if (Dbit30p2(opnd1p2)) {
+ Twoword_add(opnd3p1, opnd3p2, opnd2p1<<1 | opnd2p2>>31,
+ opnd2p2<<1);
+ }
+ if (Dbit31p2(opnd1p2)) {
+ Twoword_add(opnd3p1, opnd3p2, opnd2p1, opnd2p2);
+ }
+ Dbl_rightshiftby4(opnd1p1,opnd1p2);
+ }
+ if (Dbit3p1(opnd3p1)==0) {
+ Dbl_leftshiftby1(opnd3p1,opnd3p2);
+ }
+ else {
+ /* result mantissa >= 2. */
+ dest_exponent++;
+ }
+ /* check for denormalized result */
+ while (Dbit3p1(opnd3p1)==0) {
+ Dbl_leftshiftby1(opnd3p1,opnd3p2);
+ dest_exponent--;
+ }
+ /*
+ * check for guard, sticky and inexact bits
+ */
+ stickybit |= Dallp2(opnd3p2) << 25;
+ guardbit = (Dallp2(opnd3p2) << 24) >> 31;
+ inexact = guardbit | stickybit;
+
+ /* align result mantissa */
+ Dbl_rightshiftby8(opnd3p1,opnd3p2);
+
+ /*
+ * round result
+ */
+ if (inexact && (dest_exponent>0 || Is_underflowtrap_enabled())) {
+ Dbl_clear_signexponent(opnd3p1);
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(resultp1))
+ Dbl_increment(opnd3p1,opnd3p2);
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(resultp1))
+ Dbl_increment(opnd3p1,opnd3p2);
+ break;
+ case ROUNDNEAREST:
+ if (guardbit) {
+ if (stickybit || Dbl_isone_lowmantissap2(opnd3p2))
+ Dbl_increment(opnd3p1,opnd3p2);
+ }
+ }
+ if (Dbl_isone_hidden(opnd3p1)) dest_exponent++;
+ }
+ Dbl_set_mantissa(resultp1,resultp2,opnd3p1,opnd3p2);
+
+ /*
+ * Test for overflow
+ */
+ if (dest_exponent >= DBL_INFINITY_EXPONENT) {
+ /* trap if OVERFLOWTRAP enabled */
+ if (Is_overflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Dbl_setwrapped_exponent(resultp1,dest_exponent,ovfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return (OVERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return (OVERFLOWEXCEPTION);
+ }
+ inexact = TRUE;
+ Set_overflowflag();
+ /* set result to infinity or largest number */
+ Dbl_setoverflow(resultp1,resultp2);
+ }
+ /*
+ * Test for underflow
+ */
+ else if (dest_exponent <= 0) {
+ /* trap if UNDERFLOWTRAP enabled */
+ if (Is_underflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Dbl_setwrapped_exponent(resultp1,dest_exponent,unfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return (UNDERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return (UNDERFLOWEXCEPTION);
+ }
+
+ /* Determine if should set underflow flag */
+ is_tiny = TRUE;
+ if (dest_exponent == 0 && inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(resultp1)) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ if (Dbl_isone_hiddenoverflow(opnd3p1))
+ is_tiny = FALSE;
+ Dbl_decrement(opnd3p1,opnd3p2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(resultp1)) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ if (Dbl_isone_hiddenoverflow(opnd3p1))
+ is_tiny = FALSE;
+ Dbl_decrement(opnd3p1,opnd3p2);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Dbl_isone_lowmantissap2(opnd3p2))) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ if (Dbl_isone_hiddenoverflow(opnd3p1))
+ is_tiny = FALSE;
+ Dbl_decrement(opnd3p1,opnd3p2);
+ }
+ break;
+ }
+ }
+
+ /*
+ * denormalize result or set to signed zero
+ */
+ stickybit = inexact;
+ Dbl_denormalize(opnd3p1,opnd3p2,dest_exponent,guardbit,
+ stickybit,inexact);
+
+ /* return zero or smallest number */
+ if (inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(resultp1)) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(resultp1)) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Dbl_isone_lowmantissap2(opnd3p2))) {
+ Dbl_increment(opnd3p1,opnd3p2);
+ }
+ break;
+ }
+ if (is_tiny) Set_underflowflag();
+ }
+ Dbl_set_exponentmantissa(resultp1,resultp2,opnd3p1,opnd3p2);
+ }
+ else Dbl_set_exponent(resultp1,dest_exponent);
+ /* check for inexact */
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/dfrem.c b/sys/arch/hppa/spmath/dfrem.c
new file mode 100644
index 00000000000..61be22d148a
--- /dev/null
+++ b/sys/arch/hppa/spmath/dfrem.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/dfrem.c,v $
+ * $Revision: 1.1 $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:53 $
+ */
+
+
+#include "../spmath/float.h"
+#include "../spmath/dbl_float.h"
+
+/*
+ * Double Precision Floating-point Remainder
+ */
+
+dbl_frem(srcptr1,srcptr2,dstptr,status)
+
+dbl_floating_point *srcptr1, *srcptr2, *dstptr;
+unsigned int *status;
+{
+ register unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2;
+ register unsigned int resultp1, resultp2;
+ register int opnd1_exponent, opnd2_exponent, dest_exponent, stepcount;
+ register boolean roundup = FALSE;
+
+ Dbl_copyfromptr(srcptr1,opnd1p1,opnd1p2);
+ Dbl_copyfromptr(srcptr2,opnd2p1,opnd2p2);
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if ((opnd1_exponent = Dbl_exponent(opnd1p1)) == DBL_INFINITY_EXPONENT) {
+ if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
+ if (Dbl_isnotnan(opnd2p1,opnd2p2)) {
+ /* invalid since first operand is infinity */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Dbl_makequietnan(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ else {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(opnd1p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd1p1);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Dbl_is_signalingnan(opnd2p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd2p1);
+ Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if ((opnd2_exponent = Dbl_exponent(opnd2p1)) == DBL_INFINITY_EXPONENT) {
+ if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
+ /*
+ * return first operand
+ */
+ Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(opnd2p1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(opnd2p1);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * check second operand for zero
+ */
+ if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
+ /* invalid since second operand is zero */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Dbl_makequietnan(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+
+ /*
+ * get sign of result
+ */
+ resultp1 = opnd1p1;
+
+ /*
+ * check for denormalized operands
+ */
+ if (opnd1_exponent == 0) {
+ /* check for zero */
+ if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
+ Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /* normalize, then continue */
+ opnd1_exponent = 1;
+ Dbl_normalize(opnd1p1,opnd1p2,opnd1_exponent);
+ }
+ else {
+ Dbl_clear_signexponent_set_hidden(opnd1p1);
+ }
+ if (opnd2_exponent == 0) {
+ /* normalize, then continue */
+ opnd2_exponent = 1;
+ Dbl_normalize(opnd2p1,opnd2p2,opnd2_exponent);
+ }
+ else {
+ Dbl_clear_signexponent_set_hidden(opnd2p1);
+ }
+
+ /* find result exponent and divide step loop count */
+ dest_exponent = opnd2_exponent - 1;
+ stepcount = opnd1_exponent - opnd2_exponent;
+
+ /*
+ * check for opnd1/opnd2 < 1
+ */
+ if (stepcount < 0) {
+ /*
+ * check for opnd1/opnd2 > 1/2
+ *
+ * In this case n will round to 1, so
+ * r = opnd1 - opnd2
+ */
+ if (stepcount == -1 &&
+ Dbl_isgreaterthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
+ /* set sign */
+ Dbl_allp1(resultp1) = ~Dbl_allp1(resultp1);
+ /* align opnd2 with opnd1 */
+ Dbl_leftshiftby1(opnd2p1,opnd2p2);
+ Dbl_subtract(opnd2p1,opnd2p2,opnd1p1,opnd1p2,
+ opnd2p1,opnd2p2);
+ /* now normalize */
+ while (Dbl_iszero_hidden(opnd2p1)) {
+ Dbl_leftshiftby1(opnd2p1,opnd2p2);
+ dest_exponent--;
+ }
+ Dbl_set_exponentmantissa(resultp1,resultp2,opnd2p1,opnd2p2);
+ goto testforunderflow;
+ }
+ /*
+ * opnd1/opnd2 <= 1/2
+ *
+ * In this case n will round to zero, so
+ * r = opnd1
+ */
+ Dbl_set_exponentmantissa(resultp1,resultp2,opnd1p1,opnd1p2);
+ dest_exponent = opnd1_exponent;
+ goto testforunderflow;
+ }
+
+ /*
+ * Generate result
+ *
+ * Do iterative subtract until remainder is less than operand 2.
+ */
+ while (stepcount-- > 0 && (Dbl_allp1(opnd1p1) || Dbl_allp2(opnd1p2))) {
+ if (Dbl_isnotlessthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
+ Dbl_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2,opnd1p1,opnd1p2);
+ }
+ Dbl_leftshiftby1(opnd1p1,opnd1p2);
+ }
+ /*
+ * Do last subtract, then determine which way to round if remainder
+ * is exactly 1/2 of opnd2
+ */
+ if (Dbl_isnotlessthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
+ Dbl_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2,opnd1p1,opnd1p2);
+ roundup = TRUE;
+ }
+ if (stepcount > 0 || Dbl_iszero(opnd1p1,opnd1p2)) {
+ /* division is exact, remainder is zero */
+ Dbl_setzero_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+
+ /*
+ * Check for cases where opnd1/opnd2 < n
+ *
+ * In this case the result's sign will be opposite that of
+ * opnd1. The mantissa also needs some correction.
+ */
+ Dbl_leftshiftby1(opnd1p1,opnd1p2);
+ if (Dbl_isgreaterthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
+ Dbl_invert_sign(resultp1);
+ Dbl_leftshiftby1(opnd2p1,opnd2p2);
+ Dbl_subtract(opnd2p1,opnd2p2,opnd1p1,opnd1p2,opnd1p1,opnd1p2);
+ }
+ /* check for remainder being exactly 1/2 of opnd2 */
+ else if (Dbl_isequal(opnd1p1,opnd1p2,opnd2p1,opnd2p2) && roundup) {
+ Dbl_invert_sign(resultp1);
+ }
+
+ /* normalize result's mantissa */
+ while (Dbl_iszero_hidden(opnd1p1)) {
+ dest_exponent--;
+ Dbl_leftshiftby1(opnd1p1,opnd1p2);
+ }
+ Dbl_set_exponentmantissa(resultp1,resultp2,opnd1p1,opnd1p2);
+
+ /*
+ * Test for underflow
+ */
+ testforunderflow:
+ if (dest_exponent <= 0) {
+ /* trap if UNDERFLOWTRAP enabled */
+ if (Is_underflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Dbl_setwrapped_exponent(resultp1,dest_exponent,unfl);
+ /* frem is always exact */
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(UNDERFLOWEXCEPTION);
+ }
+ /*
+ * denormalize result or set to signed zero
+ */
+ if (dest_exponent >= (1 - DBL_P)) {
+ Dbl_rightshift_exponentmantissa(resultp1,resultp2,
+ 1-dest_exponent);
+ }
+ else {
+ Dbl_setzero_exponentmantissa(resultp1,resultp2);
+ }
+ }
+ else Dbl_set_exponent(resultp1,dest_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/dfsqrt.c b/sys/arch/hppa/spmath/dfsqrt.c
new file mode 100644
index 00000000000..918e1024ec0
--- /dev/null
+++ b/sys/arch/hppa/spmath/dfsqrt.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/dfsqrt.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:54 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/dbl_float.h"
+
+/*
+ * Double Floating-point Square Root
+ */
+
+/*ARGSUSED*/
+dbl_fsqrt(srcptr,nullptr,dstptr,status)
+
+dbl_floating_point *srcptr, *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int srcp1, srcp2, resultp1, resultp2;
+ register unsigned int newbitp1, newbitp2, sump1, sump2;
+ register int src_exponent;
+ register boolean guardbit = FALSE, even_exponent;
+
+ Dbl_copyfromptr(srcptr,srcp1,srcp2);
+ /*
+ * check source operand for NaN or infinity
+ */
+ if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
+ /*
+ * is signaling NaN?
+ */
+ if (Dbl_isone_signaling(srcp1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(srcp1);
+ }
+ /*
+ * Return quiet NaN or positive infinity.
+ * Fall thru to negative test if negative infinity.
+ */
+ if (Dbl_iszero_sign(srcp1) ||
+ Dbl_isnotzero_mantissa(srcp1,srcp2)) {
+ Dbl_copytoptr(srcp1,srcp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+
+ /*
+ * check for zero source operand
+ */
+ if (Dbl_iszero_exponentmantissa(srcp1,srcp2)) {
+ Dbl_copytoptr(srcp1,srcp2,dstptr);
+ return(NOEXCEPTION);
+ }
+
+ /*
+ * check for negative source operand
+ */
+ if (Dbl_isone_sign(srcp1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_makequietnan(srcp1,srcp2);
+ Dbl_copytoptr(srcp1,srcp2,dstptr);
+ return(NOEXCEPTION);
+ }
+
+ /*
+ * Generate result
+ */
+ if (src_exponent > 0) {
+ even_exponent = Dbl_hidden(srcp1);
+ Dbl_clear_signexponent_set_hidden(srcp1);
+ }
+ else {
+ /* normalize operand */
+ Dbl_clear_signexponent(srcp1);
+ src_exponent++;
+ Dbl_normalize(srcp1,srcp2,src_exponent);
+ even_exponent = src_exponent & 1;
+ }
+ if (even_exponent) {
+ /* exponent is even */
+ /* Add comment here. Explain why odd exponent needs correction */
+ Dbl_leftshiftby1(srcp1,srcp2);
+ }
+ /*
+ * Add comment here. Explain following algorithm.
+ *
+ * Trust me, it works.
+ *
+ */
+ Dbl_setzero(resultp1,resultp2);
+ Dbl_allp1(newbitp1) = 1 << (DBL_P - 32);
+ Dbl_setzero_mantissap2(newbitp2);
+ while (Dbl_isnotzero(newbitp1,newbitp2) && Dbl_isnotzero(srcp1,srcp2)) {
+ Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,sump1,sump2);
+ if(Dbl_isnotgreaterthan(sump1,sump2,srcp1,srcp2)) {
+ Dbl_leftshiftby1(newbitp1,newbitp2);
+ /* update result */
+ Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,
+ resultp1,resultp2);
+ Dbl_subtract(srcp1,srcp2,sump1,sump2,srcp1,srcp2);
+ Dbl_rightshiftby2(newbitp1,newbitp2);
+ }
+ else {
+ Dbl_rightshiftby1(newbitp1,newbitp2);
+ }
+ Dbl_leftshiftby1(srcp1,srcp2);
+ }
+ /* correct exponent for pre-shift */
+ if (even_exponent) {
+ Dbl_rightshiftby1(resultp1,resultp2);
+ }
+
+ /* check for inexact */
+ if (Dbl_isnotzero(srcp1,srcp2)) {
+ if (!even_exponent & Dbl_islessthan(resultp1,resultp2,srcp1,srcp2)) {
+ Dbl_increment(resultp1,resultp2);
+ }
+ guardbit = Dbl_lowmantissap2(resultp2);
+ Dbl_rightshiftby1(resultp1,resultp2);
+
+ /* now round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ Dbl_increment(resultp1,resultp2);
+ break;
+ case ROUNDNEAREST:
+ /* stickybit is always true, so guardbit
+ * is enough to determine rounding */
+ if (guardbit) {
+ Dbl_increment(resultp1,resultp2);
+ }
+ break;
+ }
+ /* increment result exponent by 1 if mantissa overflowed */
+ if (Dbl_isone_hiddenoverflow(resultp1)) src_exponent+=2;
+
+ if (Is_inexacttrap_enabled()) {
+ Dbl_set_exponent(resultp1,
+ ((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(INEXACTEXCEPTION);
+ }
+ else Set_inexactflag();
+ }
+ else {
+ Dbl_rightshiftby1(resultp1,resultp2);
+ }
+ Dbl_set_exponent(resultp1,((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/dfsub.c b/sys/arch/hppa/spmath/dfsub.c
new file mode 100644
index 00000000000..03196050726
--- /dev/null
+++ b/sys/arch/hppa/spmath/dfsub.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/dfsub.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:54 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/dbl_float.h"
+
+/*
+ * Double_subtract: subtract two double precision values.
+ */
+dbl_fsub(leftptr, rightptr, dstptr, status)
+ dbl_floating_point *leftptr, *rightptr, *dstptr;
+ unsigned int *status;
+ {
+ register unsigned int signless_upper_left, signless_upper_right, save;
+ register unsigned int leftp1, leftp2, rightp1, rightp2, extent;
+ register unsigned int resultp1 = 0, resultp2 = 0;
+
+ register int result_exponent, right_exponent, diff_exponent;
+ register int sign_save, jumpsize;
+ register boolean inexact = FALSE, underflowtrap;
+
+ /* Create local copies of the numbers */
+ Dbl_copyfromptr(leftptr,leftp1,leftp2);
+ Dbl_copyfromptr(rightptr,rightp1,rightp2);
+
+ /* A zero "save" helps discover equal operands (for later), *
+ * and is used in swapping operands (if needed). */
+ Dbl_xortointp1(leftp1,rightp1,/*to*/save);
+
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if ((result_exponent = Dbl_exponent(leftp1)) == DBL_INFINITY_EXPONENT)
+ {
+ if (Dbl_iszero_mantissa(leftp1,leftp2))
+ {
+ if (Dbl_isnotnan(rightp1,rightp2))
+ {
+ if (Dbl_isinfinity(rightp1,rightp2) && save==0)
+ {
+ /*
+ * invalid since operands are same signed infinity's
+ */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Dbl_makequietnan(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ Dbl_copytoptr(leftp1,leftp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ else
+ {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(leftp1))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(leftp1);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Dbl_is_signalingnan(rightp1))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(rightp1);
+ Dbl_copytoptr(rightp1,rightp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(leftp1,leftp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ } /* End left NaN or Infinity processing */
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if (Dbl_isinfinity_exponent(rightp1))
+ {
+ if (Dbl_iszero_mantissa(rightp1,rightp2))
+ {
+ /* return infinity */
+ Dbl_invert_sign(rightp1);
+ Dbl_copytoptr(rightp1,rightp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(rightp1))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(rightp1);
+ }
+ /*
+ * return quiet NaN
+ */
+ Dbl_copytoptr(rightp1,rightp2,dstptr);
+ return(NOEXCEPTION);
+ } /* End right NaN or Infinity processing */
+
+ /* Invariant: Must be dealing with finite numbers */
+
+ /* Compare operands by removing the sign */
+ Dbl_copytoint_exponentmantissap1(leftp1,signless_upper_left);
+ Dbl_copytoint_exponentmantissap1(rightp1,signless_upper_right);
+
+ /* sign difference selects add or sub operation. */
+ if(Dbl_ismagnitudeless(leftp2,rightp2,signless_upper_left,signless_upper_right))
+ {
+ /* Set the left operand to the larger one by XOR swap *
+ * First finish the first word using "save" */
+ Dbl_xorfromintp1(save,rightp1,/*to*/rightp1);
+ Dbl_xorfromintp1(save,leftp1,/*to*/leftp1);
+ Dbl_swap_lower(leftp2,rightp2);
+ result_exponent = Dbl_exponent(leftp1);
+ Dbl_invert_sign(leftp1);
+ }
+ /* Invariant: left is not smaller than right. */
+
+ if((right_exponent = Dbl_exponent(rightp1)) == 0)
+ {
+ /* Denormalized operands. First look for zeroes */
+ if(Dbl_iszero_mantissa(rightp1,rightp2))
+ {
+ /* right is zero */
+ if(Dbl_iszero_exponentmantissa(leftp1,leftp2))
+ {
+ /* Both operands are zeros */
+ Dbl_invert_sign(rightp1);
+ if(Is_rounding_mode(ROUNDMINUS))
+ {
+ Dbl_or_signs(leftp1,/*with*/rightp1);
+ }
+ else
+ {
+ Dbl_and_signs(leftp1,/*with*/rightp1);
+ }
+ }
+ else
+ {
+ /* Left is not a zero and must be the result. Trapped
+ * underflows are signaled if left is denormalized. Result
+ * is always exact. */
+ if( (result_exponent == 0) && Is_underflowtrap_enabled() )
+ {
+ /* need to normalize results mantissa */
+ sign_save = Dbl_signextendedsign(leftp1);
+ Dbl_leftshiftby1(leftp1,leftp2);
+ Dbl_normalize(leftp1,leftp2,result_exponent);
+ Dbl_set_sign(leftp1,/*using*/sign_save);
+ Dbl_setwrapped_exponent(leftp1,result_exponent,unfl);
+ Dbl_copytoptr(leftp1,leftp2,dstptr);
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ }
+ Dbl_copytoptr(leftp1,leftp2,dstptr);
+ return(NOEXCEPTION);
+ }
+
+ /* Neither are zeroes */
+ Dbl_clear_sign(rightp1); /* Exponent is already cleared */
+ if(result_exponent == 0 )
+ {
+ /* Both operands are denormalized. The result must be exact
+ * and is simply calculated. A sum could become normalized and a
+ * difference could cancel to a true zero. */
+ if( (/*signed*/int) save >= 0 )
+ {
+ Dbl_subtract(leftp1,leftp2,/*minus*/rightp1,rightp2,
+ /*into*/resultp1,resultp2);
+ if(Dbl_iszero_mantissa(resultp1,resultp2))
+ {
+ if(Is_rounding_mode(ROUNDMINUS))
+ {
+ Dbl_setone_sign(resultp1);
+ }
+ else
+ {
+ Dbl_setzero_sign(resultp1);
+ }
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ else
+ {
+ Dbl_addition(leftp1,leftp2,rightp1,rightp2,
+ /*into*/resultp1,resultp2);
+ if(Dbl_isone_hidden(resultp1))
+ {
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ if(Is_underflowtrap_enabled())
+ {
+ /* need to normalize result */
+ sign_save = Dbl_signextendedsign(resultp1);
+ Dbl_leftshiftby1(resultp1,resultp2);
+ Dbl_normalize(resultp1,resultp2,result_exponent);
+ Dbl_set_sign(resultp1,/*using*/sign_save);
+ Dbl_setwrapped_exponent(resultp1,result_exponent,unfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ right_exponent = 1; /* Set exponent to reflect different bias
+ * with denomalized numbers. */
+ }
+ else
+ {
+ Dbl_clear_signexponent_set_hidden(rightp1);
+ }
+ Dbl_clear_exponent_set_hidden(leftp1);
+ diff_exponent = result_exponent - right_exponent;
+
+ /*
+ * Special case alignment of operands that would force alignment
+ * beyond the extent of the extension. A further optimization
+ * could special case this but only reduces the path length for this
+ * infrequent case.
+ */
+ if(diff_exponent > DBL_THRESHOLD)
+ {
+ diff_exponent = DBL_THRESHOLD;
+ }
+
+ /* Align right operand by shifting to right */
+ Dbl_right_align(/*operand*/rightp1,rightp2,/*shifted by*/diff_exponent,
+ /*and lower to*/extent);
+
+ /* Treat sum and difference of the operands separately. */
+ if( (/*signed*/int) save >= 0 )
+ {
+ /*
+ * Difference of the two operands. Their can be no overflow. A
+ * borrow can occur out of the hidden bit and force a post
+ * normalization phase.
+ */
+ Dbl_subtract_withextension(leftp1,leftp2,/*minus*/rightp1,rightp2,
+ /*with*/extent,/*into*/resultp1,resultp2);
+ if(Dbl_iszero_hidden(resultp1))
+ {
+ /* Handle normalization */
+ /* A straight foward algorithm would now shift the result
+ * and extension left until the hidden bit becomes one. Not
+ * all of the extension bits need participate in the shift.
+ * Only the two most significant bits (round and guard) are
+ * needed. If only a single shift is needed then the guard
+ * bit becomes a significant low order bit and the extension
+ * must participate in the rounding. If more than a single
+ * shift is needed, then all bits to the right of the guard
+ * bit are zeros, and the guard bit may or may not be zero. */
+ sign_save = Dbl_signextendedsign(resultp1);
+ Dbl_leftshiftby1_withextent(resultp1,resultp2,extent,resultp1,resultp2);
+
+ /* Need to check for a zero result. The sign and exponent
+ * fields have already been zeroed. The more efficient test
+ * of the full object can be used.
+ */
+ if(Dbl_iszero(resultp1,resultp2))
+ /* Must have been "x-x" or "x+(-x)". */
+ {
+ if(Is_rounding_mode(ROUNDMINUS)) Dbl_setone_sign(resultp1);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ result_exponent--;
+ /* Look to see if normalization is finished. */
+ if(Dbl_isone_hidden(resultp1))
+ {
+ if(result_exponent==0)
+ {
+ /* Denormalized, exponent should be zero. Left operand *
+ * was normalized, so extent (guard, round) was zero */
+ goto underflow;
+ }
+ else
+ {
+ /* No further normalization is needed. */
+ Dbl_set_sign(resultp1,/*using*/sign_save);
+ Ext_leftshiftby1(extent);
+ goto round;
+ }
+ }
+
+ /* Check for denormalized, exponent should be zero. Left *
+ * operand was normalized, so extent (guard, round) was zero */
+ if(!(underflowtrap = Is_underflowtrap_enabled()) &&
+ result_exponent==0) goto underflow;
+
+ /* Shift extension to complete one bit of normalization and
+ * update exponent. */
+ Ext_leftshiftby1(extent);
+
+ /* Discover first one bit to determine shift amount. Use a
+ * modified binary search. We have already shifted the result
+ * one position right and still not found a one so the remainder
+ * of the extension must be zero and simplifies rounding. */
+ /* Scan bytes */
+ while(Dbl_iszero_hiddenhigh7mantissa(resultp1))
+ {
+ Dbl_leftshiftby8(resultp1,resultp2);
+ if((result_exponent -= 8) <= 0 && !underflowtrap)
+ goto underflow;
+ }
+ /* Now narrow it down to the nibble */
+ if(Dbl_iszero_hiddenhigh3mantissa(resultp1))
+ {
+ /* The lower nibble contains the normalizing one */
+ Dbl_leftshiftby4(resultp1,resultp2);
+ if((result_exponent -= 4) <= 0 && !underflowtrap)
+ goto underflow;
+ }
+ /* Select case were first bit is set (already normalized)
+ * otherwise select the proper shift. */
+ if((jumpsize = Dbl_hiddenhigh3mantissa(resultp1)) > 7)
+ {
+ /* Already normalized */
+ if(result_exponent <= 0) goto underflow;
+ Dbl_set_sign(resultp1,/*using*/sign_save);
+ Dbl_set_exponent(resultp1,/*using*/result_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ Dbl_sethigh4bits(resultp1,/*using*/sign_save);
+ switch(jumpsize)
+ {
+ case 1:
+ {
+ Dbl_leftshiftby3(resultp1,resultp2);
+ result_exponent -= 3;
+ break;
+ }
+ case 2:
+ case 3:
+ {
+ Dbl_leftshiftby2(resultp1,resultp2);
+ result_exponent -= 2;
+ break;
+ }
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ {
+ Dbl_leftshiftby1(resultp1,resultp2);
+ result_exponent -= 1;
+ break;
+ }
+ }
+ if(result_exponent > 0)
+ {
+ Dbl_set_exponent(resultp1,/*using*/result_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION); /* Sign bit is already set */
+ }
+ /* Fixup potential underflows */
+ underflow:
+ if(Is_underflowtrap_enabled())
+ {
+ Dbl_set_sign(resultp1,sign_save);
+ Dbl_setwrapped_exponent(resultp1,result_exponent,unfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ /*
+ * Since we cannot get an inexact denormalized result,
+ * we can now return.
+ */
+ Dbl_fix_overshift(resultp1,resultp2,(1-result_exponent),extent);
+ Dbl_clear_signexponent(resultp1);
+ Dbl_set_sign(resultp1,sign_save);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ } /* end if(hidden...)... */
+ /* Fall through and round */
+ } /* end if(save >= 0)... */
+ else
+ {
+ /* Subtract magnitudes */
+ Dbl_addition(leftp1,leftp2,rightp1,rightp2,/*to*/resultp1,resultp2);
+ if(Dbl_isone_hiddenoverflow(resultp1))
+ {
+ /* Prenormalization required. */
+ Dbl_rightshiftby1_withextent(resultp2,extent,extent);
+ Dbl_arithrightshiftby1(resultp1,resultp2);
+ result_exponent++;
+ } /* end if hiddenoverflow... */
+ } /* end else ...subtract magnitudes... */
+
+ /* Round the result. If the extension is all zeros,then the result is
+ * exact. Otherwise round in the correct direction. No underflow is
+ * possible. If a postnormalization is necessary, then the mantissa is
+ * all zeros so no shift is needed. */
+ round:
+ if(Ext_isnotzero(extent))
+ {
+ inexact = TRUE;
+ switch(Rounding_mode())
+ {
+ case ROUNDNEAREST: /* The default. */
+ if(Ext_isone_sign(extent))
+ {
+ /* at least 1/2 ulp */
+ if(Ext_isnotzero_lower(extent) ||
+ Dbl_isone_lowmantissap2(resultp2))
+ {
+ /* either exactly half way and odd or more than 1/2ulp */
+ Dbl_increment(resultp1,resultp2);
+ }
+ }
+ break;
+
+ case ROUNDPLUS:
+ if(Dbl_iszero_sign(resultp1))
+ {
+ /* Round up positive results */
+ Dbl_increment(resultp1,resultp2);
+ }
+ break;
+
+ case ROUNDMINUS:
+ if(Dbl_isone_sign(resultp1))
+ {
+ /* Round down negative results */
+ Dbl_increment(resultp1,resultp2);
+ }
+
+ case ROUNDZERO:;
+ /* truncate is simple */
+ } /* end switch... */
+ if(Dbl_isone_hiddenoverflow(resultp1)) result_exponent++;
+ }
+ if(result_exponent == DBL_INFINITY_EXPONENT)
+ {
+ /* Overflow */
+ if(Is_overflowtrap_enabled())
+ {
+ Dbl_setwrapped_exponent(resultp1,result_exponent,ovfl);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(OVERFLOWEXCEPTION);
+ }
+ else
+ {
+ inexact = TRUE;
+ Set_overflowflag();
+ Dbl_setoverflow(resultp1,resultp2);
+ }
+ }
+ else Dbl_set_exponent(resultp1,result_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if(inexact)
+ if(Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(NOEXCEPTION);
+ }
diff --git a/sys/arch/hppa/spmath/divsfm.c b/sys/arch/hppa/spmath/divsfm.c
new file mode 100644
index 00000000000..e088cc36064
--- /dev/null
+++ b/sys/arch/hppa/spmath/divsfm.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/divsfm.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:55 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID divsfm(opnd1,opnd2,result)
+
+int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ register int sign, op1_sign;
+
+ /* check divisor for zero */
+ if (opnd2 == 0) {
+ overflow = TRUE;
+ return;
+ }
+
+ /* get sign of result */
+ sign = opnd1 ^ opnd2;
+
+ /* get absolute value of operands */
+ if (opnd1 < 0) {
+ opnd1 = -opnd1;
+ op1_sign = TRUE;
+ }
+ else op1_sign = FALSE;
+ if (opnd2 < 0) opnd2 = -opnd2;
+
+ /*
+ * check for overflow
+ *
+ * if abs(opnd1) < 0, then opnd1 = -2**31
+ * and abs(opnd1) >= abs(opnd2) always
+ */
+ if (opnd1 >= opnd2 || opnd1 < 0) {
+ /* check for opnd2 = -2**31 */
+ if (opnd2 < 0 && opnd1 != opnd2) {
+ result_hi = 0; /* remainder = 0 */
+ result_lo = opnd1 << 1;
+ }
+ else {
+ overflow = TRUE;
+ return;
+ }
+ }
+ else {
+ /* do the divide */
+ divu(opnd1,0,opnd2,result);
+
+ /* return positive residue */
+ if (op1_sign && result_hi) {
+ result_hi = opnd2 - result_hi;
+ result_lo++;
+ }
+ }
+
+ /* check for overflow */
+ if (result_lo < 0) {
+ overflow = TRUE;
+ return;
+ }
+ overflow = FALSE;
+
+ /* return appropriately signed result */
+ if (sign<0) result_lo = -result_lo;
+ return;
+}
diff --git a/sys/arch/hppa/spmath/divsfr.c b/sys/arch/hppa/spmath/divsfr.c
new file mode 100644
index 00000000000..d74ff9456b8
--- /dev/null
+++ b/sys/arch/hppa/spmath/divsfr.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/divsfr.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:55 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID divsfr(opnd1,opnd2,result)
+
+int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ int sign, op1_sign;
+
+ /* check divisor for zero */
+ if (opnd2 == 0) {
+ overflow = TRUE;
+ return;
+ }
+
+ /* get sign of result */
+ sign = opnd1 ^ opnd2;
+
+ /* get absolute value of operands */
+ if (opnd1 < 0) {
+ opnd1 = -opnd1;
+ op1_sign = TRUE;
+ }
+ else op1_sign = FALSE;
+ if (opnd2 < 0) opnd2 = -opnd2;
+
+ /*
+ * check for overflow
+ *
+ * if abs(opnd1) < 0, then opnd1 = -2**31
+ * and abs(opnd1) >= abs(opnd2) always
+ */
+ if (opnd1 >= opnd2 || opnd1 < 0) {
+ /* check for opnd2 = -2**31 */
+ if (opnd2 < 0 && opnd1 != opnd2) {
+ result_hi = 0; /* remainder = 0 */
+ result_lo = opnd1 << 1;
+ }
+ else {
+ overflow = TRUE;
+ return;
+ }
+ }
+ else {
+ /* do the divide */
+ divu(opnd1,0,opnd2,result);
+ }
+
+ /* check for overflow */
+ if (result_lo < 0) {
+ overflow = TRUE;
+ return;
+ }
+ overflow = FALSE;
+
+ /* return appropriately signed remainder and result */
+ if (op1_sign) result_hi = -result_hi;
+ if (sign<0) result_lo = -result_lo;
+ return;
+}
diff --git a/sys/arch/hppa/spmath/divsim.c b/sys/arch/hppa/spmath/divsim.c
new file mode 100644
index 00000000000..6459d8bb584
--- /dev/null
+++ b/sys/arch/hppa/spmath/divsim.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/divsim.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:55 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID divsim(opnd1,opnd2,result)
+
+int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ int sign, op1_sign;
+
+ /* check divisor for zero */
+ if (opnd2 == 0) {
+ overflow = TRUE;
+ return;
+ }
+
+ /* get sign of result */
+ sign = opnd1 ^ opnd2;
+
+ /* get absolute value of operands */
+ if (opnd1 < 0) {
+ opnd1 = -opnd1;
+ op1_sign = TRUE;
+ }
+ else op1_sign = FALSE;
+ if (opnd2 < 0) opnd2 = -opnd2;
+
+ /* check for opnd2 == -2**31 */
+ if (opnd2 < 0) {
+ if (opnd1 == opnd2) {
+ result_hi = 0; /* remainder = 0 */
+ result_lo = 1;
+ }
+ else {
+ result_hi = opnd1; /* remainder = opnd1 */
+ result_lo = 0;
+ }
+ }
+ else {
+ /* do the divide */
+ divu(0,opnd1,opnd2,result);
+
+ /*
+ * check for overflow
+ *
+ * at this point, the only way we can get overflow
+ * is with opnd1 = -2**31 and opnd2 = -1
+ */
+ if (sign>0 && result_lo<0) {
+ overflow = TRUE;
+ return;
+ }
+ }
+ overflow = FALSE;
+
+ /* return positive residue */
+ if (op1_sign && result_hi) {
+ result_hi = opnd2 - result_hi;
+ if (++result_lo < 0) {
+ overflow = TRUE;
+ return;
+ }
+ }
+
+ /* return appropriately signed result */
+ if (sign<0) result_lo = -result_lo;
+ return;
+}
diff --git a/sys/arch/hppa/spmath/divsir.c b/sys/arch/hppa/spmath/divsir.c
new file mode 100644
index 00000000000..d1f7bda1f86
--- /dev/null
+++ b/sys/arch/hppa/spmath/divsir.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/divsir.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:56 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID divsir(opnd1,opnd2,result)
+
+int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ int sign, op1_sign;
+
+ /* check divisor for zero */
+ if (opnd2 == 0) {
+ overflow = TRUE;
+ return;
+ }
+
+ /* get sign of result */
+ sign = opnd1 ^ opnd2;
+
+ /* get absolute value of operands */
+ if (opnd1 < 0) {
+ opnd1 = -opnd1;
+ op1_sign = TRUE;
+ }
+ else op1_sign = FALSE;
+ if (opnd2 < 0) opnd2 = -opnd2;
+
+ /* check for opnd2 = -2**31 */
+ if (opnd2 + opnd2 == 0) {
+ if (opnd1 == opnd2) {
+ result_hi = 0; /* remainder = 0 */
+ result_lo = 1;
+ }
+ else {
+ result_hi = opnd1; /* remainder = opnd1 */
+ result_lo = 0;
+ }
+ }
+ else {
+ /* do the divide */
+ divu(0,opnd1,opnd2,result);
+
+ /*
+ * check for overflow
+ *
+ * at this point, the only way we can get overflow
+ * is with opnd1 = -2**31 and opnd2 = -1
+ */
+ if (sign>0 && result_lo<0) {
+ overflow = TRUE;
+ return;
+ }
+ }
+ overflow = FALSE;
+
+ /* return appropriately signed remainder and result */
+ if (op1_sign) result_hi = -result_hi;
+ if (sign<0) result_lo = -result_lo;
+ return;
+}
diff --git a/sys/arch/hppa/spmath/divu.S b/sys/arch/hppa/spmath/divu.S
new file mode 100644
index 00000000000..c4b36ee1abd
--- /dev/null
+++ b/sys/arch/hppa/spmath/divu.S
@@ -0,0 +1,181 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/divu.S,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:56 $
+ */
+
+#include <machine/asm.h>
+
+/**************************************************************************
+ * Implement an integer divide routine for 32-bit operands and 32-bit quotient
+ * and remainder with operand values of zero (divisor only) treated specially.
+ *
+ ***************************************************************************/
+/*
+ * General registers
+ */
+gr0 .equ 0 /* General register zero */
+rem .equ 3 /* remainder and upper part of dividend */
+quo .equ 4 /* quotient and lower part of dividend */
+dvr .equ 5 /* divisor */
+tp .equ 6 /* temp. reg. */
+
+/*****************************************************************************/
+ .export divu,entry
+ .space $TEXT$
+ .subspa $CODE$
+ .align 4
+ .proc
+ .callinfo
+
+/*****************************************************************************/
+divu stws,ma rem,4(sp) # save registers on stack
+ stws,ma quo,4(sp) # save registers on stack
+ stws,ma dvr,4(sp) # save registers on stack
+ stws,ma tp,4(sp) # save registers on stack
+
+ addi 0,arg2,dvr # get divisor
+ addi 0,arg1,quo # get lower dividend
+ addi 0,arg0,rem # get upper dividend
+
+ comib,>,n 0,dvr,hibit # check for dvr >= 2**31
+ addi -1,gr0,tp # set V-bit to 1
+ ds 0,tp,0
+ add quo,quo,quo # shift msb bit into carry
+ ds rem,dvr,rem # 1st divide step, if carry
+ # out, msb of quotient = 0
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 2nd divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 3rd divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 4th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 5th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 6th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 7th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 8th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 9th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 10th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 11th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 12th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 13th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 14th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 15th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 16th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 17th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 18th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 19th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 20th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 21st divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 22nd divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 23rd divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 24th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 25th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 26th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 27th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 28th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 29th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 30th divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 31st divide step
+ addc quo,quo,quo # shift quo with/into carry
+ ds rem,dvr,rem # 32nd divide step,
+ addc quo,quo,quo # shift last quo bit into quo
+ addb,>=,n rem,0,finish # branch if pos. rem
+ add,< dvr,0,0 # if dvr > 0, add dvr
+ add,tr rem,dvr,rem # for correcting rem.
+ sub rem,dvr,rem # else subtract dvr
+#
+# end of divide routine
+#
+finish stws rem,0(arg3) # save remainder in high part
+ # of result
+ stws quo,4(arg3) # save quotient in low part
+ # of result
+ ldws,mb -4(sp),tp # restore registers
+ ldws,mb -4(sp),dvr # restore registers
+ ldws,mb -4(sp),quo # restore registers
+ bv 0(rp) # return
+ ldws,mb -4(sp),rem # restore registers
+#
+hibit ldo 32(0),tp # initialize loop counter
+ add quo,quo,quo # shift high bit into carry
+loop addc rem,rem,rem # shift in high bit of dvdl
+ addc,<> 0,0,0 # if bit shifted out of dvdu,
+ # want to do subtract
+ comb,<<,n rem,dvr,nosub # if upper dividend > dvr,
+ sub rem,dvr,rem # subtract and
+ add,tr dvr,dvr,0 # set carry
+nosub addi 0,0,0 # otherwise clear carry
+ addib,> -1,tp,loop # inc. counter# finished?
+ addc quo,quo,quo # shift bit of result into dvdl
+ b finish+4 # finish up
+ stws rem,0(arg3) # save remainder in high part
+ # of result
+
+ .procend
+ .end
diff --git a/sys/arch/hppa/spmath/divufr.c b/sys/arch/hppa/spmath/divufr.c
new file mode 100644
index 00000000000..6f706ef15ca
--- /dev/null
+++ b/sys/arch/hppa/spmath/divufr.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/divufr.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:56 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID divufr(opnd1,opnd2,result)
+
+unsigned int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ /* check divisor for zero */
+ if (opnd2 == 0) {
+ overflow = TRUE;
+ return;
+ }
+
+ /* check for overflow */
+ if (opnd1 >= opnd2) {
+ overflow = TRUE;
+ return;
+ }
+ overflow = FALSE;
+
+ /* do the divide */
+ divu(opnd1,0,opnd2,result);
+ return;
+}
diff --git a/sys/arch/hppa/spmath/divuir.c b/sys/arch/hppa/spmath/divuir.c
new file mode 100644
index 00000000000..1a575564973
--- /dev/null
+++ b/sys/arch/hppa/spmath/divuir.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/divuir.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:57 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID divuir(opnd1,opnd2,result)
+
+unsigned int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ /* get source operands, check divisor for zero */
+ if (opnd2 == 0) {
+ overflow = TRUE;
+ return;
+ }
+ overflow = FALSE;
+
+ /* do the divide */
+ divu(0,opnd1,opnd2,result);
+ return;
+}
diff --git a/sys/arch/hppa/spmath/fcnvff.c b/sys/arch/hppa/spmath/fcnvff.c
new file mode 100644
index 00000000000..c71dbda1d83
--- /dev/null
+++ b/sys/arch/hppa/spmath/fcnvff.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/fcnvff.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:57 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+#include "../spmath/dbl_float.h"
+#include "../spmath/cnv_float.h"
+
+/*
+ * Single Floating-point to Double Floating-point
+ */
+/*ARGSUSED*/
+sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
+
+sgl_floating_point *srcptr;
+dbl_floating_point *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int src, resultp1, resultp2;
+ register int src_exponent;
+
+ src = *srcptr;
+ src_exponent = Sgl_exponent(src);
+ Dbl_allp1(resultp1) = Sgl_all(src); /* set sign of result */
+ /*
+ * Test for NaN or infinity
+ */
+ if (src_exponent == SGL_INFINITY_EXPONENT) {
+ /*
+ * determine if NaN or infinity
+ */
+ if (Sgl_iszero_mantissa(src)) {
+ /*
+ * is infinity; want to return double infinity
+ */
+ Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ else {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(src)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ else {
+ Set_invalidflag();
+ Sgl_set_quiet(src);
+ }
+ }
+ /*
+ * NaN is quiet, return as double NaN
+ */
+ Dbl_setinfinity_exponent(resultp1);
+ Sgl_to_dbl_mantissa(src,resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * Test for zero or denormalized
+ */
+ if (src_exponent == 0) {
+ /*
+ * determine if zero or denormalized
+ */
+ if (Sgl_isnotzero_mantissa(src)) {
+ /*
+ * is denormalized; want to normalize
+ */
+ Sgl_clear_signexponent(src);
+ Sgl_leftshiftby1(src);
+ Sgl_normalize(src,src_exponent);
+ Sgl_to_dbl_exponent(src_exponent,resultp1);
+ Sgl_to_dbl_mantissa(src,resultp1,resultp2);
+ }
+ else {
+ Dbl_setzero_exponentmantissa(resultp1,resultp2);
+ }
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * No special cases, just complete the conversion
+ */
+ Sgl_to_dbl_exponent(src_exponent, resultp1);
+ Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+}
+
+/*
+ * Double Floating-point to Single Floating-point
+ */
+/*ARGSUSED*/
+dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
+
+dbl_floating_point *srcptr;
+sgl_floating_point *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int srcp1, srcp2, result;
+ register int src_exponent, dest_exponent, dest_mantissa;
+ register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
+ register boolean lsb_odd = FALSE;
+ boolean is_tiny;
+
+ Dbl_copyfromptr(srcptr,srcp1,srcp2);
+ src_exponent = Dbl_exponent(srcp1);
+ Sgl_all(result) = Dbl_allp1(srcp1); /* set sign of result */
+ /*
+ * Test for NaN or infinity
+ */
+ if (src_exponent == DBL_INFINITY_EXPONENT) {
+ /*
+ * determine if NaN or infinity
+ */
+ if (Dbl_iszero_mantissa(srcp1,srcp2)) {
+ /*
+ * is infinity; want to return single infinity
+ */
+ Sgl_setinfinity_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Dbl_isone_signaling(srcp1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ else {
+ Set_invalidflag();
+ /* make NaN quiet */
+ Dbl_set_quiet(srcp1);
+ }
+ }
+ /*
+ * NaN is quiet, return as single NaN
+ */
+ Sgl_setinfinity_exponent(result);
+ Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
+ if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate result
+ */
+ Dbl_to_sgl_exponent(src_exponent,dest_exponent);
+ if (dest_exponent > 0) {
+ Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit,
+ stickybit,lsb_odd);
+ }
+ else {
+ if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
+ Sgl_setzero_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ if (Is_underflowtrap_enabled()) {
+ Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
+ guardbit,stickybit,lsb_odd);
+ }
+ else {
+ /* compute result, determine inexact info,
+ * and set Underflowflag if appropriate
+ */
+ Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
+ dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
+ is_tiny);
+ }
+ }
+ /*
+ * Now round result if not exact
+ */
+ if (inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result)) dest_mantissa++;
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result)) dest_mantissa++;
+ break;
+ case ROUNDNEAREST:
+ if (guardbit) {
+ if (stickybit || lsb_odd) dest_mantissa++;
+ }
+ }
+ }
+ Sgl_set_exponentmantissa(result,dest_mantissa);
+
+ /*
+ * check for mantissa overflow after rounding
+ */
+ if ((dest_exponent>0 || Is_underflowtrap_enabled()) &&
+ Sgl_isone_hidden(result)) dest_exponent++;
+
+ /*
+ * Test for overflow
+ */
+ if (dest_exponent >= SGL_INFINITY_EXPONENT) {
+ /* trap if OVERFLOWTRAP enabled */
+ if (Is_overflowtrap_enabled()) {
+ /*
+ * Check for gross overflow
+ */
+ if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP)
+ return(UNIMPLEMENTEDEXCEPTION);
+
+ /*
+ * Adjust bias of result
+ */
+ Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(OVERFLOWEXCEPTION);
+ }
+ Set_overflowflag();
+ inexact = TRUE;
+ /* set result to infinity or largest number */
+ Sgl_setoverflow(result);
+ }
+ /*
+ * Test for underflow
+ */
+ else if (dest_exponent <= 0) {
+ /* trap if UNDERFLOWTRAP enabled */
+ if (Is_underflowtrap_enabled()) {
+ /*
+ * Check for gross underflow
+ */
+ if (dest_exponent <= -(SGL_WRAP))
+ return(UNIMPLEMENTEDEXCEPTION);
+ /*
+ * Adjust bias of result
+ */
+ Sgl_setwrapped_exponent(result,dest_exponent,unfl);
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(UNDERFLOWEXCEPTION);
+ }
+ /*
+ * result is denormalized or signed zero
+ */
+ if (inexact && is_tiny) Set_underflowflag();
+
+ }
+ else Sgl_set_exponent(result,dest_exponent);
+ *dstptr = result;
+ /*
+ * Trap if inexact trap is enabled
+ */
+ if (inexact)
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/fcnvfx.c b/sys/arch/hppa/spmath/fcnvfx.c
new file mode 100644
index 00000000000..519e697e95d
--- /dev/null
+++ b/sys/arch/hppa/spmath/fcnvfx.c
@@ -0,0 +1,462 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/fcnvfx.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:58 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+#include "../spmath/dbl_float.h"
+#include "../spmath/cnv_float.h"
+
+/*
+ * Single Floating-point to Single Fixed-point
+ */
+/*ARGSUSED*/
+sgl_to_sgl_fcnvfx(srcptr,nullptr,dstptr,status)
+
+sgl_floating_point *srcptr, *nullptr, *status;
+int *dstptr;
+{
+ register unsigned int src, temp;
+ register int src_exponent, result;
+ register boolean inexact = FALSE;
+
+ src = *srcptr;
+ src_exponent = Sgl_exponent(src) - SGL_BIAS;
+
+ /*
+ * Test for overflow
+ */
+ if (src_exponent > SGL_FX_MAX_EXP) {
+ /* check for MININT */
+ if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
+ Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
+ /*
+ * Since source is a number which cannot be
+ * represented in fixed-point format, return
+ * largest (or smallest) fixed-point number.
+ */
+ Sgl_return_overflow(src,dstptr);
+ }
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ temp = src;
+ Sgl_clear_signexponent_set_hidden(temp);
+ Int_from_sgl_mantissa(temp,src_exponent);
+ if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
+ else result = Sgl_all(temp);
+
+ /* check for inexact */
+ if (Sgl_isinexact_to_fix(src,src_exponent)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(src)) result++;
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(src)) result--;
+ break;
+ case ROUNDNEAREST:
+ if (Sgl_isone_roundbit(src,src_exponent)) {
+ if (Sgl_isone_stickybit(src,src_exponent)
+ || (Sgl_isone_lowmantissa(temp)))
+ if (Sgl_iszero_sign(src)) result++;
+ else result--;
+ }
+ }
+ }
+ }
+ else {
+ result = 0;
+
+ /* check for inexact */
+ if (Sgl_isnotzero_exponentmantissa(src)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(src)) result++;
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(src)) result--;
+ break;
+ case ROUNDNEAREST:
+ if (src_exponent == -1)
+ if (Sgl_isnotzero_mantissa(src))
+ if (Sgl_iszero_sign(src)) result++;
+ else result--;
+ }
+ }
+ }
+ *dstptr = result;
+ if (inexact) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ return(NOEXCEPTION);
+}
+
+/*
+ * Single Floating-point to Double Fixed-point
+ */
+/*ARGSUSED*/
+sgl_to_dbl_fcnvfx(srcptr,nullptr,dstptr,status)
+
+sgl_floating_point *srcptr;
+dbl_integer *dstptr;
+unsigned int *nullptr, *status;
+{
+ register int src_exponent, resultp1;
+ register unsigned int src, temp, resultp2;
+ register boolean inexact = FALSE;
+
+ src = *srcptr;
+ src_exponent = Sgl_exponent(src) - SGL_BIAS;
+
+ /*
+ * Test for overflow
+ */
+ if (src_exponent > DBL_FX_MAX_EXP) {
+ /* check for MININT */
+ if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
+ Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
+ /*
+ * Since source is a number which cannot be
+ * represented in fixed-point format, return
+ * largest (or smallest) fixed-point number.
+ */
+ Sgl_return_overflow_dbl(src,dstptr);
+ }
+ Dint_set_minint(resultp1,resultp2);
+ Dint_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ temp = src;
+ Sgl_clear_signexponent_set_hidden(temp);
+ Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
+ if (Sgl_isone_sign(src)) {
+ Dint_setone_sign(resultp1,resultp2);
+ }
+
+ /* check for inexact */
+ if (Sgl_isinexact_to_fix(src,src_exponent)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(src)) {
+ Dint_increment(resultp1,resultp2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(src)) {
+ Dint_decrement(resultp1,resultp2);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (Sgl_isone_roundbit(src,src_exponent))
+ if (Sgl_isone_stickybit(src,src_exponent) ||
+ (Dint_isone_lowp2(resultp2)))
+ if (Sgl_iszero_sign(src)) {
+ Dint_increment(resultp1,resultp2);
+ }
+ else {
+ Dint_decrement(resultp1,resultp2);
+ }
+ }
+ }
+ }
+ else {
+ Dint_setzero(resultp1,resultp2);
+
+ /* check for inexact */
+ if (Sgl_isnotzero_exponentmantissa(src)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(src)) {
+ Dint_increment(resultp1,resultp2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(src)) {
+ Dint_decrement(resultp1,resultp2);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (src_exponent == -1)
+ if (Sgl_isnotzero_mantissa(src))
+ if (Sgl_iszero_sign(src)) {
+ Dint_increment(resultp1,resultp2);
+ }
+ else {
+ Dint_decrement(resultp1,resultp2);
+ }
+ }
+ }
+ }
+ Dint_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ return(NOEXCEPTION);
+}
+
+/*
+ * Double Floating-point to Single Fixed-point
+ */
+/*ARGSUSED*/
+dbl_to_sgl_fcnvfx(srcptr,nullptr,dstptr,status)
+
+dbl_floating_point *srcptr;
+int *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int srcp1,srcp2, tempp1,tempp2;
+ register int src_exponent, result;
+ register boolean inexact = FALSE;
+
+ Dbl_copyfromptr(srcptr,srcp1,srcp2);
+ src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
+
+ /*
+ * Test for overflow
+ */
+ if (src_exponent > SGL_FX_MAX_EXP) {
+ /* check for MININT */
+ if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
+ /*
+ * Since source is a number which cannot be
+ * represented in fixed-point format, return
+ * largest (or smallest) fixed-point number.
+ */
+ Dbl_return_overflow(srcp1,srcp2,dstptr);
+ }
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ tempp1 = srcp1;
+ tempp2 = srcp2;
+ Dbl_clear_signexponent_set_hidden(tempp1);
+ Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
+ if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
+ result = -Dbl_allp1(tempp1);
+ else result = Dbl_allp1(tempp1);
+
+ /* check for inexact */
+ if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(srcp1)) result++;
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(srcp1)) result--;
+ break;
+ case ROUNDNEAREST:
+ if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
+ if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
+ (Dbl_isone_lowmantissap1(tempp1)))
+ if (Dbl_iszero_sign(srcp1)) result++;
+ else result--;
+ }
+ /* check for overflow */
+ if ((Dbl_iszero_sign(srcp1) && result < 0) ||
+ (Dbl_isone_sign(srcp1) && result > 0)) {
+ Dbl_return_overflow(srcp1,srcp2,dstptr);
+ }
+ }
+ }
+ else {
+ result = 0;
+
+ /* check for inexact */
+ if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(srcp1)) result++;
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(srcp1)) result--;
+ break;
+ case ROUNDNEAREST:
+ if (src_exponent == -1)
+ if (Dbl_isnotzero_mantissa(srcp1,srcp2))
+ if (Dbl_iszero_sign(srcp1)) result++;
+ else result--;
+ }
+ }
+ }
+ *dstptr = result;
+ if (inexact) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ return(NOEXCEPTION);
+}
+
+/*
+ * Double Floating-point to Double Fixed-point
+ */
+/*ARGSUSED*/
+dbl_to_dbl_fcnvfx(srcptr,nullptr,dstptr,status)
+
+dbl_floating_point *srcptr;
+dbl_integer *dstptr;
+unsigned int *nullptr, *status;
+{
+ register int src_exponent, resultp1;
+ register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
+ register boolean inexact = FALSE;
+
+ Dbl_copyfromptr(srcptr,srcp1,srcp2);
+ src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
+
+ /*
+ * Test for overflow
+ */
+ if (src_exponent > DBL_FX_MAX_EXP) {
+ /* check for MININT */
+ if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
+ Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
+ /*
+ * Since source is a number which cannot be
+ * represented in fixed-point format, return
+ * largest (or smallest) fixed-point number.
+ */
+ Dbl_return_overflow_dbl(srcp1,srcp2,dstptr);
+ }
+ }
+
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ tempp1 = srcp1;
+ tempp2 = srcp2;
+ Dbl_clear_signexponent_set_hidden(tempp1);
+ Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,resultp1,
+ resultp2);
+ if (Dbl_isone_sign(srcp1)) {
+ Dint_setone_sign(resultp1,resultp2);
+ }
+
+ /* check for inexact */
+ if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(srcp1)) {
+ Dint_increment(resultp1,resultp2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(srcp1)) {
+ Dint_decrement(resultp1,resultp2);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
+ if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
+ (Dint_isone_lowp2(resultp2)))
+ if (Dbl_iszero_sign(srcp1)) {
+ Dint_increment(resultp1,resultp2);
+ }
+ else {
+ Dint_decrement(resultp1,resultp2);
+ }
+ }
+ }
+ }
+ else {
+ Dint_setzero(resultp1,resultp2);
+
+ /* check for inexact */
+ if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(srcp1)) {
+ Dint_increment(resultp1,resultp2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(srcp1)) {
+ Dint_decrement(resultp1,resultp2);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (src_exponent == -1)
+ if (Dbl_isnotzero_mantissa(srcp1,srcp2))
+ if (Dbl_iszero_sign(srcp1)) {
+ Dint_increment(resultp1,resultp2);
+ }
+ else {
+ Dint_decrement(resultp1,resultp2);
+ }
+ }
+ }
+ }
+ Dint_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/fcnvfxt.c b/sys/arch/hppa/spmath/fcnvfxt.c
new file mode 100644
index 00000000000..7fe4311ccfe
--- /dev/null
+++ b/sys/arch/hppa/spmath/fcnvfxt.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/fcnvfxt.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:58 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+#include "../spmath/dbl_float.h"
+#include "../spmath/cnv_float.h"
+
+/*
+ * Convert single floating-point to single fixed-point format
+ * with truncated result
+ */
+/*ARGSUSED*/
+sgl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
+
+sgl_floating_point *srcptr;
+int *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int src, temp;
+ register int src_exponent, result;
+
+ src = *srcptr;
+ src_exponent = Sgl_exponent(src) - SGL_BIAS;
+
+ /*
+ * Test for overflow
+ */
+ if (src_exponent > SGL_FX_MAX_EXP) {
+ /* check for MININT */
+ if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
+ Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
+ /*
+ * Since source is a number which cannot be
+ * represented in fixed-point format, return
+ * largest (or smallest) fixed-point number.
+ */
+ Sgl_return_overflow(src,dstptr);
+ }
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ temp = src;
+ Sgl_clear_signexponent_set_hidden(temp);
+ Int_from_sgl_mantissa(temp,src_exponent);
+ if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
+ else result = Sgl_all(temp);
+ *dstptr = result;
+
+ /* check for inexact */
+ if (Sgl_isinexact_to_fix(src,src_exponent)) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ }
+ else {
+ *dstptr = 0;
+
+ /* check for inexact */
+ if (Sgl_isnotzero_exponentmantissa(src)) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ }
+ return(NOEXCEPTION);
+}
+
+/*
+ * Single Floating-point to Double Fixed-point
+ */
+/*ARGSUSED*/
+sgl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
+
+sgl_floating_point *srcptr;
+dbl_integer *dstptr;
+unsigned int *nullptr, *status;
+{
+ register int src_exponent, resultp1;
+ register unsigned int src, temp, resultp2;
+
+ src = *srcptr;
+ src_exponent = Sgl_exponent(src) - SGL_BIAS;
+
+ /*
+ * Test for overflow
+ */
+ if (src_exponent > DBL_FX_MAX_EXP) {
+ /* check for MININT */
+ if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
+ Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
+ /*
+ * Since source is a number which cannot be
+ * represented in fixed-point format, return
+ * largest (or smallest) fixed-point number.
+ */
+ Sgl_return_overflow_dbl(src,dstptr);
+ }
+ Dint_set_minint(resultp1,resultp2);
+ Dint_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ temp = src;
+ Sgl_clear_signexponent_set_hidden(temp);
+ Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
+ if (Sgl_isone_sign(src)) {
+ Dint_setone_sign(resultp1,resultp2);
+ }
+ Dint_copytoptr(resultp1,resultp2,dstptr);
+
+ /* check for inexact */
+ if (Sgl_isinexact_to_fix(src,src_exponent)) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ }
+ else {
+ Dint_setzero(resultp1,resultp2);
+ Dint_copytoptr(resultp1,resultp2,dstptr);
+
+ /* check for inexact */
+ if (Sgl_isnotzero_exponentmantissa(src)) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ }
+ return(NOEXCEPTION);
+}
+
+/*
+ * Double Floating-point to Single Fixed-point
+ */
+/*ARGSUSED*/
+dbl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
+
+dbl_floating_point *srcptr;
+int *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int srcp1, srcp2, tempp1, tempp2;
+ register int src_exponent, result;
+
+ Dbl_copyfromptr(srcptr,srcp1,srcp2);
+ src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
+
+ /*
+ * Test for overflow
+ */
+ if (src_exponent > SGL_FX_MAX_EXP) {
+ /* check for MININT */
+ if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
+ Dbl_return_overflow(srcp1,srcp2,dstptr);
+ }
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ tempp1 = srcp1;
+ tempp2 = srcp2;
+ Dbl_clear_signexponent_set_hidden(tempp1);
+ Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
+ if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
+ result = -Dbl_allp1(tempp1);
+ else result = Dbl_allp1(tempp1);
+ *dstptr = result;
+
+ /* check for inexact */
+ if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ }
+ else {
+ *dstptr = 0;
+
+ /* check for inexact */
+ if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ }
+ return(NOEXCEPTION);
+}
+
+/*
+ * Double Floating-point to Double Fixed-point
+ */
+/*ARGSUSED*/
+dbl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
+
+dbl_floating_point *srcptr;
+dbl_integer *dstptr;
+unsigned int *nullptr, *status;
+{
+ register int src_exponent, resultp1;
+ register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
+
+ Dbl_copyfromptr(srcptr,srcp1,srcp2);
+ src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
+
+ /*
+ * Test for overflow
+ */
+ if (src_exponent > DBL_FX_MAX_EXP) {
+ /* check for MININT */
+ if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
+ Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
+ /*
+ * Since source is a number which cannot be
+ * represented in fixed-point format, return
+ * largest (or smallest) fixed-point number.
+ */
+ Dbl_return_overflow_dbl(srcp1,srcp2,dstptr);
+ }
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ tempp1 = srcp1;
+ tempp2 = srcp2;
+ Dbl_clear_signexponent_set_hidden(tempp1);
+ Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
+ resultp1,resultp2);
+ if (Dbl_isone_sign(srcp1)) {
+ Dint_setone_sign(resultp1,resultp2);
+ }
+ Dint_copytoptr(resultp1,resultp2,dstptr);
+
+ /* check for inexact */
+ if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ }
+ else {
+ Dint_setzero(resultp1,resultp2);
+ Dint_copytoptr(resultp1,resultp2,dstptr);
+
+ /* check for inexact */
+ if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ }
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/fcnvxf.c b/sys/arch/hppa/spmath/fcnvxf.c
new file mode 100644
index 00000000000..c087155fa0f
--- /dev/null
+++ b/sys/arch/hppa/spmath/fcnvxf.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/fcnvxf.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:33:59 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+#include "../spmath/dbl_float.h"
+#include "../spmath/cnv_float.h"
+
+/*
+ * Convert single fixed-point to single floating-point format
+ */
+
+sgl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
+
+int *srcptr;
+sgl_floating_point *dstptr;
+unsigned int *nullptr, *status;
+{
+ register int src, dst_exponent;
+ register unsigned int result = 0;
+
+ src = *srcptr;
+ /*
+ * set sign bit of result and get magnitude of source
+ */
+ if (src < 0) {
+ Sgl_setone_sign(result);
+ Int_negate(src);
+ }
+ else {
+ Sgl_setzero_sign(result);
+ /* Check for zero */
+ if (src == 0) {
+ Sgl_setzero(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * Generate exponent and normalized mantissa
+ */
+ dst_exponent = 16; /* initialize for normalization */
+ /*
+ * Check word for most significant bit set. Returns
+ * a value in dst_exponent indicating the bit position,
+ * between -1 and 30.
+ */
+ Find_ms_one_bit(src,dst_exponent);
+ /* left justify source, with msb at bit position 1 */
+ if (dst_exponent >= 0) src <<= dst_exponent;
+ else src = 1 << 30;
+ Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
+ Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
+
+ /* check for inexact */
+ if (Int_isinexact_to_sgl(src)) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result))
+ Sgl_increment(result);
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result))
+ Sgl_increment(result);
+ break;
+ case ROUNDNEAREST:
+ Sgl_roundnearest_from_int(src,result);
+ }
+ if (Is_inexacttrap_enabled()) {
+ *dstptr = result;
+ return(INEXACTEXCEPTION);
+ }
+ else Set_inexactflag();
+ }
+ *dstptr = result;
+ return(NOEXCEPTION);
+}
+
+/*
+ * Single Fixed-point to Double Floating-point
+ */
+
+sgl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
+
+int *srcptr;
+dbl_floating_point *dstptr;
+unsigned int *nullptr, *status;
+{
+ register int src, dst_exponent;
+ register unsigned int resultp1 = 0, resultp2 = 0;
+
+ src = *srcptr;
+ /*
+ * set sign bit of result and get magnitude of source
+ */
+ if (src < 0) {
+ Dbl_setone_sign(resultp1);
+ Int_negate(src);
+ }
+ else {
+ Dbl_setzero_sign(resultp1);
+ /* Check for zero */
+ if (src == 0) {
+ Dbl_setzero(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * Generate exponent and normalized mantissa
+ */
+ dst_exponent = 16; /* initialize for normalization */
+ /*
+ * Check word for most significant bit set. Returns
+ * a value in dst_exponent indicating the bit position,
+ * between -1 and 30.
+ */
+ Find_ms_one_bit(src,dst_exponent);
+ /* left justify source, with msb at bit position 1 */
+ if (dst_exponent >= 0) src <<= dst_exponent;
+ else src = 1 << 30;
+ Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH - 1);
+ Dbl_set_mantissap2(resultp2, src << (33-DBL_EXP_LENGTH));
+ Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+}
+
+/*
+ * Double Fixed-point to Single Floating-point
+ */
+
+dbl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
+
+dbl_integer *srcptr;
+sgl_floating_point *dstptr;
+unsigned int *nullptr, *status;
+{
+ int dst_exponent, srcp1;
+ unsigned int result = 0, srcp2;
+
+ Dint_copyfromptr(srcptr,srcp1,srcp2);
+ /*
+ * set sign bit of result and get magnitude of source
+ */
+ if (srcp1 < 0) {
+ Sgl_setone_sign(result);
+ Dint_negate(srcp1,srcp2);
+ }
+ else {
+ Sgl_setzero_sign(result);
+ /* Check for zero */
+ if (srcp1 == 0 && srcp2 == 0) {
+ Sgl_setzero(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * Generate exponent and normalized mantissa
+ */
+ dst_exponent = 16; /* initialize for normalization */
+ if (srcp1 == 0) {
+ /*
+ * Check word for most significant bit set. Returns
+ * a value in dst_exponent indicating the bit position,
+ * between -1 and 30.
+ */
+ Find_ms_one_bit(srcp2,dst_exponent);
+ /* left justify source, with msb at bit position 1 */
+ if (dst_exponent >= 0) {
+ srcp1 = srcp2 << dst_exponent;
+ srcp2 = 0;
+ }
+ else {
+ srcp1 = srcp2 >> 1;
+ srcp2 <<= 31;
+ }
+ /*
+ * since msb set is in second word, need to
+ * adjust bit position count
+ */
+ dst_exponent += 32;
+ }
+ else {
+ /*
+ * Check word for most significant bit set. Returns
+ * a value in dst_exponent indicating the bit position,
+ * between -1 and 30.
+ *
+ */
+ Find_ms_one_bit(srcp1,dst_exponent);
+ /* left justify source, with msb at bit position 1 */
+ if (dst_exponent > 0) {
+ Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
+ srcp1);
+ srcp2 <<= dst_exponent;
+ }
+ /*
+ * If dst_exponent = 0, we don't need to shift anything.
+ * If dst_exponent = -1, src = - 2**63 so we won't need to
+ * shift srcp2.
+ */
+ else srcp1 >>= -(dst_exponent);
+ }
+ Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH - 1);
+ Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
+
+ /* check for inexact */
+ if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result))
+ Sgl_increment(result);
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result))
+ Sgl_increment(result);
+ break;
+ case ROUNDNEAREST:
+ Sgl_roundnearest_from_dint(srcp1,srcp2,result);
+ }
+ if (Is_inexacttrap_enabled()) {
+ *dstptr = result;
+ return(INEXACTEXCEPTION);
+ }
+ else Set_inexactflag();
+ }
+ *dstptr = result;
+ return(NOEXCEPTION);
+}
+
+/*
+ * Double Fixed-point to Double Floating-point
+ */
+
+dbl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
+
+dbl_integer *srcptr;
+dbl_floating_point *dstptr;
+unsigned int *nullptr, *status;
+{
+ register int srcp1, dst_exponent;
+ register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
+
+ Dint_copyfromptr(srcptr,srcp1,srcp2);
+ /*
+ * set sign bit of result and get magnitude of source
+ */
+ if (srcp1 < 0) {
+ Dbl_setone_sign(resultp1);
+ Dint_negate(srcp1,srcp2);
+ }
+ else {
+ Dbl_setzero_sign(resultp1);
+ /* Check for zero */
+ if (srcp1 == 0 && srcp2 ==0) {
+ Dbl_setzero(resultp1,resultp2);
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * Generate exponent and normalized mantissa
+ */
+ dst_exponent = 16; /* initialize for normalization */
+ if (srcp1 == 0) {
+ /*
+ * Check word for most significant bit set. Returns
+ * a value in dst_exponent indicating the bit position,
+ * between -1 and 30.
+ */
+ Find_ms_one_bit(srcp2,dst_exponent);
+ /* left justify source, with msb at bit position 1 */
+ if (dst_exponent >= 0) {
+ srcp1 = srcp2 << dst_exponent;
+ srcp2 = 0;
+ }
+ else {
+ srcp1 = srcp2 >> 1;
+ srcp2 <<= 31;
+ }
+ /*
+ * since msb set is in second word, need to
+ * adjust bit position count
+ */
+ dst_exponent += 32;
+ }
+ else {
+ /*
+ * Check word for most significant bit set. Returns
+ * a value in dst_exponent indicating the bit position,
+ * between -1 and 30.
+ */
+ Find_ms_one_bit(srcp1,dst_exponent);
+ /* left justify source, with msb at bit position 1 */
+ if (dst_exponent > 0) {
+ Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
+ srcp1);
+ srcp2 <<= dst_exponent;
+ }
+ /*
+ * If dst_exponent = 0, we don't need to shift anything.
+ * If dst_exponent = -1, src = - 2**63 so we won't need to
+ * shift srcp2.
+ */
+ else srcp1 >>= -(dst_exponent);
+ }
+ Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
+ Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
+ Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
+
+ /* check for inexact */
+ if (Dint_isinexact_to_dbl(srcp2)) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(resultp1)) {
+ Dbl_increment(resultp1,resultp2);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(resultp1)) {
+ Dbl_increment(resultp1,resultp2);
+ }
+ break;
+ case ROUNDNEAREST:
+ Dbl_roundnearest_from_dint(srcp2,resultp1,
+ resultp2);
+ }
+ if (Is_inexacttrap_enabled()) {
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(INEXACTEXCEPTION);
+ }
+ else Set_inexactflag();
+ }
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/float.h b/sys/arch/hppa/spmath/float.h
new file mode 100644
index 00000000000..3bbafecc45c
--- /dev/null
+++ b/sys/arch/hppa/spmath/float.h
@@ -0,0 +1,547 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/*
+ * @(#)float.h: $Revision: 1.1 $ $Date: 1998/06/23 20:34:00 $
+ * $Locker: $
+ *
+ */
+#include "../spmath/fpbits.h"
+#include "../spmath/hppa.h"
+
+/*
+ * Declare the basic structures for the 3 different
+ * floating-point precisions.
+ *
+ * Single number
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |s| exp | mantissa |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+#define Sall(object) (object)
+#define Ssign(object) Bitfield_extract( 0, 1,object)
+#define Ssignedsign(object) Bitfield_signed_extract( 0, 1,object)
+#define Sexponent(object) Bitfield_extract( 1, 8,object)
+#define Smantissa(object) Bitfield_mask( 9, 23,object)
+#define Ssignaling(object) Bitfield_extract( 9, 1,object)
+#define Ssignalingnan(object) Bitfield_extract( 1, 9,object)
+#define Shigh2mantissa(object) Bitfield_extract( 9, 2,object)
+#define Sexponentmantissa(object) Bitfield_mask( 1, 31,object)
+#define Ssignexponent(object) Bitfield_extract( 0, 9,object)
+#define Shidden(object) Bitfield_extract( 8, 1,object)
+#define Shiddenoverflow(object) Bitfield_extract( 7, 1,object)
+#define Shiddenhigh7mantissa(object) Bitfield_extract( 8, 8,object)
+#define Shiddenhigh3mantissa(object) Bitfield_extract( 8, 4,object)
+#define Slow(object) Bitfield_mask( 31, 1,object)
+#define Slow4(object) Bitfield_mask( 28, 4,object)
+#define Slow31(object) Bitfield_mask( 1, 31,object)
+#define Shigh31(object) Bitfield_extract( 0, 31,object)
+#define Ssignedhigh31(object) Bitfield_signed_extract( 0, 31,object)
+#define Shigh4(object) Bitfield_extract( 0, 4,object)
+#define Sbit24(object) Bitfield_extract( 24, 1,object)
+#define Sbit28(object) Bitfield_extract( 28, 1,object)
+#define Sbit29(object) Bitfield_extract( 29, 1,object)
+#define Sbit30(object) Bitfield_extract( 30, 1,object)
+#define Sbit31(object) Bitfield_mask( 31, 1,object)
+
+#define Deposit_ssign(object,value) Bitfield_deposit(value,0,1,object)
+#define Deposit_sexponent(object,value) Bitfield_deposit(value,1,8,object)
+#define Deposit_smantissa(object,value) Bitfield_deposit(value,9,23,object)
+#define Deposit_shigh2mantissa(object,value) Bitfield_deposit(value,9,2,object)
+#define Deposit_sexponentmantissa(object,value) \
+ Bitfield_deposit(value,1,31,object)
+#define Deposit_ssignexponent(object,value) Bitfield_deposit(value,0,9,object)
+#define Deposit_slow(object,value) Bitfield_deposit(value,31,1,object)
+#define Deposit_shigh4(object,value) Bitfield_deposit(value,0,4,object)
+
+#define Is_ssign(object) Bitfield_mask( 0, 1,object)
+#define Is_ssignaling(object) Bitfield_mask( 9, 1,object)
+#define Is_shidden(object) Bitfield_mask( 8, 1,object)
+#define Is_shiddenoverflow(object) Bitfield_mask( 7, 1,object)
+#define Is_slow(object) Bitfield_mask( 31, 1,object)
+#define Is_sbit24(object) Bitfield_mask( 24, 1,object)
+#define Is_sbit28(object) Bitfield_mask( 28, 1,object)
+#define Is_sbit29(object) Bitfield_mask( 29, 1,object)
+#define Is_sbit30(object) Bitfield_mask( 30, 1,object)
+#define Is_sbit31(object) Bitfield_mask( 31, 1,object)
+
+/*
+ * Double number.
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |s| exponent | mantissa part 1 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | mantissa part 2 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+#define Dallp1(object) (object)
+#define Dsign(object) Bitfield_extract( 0, 1,object)
+#define Dsignedsign(object) Bitfield_signed_extract( 0, 1,object)
+#define Dexponent(object) Bitfield_extract( 1, 11,object)
+#define Dmantissap1(object) Bitfield_mask( 12, 20,object)
+#define Dsignaling(object) Bitfield_extract( 12, 1,object)
+#define Dsignalingnan(object) Bitfield_extract( 1, 12,object)
+#define Dhigh2mantissa(object) Bitfield_extract( 12, 2,object)
+#define Dexponentmantissap1(object) Bitfield_mask( 1, 31,object)
+#define Dsignexponent(object) Bitfield_extract( 0, 12,object)
+#define Dhidden(object) Bitfield_extract( 11, 1,object)
+#define Dhiddenoverflow(object) Bitfield_extract( 10, 1,object)
+#define Dhiddenhigh7mantissa(object) Bitfield_extract( 11, 8,object)
+#define Dhiddenhigh3mantissa(object) Bitfield_extract( 11, 4,object)
+#define Dlowp1(object) Bitfield_mask( 31, 1,object)
+#define Dlow31p1(object) Bitfield_mask( 1, 31,object)
+#define Dhighp1(object) Bitfield_extract( 0, 1,object)
+#define Dhigh4p1(object) Bitfield_extract( 0, 4,object)
+#define Dhigh31p1(object) Bitfield_extract( 0, 31,object)
+#define Dsignedhigh31p1(object) Bitfield_signed_extract( 0, 31,object)
+#define Dbit3p1(object) Bitfield_extract( 3, 1,object)
+
+#define Deposit_dsign(object,value) Bitfield_deposit(value,0,1,object)
+#define Deposit_dexponent(object,value) Bitfield_deposit(value,1,11,object)
+#define Deposit_dmantissap1(object,value) Bitfield_deposit(value,12,20,object)
+#define Deposit_dhigh2mantissa(object,value) Bitfield_deposit(value,12,2,object)
+#define Deposit_dexponentmantissap1(object,value) \
+ Bitfield_deposit(value,1,31,object)
+#define Deposit_dsignexponent(object,value) Bitfield_deposit(value,0,12,object)
+#define Deposit_dlowp1(object,value) Bitfield_deposit(value,31,1,object)
+#define Deposit_dhigh4p1(object,value) Bitfield_deposit(value,0,4,object)
+
+#define Is_dsign(object) Bitfield_mask( 0, 1,object)
+#define Is_dsignaling(object) Bitfield_mask( 12, 1,object)
+#define Is_dhidden(object) Bitfield_mask( 11, 1,object)
+#define Is_dhiddenoverflow(object) Bitfield_mask( 10, 1,object)
+#define Is_dlowp1(object) Bitfield_mask( 31, 1,object)
+#define Is_dhighp1(object) Bitfield_mask( 0, 1,object)
+#define Is_dbit3p1(object) Bitfield_mask( 3, 1,object)
+
+#define Dallp2(object) (object)
+#define Dmantissap2(object) (object)
+#define Dlowp2(object) Bitfield_mask( 31, 1,object)
+#define Dlow4p2(object) Bitfield_mask( 28, 4,object)
+#define Dlow31p2(object) Bitfield_mask( 1, 31,object)
+#define Dhighp2(object) Bitfield_extract( 0, 1,object)
+#define Dhigh31p2(object) Bitfield_extract( 0, 31,object)
+#define Dbit2p2(object) Bitfield_extract( 2, 1,object)
+#define Dbit3p2(object) Bitfield_extract( 3, 1,object)
+#define Dbit21p2(object) Bitfield_extract( 21, 1,object)
+#define Dbit28p2(object) Bitfield_extract( 28, 1,object)
+#define Dbit29p2(object) Bitfield_extract( 29, 1,object)
+#define Dbit30p2(object) Bitfield_extract( 30, 1,object)
+#define Dbit31p2(object) Bitfield_mask( 31, 1,object)
+
+#define Deposit_dlowp2(object,value) Bitfield_deposit(value,31,1,object)
+
+#define Is_dlowp2(object) Bitfield_mask( 31, 1,object)
+#define Is_dhighp2(object) Bitfield_mask( 0, 1,object)
+#define Is_dbit2p2(object) Bitfield_mask( 2, 1,object)
+#define Is_dbit3p2(object) Bitfield_mask( 3, 1,object)
+#define Is_dbit21p2(object) Bitfield_mask( 21, 1,object)
+#define Is_dbit28p2(object) Bitfield_mask( 28, 1,object)
+#define Is_dbit29p2(object) Bitfield_mask( 29, 1,object)
+#define Is_dbit30p2(object) Bitfield_mask( 30, 1,object)
+#define Is_dbit31p2(object) Bitfield_mask( 31, 1,object)
+
+/*
+ * Quad number.
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |s| exponent | mantissa part 1 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | mantissa part 2 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | mantissa part 3 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | mantissa part 4 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+typedef struct
+ {
+ union
+ {
+ struct { unsigned qallp1; } u_qallp1;
+/* Not needed for now...
+ Bitfield_extract( 0, 1,u_qsign,qsign)
+ Bitfield_signed_extract( 0, 1,u_qsignedsign,qsignedsign)
+ Bitfield_extract( 1, 15,u_qexponent,qexponent)
+ Bitfield_extract(16, 16,u_qmantissap1,qmantissap1)
+ Bitfield_extract(16, 1,u_qsignaling,qsignaling)
+ Bitfield_extract(1, 16,u_qsignalingnan,qsignalingnan)
+ Bitfield_extract(16, 2,u_qhigh2mantissa,qhigh2mantissa)
+ Bitfield_extract( 1, 31,u_qexponentmantissap1,qexponentmantissap1)
+ Bitfield_extract( 0, 16,u_qsignexponent,qsignexponent)
+ Bitfield_extract(15, 1,u_qhidden,qhidden)
+ Bitfield_extract(14, 1,u_qhiddenoverflow,qhiddenoverflow)
+ Bitfield_extract(15, 8,u_qhiddenhigh7mantissa,qhiddenhigh7mantissa)
+ Bitfield_extract(15, 4,u_qhiddenhigh3mantissa,qhiddenhigh3mantissa)
+ Bitfield_extract(31, 1,u_qlowp1,qlowp1)
+ Bitfield_extract( 1, 31,u_qlow31p1,qlow31p1)
+ Bitfield_extract( 0, 1,u_qhighp1,qhighp1)
+ Bitfield_extract( 0, 4,u_qhigh4p1,qhigh4p1)
+ Bitfield_extract( 0, 31,u_qhigh31p1,qhigh31p1)
+ */
+ } quad_u1;
+ union
+ {
+ struct { unsigned qallp2; } u_qallp2;
+ /* Not needed for now...
+ Bitfield_extract(31, 1,u_qlowp2,qlowp2)
+ Bitfield_extract( 1, 31,u_qlow31p2,qlow31p2)
+ Bitfield_extract( 0, 1,u_qhighp2,qhighp2)
+ Bitfield_extract( 0, 31,u_qhigh31p2,qhigh31p2)
+ */
+ } quad_u2;
+ union
+ {
+ struct { unsigned qallp3; } u_qallp3;
+ /* Not needed for now...
+ Bitfield_extract(31, 1,u_qlowp3,qlowp3)
+ Bitfield_extract( 1, 31,u_qlow31p3,qlow31p3)
+ Bitfield_extract( 0, 1,u_qhighp3,qhighp3)
+ Bitfield_extract( 0, 31,u_qhigh31p3,qhigh31p3)
+ */
+ } quad_u3;
+ union
+ {
+ struct { unsigned qallp4; } u_qallp4;
+ /* Not need for now...
+ Bitfield_extract(31, 1,u_qlowp4,qlowp4)
+ Bitfield_extract( 1, 31,u_qlow31p4,qlow31p4)
+ Bitfield_extract( 0, 1,u_qhighp4,qhighp4)
+ Bitfield_extract( 0, 31,u_qhigh31p4,qhigh31p4)
+ */
+ } quad_u4;
+ } quad_floating_point;
+
+/* Extension - An additional structure to hold the guard, round and
+ * sticky bits during computations.
+ */
+#define Extall(object) (object)
+#define Extsign(object) Bitfield_extract( 0, 1,object)
+#define Exthigh31(object) Bitfield_extract( 0, 31,object)
+#define Extlow31(object) Bitfield_extract( 1, 31,object)
+#define Extlow(object) Bitfield_extract( 31, 1,object)
+
+/*
+ * Declare the basic structures for the 3 different
+ * fixed-point precisions.
+ *
+ * Single number
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |s| integer |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+typedef int sgl_integer;
+
+/*
+ * Double number.
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |s| high integer |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | low integer |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+struct dint {
+ int wd0;
+ unsigned int wd1;
+};
+
+struct dblwd {
+ unsigned int wd0;
+ unsigned int wd1;
+};
+
+/*
+ * Quad number.
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |s| integer part1 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | integer part 2 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | integer part 3 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | integer part 4 |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+
+struct quadwd {
+ int wd0;
+ unsigned int wd1;
+ unsigned int wd2;
+ unsigned int wd3;
+};
+
+typedef struct quadwd quad_integer;
+
+
+/* useful typedefs */
+typedef int sgl_floating_point;
+typedef struct dblwd dbl_floating_point;
+typedef struct dint dbl_integer;
+
+/*
+ * Define the different precisions' parameters.
+ */
+#define SGL_BITLENGTH 32
+#define SGL_EMAX 127
+#define SGL_EMIN (-126)
+#define SGL_BIAS 127
+#define SGL_WRAP 192
+#define SGL_INFINITY_EXPONENT (SGL_EMAX+SGL_BIAS+1)
+#define SGL_THRESHOLD 32
+#define SGL_EXP_LENGTH 8
+#define SGL_P 24
+
+#define DBL_BITLENGTH 64
+#define DBL_EMAX 1023
+#define DBL_EMIN (-1022)
+#define DBL_BIAS 1023
+#define DBL_WRAP 1536
+#define DBL_INFINITY_EXPONENT (DBL_EMAX+DBL_BIAS+1)
+#define DBL_THRESHOLD 64
+#define DBL_EXP_LENGTH 11
+#define DBL_P 53
+
+#define QUAD_BITLENGTH 128
+#define QUAD_EMAX 16383
+#define QUAD_EMIN (-16382)
+#define QUAD_BIAS 16383
+#define QUAD_WRAP 24576
+#define QUAD_INFINITY_EXPONENT (QUAD_EMAX+QUAD_BIAS+1)
+#define QUAD_P 113
+
+/* Boolean Values etc. */
+#define FALSE 0
+#define TRUE (!FALSE)
+#define NOT !
+#define XOR ^
+
+/* other constants */
+#undef NULL
+#define NULL 0
+#define NIL 0
+#define SGL 0
+#define DBL 1
+#define BADFMT 2
+#define QUAD 3
+
+
+/* Types */
+typedef int boolean;
+typedef int FORMAT;
+typedef int VOID;
+
+
+/* Declare status register equivalent to FPUs architecture.
+ *
+ * 0 1 2 3 4 5 6 7 8 910 1 2 3 4 5 6 7 8 920 1 2 3 4 5 6 7 8 930 1
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |V|Z|O|U|I|C| rsv | model | version |RM |rsv|T|r|V|Z|O|U|I|
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+#define Cbit(object) Bitfield_extract( 5, 1,object)
+#define Tbit(object) Bitfield_extract( 25, 1,object)
+#define Roundingmode(object) Bitfield_extract( 21, 2,object)
+#define Invalidtrap(object) Bitfield_extract( 27, 1,object)
+#define Divisionbyzerotrap(object) Bitfield_extract( 28, 1,object)
+#define Overflowtrap(object) Bitfield_extract( 29, 1,object)
+#define Underflowtrap(object) Bitfield_extract( 30, 1,object)
+#define Inexacttrap(object) Bitfield_extract( 31, 1,object)
+#define Invalidflag(object) Bitfield_extract( 0, 1,object)
+#define Divisionbyzeroflag(object) Bitfield_extract( 1, 1,object)
+#define Overflowflag(object) Bitfield_extract( 2, 1,object)
+#define Underflowflag(object) Bitfield_extract( 3, 1,object)
+#define Inexactflag(object) Bitfield_extract( 4, 1,object)
+#define Allflags(object) Bitfield_extract( 0, 5,object)
+
+/* Definitions relevant to the status register */
+
+/* Rounding Modes */
+#define ROUNDNEAREST 0
+#define ROUNDZERO 1
+#define ROUNDPLUS 2
+#define ROUNDMINUS 3
+
+/* Exceptions */
+#define NOEXCEPTION 0x0
+#define INVALIDEXCEPTION 0x20
+#define DIVISIONBYZEROEXCEPTION 0x10
+#define OVERFLOWEXCEPTION 0x08
+#define UNDERFLOWEXCEPTION 0x04
+#define INEXACTEXCEPTION 0x02
+#define UNIMPLEMENTEDEXCEPTION 0x01
+
+/* Declare exception registers equivalent to FPUs architecture
+ *
+ * 0 1 2 3 4 5 6 7 8 910 1 2 3 4 5 6 7 8 920 1 2 3 4 5 6 7 8 930 1
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * |excepttype | r1 | r2/ext | operation |parm |n| t/cond |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+#define Allexception(object) (object)
+#define Exceptiontype(object) Bitfield_extract( 0, 6,object)
+#define Instructionfield(object) Bitfield_mask( 6,26,object)
+#define Parmfield(object) Bitfield_extract( 23, 3,object)
+#define Rabit(object) Bitfield_extract( 24, 1,object)
+#define Ibit(object) Bitfield_extract( 25, 1,object)
+
+#define Set_exceptiontype(object,value) Bitfield_deposit(value, 0, 6,object)
+#define Set_parmfield(object,value) Bitfield_deposit(value, 23, 3,object)
+#define Set_exceptiontype_and_instr_field(exception,instruction,object) \
+ object = exception << 26 | instruction
+
+/* Declare the condition field
+ *
+ * 0 1 2 3 4 5 6 7 8 910 1 2 3 4 5 6 7 8 920 1 2 3 4 5 6 7 8 930 1
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * | |G|L|E|U|X|
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ */
+#define Allexception(object) (object)
+#define Greaterthanbit(object) Bitfield_extract( 27, 1,object)
+#define Lessthanbit(object) Bitfield_extract( 28, 1,object)
+#define Equalbit(object) Bitfield_extract( 29, 1,object)
+#define Unorderedbit(object) Bitfield_extract( 30, 1,object)
+#define Exceptionbit(object) Bitfield_extract( 31, 1,object)
+
+/* An alias name for the status register */
+#define Fpustatus_register (*status)
+
+/**************************************************
+ * Status register referencing and manipulation. *
+ **************************************************/
+
+/* Rounding mode */
+#define Rounding_mode() Roundingmode(Fpustatus_register)
+#define Is_rounding_mode(rmode) \
+ (Roundingmode(Fpustatus_register) == rmode)
+#define Set_rounding_mode(value) \
+ Bitfield_deposit(value,21,2,Fpustatus_register)
+
+/* Boolean testing of the trap enable bits */
+#define Is_invalidtrap_enabled() Invalidtrap(Fpustatus_register)
+#define Is_divisionbyzerotrap_enabled() Divisionbyzerotrap(Fpustatus_register)
+#define Is_overflowtrap_enabled() Overflowtrap(Fpustatus_register)
+#define Is_underflowtrap_enabled() Underflowtrap(Fpustatus_register)
+#define Is_inexacttrap_enabled() Inexacttrap(Fpustatus_register)
+
+/* Set the indicated flags in the status register */
+#define Set_invalidflag() Bitfield_deposit(1,0,1,Fpustatus_register)
+#define Set_divisionbyzeroflag() Bitfield_deposit(1,1,1,Fpustatus_register)
+#define Set_overflowflag() Bitfield_deposit(1,2,1,Fpustatus_register)
+#define Set_underflowflag() Bitfield_deposit(1,3,1,Fpustatus_register)
+#define Set_inexactflag() Bitfield_deposit(1,4,1,Fpustatus_register)
+
+#define Clear_all_flags() Bitfield_deposit(0,0,5,Fpustatus_register)
+
+/* Manipulate the trap and condition code bits (tbit and cbit) */
+#define Set_tbit() Bitfield_deposit(1,25,1,Fpustatus_register)
+#define Clear_tbit() Bitfield_deposit(0,25,1,Fpustatus_register)
+#define Is_tbit_set() Tbit(Fpustatus_register)
+#define Is_cbit_set() Cbit(Fpustatus_register)
+
+#ifdef TIMEX
+#define Set_status_cbit(value) \
+ Bitfield_deposit(Bitfield_extract(10,10,Fpustatus_register),11,10,Fpustatus_register); \
+ Bitfield_deposit(Bitfield_extract(5,1,Fpustatus_register),10,1,Fpustatus_register); \
+ Bitfield_deposit(value,5,1,Fpustatus_register)
+#else
+#define Set_status_cbit(value) Bitfield_deposit(value,5,1,Fpustatus_register)
+#endif
+
+/*******************************
+ * Condition field referencing *
+ *******************************/
+#define Unordered(cond) Unorderedbit(cond)
+#define Equal(cond) Equalbit(cond)
+#define Lessthan(cond) Lessthanbit(cond)
+#define Greaterthan(cond) Greaterthanbit(cond)
+#define Exception(cond) Exceptionbit(cond)
+
+
+/* Defines for the extension */
+#define Ext_isone_sign(extent) (Extsign(extent))
+#define Ext_isnotzero(extent) \
+ (Extall(extent))
+#define Ext_isnotzero_lower(extent) \
+ (Extlow31(extent))
+#define Ext_leftshiftby1(extent) \
+ Extall(extent) <<= 1
+#define Ext_negate(extent) \
+ (int )Extall(extent) = 0 - (int )Extall(extent)
+#define Ext_setone_low(extent) Bitfield_deposit(1,31,1,extent)
+
+typedef int operation;
+
+/* error messages */
+
+#define NONE 0
+#define UNDEFFPINST 1
+
+/* Function definitions: opcode, opclass */
+#define FTEST (1<<2) | 0
+#define FCPY (2<<2) | 0
+#define FABS (3<<2) | 0
+#define FSQRT (4<<2) | 0
+#define FRND (5<<2) | 0
+
+#define FCNVFF (0<<2) | 1
+#define FCNVXF (1<<2) | 1
+#define FCNVFX (2<<2) | 1
+#define FCNVFXT (3<<2) | 1
+
+#define FCMP (0<<2) | 2
+
+#define FADD (0<<2) | 3
+#define FSUB (1<<2) | 3
+#define FMPY (2<<2) | 3
+#define FDIV (3<<2) | 3
+#define FREM (4<<2) | 3
+
diff --git a/sys/arch/hppa/spmath/fpbits.h b/sys/arch/hppa/spmath/fpbits.h
new file mode 100644
index 00000000000..27f9d9e449d
--- /dev/null
+++ b/sys/arch/hppa/spmath/fpbits.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/*
+ * @(#)fpbits.h: $Revision: 1.1 $ $Date: 1998/06/23 20:34:00 $
+ * $Locker: $
+ *
+ */
+
+/*
+ * These macros are designed to be portable to all machines that have
+ * a wordsize greater than or equal to 32 bits that support the portable
+ * C compiler and the standard C preprocessor. Wordsize (default 32)
+ * and bitfield assignment (default left-to-right, unlike VAX, PDP-11)
+ * should be predefined using the constants HOSTWDSZ and BITFRL and
+ * the C compiler "-D" flag (e.g., -DHOSTWDSZ=36 -DBITFLR for the DEC-20).
+ * Note that the macro arguments assume that the integer being referenced
+ * is a 32-bit integer (right-justified on the 20) and that bit 0 is the
+ * most significant bit.
+ */
+
+#ifndef HOSTWDSZ
+#define HOSTWDSZ 32
+#endif
+
+
+/*########################### Macros ######################################*/
+
+/*-------------------------------------------------------------------------
+ * NewDeclareBitField_Reference - Declare a structure similar to the simulator
+ * function "DeclBitfR" except its use is restricted to occur within a larger
+ * enclosing structure or union definition. This declaration is an unnamed
+ * structure with the argument, name, as the member name and the argument,
+ * uname, as the element name.
+ *----------------------------------------------------------------------- */
+#define Bitfield_extract(start, length, object) \
+ ((object) >> (HOSTWDSZ - (start) - (length)) & \
+ ((unsigned)-1 >> (HOSTWDSZ - (length))))
+
+#define Bitfield_signed_extract(start, length, object) \
+ ((int)((object) << start) >> (HOSTWDSZ - (length)))
+
+#define Bitfield_mask(start, len, object) \
+ ((object) & (((unsigned)-1 >> (HOSTWDSZ-len)) << (HOSTWDSZ-start-len)))
+
+#define Bitfield_deposit(value,start,len,object) object = \
+ ((object) & ~(((unsigned)-1 >> (HOSTWDSZ-len)) << (HOSTWDSZ-start-len))) | \
+ (((value) & ((unsigned)-1 >> (HOSTWDSZ-len))) << (HOSTWDSZ-start-len))
diff --git a/sys/arch/hppa/spmath/frnd.c b/sys/arch/hppa/spmath/frnd.c
new file mode 100644
index 00000000000..4f331d00d0c
--- /dev/null
+++ b/sys/arch/hppa/spmath/frnd.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/frnd.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:01 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+#include "../spmath/dbl_float.h"
+#include "../spmath/quad_float.h"
+#include "../spmath/cnv_float.h"
+
+/*
+ * Single Floating-point Round to Integer
+ */
+
+/*ARGSUSED*/
+sgl_frnd(srcptr,nullptr,dstptr,status)
+
+sgl_floating_point *srcptr, *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int src, result;
+ register int src_exponent;
+ register boolean inexact = FALSE;
+
+ src = *srcptr;
+ /*
+ * check source operand for NaN or infinity
+ */
+ if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) {
+ /*
+ * is signaling NaN?
+ */
+ if (Sgl_isone_signaling(src)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(src);
+ }
+ /*
+ * return quiet NaN or infinity
+ */
+ *dstptr = src;
+ return(NOEXCEPTION);
+ }
+ /*
+ * Need to round?
+ */
+ if ((src_exponent -= SGL_BIAS) >= SGL_P - 1) {
+ *dstptr = src;
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ Sgl_clear_exponent_set_hidden(src);
+ result = src;
+ Sgl_rightshift(result,(SGL_P-1) - (src_exponent));
+ /* check for inexact */
+ if (Sgl_isinexact_to_fix(src,src_exponent)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(src)) Sgl_increment(result);
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(src)) Sgl_increment(result);
+ break;
+ case ROUNDNEAREST:
+ if (Sgl_isone_roundbit(src,src_exponent))
+ if (Sgl_isone_stickybit(src,src_exponent)
+ || (Sgl_isone_lowmantissa(result)))
+ Sgl_increment(result);
+ }
+ }
+ Sgl_leftshift(result,(SGL_P-1) - (src_exponent));
+ if (Sgl_isone_hiddenoverflow(result))
+ Sgl_set_exponent(result,src_exponent + (SGL_BIAS+1));
+ else Sgl_set_exponent(result,src_exponent + SGL_BIAS);
+ }
+ else {
+ result = src; /* set sign */
+ Sgl_setzero_exponentmantissa(result);
+ /* check for inexact */
+ if (Sgl_isnotzero_exponentmantissa(src)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(src))
+ Sgl_set_exponent(result,SGL_BIAS);
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(src))
+ Sgl_set_exponent(result,SGL_BIAS);
+ break;
+ case ROUNDNEAREST:
+ if (src_exponent == -1)
+ if (Sgl_isnotzero_mantissa(src))
+ Sgl_set_exponent(result,SGL_BIAS);
+ }
+ }
+ }
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(NOEXCEPTION);
+}
+
+/*
+ * Double Floating-point Round to Integer
+ */
+
+/*ARGSUSED*/
+dbl_frnd(srcptr,nullptr,dstptr,status)
+
+dbl_floating_point *srcptr, *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int srcp1, srcp2, resultp1, resultp2;
+ register int src_exponent;
+ register boolean inexact = FALSE;
+
+ Dbl_copyfromptr(srcptr,srcp1,srcp2);
+ /*
+ * check source operand for NaN or infinity
+ */
+ if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
+ /*
+ * is signaling NaN?
+ */
+ if (Dbl_isone_signaling(srcp1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Dbl_set_quiet(srcp1);
+ }
+ /*
+ * return quiet NaN or infinity
+ */
+ Dbl_copytoptr(srcp1,srcp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * Need to round?
+ */
+ if ((src_exponent -= DBL_BIAS) >= DBL_P - 1) {
+ Dbl_copytoptr(srcp1,srcp2,dstptr);
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate result
+ */
+ if (src_exponent >= 0) {
+ Dbl_clear_exponent_set_hidden(srcp1);
+ resultp1 = srcp1;
+ resultp2 = srcp2;
+ Dbl_rightshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
+ /* check for inexact */
+ if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(srcp1))
+ Dbl_increment(resultp1,resultp2);
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(srcp1))
+ Dbl_increment(resultp1,resultp2);
+ break;
+ case ROUNDNEAREST:
+ if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
+ if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent)
+ || (Dbl_isone_lowmantissap2(resultp2)))
+ Dbl_increment(resultp1,resultp2);
+ }
+ }
+ Dbl_leftshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
+ if (Dbl_isone_hiddenoverflow(resultp1))
+ Dbl_set_exponent(resultp1,src_exponent + (DBL_BIAS+1));
+ else Dbl_set_exponent(resultp1,src_exponent + DBL_BIAS);
+ }
+ else {
+ resultp1 = srcp1; /* set sign */
+ Dbl_setzero_exponentmantissa(resultp1,resultp2);
+ /* check for inexact */
+ if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
+ inexact = TRUE;
+ /* round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Dbl_iszero_sign(srcp1))
+ Dbl_set_exponent(resultp1,DBL_BIAS);
+ break;
+ case ROUNDMINUS:
+ if (Dbl_isone_sign(srcp1))
+ Dbl_set_exponent(resultp1,DBL_BIAS);
+ break;
+ case ROUNDNEAREST:
+ if (src_exponent == -1)
+ if (Dbl_isnotzero_mantissa(srcp1,srcp2))
+ Dbl_set_exponent(resultp1,DBL_BIAS);
+ }
+ }
+ }
+ Dbl_copytoptr(resultp1,resultp2,dstptr);
+ if (inexact)
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(NOEXCEPTION);
+}
+
+/*ARGSUSED*/
+quad_frnd(srcptr,nullptr,dstptr,status)
+
+quad_floating_point *srcptr, *dstptr;
+unsigned int *nullptr, *status;
+{
+ return(UNIMPLEMENTEDEXCEPTION);
+}
+
diff --git a/sys/arch/hppa/spmath/hppa.h b/sys/arch/hppa/spmath/hppa.h
new file mode 100644
index 00000000000..0995e753cdc
--- /dev/null
+++ b/sys/arch/hppa/spmath/hppa.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/*
+ * @(#)hppa.h: $Revision: 1.1 $ $Date: 1998/06/23 20:34:01 $
+ * $Locker: $
+ */
+
+/* amount is assumed to be a constant between 0 and 32 (non-inclusive) */
+#define Shiftdouble(left,right,amount,dest) \
+ /* int left, right, amount, dest; */ \
+ dest = ((left) << (32-(amount))) | ((unsigned int)(right) >> (amount))
+
+/* amount must be less than 32 */
+#define Variableshiftdouble(left,right,amount,dest) \
+ /* unsigned int left, right; int amount, dest; */ \
+ if (amount == 0) dest = right; \
+ else dest = ((((unsigned) left)&0x7fffffff) << (32-(amount))) | \
+ ((unsigned) right >> (amount))
+
+/* amount must be between 0 and 32 (non-inclusive) */
+#define Variable_shift_double(left,right,amount,dest) \
+ /* unsigned int left, right; int amount, dest; */ \
+ dest = (left << (32-(amount))) | ((unsigned) right >> (amount))
diff --git a/sys/arch/hppa/spmath/impys.S b/sys/arch/hppa/spmath/impys.S
new file mode 100644
index 00000000000..7f5251337fc
--- /dev/null
+++ b/sys/arch/hppa/spmath/impys.S
@@ -0,0 +1,323 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/impys.S,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:01 $
+ */
+
+#include <machine/asm.h>
+
+/****************************************************************************
+ *
+ * Implement an integer multiply routine for 32-bit operands and 64-bit product
+ * with operand values of zero (multiplicand only) and -2**31 treated specially.
+ * The algorithm uses the absolute value of the multiplier, four bits at a time,
+ * from right to left, to generate partial product. Execution speed is more
+ * important than program size in this implementation.
+ *
+ ***************************************************************************/
+#
+# Definitions - General registers
+#
+gr0 .equ 0 # General register zero
+pu .equ 3 # upper part of product
+pl .equ 4 # lower part of product
+op2 .equ 4 # multiplier
+op1 .equ 5 # multiplicand
+cnt .equ 6 # count in multiply
+brindex .equ 7 # index into the br. table
+sign .equ 8 # sign of product
+pc .equ 9 # carry bit of product, = 00...01
+pm .equ 10 # value of -1 used in shifting
+
+#*****************************************************************************
+ .export impys,entry
+ .space $TEXT$
+ .subspa $CODE$
+ .align 4
+ .proc
+ .callinfo
+#
+#****************************************************************************
+impys stws,ma pu,4(sp) # save registers on stack
+ stws,ma pl,4(sp) # save registers on stack
+ stws,ma op1,4(sp) # save registers on stack
+ stws,ma cnt,4(sp) # save registers on stack
+ stws,ma brindex,4(sp) # save registers on stack
+ stws,ma sign,4(sp) # save registers on stack
+ stws,ma pc,4(sp) # save registers on stack
+ stws,ma pm,4(sp) # save registers on stack
+#
+# Start multiply process
+#
+ ldws 0(arg1),op2 # get multiplier
+ ldws 0(arg0),op1 # get multiplicand
+ addi -1,gr0,pm # initialize pm to 111...1
+ comb,< op2,gr0,mpyb # br. if multiplier < 0
+ xor op2,op1,sign # sign(0) = sign of product
+mpy1 comb,< op1,gr0,mpya # br. if multiplicand < 0
+ addi 0,gr0,pu # clear product
+ addib,= 0,op1,fini0 # op1 = 0, product = 0
+mpy2 addi 1,gr0,pc # initialize pc to 00...01
+ movib,tr 8,cnt,mloop # set count for mpy loop
+ extru op2,31,4,brindex # 4 bits as index into table
+#
+ .align 8
+#
+ b sh4c # br. if sign overflow
+sh4n shd pu,pl,4,pl # shift product right 4 bits
+ addib,<= -1,cnt,mulend # reduce count by 1, exit if
+ extru pu,27,28,pu # <= zero
+#
+mloop blr brindex,gr0 # br. into table
+ # entries of 2 words
+ extru op2,27,4,brindex # next 4 bits into index
+#
+#
+# branch table for the multiplication process with four multiplier bits
+#
+mtable # two words per entry
+#
+# ---- bits = 0000 ---- shift product 4 bits -------------------------------
+#
+ b sh4n+4 # just shift partial
+ shd pu,pl,4,pl # product right 4 bits
+#
+# ---- bits = 0001 ---- add op1, then shift 4 bits
+#
+ addb,tr op1,pu,sh4n+4 # add op1 to product, to shift
+ shd pu,pl,4,pl # product right 4 bits
+#
+# ---- bits = 0010 ---- add op1, add op1, then shift 4 bits
+#
+ addb,tr op1,pu,sh4n # add 2*op1, to shift
+ addb,uv op1,pu,sh4c # product right 4 bits
+#
+# ---- bits = 0011 ---- add op1, add 2*op1, shift 4 bits
+#
+ addb,tr op1,pu,sh4n-4 # add op1 & 2*op1, shift
+ sh1add,nsv op1,pu,pu # product right 4 bits
+#
+# ---- bits = 0100 ---- shift 2, add op1, shift 2
+#
+ b sh2sa
+ shd pu,pl,2,pl # shift product 2 bits
+#
+# ---- bits = 0101 ---- add op1, shift 2, add op1, and shift 2 again
+#
+ addb,tr op1,pu,sh2us # add op1 to product
+ shd pu,pl,2,pl # shift 2 bits
+#
+# ---- bits = 0110 ---- add op1, add op1, shift 2, add op1, and shift 2 again
+#
+ addb,tr op1,pu,sh2c # add 2*op1, to shift 2 bits
+ addb,nuv op1,pu,sh2us # br. if not overflow
+#
+# ---- bits = 0111 ---- subtract op1, shift 3, add op1, and shift 1
+#
+ b sh3s
+ sub pu,op1,pu # subtract op1, br. to sh3s
+
+#
+# ---- bits = 1000 ---- shift 3, add op1, shift 1
+#
+ b sh3sa
+ shd pu,pl,3,pl # shift product right 3 bits
+#
+# ---- bits = 1001 ---- add op1, shift 3, add op1, shift 1
+#
+ addb,tr op1,pu,sh3us # add op1, to shift 3, add op1,
+ shd pu,pl,3,pl # and shift 1
+#
+# ---- bits = 1010 ---- add op1, add op1, shift 3, add op1, shift 1
+#
+ addb,tr op1,pu,sh3c # add 2*op1, to shift 3 bits
+ addb,nuv op1,pu,sh3us # br. if no overflow
+#
+# ---- bits = 1011 ---- add -op1, shift 2, add -op1, shift 2, inc. next index
+#
+ addib,tr 1,brindex,sh2s # add 1 to index, subtract op1,
+ sub pu,op1,pu # shift 2 with minus sign
+#
+# ---- bits = 1100 ---- shift 2, subtract op1, shift 2, increment next index
+#
+ addib,tr 1,brindex,sh2sb # add 1 to index, to shift
+ shd pu,pl,2,pl # shift right 2 bits signed
+#
+# ---- bits = 1101 ---- add op1, shift 2, add -op1, shift 2
+#
+ addb,tr op1,pu,sh2ns # add op1, to shift 2
+ shd pu,pl,2,pl # right 2 unsigned, etc.
+#
+# ---- bits = 1110 ---- shift 1 signed, add -op1, shift 3 signed
+#
+ addib,tr 1,brindex,sh1sa # add 1 to index, to shift
+ shd pu,pl,1,pl # shift 1 bit
+#
+# ---- bits = 1111 ---- add -op1, shift 4 signed
+#
+ addib,tr 1,brindex,sh4s # add 1 to index, subtract op1,
+ sub pu,op1,pu # to shift 4 signed
+
+#
+# ---- bits = 10000 ---- shift 4 signed
+#
+ addib,tr 1,brindex,sh4s+4 # add 1 to index
+ shd pu,pl,4,pl # shift 4 signed
+#
+# ---- end of table ---------------------------------------------------------
+#
+sh4s shd pu,pl,4,pl
+ addib,tr -1,cnt,mloop # loop (count > 0 always here)
+ shd pm,pu,4,pu # shift 4, minus signed
+#
+sh4c addib,> -1,cnt,mloop # decrement count, loop if > 0
+ shd pc,pu,4,pu # shift 4 with overflow
+ b signs # end of multiply
+ bb,>=,n sign,0,fini # test sign of procduct
+#
+mpyb add,= op2,op2,gr0 # if <> 0, back to main sect.
+ b mpy1
+ sub 0,op2,op2 # op2 = |multiplier|
+ add,>= op1,gr0,gr0 # if op1 < 0, invert sign,
+ xor pm,sign,sign # for correct result
+#
+# special case for multiplier = -2**31, op1 = signed multiplicand
+# or multiplicand = -2**31, op1 = signed multiplier
+#
+ shd op1,0,1,pl # shift op1 left 31 bits
+mmax extrs op1,30,31,pu
+ b signs # negate product (if needed)
+ bb,>=,n sign,0,fini # test sign of product
+#
+mpya add,= op1,op1,gr0 # op1 = -2**31, special case
+ b mpy2
+ sub 0,op1,op1 # op1 = |multiplicand|
+ add,>= op2,gr0,gr0 # if op2 < 0, invert sign,
+ xor pm,sign,sign # for correct result
+ movb,tr op2,op1,mmax # use op2 as multiplicand
+ shd op1,0,1,pl # shift it left 31 bits
+#
+sh3c shd pu,pl,3,pl # shift product 3 bits
+ shd pc,pu,3,pu # shift 3 signed
+ addb,tr op1,pu,sh1 # add op1, to shift 1 bit
+ shd pu,pl,1,pl
+#
+sh3us extru pu,28,29,pu # shift 3 unsigned
+ addb,tr op1,pu,sh1 # add op1, to shift 1 bit
+ shd pu,pl,1,pl
+#
+sh3sa extrs pu,28,29,pu # shift 3 signed
+ addb,tr op1,pu,sh1 # add op1, to shift 1 bit
+ shd pu,pl,1,pl
+#
+sh3s shd pu,pl,3,pl # shift 3 minus signed
+ shd pm,pu,3,pu
+ addb,tr op1,pu,sh1 # add op1, to shift 1 bit
+ shd pu,pl,1,pl
+#
+sh1 addib,> -1,cnt,mloop # loop if count > 0
+ extru pu,30,31,pu
+ b signs # end of multiply
+ bb,>=,n sign,0,fini # test sign of product
+#
+sh2ns addib,tr 1,brindex,sh2sb+4 # increment index
+ extru pu,29,30,pu # shift unsigned
+#
+sh2s shd pu,pl,2,pl # shift with minus sign
+ shd pm,pu,2,pu #
+ sub pu,op1,pu # subtract op1
+ shd pu,pl,2,pl # shift with minus sign
+ addib,tr -1,cnt,mloop # decrement count, loop
+ shd pm,pu,2,pu # shift with minus sign
+ # count never reaches 0 here
+#
+sh2sb extrs pu,29,30,pu # shift 2 signed
+ sub pu,op1,pu # subtract op1 from product
+ shd pu,pl,2,pl # shift with minus sign
+ addib,tr -1,cnt,mloop # decrement count, loop
+ shd pm,pu,2,pu # shift with minus sign
+ # count never reaches 0 here
+#
+sh1sa extrs pu,30,31,pu # signed
+ sub pu,op1,pu # subtract op1 from product
+ shd pu,pl,3,pl # shift 3 with minus sign
+ addib,tr -1,cnt,mloop # dec. count, to loop
+ shd pm,pu,3,pu # count never reaches 0 here
+#
+fini0 movib,tr,n 0,pl,fini # product = 0 as op1 = 0
+#
+sh2us extru pu,29,30,pu # shift 2 unsigned
+ addb,tr op1,pu,sh2a # add op1
+ shd pu,pl,2,pl # shift 2 bits
+#
+sh2c shd pu,pl,2,pl
+ shd pc,pu,2,pu # shift with carry
+ addb,tr op1,pu,sh2a # add op1 to product
+ shd pu,pl,2,pl # br. to sh2 to shift pu
+#
+sh2sa extrs pu,29,30,pu # shift with sign
+ addb,tr op1,pu,sh2a # add op1 to product
+ shd pu,pl,2,pl # br. to sh2 to shift pu
+#
+sh2a addib,> -1,cnt,mloop # loop if count > 0
+ extru pu,29,30,pu
+#
+mulend bb,>=,n sign,0,fini # test sign of product
+signs sub 0,pl,pl # negate product if sign
+ subb 0,pu,pu # is negative
+#
+# finish
+#
+fini stws pu,0(arg2) # save high part of result
+ stws pl,4(arg2) # save low part of result
+
+ ldws,mb -4(sp),pm # restore registers
+ ldws,mb -4(sp),pc # restore registers
+ ldws,mb -4(sp),sign # restore registers
+ ldws,mb -4(sp),brindex # restore registers
+ ldws,mb -4(sp),cnt # restore registers
+ ldws,mb -4(sp),op1 # restore registers
+ ldws,mb -4(sp),pl # restore registers
+ bv 0(rp) # return
+ ldws,mb -4(sp),pu # restore registers
+
+ .procend
+ .end
diff --git a/sys/arch/hppa/spmath/impyu.S b/sys/arch/hppa/spmath/impyu.S
new file mode 100644
index 00000000000..ce7e995601f
--- /dev/null
+++ b/sys/arch/hppa/spmath/impyu.S
@@ -0,0 +1,322 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/impyu.S,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:02 $
+ */
+
+#include <machine/asm.h>
+
+/****************************************************************************
+ *
+ *Implement an integer multiply routine for 32-bit operands and 64-bit product
+ * with operand values of zero (multiplicand only) and 2**32reated specially.
+ * The algorithm uses the multiplier, four bits at a time, from right to left,
+ * to generate partial product. Execution speed is more important than program
+ * size in this implementation.
+ *
+ *****************************************************************************/
+#
+# Definitions - General registers
+#
+gr0 .equ 0 # General register zero
+pu .equ 3 # upper part of product
+pl .equ 4 # lower part of product
+op2 .equ 4 # multiplier
+op1 .equ 5 # multiplicand
+cnt .equ 6 # count in multiply
+brindex .equ 7 # index into the br. table
+saveop2 .equ 8 # save op2 if high bit of multiplicand
+ # is set
+pc .equ 9 # carry bit of product, = 00...01
+pm .equ 10 # value of -1 used in shifting
+temp .equ 6
+
+#****************************************************************************
+ .export impyu,entry
+ .space $TEXT$
+ .subspa $CODE$
+ .align 4
+ .proc
+ .callinfo
+#
+#****************************************************************************
+impyu stws,ma pu,4(sp) # save registers on stack
+ stws,ma pl,4(sp) # save registers on stack
+ stws,ma op1,4(sp) # save registers on stack
+ stws,ma cnt,4(sp) # save registers on stack
+ stws,ma brindex,4(sp) # save registers on stack
+ stws,ma saveop2,4(sp) # save registers on stack
+ stws,ma pc,4(sp) # save registers on stack
+ stws,ma pm,4(sp) # save registers on stack
+#
+# Start multiply process
+#
+ ldws 0(arg0),op1 # get multiplicand
+ ldws 0(arg1),op2 # get multiplier
+ addib,= 0,op1,fini0 # op1 = 0, product = 0
+ addi 0,gr0,pu # clear product
+ bb,>= op1,0,mpy1 # test msb of multiplicand
+ addi 0,gr0,saveop2 # clear saveop2
+#
+# msb of multiplicand is set so will save multiplier for a final
+# addition into the result
+#
+ extru,= op1,31,31,op1 # clear msb of multiplicand
+ b mpy1 # if op1 < 2**32, start multiply
+ add op2,gr0,saveop2 # save op2 in saveop2
+ shd gr0,op2,1,pu # shift op2 left 31 for result
+ b fini # go to finish
+ shd op2,gr0,1,pl
+#
+mpy1 addi -1,gr0,pm # initialize pm to 111...1
+ addi 1,gr0,pc # initialize pc to 00...01
+ movib,tr 8,cnt,mloop # set count for mpy loop
+ extru op2,31,4,brindex # 4 bits as index into table
+#
+ .align 8
+#
+ b sh4c # br. if sign overflow
+sh4n shd pu,pl,4,pl # shift product right 4 bits
+ addib,<= -1,cnt,mulend # reduce count by 1, exit if
+ extru pu,27,28,pu # <= zero
+#
+mloop blr brindex,gr0 # br. into table
+ # entries of 2 words
+ extru op2,27,4,brindex # next 4 bits into index
+#
+#
+# branch table for the multiplication process with four multiplier bits
+#
+mtable # two words per entry
+#
+# ---- bits = 0000 ---- shift product 4 bits -------------------------------
+#
+ b sh4n+4 # just shift partial
+ shd pu,pl,4,pl # product right 4 bits
+#
+# ---- bits = 0001 ---- add op1, then shift 4 bits
+#
+ addb,tr op1,pu,sh4n+4 # add op1 to product, to shift
+ shd pu,pl,4,pl # product right 4 bits
+#
+# ---- bits = 0010 ---- add op1, add op1, then shift 4 bits
+#
+ addb,tr op1,pu,sh4n # add 2*op1, to shift
+ addb,uv op1,pu,sh4c # product right 4 bits
+#
+# ---- bits = 0011 ---- add op1, add 2*op1, shift 4 bits
+#
+ addb,tr op1,pu,sh4n-4 # add op1 & 2*op1, shift
+ sh1add,nuv op1,pu,pu # product right 4 bits
+#
+# ---- bits = 0100 ---- shift 2, add op1, shift 2
+#
+ b sh2sa
+ shd pu,pl,2,pl # shift product 2 bits
+#
+# ---- bits = 0101 ---- add op1, shift 2, add op1, and shift 2 again
+#
+ addb,tr op1,pu,sh2us # add op1 to product
+ shd pu,pl,2,pl # shift 2 bits
+#
+# ---- bits = 0110 ---- add op1, add op1, shift 2, add op1, and shift 2 again
+#
+ addb,tr op1,pu,sh2c # add 2*op1, to shift 2 bits
+ addb,nuv op1,pu,sh2us # br. if not overflow
+#
+# ---- bits = 0111 ---- subtract op1, shift 3, add op1, and shift 1
+#
+ b sh3s
+ sub pu,op1,pu # subtract op1, br. to sh3s
+
+#
+# ---- bits = 1000 ---- shift 3, add op1, shift 1
+#
+ b sh3sa
+ shd pu,pl,3,pl # shift product right 3 bits
+#
+# ---- bits = 1001 ---- add op1, shift 3, add op1, shift 1
+#
+ addb,tr op1,pu,sh3us # add op1, to shift 3, add op1,
+ shd pu,pl,3,pl # and shift 1
+#
+# ---- bits = 1010 ---- add op1, add op1, shift 3, add op1, shift 1
+#
+ addb,tr op1,pu,sh3c # add 2*op1, to shift 3 bits
+ addb,nuv op1,pu,sh3us # br. if no overflow
+#
+# ---- bits = 1011 ---- add -op1, shift 2, add -op1, shift 2, inc. next index
+#
+ addib,tr 1,brindex,sh2s # add 1 to index, subtract op1,
+ sub pu,op1,pu # shift 2 with minus sign
+#
+# ---- bits = 1100 ---- shift 2, subtract op1, shift 2, increment next index
+#
+ addib,tr 1,brindex,sh2sb # add 1 to index, to shift
+ shd pu,pl,2,pl # shift right 2 bits signed
+#
+# ---- bits = 1101 ---- add op1, shift 2, add -op1, shift 2
+#
+ addb,tr op1,pu,sh2ns # add op1, to shift 2
+ shd pu,pl,2,pl # right 2 unsigned, etc.
+#
+# ---- bits = 1110 ---- shift 1 signed, add -op1, shift 3 signed
+#
+ addib,tr 1,brindex,sh1sa # add 1 to index, to shift
+ shd pu,pl,1,pl # shift 1 bit
+#
+# ---- bits = 1111 ---- add -op1, shift 4 signed
+#
+ addib,tr 1,brindex,sh4s # add 1 to index, subtract op1,
+ sub pu,op1,pu # to shift 4 signed
+
+#
+# ---- bits = 10000 ---- shift 4 signed
+#
+ addib,tr 1,brindex,sh4s+4 # add 1 to index
+ shd pu,pl,4,pl # shift 4 signed
+#
+# ---- end of table ---------------------------------------------------------
+#
+sh4s shd pu,pl,4,pl
+ addib,> -1,cnt,mloop # decrement count, loop if > 0
+ shd pm,pu,4,pu # shift 4, minus signed
+ addb,tr op1,pu,lastadd # do one more add, then finish
+ addb,=,n saveop2,gr0,fini # check saveop2
+#
+sh4c addib,> -1,cnt,mloop # decrement count, loop if > 0
+ shd pc,pu,4,pu # shift 4 with overflow
+ b lastadd # end of multiply
+ addb,=,n saveop2,gr0,fini # check saveop2
+#
+sh3c shd pu,pl,3,pl # shift product 3 bits
+ shd pc,pu,3,pu # shift 3 signed
+ addb,tr op1,pu,sh1 # add op1, to shift 1 bit
+ shd pu,pl,1,pl
+#
+sh3us extru pu,28,29,pu # shift 3 unsigned
+ addb,tr op1,pu,sh1 # add op1, to shift 1 bit
+ shd pu,pl,1,pl
+#
+sh3sa extrs pu,28,29,pu # shift 3 signed
+ addb,tr op1,pu,sh1 # add op1, to shift 1 bit
+ shd pu,pl,1,pl
+#
+sh3s shd pu,pl,3,pl # shift 3 minus signed
+ shd pm,pu,3,pu
+ addb,tr op1,pu,sh1 # add op1, to shift 1 bit
+ shd pu,pl,1,pl
+#
+sh1 addib,> -1,cnt,mloop # loop if count > 0
+ extru pu,30,31,pu
+ b lastadd # end of multiply
+ addb,=,n saveop2,gr0,fini # check saveop2
+#
+sh2ns addib,tr 1,brindex,sh2sb+4 # increment index
+ extru pu,29,30,pu # shift unsigned
+#
+sh2s shd pu,pl,2,pl # shift with minus sign
+ shd pm,pu,2,pu #
+ sub pu,op1,pu # subtract op1
+ shd pu,pl,2,pl # shift with minus sign
+ addib,> -1,cnt,mloop # decrement count, loop if > 0
+ shd pm,pu,2,pu # shift with minus sign
+ addb,tr op1,pu,lastadd # do one more add, then finish
+ addb,=,n saveop2,gr0,fini # check saveop2
+#
+sh2sb extrs pu,29,30,pu # shift 2 signed
+ sub pu,op1,pu # subtract op1 from product
+ shd pu,pl,2,pl # shift with minus sign
+ addib,> -1,cnt,mloop # decrement count, loop if > 0
+ shd pm,pu,2,pu # shift with minus sign
+ addb,tr op1,pu,lastadd # do one more add, then finish
+ addb,=,n saveop2,gr0,fini # check saveop2
+#
+sh1sa extrs pu,30,31,pu # signed
+ sub pu,op1,pu # subtract op1 from product
+ shd pu,pl,3,pl # shift 3 with minus sign
+ addib,> -1,cnt,mloop # decrement count, loop if >0
+ shd pm,pu,3,pu
+ addb,tr op1,pu,lastadd # do one more add, then finish
+ addb,=,n saveop2,gr0,fini # check saveop2
+#
+fini0 movib,tr 0,pl,fini # product = 0 as op1 = 0
+ stws pu,0(arg2) # save high part of result
+#
+sh2us extru pu,29,30,pu # shift 2 unsigned
+ addb,tr op1,pu,sh2a # add op1
+ shd pu,pl,2,pl # shift 2 bits
+#
+sh2c shd pu,pl,2,pl
+ shd pc,pu,2,pu # shift with carry
+ addb,tr op1,pu,sh2a # add op1 to product
+ shd pu,pl,2,pl # br. to sh2 to shift pu
+#
+sh2sa extrs pu,29,30,pu # shift with sign
+ addb,tr op1,pu,sh2a # add op1 to product
+ shd pu,pl,2,pl # br. to sh2 to shift pu
+#
+sh2a addib,> -1,cnt,mloop # loop if count > 0
+ extru pu,29,30,pu
+#
+mulend addb,=,n saveop2,gr0,fini # check saveop2
+lastadd shd saveop2,gr0,1,temp # if saveop2 <> 0, shift it
+ shd gr0,saveop2,1,saveop2 # left 31 and add to result
+ add pl,temp,pl
+ addc pu,saveop2,pu
+#
+# finish
+#
+fini stws pu,0(arg2) # save high part of result
+ stws pl,4(arg2) # save low part of result
+
+ ldws,mb -4(sp),pm # restore registers
+ ldws,mb -4(sp),pc # restore registers
+ ldws,mb -4(sp),saveop2 # restore registers
+ ldws,mb -4(sp),brindex # restore registers
+ ldws,mb -4(sp),cnt # restore registers
+ ldws,mb -4(sp),op1 # restore registers
+ ldws,mb -4(sp),pl # restore registers
+ bv 0(rp) # return
+ ldws,mb -4(sp),pu # restore registers
+
+ .procend
+ .end
diff --git a/sys/arch/hppa/spmath/md.h b/sys/arch/hppa/spmath/md.h
new file mode 100644
index 00000000000..535d02f8f32
--- /dev/null
+++ b/sys/arch/hppa/spmath/md.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/*
+ * @(#)md.h: $Revision: 1.1 $ $Date: 1998/06/23 20:34:02 $
+ * $Locker: $
+ *
+ */
+
+/*****************************************************************
+ * Muliply/Divide SFU Internal State *
+ *****************************************************************/
+struct mdsfu_register {
+ int rslt_hi,
+ rslt_lo,
+ ovflow;
+ };
+
+#define result_hi result->rslt_hi
+#define result_lo result->rslt_lo
+#define overflow result->ovflow
+
+/*
+ * Types
+ */
+typedef int VOID;
+typedef int boolean;
+
+
+/*
+ * Constants
+ */
+
+#undef FALSE
+#define FALSE 0
+
+#undef TRUE
+#define TRUE (!FALSE)
+
+#undef NIL
+#define NIL 0
+
+#define WORD_LEN 32
+#define BIT0 1<<31
+#define BIT28 0x8
+#define BIT29 0x4
+#define BIT30 0x2
+#define BIT31 0x1
+
+
+/*
+ * Structures
+ */
+
+struct md_state {
+ int resulthi, /* high word of result */
+ resultlo; /* low word of result */
+};
diff --git a/sys/arch/hppa/spmath/mpyaccs.c b/sys/arch/hppa/spmath/mpyaccs.c
new file mode 100644
index 00000000000..ce5f2670830
--- /dev/null
+++ b/sys/arch/hppa/spmath/mpyaccs.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/mpyaccs.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:03 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID mpyaccs(opnd1,opnd2,result)
+
+int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ struct mdsfu_register temp;
+ int carry, sign;
+
+ impys(&opnd1,&opnd2,&temp);
+
+ /* get result of low word add, and check for carry out */
+ if ((result_lo += (unsigned)temp.rslt_lo) < (unsigned)temp.rslt_lo)
+ carry = 1;
+ else carry = 0;
+
+ /* get result of high word add, and determine overflow status */
+ sign = result_hi ^ temp.rslt_hi;
+ result_hi += temp.rslt_hi + carry;
+ if (sign >= 0 && (temp.rslt_hi ^ result_hi) < 0) overflow = TRUE;
+
+ return;
+}
diff --git a/sys/arch/hppa/spmath/mpyaccu.c b/sys/arch/hppa/spmath/mpyaccu.c
new file mode 100644
index 00000000000..e0da85e30a8
--- /dev/null
+++ b/sys/arch/hppa/spmath/mpyaccu.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/mpyaccu.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:03 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID mpyaccu(opnd1,opnd2,result)
+
+unsigned int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ struct mdsfu_register temp;
+ int carry;
+
+ impyu(&opnd1,&opnd2,&temp);
+
+ /* get result of low word add, and check for carry out */
+ if ((result_lo += (unsigned)temp.rslt_lo) < (unsigned)temp.rslt_lo)
+ carry = 1;
+ else carry = 0;
+
+ /* get result of high word add, and determine overflow status */
+ if ((result_hi += (unsigned)temp.rslt_hi + carry) <
+ (unsigned)temp.rslt_hi) overflow = TRUE;
+
+ return;
+}
diff --git a/sys/arch/hppa/spmath/mpys.c b/sys/arch/hppa/spmath/mpys.c
new file mode 100644
index 00000000000..8b0d5063b50
--- /dev/null
+++ b/sys/arch/hppa/spmath/mpys.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/mpys.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:04 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID mpys(opnd1,opnd2,result)
+
+int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ impys(&opnd1,&opnd2,result);
+
+ /* determine overflow status */
+ if ((result_hi == 0 && result_lo >= 0) ||
+ (result_hi == -1 && result_lo < 0)) overflow = FALSE;
+ else overflow = TRUE;
+ return;
+}
diff --git a/sys/arch/hppa/spmath/mpyscv.c b/sys/arch/hppa/spmath/mpyscv.c
new file mode 100644
index 00000000000..7e020eb4aa6
--- /dev/null
+++ b/sys/arch/hppa/spmath/mpyscv.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/mpyscv.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:04 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID mpyscv(opnd1,opnd2,result)
+
+int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ impys(&opnd1,&opnd2,result);
+ overflow = FALSE;
+ return;
+}
diff --git a/sys/arch/hppa/spmath/mpyu.c b/sys/arch/hppa/spmath/mpyu.c
new file mode 100644
index 00000000000..e2ad3591ca4
--- /dev/null
+++ b/sys/arch/hppa/spmath/mpyu.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/mpyu.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:04 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID mpyu(opnd1,opnd2,result)
+
+unsigned int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ impyu(&opnd1,&opnd2,result);
+ /* determine overflow status */
+ if (result_hi) overflow = TRUE;
+ else overflow = FALSE;
+ return;
+}
diff --git a/sys/arch/hppa/spmath/mpyucv.c b/sys/arch/hppa/spmath/mpyucv.c
new file mode 100644
index 00000000000..c3fb9f4036e
--- /dev/null
+++ b/sys/arch/hppa/spmath/mpyucv.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/mpyucv.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:05 $
+ */
+
+
+#include "../spmath/md.h"
+
+VOID mpyucv(opnd1,opnd2,result)
+
+unsigned int opnd1, opnd2;
+struct mdsfu_register *result;
+{
+ impyu(&opnd1,&opnd2,result);
+ overflow = FALSE;
+ return;
+}
diff --git a/sys/arch/hppa/spmath/quad_float.h b/sys/arch/hppa/spmath/quad_float.h
new file mode 100644
index 00000000000..e22403729fd
--- /dev/null
+++ b/sys/arch/hppa/spmath/quad_float.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/*
+ * @(#)quad_float.h: $Revision: 1.1 $ $Date: 1998/06/23 20:34:05 $
+ * $Locker: $
+ *
+ */
+/******************************
+ * Quad precision functions *
+ ******************************/
+
+/* 32-bit word grabing functions */
+#define Quad_firstword(value) Qallp1(value)
+#define Quad_secondword(value) Qallp2(value)
+#define Quad_thirdword(value) Qallp3(value)
+#define Quad_fourthword(value) Qallp4(value)
+
+
+/* This magnitude comparison uses the signless first words and
+ * the regular part2 words. The comparison is graphically:
+ *
+ * 1st greater? ----------->|
+ * |
+ * 1st less?-----------------+------->|
+ * | |
+ * 2nd greater?------------->| |
+ * | |
+ * 2nd less?-----------------+------->|
+ * | |
+ * 3rd greater?------------->| |
+ * | |
+ * 3rd less?-----------------+------->|
+ * | |
+ * 4th greater or equal?---->| |
+ * | |
+ * False True
+ */
+#define Quad_ismagnitudeless(leftp3,leftp4,rightp1,rightp2,rightp3,rightp4,signlessleft,signlessright) \
+/* Quad_floating_point left, right; * \
+ * unsigned int signlessleft, signlessright; */ \
+ ( signlessleft<=signlessright && \
+ (signlessleft<signlessright || (Qallp2(leftp2)<=Qallp2(rightp2) && \
+ (Qallp2(leftp2)<Qallp2(rightp2) || (Qallp3(leftp3)<=Qallp3(rightp3) && \
+ (Qallp3(leftp3)<Qallp3(rightp3) || Qallp4(leftp4)<Qallp4(rightp4)))))))
+
+#define Quad_xor_to_intp1(leftp1,rightp1,result) \
+ /* quad_floating_point left, right; \
+ * unsigned int result; */ \
+ result = Qallp1(leftp1) XOR Qallp1(rightp1);
+
+#define Quad_xor_from_intp1(leftp1,rightp1,result) \
+ /* quad_floating_point right, result; \
+ * unsigned int left; */ \
+ Qallp1(resultp1) = left XOR Qallp1(rightp1)
+
+#define Quad_swap_lower(leftp1,leftp2,leftp3,leftp4,rightp1,rightp2,rightp3,rightp4) \
+ /* quad_floating_point left, right; */ \
+ Qallp2(leftp2) = Qallp2(leftp2) XOR Qallp2(rightp2) \
+ Qallp2(rightp2) = Qallp2(leftp2) XOR Qallp2(rightp2) \
+ Qallp2(leftp2) = Qallp2(leftp2) XOR Qallp2(rightp2) \
+ Qallp3(leftp3) = Qallp3(leftp3) XOR Qallp3(rightp3) \
+ Qallp3(rightp3) = Qallp3(leftp3) XOR Qallp3(rightp3) \
+ Qallp3(leftp3) = Qallp3(leftp3) XOR Qallp3(rightp3) \
+ Qallp4(leftp4) = Qallp4(leftp4) XOR Qallp4(rightp4) \
+ Qallp4(rightp4) = Qallp4(leftp4) XOR Qallp4(rightp4) \
+ Qallp4(leftp4) = Qallp4(leftp4) XOR Qallp4(rightp4)
diff --git a/sys/arch/hppa/spmath/setovfl.c b/sys/arch/hppa/spmath/setovfl.c
new file mode 100644
index 00000000000..ecf06a13c52
--- /dev/null
+++ b/sys/arch/hppa/spmath/setovfl.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/Attic/setovfl.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:06 $
+ */
+
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+#include "../spmath/dbl_float.h"
+
+sgl_floating_point sgl_setoverflow(sign)
+
+unsigned int sign;
+{
+ sgl_floating_point result;
+
+ /* set result to infinity or largest number */
+ /* ignore for now
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (sign) {
+ Sgl_setlargestnegative(result);
+ }
+ else {
+ Sgl_setinfinitypositive(result);
+ }
+ break;
+ case ROUNDMINUS:
+ if (sign==0) {
+ Sgl_setlargestpositive(result);
+ }
+ else {
+ Sgl_setinfinitynegative(result);
+ }
+ break;
+ case ROUNDNEAREST:
+ Sgl_setinfinity(result,sign);
+ break;
+ case ROUNDZERO:
+ Sgl_setlargest(result,sign);
+ }
+ return(result);
+ */
+}
+
+dbl_floating_point dbl_setoverflow(sign)
+
+unsigned int sign;
+{
+ dbl_floating_point result;
+
+ /* set result to infinity or largest number */
+ /* ignore for now
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (sign) {
+ Dbl_setlargestnegative(result);
+ }
+ else {
+ Dbl_setinfinitypositive(result);
+ }
+ break;
+ case ROUNDMINUS:
+ if (sign==0) {
+ Dbl_setlargestpositive(result);
+ }
+ else {
+ Dbl_setinfinitynegative(result);
+ }
+ break;
+ case ROUNDNEAREST:
+ Dbl_setinfinity(result,sign);
+ break;
+ case ROUNDZERO:
+ Dbl_setlargest(result,sign);
+ }
+ return(result);
+ */
+}
diff --git a/sys/arch/hppa/spmath/sfadd.c b/sys/arch/hppa/spmath/sfadd.c
new file mode 100644
index 00000000000..c1a3c5555fd
--- /dev/null
+++ b/sys/arch/hppa/spmath/sfadd.c
@@ -0,0 +1,518 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/sfadd.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:06 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+
+/*
+ * Single_add: add two single precision values.
+ */
+sgl_fadd(leftptr, rightptr, dstptr, status)
+ sgl_floating_point *leftptr, *rightptr, *dstptr;
+ unsigned int *status;
+ {
+ register unsigned int left, right, result, extent;
+ register unsigned int signless_upper_left, signless_upper_right, save;
+
+
+ register int result_exponent, right_exponent, diff_exponent;
+ register int sign_save, jumpsize;
+ register boolean inexact = FALSE;
+ register boolean underflowtrap;
+
+ /* Create local copies of the numbers */
+ left = *leftptr;
+ right = *rightptr;
+
+ /* A zero "save" helps discover equal operands (for later), *
+ * and is used in swapping operands (if needed). */
+ Sgl_xortointp1(left,right,/*to*/save);
+
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if ((result_exponent = Sgl_exponent(left)) == SGL_INFINITY_EXPONENT)
+ {
+ if (Sgl_iszero_mantissa(left))
+ {
+ if (Sgl_isnotnan(right))
+ {
+ if (Sgl_isinfinity(right) && save!=0)
+ {
+ /*
+ * invalid since operands are opposite signed infinity's
+ */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Sgl_makequietnan(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ *dstptr = left;
+ return(NOEXCEPTION);
+ }
+ }
+ else
+ {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(left))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(left);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Sgl_is_signalingnan(right))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(right);
+ *dstptr = right;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = left;
+ return(NOEXCEPTION);
+ }
+ } /* End left NaN or Infinity processing */
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if (Sgl_isinfinity_exponent(right))
+ {
+ if (Sgl_iszero_mantissa(right))
+ {
+ /* return infinity */
+ *dstptr = right;
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(right))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(right);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = right;
+ return(NOEXCEPTION);
+ } /* End right NaN or Infinity processing */
+
+ /* Invariant: Must be dealing with finite numbers */
+
+ /* Compare operands by removing the sign */
+ Sgl_copytoint_exponentmantissa(left,signless_upper_left);
+ Sgl_copytoint_exponentmantissa(right,signless_upper_right);
+
+ /* sign difference selects add or sub operation. */
+ if(Sgl_ismagnitudeless(signless_upper_left,signless_upper_right))
+ {
+ /* Set the left operand to the larger one by XOR swap *
+ * First finish the first word using "save" */
+ Sgl_xorfromintp1(save,right,/*to*/right);
+ Sgl_xorfromintp1(save,left,/*to*/left);
+ result_exponent = Sgl_exponent(left);
+ }
+ /* Invariant: left is not smaller than right. */
+
+ if((right_exponent = Sgl_exponent(right)) == 0)
+ {
+ /* Denormalized operands. First look for zeroes */
+ if(Sgl_iszero_mantissa(right))
+ {
+ /* right is zero */
+ if(Sgl_iszero_exponentmantissa(left))
+ {
+ /* Both operands are zeros */
+ if(Is_rounding_mode(ROUNDMINUS))
+ {
+ Sgl_or_signs(left,/*with*/right);
+ }
+ else
+ {
+ Sgl_and_signs(left,/*with*/right);
+ }
+ }
+ else
+ {
+ /* Left is not a zero and must be the result. Trapped
+ * underflows are signaled if left is denormalized. Result
+ * is always exact. */
+ if( (result_exponent == 0) && Is_underflowtrap_enabled() )
+ {
+ /* need to normalize results mantissa */
+ sign_save = Sgl_signextendedsign(left);
+ Sgl_leftshiftby1(left);
+ Sgl_normalize(left,result_exponent);
+ Sgl_set_sign(left,/*using*/sign_save);
+ Sgl_setwrapped_exponent(left,result_exponent,unfl);
+ *dstptr = left;
+ return(UNDERFLOWEXCEPTION);
+ }
+ }
+ *dstptr = left;
+ return(NOEXCEPTION);
+ }
+
+ /* Neither are zeroes */
+ Sgl_clear_sign(right); /* Exponent is already cleared */
+ if(result_exponent == 0 )
+ {
+ /* Both operands are denormalized. The result must be exact
+ * and is simply calculated. A sum could become normalized and a
+ * difference could cancel to a true zero. */
+ if( (/*signed*/int) save < 0 )
+ {
+ Sgl_subtract(left,/*minus*/right,/*into*/result);
+ if(Sgl_iszero_mantissa(result))
+ {
+ if(Is_rounding_mode(ROUNDMINUS))
+ {
+ Sgl_setone_sign(result);
+ }
+ else
+ {
+ Sgl_setzero_sign(result);
+ }
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ else
+ {
+ Sgl_addition(left,right,/*into*/result);
+ if(Sgl_isone_hidden(result))
+ {
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ if(Is_underflowtrap_enabled())
+ {
+ /* need to normalize result */
+ sign_save = Sgl_signextendedsign(result);
+ Sgl_leftshiftby1(result);
+ Sgl_normalize(result,result_exponent);
+ Sgl_set_sign(result,/*using*/sign_save);
+ Sgl_setwrapped_exponent(result,result_exponent,unfl);
+ *dstptr = result;
+ return(UNDERFLOWEXCEPTION);
+ }
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ right_exponent = 1; /* Set exponent to reflect different bias
+ * with denomalized numbers. */
+ }
+ else
+ {
+ Sgl_clear_signexponent_set_hidden(right);
+ }
+ Sgl_clear_exponent_set_hidden(left);
+ diff_exponent = result_exponent - right_exponent;
+
+ /*
+ * Special case alignment of operands that would force alignment
+ * beyond the extent of the extension. A further optimization
+ * could special case this but only reduces the path length for this
+ * infrequent case.
+ */
+ if(diff_exponent > SGL_THRESHOLD)
+ {
+ diff_exponent = SGL_THRESHOLD;
+ }
+
+ /* Align right operand by shifting to right */
+ Sgl_right_align(/*operand*/right,/*shifted by*/diff_exponent,
+ /*and lower to*/extent);
+
+ /* Treat sum and difference of the operands separately. */
+ if( (/*signed*/int) save < 0 )
+ {
+ /*
+ * Difference of the two operands. Their can be no overflow. A
+ * borrow can occur out of the hidden bit and force a post
+ * normalization phase.
+ */
+ Sgl_subtract_withextension(left,/*minus*/right,/*with*/extent,/*into*/result);
+ if(Sgl_iszero_hidden(result))
+ {
+ /* Handle normalization */
+ /* A straight foward algorithm would now shift the result
+ * and extension left until the hidden bit becomes one. Not
+ * all of the extension bits need participate in the shift.
+ * Only the two most significant bits (round and guard) are
+ * needed. If only a single shift is needed then the guard
+ * bit becomes a significant low order bit and the extension
+ * must participate in the rounding. If more than a single
+ * shift is needed, then all bits to the right of the guard
+ * bit are zeros, and the guard bit may or may not be zero. */
+ sign_save = Sgl_signextendedsign(result);
+ Sgl_leftshiftby1_withextent(result,extent,result);
+
+ /* Need to check for a zero result. The sign and exponent
+ * fields have already been zeroed. The more efficient test
+ * of the full object can be used.
+ */
+ if(Sgl_iszero(result))
+ /* Must have been "x-x" or "x+(-x)". */
+ {
+ if(Is_rounding_mode(ROUNDMINUS)) Sgl_setone_sign(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ result_exponent--;
+ /* Look to see if normalization is finished. */
+ if(Sgl_isone_hidden(result))
+ {
+ if(result_exponent==0)
+ {
+ /* Denormalized, exponent should be zero. Left operand *
+ * was normalized, so extent (guard, round) was zero */
+ goto underflow;
+ }
+ else
+ {
+ /* No further normalization is needed. */
+ Sgl_set_sign(result,/*using*/sign_save);
+ Ext_leftshiftby1(extent);
+ goto round;
+ }
+ }
+
+ /* Check for denormalized, exponent should be zero. Left *
+ * operand was normalized, so extent (guard, round) was zero */
+ if(!(underflowtrap = Is_underflowtrap_enabled()) &&
+ result_exponent==0) goto underflow;
+
+ /* Shift extension to complete one bit of normalization and
+ * update exponent. */
+ Ext_leftshiftby1(extent);
+
+ /* Discover first one bit to determine shift amount. Use a
+ * modified binary search. We have already shifted the result
+ * one position right and still not found a one so the remainder
+ * of the extension must be zero and simplifies rounding. */
+ /* Scan bytes */
+ while(Sgl_iszero_hiddenhigh7mantissa(result))
+ {
+ Sgl_leftshiftby8(result);
+ if((result_exponent -= 8) <= 0 && !underflowtrap)
+ goto underflow;
+ }
+ /* Now narrow it down to the nibble */
+ if(Sgl_iszero_hiddenhigh3mantissa(result))
+ {
+ /* The lower nibble contains the normalizing one */
+ Sgl_leftshiftby4(result);
+ if((result_exponent -= 4) <= 0 && !underflowtrap)
+ goto underflow;
+ }
+ /* Select case were first bit is set (already normalized)
+ * otherwise select the proper shift. */
+ if((jumpsize = Sgl_hiddenhigh3mantissa(result)) > 7)
+ {
+ /* Already normalized */
+ if(result_exponent <= 0) goto underflow;
+ Sgl_set_sign(result,/*using*/sign_save);
+ Sgl_set_exponent(result,/*using*/result_exponent);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ Sgl_sethigh4bits(result,/*using*/sign_save);
+ switch(jumpsize)
+ {
+ case 1:
+ {
+ Sgl_leftshiftby3(result);
+ result_exponent -= 3;
+ break;
+ }
+ case 2:
+ case 3:
+ {
+ Sgl_leftshiftby2(result);
+ result_exponent -= 2;
+ break;
+ }
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ {
+ Sgl_leftshiftby1(result);
+ result_exponent -= 1;
+ break;
+ }
+ }
+ if(result_exponent > 0)
+ {
+ Sgl_set_exponent(result,/*using*/result_exponent);
+ *dstptr = result;
+ return(NOEXCEPTION); /* Sign bit is already set */
+ }
+ /* Fixup potential underflows */
+ underflow:
+ if(Is_underflowtrap_enabled())
+ {
+ Sgl_set_sign(result,sign_save);
+ Sgl_setwrapped_exponent(result,result_exponent,unfl);
+ *dstptr = result;
+ /* inexact = FALSE; */
+ return(UNDERFLOWEXCEPTION);
+ }
+ /*
+ * Since we cannot get an inexact denormalized result,
+ * we can now return.
+ */
+ Sgl_right_align(result,/*by*/(1-result_exponent),extent);
+ Sgl_clear_signexponent(result);
+ Sgl_set_sign(result,sign_save);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ } /* end if(hidden...)... */
+ /* Fall through and round */
+ } /* end if(save < 0)... */
+ else
+ {
+ /* Add magnitudes */
+ Sgl_addition(left,right,/*to*/result);
+ if(Sgl_isone_hiddenoverflow(result))
+ {
+ /* Prenormalization required. */
+ Sgl_rightshiftby1_withextent(result,extent,extent);
+ Sgl_arithrightshiftby1(result);
+ result_exponent++;
+ } /* end if hiddenoverflow... */
+ } /* end else ...add magnitudes... */
+
+ /* Round the result. If the extension is all zeros,then the result is
+ * exact. Otherwise round in the correct direction. No underflow is
+ * possible. If a postnormalization is necessary, then the mantissa is
+ * all zeros so no shift is needed. */
+ round:
+ if(Ext_isnotzero(extent))
+ {
+ inexact = TRUE;
+ switch(Rounding_mode())
+ {
+ case ROUNDNEAREST: /* The default. */
+ if(Ext_isone_sign(extent))
+ {
+ /* at least 1/2 ulp */
+ if(Ext_isnotzero_lower(extent) ||
+ Sgl_isone_lowmantissa(result))
+ {
+ /* either exactly half way and odd or more than 1/2ulp */
+ Sgl_increment(result);
+ }
+ }
+ break;
+
+ case ROUNDPLUS:
+ if(Sgl_iszero_sign(result))
+ {
+ /* Round up positive results */
+ Sgl_increment(result);
+ }
+ break;
+
+ case ROUNDMINUS:
+ if(Sgl_isone_sign(result))
+ {
+ /* Round down negative results */
+ Sgl_increment(result);
+ }
+
+ case ROUNDZERO:;
+ /* truncate is simple */
+ } /* end switch... */
+ if(Sgl_isone_hiddenoverflow(result)) result_exponent++;
+ }
+ if(result_exponent == SGL_INFINITY_EXPONENT)
+ {
+ /* Overflow */
+ if(Is_overflowtrap_enabled())
+ {
+ Sgl_setwrapped_exponent(result,result_exponent,ovfl);
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(OVERFLOWEXCEPTION);
+ }
+ else
+ {
+ Set_overflowflag();
+ inexact = TRUE;
+ Sgl_setoverflow(result);
+ }
+ }
+ else Sgl_set_exponent(result,result_exponent);
+ *dstptr = result;
+ if(inexact)
+ if(Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(NOEXCEPTION);
+ }
diff --git a/sys/arch/hppa/spmath/sfcmp.c b/sys/arch/hppa/spmath/sfcmp.c
new file mode 100644
index 00000000000..d1e7e73c69a
--- /dev/null
+++ b/sys/arch/hppa/spmath/sfcmp.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/sfcmp.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:06 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+
+/*
+ * sgl_cmp: compare two values
+ */
+sgl_fcmp(leftptr, rightptr, cond, status)
+ sgl_floating_point *leftptr, *rightptr;
+ unsigned int cond; /* The predicate to be tested */
+ unsigned int *status;
+ {
+ register unsigned int left, right;
+ register int xorresult;
+
+ /* Create local copies of the numbers */
+ left = *leftptr;
+ right = *rightptr;
+ /*
+ * Test for NaN
+ */
+ if( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
+ || (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) )
+ {
+ /* Check if a NaN is involved. Signal an invalid exception when
+ * comparing a signaling NaN or when comparing quiet NaNs and the
+ * low bit of the condition is set */
+ if( ( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
+ && Sgl_isnotzero_mantissa(left)
+ && (Exception(cond) || Sgl_isone_signaling(left)))
+ ||
+ ( (Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
+ && Sgl_isnotzero_mantissa(right)
+ && (Exception(cond) || Sgl_isone_signaling(right)) ) )
+ {
+ if( Is_invalidtrap_enabled() ) {
+ Set_status_cbit(Unordered(cond));
+ return(INVALIDEXCEPTION);
+ }
+ else Set_invalidflag();
+ Set_status_cbit(Unordered(cond));
+ return(NOEXCEPTION);
+ }
+ /* All the exceptional conditions are handled, now special case
+ NaN compares */
+ else if( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
+ && Sgl_isnotzero_mantissa(left))
+ ||
+ ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
+ && Sgl_isnotzero_mantissa(right)) )
+ {
+ /* NaNs always compare unordered. */
+ Set_status_cbit(Unordered(cond));
+ return(NOEXCEPTION);
+ }
+ /* infinities will drop down to the normal compare mechanisms */
+ }
+ /* First compare for unequal signs => less or greater or
+ * special equal case */
+ Sgl_xortointp1(left,right,xorresult);
+ if( xorresult < 0 )
+ {
+ /* left negative => less, left positive => greater.
+ * equal is possible if both operands are zeros. */
+ if( Sgl_iszero_exponentmantissa(left)
+ && Sgl_iszero_exponentmantissa(right) )
+ {
+ Set_status_cbit(Equal(cond));
+ }
+ else if( Sgl_isone_sign(left) )
+ {
+ Set_status_cbit(Lessthan(cond));
+ }
+ else
+ {
+ Set_status_cbit(Greaterthan(cond));
+ }
+ }
+ /* Signs are the same. Treat negative numbers separately
+ * from the positives because of the reversed sense. */
+ else if( Sgl_all(left) == Sgl_all(right) )
+ {
+ Set_status_cbit(Equal(cond));
+ }
+ else if( Sgl_iszero_sign(left) )
+ {
+ /* Positive compare */
+ if( Sgl_all(left) < Sgl_all(right) )
+ {
+ Set_status_cbit(Lessthan(cond));
+ }
+ else
+ {
+ Set_status_cbit(Greaterthan(cond));
+ }
+ }
+ else
+ {
+ /* Negative compare. Signed or unsigned compares
+ * both work the same. That distinction is only
+ * important when the sign bits differ. */
+ if( Sgl_all(left) > Sgl_all(right) )
+ {
+ Set_status_cbit(Lessthan(cond));
+ }
+ else
+ {
+ Set_status_cbit(Greaterthan(cond));
+ }
+ }
+ return(NOEXCEPTION);
+ }
diff --git a/sys/arch/hppa/spmath/sfdiv.c b/sys/arch/hppa/spmath/sfdiv.c
new file mode 100644
index 00000000000..e6fc937f7bb
--- /dev/null
+++ b/sys/arch/hppa/spmath/sfdiv.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/sfdiv.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:07 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+
+/*
+ * Single Precision Floating-point Divide
+ */
+
+sgl_fdiv(srcptr1,srcptr2,dstptr,status)
+
+sgl_floating_point *srcptr1, *srcptr2, *dstptr;
+unsigned int *status;
+{
+ register unsigned int opnd1, opnd2, opnd3, result;
+ register int dest_exponent, count;
+ register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
+ boolean is_tiny;
+
+ opnd1 = *srcptr1;
+ opnd2 = *srcptr2;
+ /*
+ * set sign bit of result
+ */
+ if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2)) Sgl_setnegativezero(result);
+ else Sgl_setzero(result);
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if (Sgl_isinfinity_exponent(opnd1)) {
+ if (Sgl_iszero_mantissa(opnd1)) {
+ if (Sgl_isnotnan(opnd2)) {
+ if (Sgl_isinfinity(opnd2)) {
+ /*
+ * invalid since both operands
+ * are infinity
+ */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Sgl_makequietnan(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ Sgl_setinfinity_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ else {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(opnd1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd1);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Sgl_is_signalingnan(opnd2)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd2);
+ *dstptr = opnd2;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = opnd1;
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if (Sgl_isinfinity_exponent(opnd2)) {
+ if (Sgl_iszero_mantissa(opnd2)) {
+ /*
+ * return zero
+ */
+ Sgl_setzero_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(opnd2)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd2);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = opnd2;
+ return(NOEXCEPTION);
+ }
+ /*
+ * check for division by zero
+ */
+ if (Sgl_iszero_exponentmantissa(opnd2)) {
+ if (Sgl_iszero_exponentmantissa(opnd1)) {
+ /* invalid since both operands are zero */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Sgl_makequietnan(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ if (Is_divisionbyzerotrap_enabled())
+ return(DIVISIONBYZEROEXCEPTION);
+ Set_divisionbyzeroflag();
+ Sgl_setinfinity_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate exponent
+ */
+ dest_exponent = Sgl_exponent(opnd1) - Sgl_exponent(opnd2) + SGL_BIAS;
+
+ /*
+ * Generate mantissa
+ */
+ if (Sgl_isnotzero_exponent(opnd1)) {
+ /* set hidden bit */
+ Sgl_clear_signexponent_set_hidden(opnd1);
+ }
+ else {
+ /* check for zero */
+ if (Sgl_iszero_mantissa(opnd1)) {
+ Sgl_setzero_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /* is denormalized; want to normalize */
+ Sgl_clear_signexponent(opnd1);
+ Sgl_leftshiftby1(opnd1);
+ Sgl_normalize(opnd1,dest_exponent);
+ }
+ /* opnd2 needs to have hidden bit set with msb in hidden bit */
+ if (Sgl_isnotzero_exponent(opnd2)) {
+ Sgl_clear_signexponent_set_hidden(opnd2);
+ }
+ else {
+ /* is denormalized; want to normalize */
+ Sgl_clear_signexponent(opnd2);
+ Sgl_leftshiftby1(opnd2);
+ while(Sgl_iszero_hiddenhigh7mantissa(opnd2)) {
+ Sgl_leftshiftby8(opnd2);
+ dest_exponent += 8;
+ }
+ if(Sgl_iszero_hiddenhigh3mantissa(opnd2)) {
+ Sgl_leftshiftby4(opnd2);
+ dest_exponent += 4;
+ }
+ while(Sgl_iszero_hidden(opnd2)) {
+ Sgl_leftshiftby1(opnd2);
+ dest_exponent += 1;
+ }
+ }
+
+ /* Divide the source mantissas */
+
+ /*
+ * A non_restoring divide algorithm is used.
+ */
+ Sgl_subtract(opnd1,opnd2,opnd1);
+ Sgl_setzero(opnd3);
+ for (count=1;count<=SGL_P && Sgl_all(opnd1);count++) {
+ Sgl_leftshiftby1(opnd1);
+ Sgl_leftshiftby1(opnd3);
+ if (Sgl_iszero_sign(opnd1)) {
+ Sgl_setone_lowmantissa(opnd3);
+ Sgl_subtract(opnd1,opnd2,opnd1);
+ }
+ else Sgl_addition(opnd1,opnd2,opnd1);
+ }
+ if (count <= SGL_P) {
+ Sgl_leftshiftby1(opnd3);
+ Sgl_setone_lowmantissa(opnd3);
+ Sgl_leftshift(opnd3,SGL_P-count);
+ if (Sgl_iszero_hidden(opnd3)) {
+ Sgl_leftshiftby1(opnd3);
+ dest_exponent--;
+ }
+ }
+ else {
+ if (Sgl_iszero_hidden(opnd3)) {
+ /* need to get one more bit of result */
+ Sgl_leftshiftby1(opnd1);
+ Sgl_leftshiftby1(opnd3);
+ if (Sgl_iszero_sign(opnd1)) {
+ Sgl_setone_lowmantissa(opnd3);
+ Sgl_subtract(opnd1,opnd2,opnd1);
+ }
+ else Sgl_addition(opnd1,opnd2,opnd1);
+ dest_exponent--;
+ }
+ if (Sgl_iszero_sign(opnd1)) guardbit = TRUE;
+ stickybit = Sgl_all(opnd1);
+ }
+ inexact = guardbit | stickybit;
+
+ /*
+ * round result
+ */
+ if (inexact && (dest_exponent > 0 || Is_underflowtrap_enabled())) {
+ Sgl_clear_signexponent(opnd3);
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result))
+ Sgl_increment_mantissa(opnd3);
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result))
+ Sgl_increment_mantissa(opnd3);
+ break;
+ case ROUNDNEAREST:
+ if (guardbit) {
+ if (stickybit || Sgl_isone_lowmantissa(opnd3))
+ Sgl_increment_mantissa(opnd3);
+ }
+ }
+ if (Sgl_isone_hidden(opnd3)) dest_exponent++;
+ }
+ Sgl_set_mantissa(result,opnd3);
+
+ /*
+ * Test for overflow
+ */
+ if (dest_exponent >= SGL_INFINITY_EXPONENT) {
+ /* trap if OVERFLOWTRAP enabled */
+ if (Is_overflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(OVERFLOWEXCEPTION);
+ }
+ Set_overflowflag();
+ /* set result to infinity or largest number */
+ Sgl_setoverflow(result);
+ inexact = TRUE;
+ }
+ /*
+ * Test for underflow
+ */
+ else if (dest_exponent <= 0) {
+ /* trap if UNDERFLOWTRAP enabled */
+ if (Is_underflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Sgl_setwrapped_exponent(result,dest_exponent,unfl);
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(UNDERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(UNDERFLOWEXCEPTION);
+ }
+
+ /* Determine if should set underflow flag */
+ is_tiny = TRUE;
+ if (dest_exponent == 0 && inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result)) {
+ Sgl_increment(opnd3);
+ if (Sgl_isone_hiddenoverflow(opnd3))
+ is_tiny = FALSE;
+ Sgl_decrement(opnd3);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result)) {
+ Sgl_increment(opnd3);
+ if (Sgl_isone_hiddenoverflow(opnd3))
+ is_tiny = FALSE;
+ Sgl_decrement(opnd3);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Sgl_isone_lowmantissa(opnd3))) {
+ Sgl_increment(opnd3);
+ if (Sgl_isone_hiddenoverflow(opnd3))
+ is_tiny = FALSE;
+ Sgl_decrement(opnd3);
+ }
+ break;
+ }
+ }
+
+ /*
+ * denormalize result or set to signed zero
+ */
+ stickybit = inexact;
+ Sgl_denormalize(opnd3,dest_exponent,guardbit,stickybit,inexact);
+
+ /* return rounded number */
+ if (inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result)) {
+ Sgl_increment(opnd3);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result)) {
+ Sgl_increment(opnd3);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Sgl_isone_lowmantissa(opnd3))) {
+ Sgl_increment(opnd3);
+ }
+ break;
+ }
+ if (is_tiny) Set_underflowflag();
+ }
+ Sgl_set_exponentmantissa(result,opnd3);
+ }
+ else Sgl_set_exponent(result,dest_exponent);
+ *dstptr = result;
+ /* check for inexact */
+ if (inexact) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/sfmpy.c b/sys/arch/hppa/spmath/sfmpy.c
new file mode 100644
index 00000000000..11a83ef9658
--- /dev/null
+++ b/sys/arch/hppa/spmath/sfmpy.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/sfmpy.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:07 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+
+/*
+ * Single Precision Floating-point Multiply
+ */
+
+sgl_fmpy(srcptr1,srcptr2,dstptr,status)
+
+sgl_floating_point *srcptr1, *srcptr2, *dstptr;
+unsigned int *status;
+{
+ register unsigned int opnd1, opnd2, opnd3, result;
+ register int dest_exponent, count;
+ register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
+ boolean is_tiny;
+
+ opnd1 = *srcptr1;
+ opnd2 = *srcptr2;
+ /*
+ * set sign bit of result
+ */
+ if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2)) Sgl_setnegativezero(result);
+ else Sgl_setzero(result);
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if (Sgl_isinfinity_exponent(opnd1)) {
+ if (Sgl_iszero_mantissa(opnd1)) {
+ if (Sgl_isnotnan(opnd2)) {
+ if (Sgl_iszero_exponentmantissa(opnd2)) {
+ /*
+ * invalid since operands are infinity
+ * and zero
+ */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Sgl_makequietnan(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ Sgl_setinfinity_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ else {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(opnd1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd1);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Sgl_is_signalingnan(opnd2)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd2);
+ *dstptr = opnd2;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = opnd1;
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if (Sgl_isinfinity_exponent(opnd2)) {
+ if (Sgl_iszero_mantissa(opnd2)) {
+ if (Sgl_iszero_exponentmantissa(opnd1)) {
+ /* invalid since operands are zero & infinity */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Sgl_makequietnan(opnd2);
+ *dstptr = opnd2;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ Sgl_setinfinity_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(opnd2)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd2);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = opnd2;
+ return(NOEXCEPTION);
+ }
+ /*
+ * Generate exponent
+ */
+ dest_exponent = Sgl_exponent(opnd1) + Sgl_exponent(opnd2) - SGL_BIAS;
+
+ /*
+ * Generate mantissa
+ */
+ if (Sgl_isnotzero_exponent(opnd1)) {
+ /* set hidden bit */
+ Sgl_clear_signexponent_set_hidden(opnd1);
+ }
+ else {
+ /* check for zero */
+ if (Sgl_iszero_mantissa(opnd1)) {
+ Sgl_setzero_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /* is denormalized, adjust exponent */
+ Sgl_clear_signexponent(opnd1);
+ Sgl_leftshiftby1(opnd1);
+ Sgl_normalize(opnd1,dest_exponent);
+ }
+ /* opnd2 needs to have hidden bit set with msb in hidden bit */
+ if (Sgl_isnotzero_exponent(opnd2)) {
+ Sgl_clear_signexponent_set_hidden(opnd2);
+ }
+ else {
+ /* check for zero */
+ if (Sgl_iszero_mantissa(opnd2)) {
+ Sgl_setzero_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /* is denormalized; want to normalize */
+ Sgl_clear_signexponent(opnd2);
+ Sgl_leftshiftby1(opnd2);
+ Sgl_normalize(opnd2,dest_exponent);
+ }
+
+ /* Multiply two source mantissas together */
+
+ Sgl_leftshiftby4(opnd2); /* make room for guard bits */
+ Sgl_setzero(opnd3);
+ /*
+ * Four bits at a time are inspected in each loop, and a
+ * simple shift and add multiply algorithm is used.
+ */
+ for (count=1;count<SGL_P;count+=4) {
+ stickybit |= Slow4(opnd3);
+ Sgl_rightshiftby4(opnd3);
+ if (Sbit28(opnd1)) Sall(opnd3) += (Sall(opnd2) << 3);
+ if (Sbit29(opnd1)) Sall(opnd3) += (Sall(opnd2) << 2);
+ if (Sbit30(opnd1)) Sall(opnd3) += (Sall(opnd2) << 1);
+ if (Sbit31(opnd1)) Sall(opnd3) += Sall(opnd2);
+ Sgl_rightshiftby4(opnd1);
+ }
+ /* make sure result is left-justified */
+ if (Sgl_iszero_sign(opnd3)) {
+ Sgl_leftshiftby1(opnd3);
+ }
+ else {
+ /* result mantissa >= 2. */
+ dest_exponent++;
+ }
+ /* check for denormalized result */
+ while (Sgl_iszero_sign(opnd3)) {
+ Sgl_leftshiftby1(opnd3);
+ dest_exponent--;
+ }
+ /*
+ * check for guard, sticky and inexact bits
+ */
+ stickybit |= Sgl_all(opnd3) << (SGL_BITLENGTH - SGL_EXP_LENGTH + 1);
+ guardbit = Sbit24(opnd3);
+ inexact = guardbit | stickybit;
+
+ /* re-align mantissa */
+ Sgl_rightshiftby8(opnd3);
+
+ /*
+ * round result
+ */
+ if (inexact && (dest_exponent>0 || Is_underflowtrap_enabled())) {
+ Sgl_clear_signexponent(opnd3);
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result))
+ Sgl_increment(opnd3);
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result))
+ Sgl_increment(opnd3);
+ break;
+ case ROUNDNEAREST:
+ if (guardbit) {
+ if (stickybit || Sgl_isone_lowmantissa(opnd3))
+ Sgl_increment(opnd3);
+ }
+ }
+ if (Sgl_isone_hidden(opnd3)) dest_exponent++;
+ }
+ Sgl_set_mantissa(result,opnd3);
+
+ /*
+ * Test for overflow
+ */
+ if (dest_exponent >= SGL_INFINITY_EXPONENT) {
+ /* trap if OVERFLOWTRAP enabled */
+ if (Is_overflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(OVERFLOWEXCEPTION);
+ }
+ inexact = TRUE;
+ Set_overflowflag();
+ /* set result to infinity or largest number */
+ Sgl_setoverflow(result);
+ }
+ /*
+ * Test for underflow
+ */
+ else if (dest_exponent <= 0) {
+ /* trap if UNDERFLOWTRAP enabled */
+ if (Is_underflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Sgl_setwrapped_exponent(result,dest_exponent,unfl);
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(UNDERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(UNDERFLOWEXCEPTION);
+ }
+
+ /* Determine if should set underflow flag */
+ is_tiny = TRUE;
+ if (dest_exponent == 0 && inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result)) {
+ Sgl_increment(opnd3);
+ if (Sgl_isone_hiddenoverflow(opnd3))
+ is_tiny = FALSE;
+ Sgl_decrement(opnd3);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result)) {
+ Sgl_increment(opnd3);
+ if (Sgl_isone_hiddenoverflow(opnd3))
+ is_tiny = FALSE;
+ Sgl_decrement(opnd3);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Sgl_isone_lowmantissa(opnd3))) {
+ Sgl_increment(opnd3);
+ if (Sgl_isone_hiddenoverflow(opnd3))
+ is_tiny = FALSE;
+ Sgl_decrement(opnd3);
+ }
+ break;
+ }
+ }
+
+ /*
+ * denormalize result or set to signed zero
+ */
+ stickybit = inexact;
+ Sgl_denormalize(opnd3,dest_exponent,guardbit,stickybit,inexact);
+
+ /* return zero or smallest number */
+ if (inexact) {
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ if (Sgl_iszero_sign(result)) {
+ Sgl_increment(opnd3);
+ }
+ break;
+ case ROUNDMINUS:
+ if (Sgl_isone_sign(result)) {
+ Sgl_increment(opnd3);
+ }
+ break;
+ case ROUNDNEAREST:
+ if (guardbit && (stickybit ||
+ Sgl_isone_lowmantissa(opnd3))) {
+ Sgl_increment(opnd3);
+ }
+ break;
+ }
+ if (is_tiny) Set_underflowflag();
+ }
+ Sgl_set_exponentmantissa(result,opnd3);
+ }
+ else Sgl_set_exponent(result,dest_exponent);
+ *dstptr = result;
+
+ /* check for inexact */
+ if (inexact) {
+ if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ }
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/sfrem.c b/sys/arch/hppa/spmath/sfrem.c
new file mode 100644
index 00000000000..515b34ea280
--- /dev/null
+++ b/sys/arch/hppa/spmath/sfrem.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/sfrem.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:07 $
+ */
+
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+
+/*
+ * Single Precision Floating-point Remainder
+ */
+
+sgl_frem(srcptr1,srcptr2,dstptr,status)
+
+sgl_floating_point *srcptr1, *srcptr2, *dstptr;
+unsigned int *status;
+{
+ register unsigned int opnd1, opnd2, result;
+ register int opnd1_exponent, opnd2_exponent, dest_exponent, stepcount;
+ register boolean roundup = FALSE;
+
+ opnd1 = *srcptr1;
+ opnd2 = *srcptr2;
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if ((opnd1_exponent = Sgl_exponent(opnd1)) == SGL_INFINITY_EXPONENT) {
+ if (Sgl_iszero_mantissa(opnd1)) {
+ if (Sgl_isnotnan(opnd2)) {
+ /* invalid since first operand is infinity */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Sgl_makequietnan(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ else {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(opnd1)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd1);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Sgl_is_signalingnan(opnd2)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled())
+ return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd2);
+ *dstptr = opnd2;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = opnd1;
+ return(NOEXCEPTION);
+ }
+ }
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if ((opnd2_exponent = Sgl_exponent(opnd2)) == SGL_INFINITY_EXPONENT) {
+ if (Sgl_iszero_mantissa(opnd2)) {
+ /*
+ * return first operand
+ */
+ *dstptr = opnd1;
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(opnd2)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(opnd2);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = opnd2;
+ return(NOEXCEPTION);
+ }
+ /*
+ * check second operand for zero
+ */
+ if (Sgl_iszero_exponentmantissa(opnd2)) {
+ /* invalid since second operand is zero */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Sgl_makequietnan(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+
+ /*
+ * get sign of result
+ */
+ result = opnd1;
+
+ /*
+ * check for denormalized operands
+ */
+ if (opnd1_exponent == 0) {
+ /* check for zero */
+ if (Sgl_iszero_mantissa(opnd1)) {
+ *dstptr = opnd1;
+ return(NOEXCEPTION);
+ }
+ /* normalize, then continue */
+ opnd1_exponent = 1;
+ Sgl_normalize(opnd1,opnd1_exponent);
+ }
+ else {
+ Sgl_clear_signexponent_set_hidden(opnd1);
+ }
+ if (opnd2_exponent == 0) {
+ /* normalize, then continue */
+ opnd2_exponent = 1;
+ Sgl_normalize(opnd2,opnd2_exponent);
+ }
+ else {
+ Sgl_clear_signexponent_set_hidden(opnd2);
+ }
+
+ /* find result exponent and divide step loop count */
+ dest_exponent = opnd2_exponent - 1;
+ stepcount = opnd1_exponent - opnd2_exponent;
+
+ /*
+ * check for opnd1/opnd2 < 1
+ */
+ if (stepcount < 0) {
+ /*
+ * check for opnd1/opnd2 > 1/2
+ *
+ * In this case n will round to 1, so
+ * r = opnd1 - opnd2
+ */
+ if (stepcount == -1 && Sgl_isgreaterthan(opnd1,opnd2)) {
+ Sgl_all(result) = ~Sgl_all(result); /* set sign */
+ /* align opnd2 with opnd1 */
+ Sgl_leftshiftby1(opnd2);
+ Sgl_subtract(opnd2,opnd1,opnd2);
+ /* now normalize */
+ while (Sgl_iszero_hidden(opnd2)) {
+ Sgl_leftshiftby1(opnd2);
+ dest_exponent--;
+ }
+ Sgl_set_exponentmantissa(result,opnd2);
+ goto testforunderflow;
+ }
+ /*
+ * opnd1/opnd2 <= 1/2
+ *
+ * In this case n will round to zero, so
+ * r = opnd1
+ */
+ Sgl_set_exponentmantissa(result,opnd1);
+ dest_exponent = opnd1_exponent;
+ goto testforunderflow;
+ }
+
+ /*
+ * Generate result
+ *
+ * Do iterative subtract until remainder is less than operand 2.
+ */
+ while (stepcount-- > 0 && Sgl_all(opnd1)) {
+ if (Sgl_isnotlessthan(opnd1,opnd2))
+ Sgl_subtract(opnd1,opnd2,opnd1);
+ Sgl_leftshiftby1(opnd1);
+ }
+ /*
+ * Do last subtract, then determine which way to round if remainder
+ * is exactly 1/2 of opnd2
+ */
+ if (Sgl_isnotlessthan(opnd1,opnd2)) {
+ Sgl_subtract(opnd1,opnd2,opnd1);
+ roundup = TRUE;
+ }
+ if (stepcount > 0 || Sgl_iszero(opnd1)) {
+ /* division is exact, remainder is zero */
+ Sgl_setzero_exponentmantissa(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+
+ /*
+ * Check for cases where opnd1/opnd2 < n
+ *
+ * In this case the result's sign will be opposite that of
+ * opnd1. The mantissa also needs some correction.
+ */
+ Sgl_leftshiftby1(opnd1);
+ if (Sgl_isgreaterthan(opnd1,opnd2)) {
+ Sgl_invert_sign(result);
+ Sgl_subtract((opnd2<<1),opnd1,opnd1);
+ }
+ /* check for remainder being exactly 1/2 of opnd2 */
+ else if (Sgl_isequal(opnd1,opnd2) && roundup) {
+ Sgl_invert_sign(result);
+ }
+
+ /* normalize result's mantissa */
+ while (Sgl_iszero_hidden(opnd1)) {
+ dest_exponent--;
+ Sgl_leftshiftby1(opnd1);
+ }
+ Sgl_set_exponentmantissa(result,opnd1);
+
+ /*
+ * Test for underflow
+ */
+ testforunderflow:
+ if (dest_exponent <= 0) {
+ /* trap if UNDERFLOWTRAP enabled */
+ if (Is_underflowtrap_enabled()) {
+ /*
+ * Adjust bias of result
+ */
+ Sgl_setwrapped_exponent(result,dest_exponent,unfl);
+ *dstptr = result;
+ /* frem is always exact */
+ return(UNDERFLOWEXCEPTION);
+ }
+ /*
+ * denormalize result or set to signed zero
+ */
+ if (dest_exponent >= (1 - SGL_P)) {
+ Sgl_rightshift_exponentmantissa(result,1-dest_exponent);
+ }
+ else {
+ Sgl_setzero_exponentmantissa(result);
+ }
+ }
+ else Sgl_set_exponent(result,dest_exponent);
+ *dstptr = result;
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/sfsqrt.c b/sys/arch/hppa/spmath/sfsqrt.c
new file mode 100644
index 00000000000..938d1a2c13e
--- /dev/null
+++ b/sys/arch/hppa/spmath/sfsqrt.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/sfsqrt.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:08 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+
+/*
+ * Single Floating-point Square Root
+ */
+
+/*ARGSUSED*/
+sgl_fsqrt(srcptr,nullptr,dstptr,status)
+
+sgl_floating_point *srcptr, *dstptr;
+unsigned int *nullptr, *status;
+{
+ register unsigned int src, result;
+ register int src_exponent, newbit, sum;
+ register boolean guardbit = FALSE, even_exponent;
+
+ src = *srcptr;
+ /*
+ * check source operand for NaN or infinity
+ */
+ if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) {
+ /*
+ * is signaling NaN?
+ */
+ if (Sgl_isone_signaling(src)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(src);
+ }
+ /*
+ * Return quiet NaN or positive infinity.
+ * Fall thru to negative test if negative infinity.
+ */
+ if (Sgl_iszero_sign(src) || Sgl_isnotzero_mantissa(src)) {
+ *dstptr = src;
+ return(NOEXCEPTION);
+ }
+ }
+
+ /*
+ * check for zero source operand
+ */
+ if (Sgl_iszero_exponentmantissa(src)) {
+ *dstptr = src;
+ return(NOEXCEPTION);
+ }
+
+ /*
+ * check for negative source operand
+ */
+ if (Sgl_isone_sign(src)) {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_makequietnan(src);
+ *dstptr = src;
+ return(NOEXCEPTION);
+ }
+
+ /*
+ * Generate result
+ */
+ if (src_exponent > 0) {
+ even_exponent = Sgl_hidden(src);
+ Sgl_clear_signexponent_set_hidden(src);
+ }
+ else {
+ /* normalize operand */
+ Sgl_clear_signexponent(src);
+ src_exponent++;
+ Sgl_normalize(src,src_exponent);
+ even_exponent = src_exponent & 1;
+ }
+ if (even_exponent) {
+ /* exponent is even */
+ /* Add comment here. Explain why odd exponent needs correction */
+ Sgl_leftshiftby1(src);
+ }
+ /*
+ * Add comment here. Explain following algorithm.
+ *
+ * Trust me, it works.
+ *
+ */
+ Sgl_setzero(result);
+ newbit = 1 << SGL_P;
+ while (newbit && Sgl_isnotzero(src)) {
+ Sgl_addition(result,newbit,sum);
+ if(sum <= Sgl_all(src)) {
+ /* update result */
+ Sgl_addition(result,(newbit<<1),result);
+ Sgl_subtract(src,sum,src);
+ }
+ Sgl_rightshiftby1(newbit);
+ Sgl_leftshiftby1(src);
+ }
+ /* correct exponent for pre-shift */
+ if (even_exponent) {
+ Sgl_rightshiftby1(result);
+ }
+
+ /* check for inexact */
+ if (Sgl_isnotzero(src)) {
+ if (!even_exponent & Sgl_islessthan(result,src))
+ Sgl_increment(result);
+ guardbit = Sgl_lowmantissa(result);
+ Sgl_rightshiftby1(result);
+
+ /* now round result */
+ switch (Rounding_mode()) {
+ case ROUNDPLUS:
+ Sgl_increment(result);
+ break;
+ case ROUNDNEAREST:
+ /* stickybit is always true, so guardbit
+ * is enough to determine rounding */
+ if (guardbit) {
+ Sgl_increment(result);
+ }
+ break;
+ }
+ /* increment result exponent by 1 if mantissa overflowed */
+ if (Sgl_isone_hiddenoverflow(result)) src_exponent+=2;
+
+ if (Is_inexacttrap_enabled()) {
+ Sgl_set_exponent(result,
+ ((src_exponent-SGL_BIAS)>>1)+SGL_BIAS);
+ *dstptr = result;
+ return(INEXACTEXCEPTION);
+ }
+ else Set_inexactflag();
+ }
+ else {
+ Sgl_rightshiftby1(result);
+ }
+ Sgl_set_exponent(result,((src_exponent-SGL_BIAS)>>1)+SGL_BIAS);
+ *dstptr = result;
+ return(NOEXCEPTION);
+}
diff --git a/sys/arch/hppa/spmath/sfsub.c b/sys/arch/hppa/spmath/sfsub.c
new file mode 100644
index 00000000000..242978ce246
--- /dev/null
+++ b/sys/arch/hppa/spmath/sfsub.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/* $Source: /cvs/OpenBSD/src/sys/arch/hppa/spmath/sfsub.c,v $
+ * $Revision: 1.1 $ $Author: mickey $
+ * $State: Exp $ $Locker: $
+ * $Date: 1998/06/23 20:34:08 $
+ */
+
+#include "../spmath/float.h"
+#include "../spmath/sgl_float.h"
+
+/*
+ * Single_subtract: subtract two single precision values.
+ */
+sgl_fsub(leftptr, rightptr, dstptr, status)
+ sgl_floating_point *leftptr, *rightptr, *dstptr;
+ unsigned int *status;
+ {
+ register unsigned int left, right, result, extent;
+ register unsigned int signless_upper_left, signless_upper_right, save;
+
+ register int result_exponent, right_exponent, diff_exponent;
+ register int sign_save, jumpsize;
+ register boolean inexact = FALSE, underflowtrap;
+
+ /* Create local copies of the numbers */
+ left = *leftptr;
+ right = *rightptr;
+
+ /* A zero "save" helps discover equal operands (for later), *
+ * and is used in swapping operands (if needed). */
+ Sgl_xortointp1(left,right,/*to*/save);
+
+ /*
+ * check first operand for NaN's or infinity
+ */
+ if ((result_exponent = Sgl_exponent(left)) == SGL_INFINITY_EXPONENT)
+ {
+ if (Sgl_iszero_mantissa(left))
+ {
+ if (Sgl_isnotnan(right))
+ {
+ if (Sgl_isinfinity(right) && save==0)
+ {
+ /*
+ * invalid since operands are same signed infinity's
+ */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ Set_invalidflag();
+ Sgl_makequietnan(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return infinity
+ */
+ *dstptr = left;
+ return(NOEXCEPTION);
+ }
+ }
+ else
+ {
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(left))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(left);
+ }
+ /*
+ * is second operand a signaling NaN?
+ */
+ else if (Sgl_is_signalingnan(right))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(right);
+ *dstptr = right;
+ return(NOEXCEPTION);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = left;
+ return(NOEXCEPTION);
+ }
+ } /* End left NaN or Infinity processing */
+ /*
+ * check second operand for NaN's or infinity
+ */
+ if (Sgl_isinfinity_exponent(right))
+ {
+ if (Sgl_iszero_mantissa(right))
+ {
+ /* return infinity */
+ Sgl_invert_sign(right);
+ *dstptr = right;
+ return(NOEXCEPTION);
+ }
+ /*
+ * is NaN; signaling or quiet?
+ */
+ if (Sgl_isone_signaling(right))
+ {
+ /* trap if INVALIDTRAP enabled */
+ if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
+ /* make NaN quiet */
+ Set_invalidflag();
+ Sgl_set_quiet(right);
+ }
+ /*
+ * return quiet NaN
+ */
+ *dstptr = right;
+ return(NOEXCEPTION);
+ } /* End right NaN or Infinity processing */
+
+ /* Invariant: Must be dealing with finite numbers */
+
+ /* Compare operands by removing the sign */
+ Sgl_copytoint_exponentmantissa(left,signless_upper_left);
+ Sgl_copytoint_exponentmantissa(right,signless_upper_right);
+
+ /* sign difference selects sub or add operation. */
+ if(Sgl_ismagnitudeless(signless_upper_left,signless_upper_right))
+ {
+ /* Set the left operand to the larger one by XOR swap *
+ * First finish the first word using "save" */
+ Sgl_xorfromintp1(save,right,/*to*/right);
+ Sgl_xorfromintp1(save,left,/*to*/left);
+ result_exponent = Sgl_exponent(left);
+ Sgl_invert_sign(left);
+ }
+ /* Invariant: left is not smaller than right. */
+
+ if((right_exponent = Sgl_exponent(right)) == 0)
+ {
+ /* Denormalized operands. First look for zeroes */
+ if(Sgl_iszero_mantissa(right))
+ {
+ /* right is zero */
+ if(Sgl_iszero_exponentmantissa(left))
+ {
+ /* Both operands are zeros */
+ Sgl_invert_sign(right);
+ if(Is_rounding_mode(ROUNDMINUS))
+ {
+ Sgl_or_signs(left,/*with*/right);
+ }
+ else
+ {
+ Sgl_and_signs(left,/*with*/right);
+ }
+ }
+ else
+ {
+ /* Left is not a zero and must be the result. Trapped
+ * underflows are signaled if left is denormalized. Result
+ * is always exact. */
+ if( (result_exponent == 0) && Is_underflowtrap_enabled() )
+ {
+ /* need to normalize results mantissa */
+ sign_save = Sgl_signextendedsign(left);
+ Sgl_leftshiftby1(left);
+ Sgl_normalize(left,result_exponent);
+ Sgl_set_sign(left,/*using*/sign_save);
+ Sgl_setwrapped_exponent(left,result_exponent,unfl);
+ *dstptr = left;
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ }
+ *dstptr = left;
+ return(NOEXCEPTION);
+ }
+
+ /* Neither are zeroes */
+ Sgl_clear_sign(right); /* Exponent is already cleared */
+ if(result_exponent == 0 )
+ {
+ /* Both operands are denormalized. The result must be exact
+ * and is simply calculated. A sum could become normalized and a
+ * difference could cancel to a true zero. */
+ if( (/*signed*/int) save >= 0 )
+ {
+ Sgl_subtract(left,/*minus*/right,/*into*/result);
+ if(Sgl_iszero_mantissa(result))
+ {
+ if(Is_rounding_mode(ROUNDMINUS))
+ {
+ Sgl_setone_sign(result);
+ }
+ else
+ {
+ Sgl_setzero_sign(result);
+ }
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ else
+ {
+ Sgl_addition(left,right,/*into*/result);
+ if(Sgl_isone_hidden(result))
+ {
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ }
+ if(Is_underflowtrap_enabled())
+ {
+ /* need to normalize result */
+ sign_save = Sgl_signextendedsign(result);
+ Sgl_leftshiftby1(result);
+ Sgl_normalize(result,result_exponent);
+ Sgl_set_sign(result,/*using*/sign_save);
+ Sgl_setwrapped_exponent(result,result_exponent,unfl);
+ *dstptr = result;
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ right_exponent = 1; /* Set exponent to reflect different bias
+ * with denomalized numbers. */
+ }
+ else
+ {
+ Sgl_clear_signexponent_set_hidden(right);
+ }
+ Sgl_clear_exponent_set_hidden(left);
+ diff_exponent = result_exponent - right_exponent;
+
+ /*
+ * Special case alignment of operands that would force alignment
+ * beyond the extent of the extension. A further optimization
+ * could special case this but only reduces the path length for this
+ * infrequent case.
+ */
+ if(diff_exponent > SGL_THRESHOLD)
+ {
+ diff_exponent = SGL_THRESHOLD;
+ }
+
+ /* Align right operand by shifting to right */
+ Sgl_right_align(/*operand*/right,/*shifted by*/diff_exponent,
+ /*and lower to*/extent);
+
+ /* Treat sum and difference of the operands separately. */
+ if( (/*signed*/int) save >= 0 )
+ {
+ /*
+ * Difference of the two operands. Their can be no overflow. A
+ * borrow can occur out of the hidden bit and force a post
+ * normalization phase.
+ */
+ Sgl_subtract_withextension(left,/*minus*/right,/*with*/extent,/*into*/result);
+ if(Sgl_iszero_hidden(result))
+ {
+ /* Handle normalization */
+ /* A straight foward algorithm would now shift the result
+ * and extension left until the hidden bit becomes one. Not
+ * all of the extension bits need participate in the shift.
+ * Only the two most significant bits (round and guard) are
+ * needed. If only a single shift is needed then the guard
+ * bit becomes a significant low order bit and the extension
+ * must participate in the rounding. If more than a single
+ * shift is needed, then all bits to the right of the guard
+ * bit are zeros, and the guard bit may or may not be zero. */
+ sign_save = Sgl_signextendedsign(result);
+ Sgl_leftshiftby1_withextent(result,extent,result);
+
+ /* Need to check for a zero result. The sign and exponent
+ * fields have already been zeroed. The more efficient test
+ * of the full object can be used.
+ */
+ if(Sgl_iszero(result))
+ /* Must have been "x-x" or "x+(-x)". */
+ {
+ if(Is_rounding_mode(ROUNDMINUS)) Sgl_setone_sign(result);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ result_exponent--;
+ /* Look to see if normalization is finished. */
+ if(Sgl_isone_hidden(result))
+ {
+ if(result_exponent==0)
+ {
+ /* Denormalized, exponent should be zero. Left operand *
+ * was normalized, so extent (guard, round) was zero */
+ goto underflow;
+ }
+ else
+ {
+ /* No further normalization is needed. */
+ Sgl_set_sign(result,/*using*/sign_save);
+ Ext_leftshiftby1(extent);
+ goto round;
+ }
+ }
+
+ /* Check for denormalized, exponent should be zero. Left *
+ * operand was normalized, so extent (guard, round) was zero */
+ if(!(underflowtrap = Is_underflowtrap_enabled()) &&
+ result_exponent==0) goto underflow;
+
+ /* Shift extension to complete one bit of normalization and
+ * update exponent. */
+ Ext_leftshiftby1(extent);
+
+ /* Discover first one bit to determine shift amount. Use a
+ * modified binary search. We have already shifted the result
+ * one position right and still not found a one so the remainder
+ * of the extension must be zero and simplifies rounding. */
+ /* Scan bytes */
+ while(Sgl_iszero_hiddenhigh7mantissa(result))
+ {
+ Sgl_leftshiftby8(result);
+ if((result_exponent -= 8) <= 0 && !underflowtrap)
+ goto underflow;
+ }
+ /* Now narrow it down to the nibble */
+ if(Sgl_iszero_hiddenhigh3mantissa(result))
+ {
+ /* The lower nibble contains the normalizing one */
+ Sgl_leftshiftby4(result);
+ if((result_exponent -= 4) <= 0 && !underflowtrap)
+ goto underflow;
+ }
+ /* Select case were first bit is set (already normalized)
+ * otherwise select the proper shift. */
+ if((jumpsize = Sgl_hiddenhigh3mantissa(result)) > 7)
+ {
+ /* Already normalized */
+ if(result_exponent <= 0) goto underflow;
+ Sgl_set_sign(result,/*using*/sign_save);
+ Sgl_set_exponent(result,/*using*/result_exponent);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ }
+ Sgl_sethigh4bits(result,/*using*/sign_save);
+ switch(jumpsize)
+ {
+ case 1:
+ {
+ Sgl_leftshiftby3(result);
+ result_exponent -= 3;
+ break;
+ }
+ case 2:
+ case 3:
+ {
+ Sgl_leftshiftby2(result);
+ result_exponent -= 2;
+ break;
+ }
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ {
+ Sgl_leftshiftby1(result);
+ result_exponent -= 1;
+ break;
+ }
+ }
+ if(result_exponent > 0)
+ {
+ Sgl_set_exponent(result,/*using*/result_exponent);
+ *dstptr = result; /* Sign bit is already set */
+ return(NOEXCEPTION);
+ }
+ /* Fixup potential underflows */
+ underflow:
+ if(Is_underflowtrap_enabled())
+ {
+ Sgl_set_sign(result,sign_save);
+ Sgl_setwrapped_exponent(result,result_exponent,unfl);
+ *dstptr = result;
+ /* inexact = FALSE */
+ return(UNDERFLOWEXCEPTION);
+ }
+ /*
+ * Since we cannot get an inexact denormalized result,
+ * we can now return.
+ */
+ Sgl_right_align(result,/*by*/(1-result_exponent),extent);
+ Sgl_clear_signexponent(result);
+ Sgl_set_sign(result,sign_save);
+ *dstptr = result;
+ return(NOEXCEPTION);
+ } /* end if(hidden...)... */
+ /* Fall through and round */
+ } /* end if(save >= 0)... */
+ else
+ {
+ /* Add magnitudes */
+ Sgl_addition(left,right,/*to*/result);
+ if(Sgl_isone_hiddenoverflow(result))
+ {
+ /* Prenormalization required. */
+ Sgl_rightshiftby1_withextent(result,extent,extent);
+ Sgl_arithrightshiftby1(result);
+ result_exponent++;
+ } /* end if hiddenoverflow... */
+ } /* end else ...sub magnitudes... */
+
+ /* Round the result. If the extension is all zeros,then the result is
+ * exact. Otherwise round in the correct direction. No underflow is
+ * possible. If a postnormalization is necessary, then the mantissa is
+ * all zeros so no shift is needed. */
+ round:
+ if(Ext_isnotzero(extent))
+ {
+ inexact = TRUE;
+ switch(Rounding_mode())
+ {
+ case ROUNDNEAREST: /* The default. */
+ if(Ext_isone_sign(extent))
+ {
+ /* at least 1/2 ulp */
+ if(Ext_isnotzero_lower(extent) ||
+ Sgl_isone_lowmantissa(result))
+ {
+ /* either exactly half way and odd or more than 1/2ulp */
+ Sgl_increment(result);
+ }
+ }
+ break;
+
+ case ROUNDPLUS:
+ if(Sgl_iszero_sign(result))
+ {
+ /* Round up positive results */
+ Sgl_increment(result);
+ }
+ break;
+
+ case ROUNDMINUS:
+ if(Sgl_isone_sign(result))
+ {
+ /* Round down negative results */
+ Sgl_increment(result);
+ }
+
+ case ROUNDZERO:;
+ /* truncate is simple */
+ } /* end switch... */
+ if(Sgl_isone_hiddenoverflow(result)) result_exponent++;
+ }
+ if(result_exponent == SGL_INFINITY_EXPONENT)
+ {
+ /* Overflow */
+ if(Is_overflowtrap_enabled())
+ {
+ Sgl_setwrapped_exponent(result,result_exponent,ovfl);
+ *dstptr = result;
+ if (inexact)
+ if (Is_inexacttrap_enabled())
+ return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(OVERFLOWEXCEPTION);
+ }
+ else
+ {
+ Set_overflowflag();
+ inexact = TRUE;
+ Sgl_setoverflow(result);
+ }
+ }
+ else Sgl_set_exponent(result,result_exponent);
+ *dstptr = result;
+ if(inexact)
+ if(Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
+ else Set_inexactflag();
+ return(NOEXCEPTION);
+ }
diff --git a/sys/arch/hppa/spmath/sgl_float.h b/sys/arch/hppa/spmath/sgl_float.h
new file mode 100644
index 00000000000..ae2a2f36acf
--- /dev/null
+++ b/sys/arch/hppa/spmath/sgl_float.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * pmk1.1
+ */
+/*
+ * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+/*
+ * @(#)sgl_float.h: $Revision: 1.1 $ $Date: 1998/06/23 20:34:09 $
+ * $Locker: $
+ *
+ */
+/******************************
+ * Single precision functions *
+ ******************************/
+
+/* 32-bit word grabing functions */
+#define Sgl_firstword(value) Sall(value)
+#define Sgl_secondword(value) dummy_location
+#define Sgl_thirdword(value) dummy_location
+#define Sgl_fourthword(value) dummy_location
+
+#define Sgl_sign(object) Ssign(object)
+#define Sgl_exponent(object) Sexponent(object)
+#define Sgl_signexponent(object) Ssignexponent(object)
+#define Sgl_mantissa(object) Smantissa(object)
+#define Sgl_exponentmantissa(object) Sexponentmantissa(object)
+#define Sgl_all(object) Sall(object)
+
+/* sgl_and_signs ands the sign bits of each argument and puts the result
+ * into the first argument. sgl_or_signs ors those same sign bits */
+#define Sgl_and_signs( src1dst, src2) \
+ Sall(src1dst) = (Sall(src2)|~(1<<31)) & Sall(src1dst)
+#define Sgl_or_signs( src1dst, src2) \
+ Sall(src1dst) = (Sall(src2)&(1<<31)) | Sall(src1dst)
+
+/* The hidden bit is always the low bit of the exponent */
+#define Sgl_clear_exponent_set_hidden(srcdst) Deposit_sexponent(srcdst,1)
+#define Sgl_clear_signexponent_set_hidden(srcdst) \
+ Deposit_ssignexponent(srcdst,1)
+#define Sgl_clear_sign(srcdst) Sall(srcdst) &= ~(1<<31)
+#define Sgl_clear_signexponent(srcdst) Sall(srcdst) &= 0x007fffff
+
+/* varamount must be less than 32 for the next three functions */
+#define Sgl_rightshift(srcdst, varamount) \
+ Sall(srcdst) >>= varamount
+#define Sgl_leftshift(srcdst, varamount) \
+ Sall(srcdst) <<= varamount
+#define Sgl_rightshift_exponentmantissa(srcdst, varamount) \
+ Sall(srcdst) = \
+ (Sexponentmantissa(srcdst) >> varamount) | (Sall(srcdst) & (1<<31))
+
+#define Sgl_leftshiftby1_withextent(left,right,result) \
+ Shiftdouble(Sall(left),Extall(right),31,Sall(result))
+
+#define Sgl_rightshiftby1_withextent(left,right,dst) \
+ Shiftdouble(Sall(left),Extall(right),1,Extall(right))
+#define Sgl_arithrightshiftby1(srcdst) \
+ Sall(srcdst) = (int)Sall(srcdst) >> 1
+
+/* Sign extend the sign bit with an integer destination */
+#define Sgl_signextendedsign(value) Ssignedsign(value)
+
+#define Sgl_isone_hidden(sgl_value) (Shidden(sgl_value))
+#define Sgl_increment(sgl_value) Sall(sgl_value) += 1
+#define Sgl_increment_mantissa(sgl_value) \
+ Deposit_smantissa(sgl_value,sgl_value+1)
+#define Sgl_decrement(sgl_value) Sall(sgl_value) -= 1
+
+#define Sgl_isone_sign(sgl_value) (Is_ssign(sgl_value)!=0)
+#define Sgl_isone_hiddenoverflow(sgl_value) \
+ (Is_shiddenoverflow(sgl_value)!=0)
+#define Sgl_isone_lowmantissa(sgl_value) (Is_slow(sgl_value)!=0)
+#define Sgl_isone_signaling(sgl_value) (Is_ssignaling(sgl_value)!=0)
+#define Sgl_is_signalingnan(sgl_value) (Ssignalingnan(sgl_value)==0x1ff)
+#define Sgl_isnotzero(sgl_value) (Sall(sgl_value)!=0)
+#define Sgl_isnotzero_hiddenhigh7mantissa(sgl_value) \
+ (Shiddenhigh7mantissa(sgl_value)!=0)
+#define Sgl_isnotzero_low4(sgl_value) (Slow4(sgl_value)!=0)
+#define Sgl_isnotzero_exponent(sgl_value) (Sexponent(sgl_value)!=0)
+#define Sgl_isnotzero_mantissa(sgl_value) (Smantissa(sgl_value)!=0)
+#define Sgl_isnotzero_exponentmantissa(sgl_value) \
+ (Sexponentmantissa(sgl_value)!=0)
+#define Sgl_iszero(sgl_value) (Sall(sgl_value)==0)
+#define Sgl_iszero_signaling(sgl_value) (Is_ssignaling(sgl_value)==0)
+#define Sgl_iszero_hidden(sgl_value) (Is_shidden(sgl_value)==0)
+#define Sgl_iszero_hiddenoverflow(sgl_value) \
+ (Is_shiddenoverflow(sgl_value)==0)
+#define Sgl_iszero_hiddenhigh3mantissa(sgl_value) \
+ (Shiddenhigh3mantissa(sgl_value)==0)
+#define Sgl_iszero_hiddenhigh7mantissa(sgl_value) \
+ (Shiddenhigh7mantissa(sgl_value)==0)
+#define Sgl_iszero_sign(sgl_value) (Is_ssign(sgl_value)==0)
+#define Sgl_iszero_exponent(sgl_value) (Sexponent(sgl_value)==0)
+#define Sgl_iszero_mantissa(sgl_value) (Smantissa(sgl_value)==0)
+#define Sgl_iszero_exponentmantissa(sgl_value) \
+ (Sexponentmantissa(sgl_value)==0)
+#define Sgl_isinfinity_exponent(sgl_value) \
+ (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT)
+#define Sgl_isnotinfinity_exponent(sgl_value) \
+ (Sgl_exponent(sgl_value)!=SGL_INFINITY_EXPONENT)
+#define Sgl_isinfinity(sgl_value) \
+ (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT && \
+ Sgl_mantissa(sgl_value)==0)
+#define Sgl_isnan(sgl_value) \
+ (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT && \
+ Sgl_mantissa(sgl_value)!=0)
+#define Sgl_isnotnan(sgl_value) \
+ (Sgl_exponent(sgl_value)!=SGL_INFINITY_EXPONENT || \
+ Sgl_mantissa(sgl_value)==0)
+#define Sgl_islessthan(sgl_op1,sgl_op2) \
+ (Sall(sgl_op1) < Sall(sgl_op2))
+#define Sgl_isgreaterthan(sgl_op1,sgl_op2) \
+ (Sall(sgl_op1) > Sall(sgl_op2))
+#define Sgl_isnotlessthan(sgl_op1,sgl_op2) \
+ (Sall(sgl_op1) >= Sall(sgl_op2))
+#define Sgl_isequal(sgl_op1,sgl_op2) \
+ (Sall(sgl_op1) == Sall(sgl_op2))
+
+#define Sgl_leftshiftby8(sgl_value) \
+ Sall(sgl_value) <<= 8
+#define Sgl_leftshiftby4(sgl_value) \
+ Sall(sgl_value) <<= 4
+#define Sgl_leftshiftby3(sgl_value) \
+ Sall(sgl_value) <<= 3
+#define Sgl_leftshiftby2(sgl_value) \
+ Sall(sgl_value) <<= 2
+#define Sgl_leftshiftby1(sgl_value) \
+ Sall(sgl_value) <<= 1
+#define Sgl_rightshiftby1(sgl_value) \
+ Sall(sgl_value) >>= 1
+#define Sgl_rightshiftby4(sgl_value) \
+ Sall(sgl_value) >>= 4
+#define Sgl_rightshiftby8(sgl_value) \
+ Sall(sgl_value) >>= 8
+
+#define Sgl_ismagnitudeless(signlessleft,signlessright) \
+/* unsigned int signlessleft, signlessright; */ \
+ (signlessleft < signlessright)
+
+
+#define Sgl_copytoint_exponentmantissa(source,dest) \
+ dest = Sexponentmantissa(source)
+
+/* A quiet NaN has the high mantissa bit clear and at least on other (in this
+ * case the adjacent bit) bit set. */
+#define Sgl_set_quiet(sgl_value) Deposit_shigh2mantissa(sgl_value,1)
+#define Sgl_set_exponent(sgl_value,exp) Deposit_sexponent(sgl_value,exp)
+
+#define Sgl_set_mantissa(dest,value) Deposit_smantissa(dest,value)
+#define Sgl_set_exponentmantissa(dest,value) \
+ Deposit_sexponentmantissa(dest,value)
+
+/* An infinity is represented with the max exponent and a zero mantissa */
+#define Sgl_setinfinity_exponent(sgl_value) \
+ Deposit_sexponent(sgl_value,SGL_INFINITY_EXPONENT)
+#define Sgl_setinfinity_exponentmantissa(sgl_value) \
+ Deposit_sexponentmantissa(sgl_value, \
+ (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))))
+#define Sgl_setinfinitypositive(sgl_value) \
+ Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH)))
+#define Sgl_setinfinitynegative(sgl_value) \
+ Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) \
+ | (1<<31)
+#define Sgl_setinfinity(sgl_value,sign) \
+ Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) | \
+ (sign << 31)
+#define Sgl_sethigh4bits(sgl_value, extsign) \
+ Deposit_shigh4(sgl_value,extsign)
+#define Sgl_set_sign(sgl_value,sign) Deposit_ssign(sgl_value,sign)
+#define Sgl_invert_sign(sgl_value) \
+ Deposit_ssign(sgl_value,~Ssign(sgl_value))
+#define Sgl_setone_sign(sgl_value) Deposit_ssign(sgl_value,1)
+#define Sgl_setone_lowmantissa(sgl_value) Deposit_slow(sgl_value,1)
+#define Sgl_setzero_sign(sgl_value) Sall(sgl_value) &= 0x7fffffff
+#define Sgl_setzero_exponent(sgl_value) Sall(sgl_value) &= 0x807fffff
+#define Sgl_setzero_mantissa(sgl_value) Sall(sgl_value) &= 0xff800000
+#define Sgl_setzero_exponentmantissa(sgl_value) Sall(sgl_value) &= 0x80000000
+#define Sgl_setzero(sgl_value) Sall(sgl_value) = 0
+#define Sgl_setnegativezero(sgl_value) Sall(sgl_value) = 1 << 31
+
+/* Use following macro for both overflow & underflow conditions */
+#define ovfl -
+#define unfl +
+#define Sgl_setwrapped_exponent(sgl_value,exponent,op) \
+ Deposit_sexponent(sgl_value,(exponent op SGL_WRAP))
+
+#define Sgl_setlargestpositive(sgl_value) \
+ Sall(sgl_value) = ((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH))) \
+ | ((1<<(32-(1+SGL_EXP_LENGTH))) - 1 )
+#define Sgl_setlargestnegative(sgl_value) \
+ Sall(sgl_value) = ((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH))) \
+ | ((1<<(32-(1+SGL_EXP_LENGTH))) - 1 ) | (1<<31)
+
+#define Sgl_setnegativeinfinity(sgl_value) \
+ Sall(sgl_value) = \
+ ((1<<SGL_EXP_LENGTH) | SGL_INFINITY_EXPONENT) << (32-(1+SGL_EXP_LENGTH))
+#define Sgl_setlargest(sgl_value,sign) \
+ Sall(sgl_value) = sign << 31 | \
+ (((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH))) \
+ | ((1 << (32-(1+SGL_EXP_LENGTH))) - 1 ))
+#define Sgl_setlargest_exponentmantissa(sgl_value) \
+ Sall(sgl_value) = Sall(sgl_value) & (1<<31) | \
+ (((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH))) \
+ | ((1 << (32-(1+SGL_EXP_LENGTH))) - 1 ))
+
+/* The high bit is always zero so arithmetic or logical shifts will work. */
+#define Sgl_right_align(srcdst,shift,extent) \
+ /* sgl_floating_point srcdst; int shift; extension extent */ \
+ if (shift < 32) { \
+ Extall(extent) = Sall(srcdst) << (32-(shift)); \
+ Sall(srcdst) >>= shift; \
+ } \
+ else { \
+ Extall(extent) = Sall(srcdst); \
+ Sall(srcdst) = 0; \
+ }
+#define Sgl_hiddenhigh3mantissa(sgl_value) Shiddenhigh3mantissa(sgl_value)
+#define Sgl_hidden(sgl_value) Shidden(sgl_value)
+#define Sgl_lowmantissa(sgl_value) Slow(sgl_value)
+
+/* The left argument is never smaller than the right argument */
+#define Sgl_subtract(sgl_left,sgl_right,sgl_result) \
+ Sall(sgl_result) = Sall(sgl_left) - Sall(sgl_right)
+
+/* Subtract right augmented with extension from left augmented with zeros and
+ * store into result and extension. */
+#define Sgl_subtract_withextension(left,right,extent,result) \
+ /* sgl_floating_point left,right,result; extension extent */ \
+ Sgl_subtract(left,right,result); \
+ if((Extall(extent) = 0-Extall(extent))) \
+ Sall(result) = Sall(result)-1
+
+#define Sgl_addition(sgl_left,sgl_right,sgl_result) \
+ Sall(sgl_result) = Sall(sgl_left) + Sall(sgl_right)
+
+#define Sgl_xortointp1(left,right,result) \
+ result = Sall(left) XOR Sall(right);
+
+#define Sgl_xorfromintp1(left,right,result) \
+ Sall(result) = left XOR Sall(right)
+
+/* Need to Initialize */
+#define Sgl_makequietnan(dest) \
+ Sall(dest) = ((SGL_EMAX+SGL_BIAS)+1)<< (32-(1+SGL_EXP_LENGTH)) \
+ | (1<<(32-(1+SGL_EXP_LENGTH+2)))
+#define Sgl_makesignalingnan(dest) \
+ Sall(dest) = ((SGL_EMAX+SGL_BIAS)+1)<< (32-(1+SGL_EXP_LENGTH)) \
+ | (1<<(32-(1+SGL_EXP_LENGTH+1)))
+
+#define Sgl_normalize(sgl_opnd,exponent) \
+ while(Sgl_iszero_hiddenhigh7mantissa(sgl_opnd)) { \
+ Sgl_leftshiftby8(sgl_opnd); \
+ exponent -= 8; \
+ } \
+ if(Sgl_iszero_hiddenhigh3mantissa(sgl_opnd)) { \
+ Sgl_leftshiftby4(sgl_opnd); \
+ exponent -= 4; \
+ } \
+ while(Sgl_iszero_hidden(sgl_opnd)) { \
+ Sgl_leftshiftby1(sgl_opnd); \
+ exponent -= 1; \
+ }
+
+#define Sgl_setoverflow(sgl_opnd) \
+ /* set result to infinity or largest number */ \
+ switch (Rounding_mode()) { \
+ case ROUNDPLUS: \
+ if (Sgl_isone_sign(sgl_opnd)) { \
+ Sgl_setlargestnegative(sgl_opnd); \
+ } \
+ else { \
+ Sgl_setinfinitypositive(sgl_opnd); \
+ } \
+ break; \
+ case ROUNDMINUS: \
+ if (Sgl_iszero_sign(sgl_opnd)) { \
+ Sgl_setlargestpositive(sgl_opnd); \
+ } \
+ else { \
+ Sgl_setinfinitynegative(sgl_opnd); \
+ } \
+ break; \
+ case ROUNDNEAREST: \
+ Sgl_setinfinity_exponentmantissa(sgl_opnd); \
+ break; \
+ case ROUNDZERO: \
+ Sgl_setlargest_exponentmantissa(sgl_opnd); \
+ }
+
+#define Sgl_denormalize(opnd,exponent,guard,sticky,inexact) \
+ Sgl_clear_signexponent_set_hidden(opnd); \
+ if (exponent >= (1 - SGL_P)) { \
+ guard = (Sall(opnd) >> -exponent) & 1; \
+ if (exponent < 0) sticky |= Sall(opnd) << (32+exponent); \
+ inexact = guard | sticky; \
+ Sall(opnd) >>= (1-exponent); \
+ } \
+ else { \
+ guard = 0; \
+ sticky |= Sall(opnd); \
+ inexact = sticky; \
+ Sgl_setzero(opnd); \
+ }