Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / arm / nwfpe / fpa11_cprt.c
index db01fbc..7c67023 100644 (file)
 #include "fpa11.inl"
 #include "fpmodule.h"
 #include "fpmodule.inl"
+#include "softfloat.h"
 
 #ifdef CONFIG_FPE_NWFPE_XP
 extern flag floatx80_is_nan(floatx80);
 #endif
-extern flag float64_is_nan(float64);
-extern flag float32_is_nan(float32);
-
-void SetRoundingMode(const unsigned int opcode);
 
 unsigned int PerformFLT(const unsigned int opcode);
 unsigned int PerformFIX(const unsigned int opcode);
@@ -77,14 +74,17 @@ unsigned int EmulateCPRT(const unsigned int opcode)
 unsigned int PerformFLT(const unsigned int opcode)
 {
        FPA11 *fpa11 = GET_FPA11();
-       SetRoundingMode(opcode);
-       SetRoundingPrecision(opcode);
+       struct roundingData roundData;
+
+       roundData.mode = SetRoundingMode(opcode);
+       roundData.precision = SetRoundingPrecision(opcode);
+       roundData.exception = 0;
 
        switch (opcode & MASK_ROUNDING_PRECISION) {
        case ROUND_SINGLE:
                {
                        fpa11->fType[getFn(opcode)] = typeSingle;
-                       fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode)));
+                       fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(&roundData, readRegister(getRd(opcode)));
                }
                break;
 
@@ -108,6 +108,9 @@ unsigned int PerformFLT(const unsigned int opcode)
                return 0;
        }
 
+       if (roundData.exception)
+               float_raise(roundData.exception);
+
        return 1;
 }
 
@@ -115,26 +118,29 @@ unsigned int PerformFIX(const unsigned int opcode)
 {
        FPA11 *fpa11 = GET_FPA11();
        unsigned int Fn = getFm(opcode);
+       struct roundingData roundData;
 
-       SetRoundingMode(opcode);
+       roundData.mode = SetRoundingMode(opcode);
+       roundData.precision = SetRoundingPrecision(opcode);
+       roundData.exception = 0;
 
        switch (fpa11->fType[Fn]) {
        case typeSingle:
                {
-                       writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle));
+                       writeRegister(getRd(opcode), float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle));
                }
                break;
 
        case typeDouble:
                {
-                       writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble));
+                       writeRegister(getRd(opcode), float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble));
                }
                break;
 
 #ifdef CONFIG_FPE_NWFPE_XP
        case typeExtended:
                {
-                       writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
+                       writeRegister(getRd(opcode), floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended));
                }
                break;
 #endif
@@ -143,6 +149,9 @@ unsigned int PerformFIX(const unsigned int opcode)
                return 0;
        }
 
+       if (roundData.exception)
+               float_raise(roundData.exception);
+
        return 1;
 }