]> err.no Git - linux-2.6/blobdiff - arch/arm/nwfpe/fpa11_cpdt.c
Merge HEAD from master.kernel.org:/home/rmk/linux-2.6-ucb.git
[linux-2.6] / arch / arm / nwfpe / fpa11_cpdt.c
index 95fb63fa9d181238423e6c5202c7ca3d57844a70..b0db5cbcc3b190575774991ff759d1590461a7d2 100644 (file)
@@ -96,7 +96,7 @@ static inline void loadMultiple(const unsigned int Fn, const unsigned int __user
        }
 }
 
-static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
+static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        union {
@@ -106,12 +106,12 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
 
        switch (fpa11->fType[Fn]) {
        case typeDouble:
-               val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble);
+               val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble);
                break;
 
 #ifdef CONFIG_FPE_NWFPE_XP
        case typeExtended:
-               val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
+               val.f = floatx80_to_float32(roundData, fpa11->fpreg[Fn].fExtended);
                break;
 #endif
 
@@ -122,7 +122,7 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
        put_user(val.i[0], pMem);
 }
 
-static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
+static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        union {
@@ -137,7 +137,7 @@ static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
 
 #ifdef CONFIG_FPE_NWFPE_XP
        case typeExtended:
-               val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
+               val.f = floatx80_to_float64(roundData, fpa11->fpreg[Fn].fExtended);
                break;
 #endif
 
@@ -259,8 +259,11 @@ unsigned int PerformSTF(const unsigned int opcode)
 {
        unsigned int __user *pBase, *pAddress, *pFinal;
        unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
+       struct roundingData roundData;
 
-       SetRoundingMode(ROUND_TO_NEAREST);
+       roundData.mode = SetRoundingMode(opcode);
+       roundData.precision = SetRoundingPrecision(opcode);
+       roundData.exception = 0;
 
        pBase = (unsigned int __user *) readRegister(getRn(opcode));
        if (REG_PC == getRn(opcode)) {
@@ -281,10 +284,10 @@ unsigned int PerformSTF(const unsigned int opcode)
 
        switch (opcode & MASK_TRANSFER_LENGTH) {
        case TRANSFER_SINGLE:
-               storeSingle(getFd(opcode), pAddress);
+               storeSingle(&roundData, getFd(opcode), pAddress);
                break;
        case TRANSFER_DOUBLE:
-               storeDouble(getFd(opcode), pAddress);
+               storeDouble(&roundData, getFd(opcode), pAddress);
                break;
 #ifdef CONFIG_FPE_NWFPE_XP
        case TRANSFER_EXTENDED:
@@ -295,6 +298,9 @@ unsigned int PerformSTF(const unsigned int opcode)
                nRc = 0;
        }
 
+       if (roundData.exception)
+               float_raise(roundData.exception);
+
        if (write_back)
                writeRegister(getRn(opcode), (unsigned long) pFinal);
        return nRc;