|
@@ -306,3 +306,68 @@ static unsigned int PerformComparison(const unsigned int opcode)
|
|
/* test for less than condition */
|
|
/* test for less than condition */
|
|
if (float32_lt_nocheck(rFn, rFm))
|
|
if (float32_lt_nocheck(rFn, rFm))
|
|
flags |= CC_NEGATIVE;
|
|
flags |= CC_NEGATIVE;
|
|
|
|
+
|
|
|
|
+ /* test for equal condition */
|
|
|
|
+ if (float32_eq_nocheck(rFn, rFm))
|
|
|
|
+ flags |= CC_ZERO;
|
|
|
|
+
|
|
|
|
+ /* test for greater than or equal condition */
|
|
|
|
+ if (float32_lt_nocheck(rFm, rFn))
|
|
|
|
+ flags |= CC_CARRY;
|
|
|
|
+ } else {
|
|
|
|
+ /* Promote 32-bit operand to 64 bits. */
|
|
|
|
+ float64 rFm, rFn;
|
|
|
|
+
|
|
|
|
+ rFm = (fpa11->fType[Fm] == typeSingle) ?
|
|
|
|
+ float32_to_float64(fpa11->fpreg[Fm].fSingle)
|
|
|
|
+ : fpa11->fpreg[Fm].fDouble;
|
|
|
|
+
|
|
|
|
+ rFn = (fpa11->fType[Fn] == typeSingle) ?
|
|
|
|
+ float32_to_float64(fpa11->fpreg[Fn].fSingle)
|
|
|
|
+ : fpa11->fpreg[Fn].fDouble;
|
|
|
|
+
|
|
|
|
+ if (float64_is_nan(rFn)
|
|
|
|
+ || float64_is_nan(rFm))
|
|
|
|
+ goto unordered;
|
|
|
|
+
|
|
|
|
+ if (n_flag)
|
|
|
|
+ rFm ^= 0x8000000000000000ULL;
|
|
|
|
+
|
|
|
|
+ /* test for less than condition */
|
|
|
|
+ if (float64_lt_nocheck(rFn, rFm))
|
|
|
|
+ flags |= CC_NEGATIVE;
|
|
|
|
+
|
|
|
|
+ /* test for equal condition */
|
|
|
|
+ if (float64_eq_nocheck(rFn, rFm))
|
|
|
|
+ flags |= CC_ZERO;
|
|
|
|
+
|
|
|
|
+ /* test for greater than or equal condition */
|
|
|
|
+ if (float64_lt_nocheck(rFm, rFn))
|
|
|
|
+ flags |= CC_CARRY;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ writeConditionCodes(flags);
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ unordered:
|
|
|
|
+ /* ?? The FPA data sheet is pretty vague about this, in particular
|
|
|
|
+ about whether the non-E comparisons can ever raise exceptions.
|
|
|
|
+ This implementation is based on a combination of what it says in
|
|
|
|
+ the data sheet, observation of how the Acorn emulator actually
|
|
|
|
+ behaves (and how programs expect it to) and guesswork. */
|
|
|
|
+ flags |= CC_OVERFLOW;
|
|
|
|
+ flags &= ~(CC_ZERO | CC_NEGATIVE);
|
|
|
|
+
|
|
|
|
+ if (BIT_AC & readFPSR())
|
|
|
|
+ flags |= CC_CARRY;
|
|
|
|
+
|
|
|
|
+ if (e_flag)
|
|
|
|
+ float_raise(float_flag_invalid);
|
|
|
|
+
|
|
|
|
+ writeConditionCodes(flags);
|
|
|
|
+ return 1;
|
|
|
|
+}
|