[S390] Bogomips calculation for 64 bit.
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 10 Jul 2007 09:24:14 +0000 (11:24 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 10 Jul 2007 09:24:47 +0000 (11:24 +0200)
The bogomips calculation triggered via reading from /proc/cpuinfo
can return incorrect values if the qrnnd assembly is called with a
pointer in %r2 with any of the upper 32 bits set.
Fix this by using 64 bit division / remainder operation provided by
gcc instead of calling the assembly.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/lib/Makefile
include/asm-s390/sfp-machine.h
include/asm-s390/sfp-util.h

index 59aea65ce99fc0845e88c540d7866b736cd28146..52084436ab69726252e894d5ecdcecbbb6580c24 100644 (file)
@@ -4,7 +4,7 @@
 
 EXTRA_AFLAGS := -traditional
 
-lib-y += delay.o string.o uaccess_std.o uaccess_pt.o qrnnd.o
-obj-$(CONFIG_32BIT) += div64.o
+lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
+obj-$(CONFIG_32BIT) += div64.o qrnnd.o
 lib-$(CONFIG_64BIT) += uaccess_mvcos.o
 lib-$(CONFIG_SMP) += spinlock.o
index 8ca8c77b2d04c75fa3d0498217d521f2001d66f1..4e16aede4b0622b24e9660aecd5405ff5bba55fb 100644 (file)
@@ -27,9 +27,9 @@
    
 
 #define _FP_W_TYPE_SIZE                32
-#define _FP_W_TYPE             unsigned long
-#define _FP_WS_TYPE            signed long
-#define _FP_I_TYPE             long
+#define _FP_W_TYPE             unsigned int
+#define _FP_WS_TYPE            signed int
+#define _FP_I_TYPE             int
 
 #define _FP_MUL_MEAT_S(R,X,Y)                                  \
   _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
index 8cabcd23d976c8136ba0df486858c42c31e91059..0addc6466d958aede3954efeb6b7071077344e6c 100644 (file)
        wl = __wl;                                      \
 })
 
+#ifdef __s390x__
+#define udiv_qrnnd(q, r, n1, n0, d)                    \
+  do { unsigned long __n;                              \
+       unsigned int __r, __d;                          \
+    __n = ((unsigned long)(n1) << 32) + n0;            \
+    __d = (d);                                         \
+    (q) = __n / __d;                                   \
+    (r) = __n % __d;                                   \
+  } while (0)
+#else
 #define udiv_qrnnd(q, r, n1, n0, d)                    \
   do { unsigned int __r;                               \
     (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));                \
@@ -58,6 +68,7 @@
   } while (0)
 extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int,
                                   unsigned int , unsigned int);
+#endif
 
 #define UDIV_NEEDS_NORMALIZATION 0