fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / arm / nwfpe / fpa11_cpdt.c
index 59e3197..79f8e67 100644 (file)
@@ -20,7 +20,6 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <linux/config.h>
 #include "fpa11.h"
 #include "softfloat.h"
 #include "fpopcode.h"
 
 #include <asm/uaccess.h>
 
-static inline void loadSingle(const unsigned int Fn, const unsigned int *pMem)
+static inline void loadSingle(const unsigned int Fn, const unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        fpa11->fType[Fn] = typeSingle;
        get_user(fpa11->fpreg[Fn].fSingle, pMem);
 }
 
-static inline void loadDouble(const unsigned int Fn, const unsigned int *pMem)
+static inline void loadDouble(const unsigned int Fn, const unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        unsigned int *p;
        p = (unsigned int *) &fpa11->fpreg[Fn].fDouble;
        fpa11->fType[Fn] = typeDouble;
+#ifdef __ARMEB__
+       get_user(p[0], &pMem[0]);       /* sign & exponent */
+       get_user(p[1], &pMem[1]);
+#else
        get_user(p[0], &pMem[1]);
        get_user(p[1], &pMem[0]);       /* sign & exponent */
+#endif
 }
 
 #ifdef CONFIG_FPE_NWFPE_XP
-static inline void loadExtended(const unsigned int Fn, const unsigned int *pMem)
+static inline void loadExtended(const unsigned int Fn, const unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        unsigned int *p;
        p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
        fpa11->fType[Fn] = typeExtended;
        get_user(p[0], &pMem[0]);       /* sign & exponent */
+#ifdef __ARMEB__
+       get_user(p[1], &pMem[1]);       /* ms bits */
+       get_user(p[2], &pMem[2]);       /* ls bits */
+#else
        get_user(p[1], &pMem[2]);       /* ls bits */
        get_user(p[2], &pMem[1]);       /* ms bits */
+#endif
 }
 #endif
 
-static inline void loadMultiple(const unsigned int Fn, const unsigned int *pMem)
+static inline void loadMultiple(const unsigned int Fn, const unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        register unsigned int *p;
@@ -91,7 +100,7 @@ static inline void loadMultiple(const unsigned int Fn, const unsigned int *pMem)
        }
 }
 
-static inline void storeSingle(const unsigned int Fn, unsigned int *pMem)
+static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        union {
@@ -101,12 +110,12 @@ static inline void storeSingle(const unsigned int Fn, unsigned int *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
 
@@ -117,7 +126,7 @@ static inline void storeSingle(const unsigned int Fn, unsigned int *pMem)
        put_user(val.i[0], pMem);
 }
 
-static inline void storeDouble(const unsigned int Fn, unsigned int *pMem)
+static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        union {
@@ -132,7 +141,7 @@ static inline void storeDouble(const unsigned int Fn, unsigned int *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
 
@@ -140,12 +149,17 @@ static inline void storeDouble(const unsigned int Fn, unsigned int *pMem)
                val.f = fpa11->fpreg[Fn].fDouble;
        }
 
+#ifdef __ARMEB__
+       put_user(val.i[0], &pMem[0]);   /* msw */
+       put_user(val.i[1], &pMem[1]);   /* lsw */
+#else
        put_user(val.i[1], &pMem[0]);   /* msw */
        put_user(val.i[0], &pMem[1]);   /* lsw */
+#endif
 }
 
 #ifdef CONFIG_FPE_NWFPE_XP
-static inline void storeExtended(const unsigned int Fn, unsigned int *pMem)
+static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        union {
@@ -167,12 +181,17 @@ static inline void storeExtended(const unsigned int Fn, unsigned int *pMem)
        }
 
        put_user(val.i[0], &pMem[0]);   /* sign & exp */
+#ifdef __ARMEB__
+       put_user(val.i[1], &pMem[1]);   /* msw */
+       put_user(val.i[2], &pMem[2]);
+#else
        put_user(val.i[1], &pMem[2]);
        put_user(val.i[2], &pMem[1]);   /* msw */
+#endif
 }
 #endif
 
-static inline void storeMultiple(const unsigned int Fn, unsigned int *pMem)
+static inline void storeMultiple(const unsigned int Fn, unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        register unsigned int nType, *p;
@@ -204,10 +223,10 @@ static inline void storeMultiple(const unsigned int Fn, unsigned int *pMem)
 
 unsigned int PerformLDF(const unsigned int opcode)
 {
-       unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
-           write_back = WRITE_BACK(opcode);
+       unsigned int __user *pBase, *pAddress, *pFinal;
+       unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
 
-       pBase = (unsigned int *) readRegister(getRn(opcode));
+       pBase = (unsigned int __user *) readRegister(getRn(opcode));
        if (REG_PC == getRn(opcode)) {
                pBase += 2;
                write_back = 0;
@@ -241,18 +260,21 @@ unsigned int PerformLDF(const unsigned int opcode)
        }
 
        if (write_back)
-               writeRegister(getRn(opcode), (unsigned int) pFinal);
+               writeRegister(getRn(opcode), (unsigned long) pFinal);
        return nRc;
 }
 
 unsigned int PerformSTF(const unsigned int opcode)
 {
-       unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
-           write_back = WRITE_BACK(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 *) readRegister(getRn(opcode));
+       pBase = (unsigned int __user *) readRegister(getRn(opcode));
        if (REG_PC == getRn(opcode)) {
                pBase += 2;
                write_back = 0;
@@ -271,10 +293,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:
@@ -285,17 +307,20 @@ unsigned int PerformSTF(const unsigned int opcode)
                nRc = 0;
        }
 
+       if (roundData.exception)
+               float_raise(roundData.exception);
+
        if (write_back)
-               writeRegister(getRn(opcode), (unsigned int) pFinal);
+               writeRegister(getRn(opcode), (unsigned long) pFinal);
        return nRc;
 }
 
 unsigned int PerformLFM(const unsigned int opcode)
 {
-       unsigned int i, Fd, *pBase, *pAddress, *pFinal,
-           write_back = WRITE_BACK(opcode);
+       unsigned int __user *pBase, *pAddress, *pFinal;
+       unsigned int i, Fd, write_back = WRITE_BACK(opcode);
 
-       pBase = (unsigned int *) readRegister(getRn(opcode));
+       pBase = (unsigned int __user *) readRegister(getRn(opcode));
        if (REG_PC == getRn(opcode)) {
                pBase += 2;
                write_back = 0;
@@ -322,16 +347,16 @@ unsigned int PerformLFM(const unsigned int opcode)
        }
 
        if (write_back)
-               writeRegister(getRn(opcode), (unsigned int) pFinal);
+               writeRegister(getRn(opcode), (unsigned long) pFinal);
        return 1;
 }
 
 unsigned int PerformSFM(const unsigned int opcode)
 {
-       unsigned int i, Fd, *pBase, *pAddress, *pFinal,
-           write_back = WRITE_BACK(opcode);
+       unsigned int __user *pBase, *pAddress, *pFinal;
+       unsigned int i, Fd, write_back = WRITE_BACK(opcode);
 
-       pBase = (unsigned int *) readRegister(getRn(opcode));
+       pBase = (unsigned int __user *) readRegister(getRn(opcode));
        if (REG_PC == getRn(opcode)) {
                pBase += 2;
                write_back = 0;
@@ -358,7 +383,7 @@ unsigned int PerformSFM(const unsigned int opcode)
        }
 
        if (write_back)
-               writeRegister(getRn(opcode), (unsigned int) pFinal);
+               writeRegister(getRn(opcode), (unsigned long) pFinal);
        return 1;
 }