Hello, all. ARM and ia64 apparently don't generically have opcode to
make division of pointer-sized integers. Alpha has the same property but
alpha port is in very sorry state anyway so it doesn't matter anyway.
Looking at libgcc code at functions at question, I see that they use
algorithm very similar to what we have in divmod64. IA64 version uses
FPU which probably worked more by luck since we don't do proper FPU
setup on any platform. Alpha version also uses FPU and probably doesn't
work. In my alpha port I redirected all division functions to
grub_divmod64. What do you think about attached patch?
diff --git a/configure.ac b/configure.ac
index ea38f09..956cfed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -820,7 +820,7 @@ CFLAGS="$TARGET_CFLAGS -Wl,--defsym,abort=main"
 fi
 
 # Check for libgcc symbols
-AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __ucmpdi2 _restgpr_14_x __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3 __ctzdi2 __ctzsi2)
+AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __ucmpdi2 _restgpr_14_x __ctzdi2 __ctzsi2)
 
 if test "x$TARGET_APPLE_CC" = x1 ; then
 CFLAGS="$TARGET_CFLAGS -nostdlib"
diff --git a/grub-core/kern/arm/misc.S b/grub-core/kern/arm/misc.S
index 9d4c333..68e4828 100644
--- a/grub-core/kern/arm/misc.S
+++ b/grub-core/kern/arm/misc.S
@@ -30,6 +30,26 @@
 
 	.align	2
 
