summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMartynas Venckus <martynas@cvs.openbsd.org>2008-10-07 22:06:30 +0000
committerMartynas Venckus <martynas@cvs.openbsd.org>2008-10-07 22:06:30 +0000
commit13e274e30a2f3dce36a95d6cc01a2265a620eb19 (patch)
tree0eb7c8b8911c16c7d7ea19554846a1838def0749 /sys/arch
parent42029dea90615aabb34095ab75e07c870aed697e (diff)
unbreak ieeefp emulation code wrt converting double to unsigned
long ints for alpha. we've got only one instruction (cvttq) to convert double-t to quadword, and float64_to_int64 did not take into account the unsigned conversions therefore, overflow always occured, and half of the unsigned range (LONG_MAX .. ULONG_MAX) was broken introduce roundAndPackInt64NoOverflow and float64_to_int64_no_overflow for softfloat, that works with unsigned integers as well. note that this will return zero for nan/inf/oflow/uflow, raising exception flag perl is happy now looked over by miod@ tested by naddy@, and by me on nick@'s alpha
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/alpha/alpha/fp_complete.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/arch/alpha/alpha/fp_complete.c b/sys/arch/alpha/alpha/fp_complete.c
index 112f77af432..ee94b2da568 100644
--- a/sys/arch/alpha/alpha/fp_complete.c
+++ b/sys/arch/alpha/alpha/fp_complete.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fp_complete.c,v 1.7 2006/02/25 03:58:56 deraadt Exp $ */
+/* $OpenBSD: fp_complete.c,v 1.8 2008/10/07 22:06:29 martynas Exp $ */
/* $NetBSD: fp_complete.c,v 1.5 2002/01/18 22:15:56 ross Exp $ */
/*-
@@ -310,6 +310,10 @@ cvt_qt_dg_qg(u_int32_t inst_bits, struct proc *p)
* unfortunate habit of always returning the nontrapping result.
* XXX: there are several apparent AARM/AAH disagreements, as well as
* the issue of trap handler pc and trapping results.
+ * XXX: this function will work for signed and unsigned 64-bit integers.
+ * rounding will happen per IEEE 754. invalid exception will be
+ * raised if argument is infinity, not-a-number or if it
+ * overflows/underflows. zero will be returned, in this case.
*/
static void
cvt_tq_gq(u_int32_t inst_bits, struct proc *p)
@@ -319,7 +323,7 @@ cvt_tq_gq(u_int32_t inst_bits, struct proc *p)
inst.bits = inst_bits;
stt(inst.float_detail.fb, &tfb, p);
- tfc.i = float64_to_int64(tfb.i);
+ tfc.i = float64_to_int64_no_overflow(tfb.i);
alpha_ldt(inst.float_detail.fc, &tfc); /* yes, ldt */
}