aboutsummaryrefslogtreecommitdiff
path: root/fpu
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2011-01-06 15:38:19 +0100
committerAurelien Jarno <aurelien@aurel32.net>2011-01-06 16:29:35 +0100
commit084d19ba718a08d434dc44a83ff01f3152d59635 (patch)
treea917d081620e4057226535264393e19ca01765bb /fpu
parent1f398e0825b3365746ac3a3f6f5a9954b0064f28 (diff)
target-mips: Implement correct NaN propagation rules
Implement the correct NaN propagation rules for MIPS targets by providing an appropriate pickNaN function. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'fpu')
-rw-r--r--fpu/softfloat-specialize.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 3ce5bb53bf..acdd299f51 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -192,6 +192,33 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
return 1;
}
}
+#elif defined(TARGET_MIPS)
+static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
+ flag aIsLargerSignificand)
+{
+ /* According to MIPS specifications, if one of the two operands is
+ * a sNaN, a new qNaN has to be generated. This is done in
+ * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
+ * says: "When possible, this QNaN result is one of the operand QNaN
+ * values." In practice it seems that most implementations choose
+ * the first operand if both operands are qNaN. In short this gives
+ * the following rules:
+ * 1. A if it is signaling
+ * 2. B if it is signaling
+ * 3. A (quiet)
+ * 4. B (quiet)
+ * A signaling NaN is always silenced before returning it.
+ */
+ if (aIsSNaN) {
+ return 0;
+ } else if (bIsSNaN) {
+ return 1;
+ } else if (aIsQNaN) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
#else
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
flag aIsLargerSignificand)