+	.macro division parent
+
+        stmfd   sp!, {lr}
+        sub     sp, sp, #12
+        mov     r2, r1
+        add     r1, sp, #4
+        str     r1, [sp, #0]
+        mov     r1, #0
+        mov     r3, #0
+        bl      \parent
+	ldr     r1, [sp, #4]
+        add     sp, sp, #12
+        ldmfd   sp!, {lr}
+        bx      lr
+	.endm
+
+FUNCTION(__aeabi_uidivmod)
+	division grub_divmod64
+
+
 /*
  * Null divide-by-zero handler
  */
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index f883fb9..caf7779 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -589,6 +589,49 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
   return q;
 }
 
+#if defined (__arm__)
+
+grub_uint32_t
+__udivsi3 (grub_uint32_t a, grub_uint32_t b)
+{
+  return grub_divmod64 (a, b, 0);
+}
+
+grub_uint32_t
+__umodsi3 (grub_uint32_t a, grub_uint32_t b)
+{
+  grub_uint64_t ret;
+  grub_divmod64 (a, b, &ret);
+  return ret;
+}
+
+
+#endif
+
+#ifdef __arm__
+grub_uint32_t
+__aeabi_uidiv (grub_uint32_t a, grub_uint32_t b)
+  __attribute__ ((alias ("__udivsi3")));
+#endif
+
+#if defined (__ia64__)
+
+grub_uint64_t
+__udivdi3 (grub_uint64_t a, grub_uint64_t b)
+{
+  return grub_divmod64 (a, b, 0);
+}
+
+grub_uint64_t
+__umoddi3 (grub_uint64_t a, grub_uint64_t b)
+{
+  grub_uint64_t ret;
+  grub_divmod64 (a, b, &ret);
+  return ret;
+}
+
+#endif
+
 /* Convert a long long value to a string. This function avoids 64-bit
    modular arithmetic or divisions.  */
 static char *
diff --git a/grub-core/lib/libgcrypt/cipher/idea.c b/grub-core/lib/libgcrypt/cipher/idea.c
index c025c95..3c5578f 100644
--- a/grub-core/lib/libgcrypt/cipher/idea.c
+++ b/grub-core/lib/libgcrypt/cipher/idea.c
@@ -72,8 +72,8 @@ mul_inv( u16 x )
 
     if( x < 2 )
 	return x;
-    t1 = 0x10001L / x;
-    y =  0x10001L % x;
+    t1 = 0x10001UL / x;
+    y =  0x10001UL % x;
     if( y == 1 )
 	return (1-t1) & 0xffff;
 
diff --git a/grub-core/term/tparm.c b/grub-core/term/tparm.c
index 8c1c288..f659f13 100644
--- a/grub-core/term/tparm.c
+++ b/grub-core/term/tparm.c
@@ -614,13 +614,13 @@ tparam_internal(const char *string, va_list ap)
 	    case '/':
 		y = npop();
 		x = npop();
-		npush(y ? (x / y) : 0);
+		npush(y ? ((unsigned)x / (unsigned)y) : 0);
 		break;
 
 	    case 'm':
 		y = npop();
 		x = npop();
-		npush(y ? (x % y) : 0);
+		npush(y ? ((unsigned)x % (unsigned)y) : 0);
 		break;
 
 	    case 'A':
diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h
index d101db4..fdc6611 100644
--- a/include/grub/libgcc.h
+++ b/include/grub/libgcc.h
@@ -42,30 +42,6 @@ void EXPORT_FUNC (__bswapsi2) (void);
 # ifdef HAVE___BSWAPDI2
 void EXPORT_FUNC (__bswapdi2) (void);
 # endif
-# ifdef HAVE___UDIVSI3
-void EXPORT_FUNC (__udivsi3) (void);
-# endif
-# ifdef HAVE___UMODSI3
-void EXPORT_FUNC (__umodsi3) (void);
-# endif
-# ifdef HAVE___UMODDI3
-void EXPORT_FUNC (__umoddi3) (void);
-# endif
-# ifdef HAVE___UDIVDI3
-void EXPORT_FUNC (__udivdi3) (void);
-# endif
-# ifdef HAVE___MODDI3
-void EXPORT_FUNC (__moddi3) (void);
-# endif
-# ifdef HAVE___DIVDI3
-void EXPORT_FUNC (__divdi3) (void);
-# endif
-# ifdef HAVE___DIVSI3
-void EXPORT_FUNC (__divsi3) (void);
-# endif
-# ifdef HAVE___MODSI3
-void EXPORT_FUNC (__modsi3) (void);
-# endif
 # ifdef HAVE___CTZDI2
 void EXPORT_FUNC (__ctzdi2) (void);
 # endif
@@ -114,12 +90,8 @@ void EXPORT_FUNC (_savegpr_31) (void);
 #endif
 
 #if defined (__arm__)
-void EXPORT_FUNC (__aeabi_idiv) (void);
-void EXPORT_FUNC (__aeabi_idivmod) (void);
 void EXPORT_FUNC (__aeabi_lasr) (void);
 void EXPORT_FUNC (__aeabi_llsl) (void);
 void EXPORT_FUNC (__aeabi_llsr) (void);
-void EXPORT_FUNC (__aeabi_uidiv) (void);
-void EXPORT_FUNC (__aeabi_uidivmod) (void);
 void EXPORT_FUNC (__aeabi_ulcmp) (void);
 #endif
diff --git a/include/grub/misc.h b/include/grub/misc.h
index 9583724..6767953 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -449,6 +449,35 @@ grub_error_load (const struct grub_error_saved *save)
   grub_errno = save->grub_errno;
 }
 
+#if defined (__arm__)
+
+grub_uint32_t
+EXPORT_FUNC (__udivsi3) (grub_uint32_t a, grub_uint32_t b);
+
+grub_uint32_t
+EXPORT_FUNC (__umodsi3) (grub_uint32_t a, grub_uint32_t b);
+
+#endif
+
+#ifdef __arm__
+grub_uint32_t
+EXPORT_FUNC (__aeabi_uidiv) (grub_uint32_t a, grub_uint32_t b);
+grub_uint32_t
+EXPORT_FUNC (__aeabi_uidivmod) (grub_uint32_t a, grub_uint32_t b);
+
+#endif
+
+#if defined (__ia64__)
+
+grub_uint64_t
+EXPORT_FUNC (__udivdi3) (grub_uint64_t a, grub_uint64_t b);
+
+grub_uint64_t
+EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b);
+
+#endif
+
+
 #if BOOT_TIME_STATS
 struct grub_boot_time
 {

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to