summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-12-26 18:27:44 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-12-26 18:27:44 +0000
commitc778ad83bcbeec8aeb86c78df8360534a26ccc8c (patch)
tree39f7e7cc45fd9c641753f7004d4d3ba7359ff725 /sys/arch
parent67bdfec6cec309abdc6396a543053b309ae1fb58 (diff)
First try at getting the interval bits filled in fcmp{,u} results.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/m88k/fpu/fpu_compare.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/sys/arch/m88k/fpu/fpu_compare.c b/sys/arch/m88k/fpu/fpu_compare.c
index 16472c79de5..3d539dfe48e 100644
--- a/sys/arch/m88k/fpu/fpu_compare.c
+++ b/sys/arch/m88k/fpu/fpu_compare.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fpu_compare.c,v 1.2 2007/12/25 15:47:16 miod Exp $ */
+/* $OpenBSD: fpu_compare.c,v 1.3 2007/12/26 18:27:43 miod Exp $ */
/*
* Copyright (c) 2007 Miodrag Vallat.
@@ -180,12 +180,12 @@ done:
/*
* Complete condition code mask.
- * XXX Range bits (ob, in, ib and ou) are not handled yet.
*/
+
if (cc & CC_UN)
cc |= CC_UE | CC_UG | CC_ULE | CC_UL | CC_UGE;
if (cc & CC_EQ)
- cc |= CC_LE | CC_GE | CC_IB | CC_OB | CC_UE;
+ cc |= CC_LE | CC_GE | CC_UE;
if (cc & CC_GT)
cc |= CC_GE;
if (cc & CC_LT)
@@ -203,5 +203,41 @@ done:
if (cc & CC_GE)
cc |= CC_UGE;
+ /*
+ * Fill the interval bits.
+ * s1 (here `a') is compared to the interval [0, s2 (here `b')].
+ */
+ if (!(cc & CC_UN)) {
+ /* s1 and s2 are either Zero, numbers or Inf */
+ if (ISZERO(a) || (cc & CC_EQ)) {
+ /* if s1 and s2 are equal, s1 is on boundary */
+ cc |= CC_IB | CC_OB;
+ } else if (b->fp_sign == 0) {
+ /* s2 is positive, the interval is [0, s2] */
+ if (cc & CC_GT) {
+ /* 0 <= s2 < s1 -> out of interval */
+ cc |= CC_OU | CC_OB;
+ } else if (a->fp_sign == 0) {
+ /* 0 < s1 < s2 -> in interval */
+ cc |= CC_IB | CC_IN;
+ } else {
+ /* s1 < 0 <= s2 */
+ cc |= CC_OU | CC_OB;
+ }
+ } else {
+ /* s2 is negative, the interval is [s2, 0] */
+ if (cc & CC_LT) {
+ /* s1 < s2 <= 0 */
+ cc |= CC_OU | CC_OB;
+ } else if (a->fp_sign != 0) {
+ /* s2 < s1 < 0 */
+ cc |= CC_IB | CC_IN;
+ } else {
+ /* s2 < 0 < s1 */
+ cc |= CC_OU | CC_OB;
+ }
+ }
+ }
+
return (cc);
}