patch-2.4.4 linux/include/asm-s390/div64.h

Next file: linux/include/asm-s390/ebcdic.h
Previous file: linux/include/asm-s390/delay.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/include/asm-s390/div64.h linux/include/asm-s390/div64.h
@@ -1,10 +1,44 @@
 #ifndef __S390_DIV64
 #define __S390_DIV64
 
-#define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
+/* for do_div "base" needs to be smaller than 2^31-1 */
+ 
+#define do_div(n, base) ({                                      \
+	unsigned long long __n = (n);				\
+	unsigned long __r;					\
+								\
+	asm ("   slr  0,0\n"					\
+	     "   l    1,%1\n"					\
+	     "   srdl 0,1\n"					\
+	     "   dr   0,%2\n"					\
+	     "   alr  1,1\n"					\
+	     "   alr  0,0\n"					\
+	     "   lhi  2,1\n"					\
+	     "   n    2,%1\n"					\
+	     "   alr  0,2\n"					\
+	     "   clr  0,%2\n"					\
+	     "   jl   0f\n"					\
+	     "   slr  0,%2\n"					\
+             "   ahi  1,1\n"					\
+	     "0: st   1,%1\n"					\
+	     "   l    1,4+%1\n"					\
+	     "   srdl 0,1\n"					\
+             "   dr   0,%2\n"					\
+	     "   alr  1,1\n"					\
+	     "   alr  0,0\n"					\
+	     "   lhi  2,1\n"					\
+	     "   n    2,4+%1\n"					\
+	     "   alr  0,2\n"					\
+	     "   clr  0,%2\n"					\
+             "   jl   1f\n"					\
+	     "   slr  0,%2\n"					\
+	     "   ahi  1,1\n"					\
+	     "1: st   1,4+%1\n"					\
+             "   lr   %0,0"					\
+	     : "=d" (__r), "+m" (__n)				\
+	     : "d" (base) : "0", "1", "2" );			\
+	(n) = (__n);						\
+        __r;                                                    \
+})
 
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)