From 16057d6bbb0c8475de6a04c2562ccdb192a41f9b Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 13 Nov 2013 00:53:53 +0100 Subject: [PATCH] Redirect all divisions to grub_divmod64. --- ChangeLog | 4 ++++ configure.ac | 2 +- grub-core/kern/arm/misc.S | 20 ++++++++++++++++++ grub-core/kern/misc.c | 43 +++++++++++++++++++++++++++++++++++++++ include/grub/libgcc.h | 28 ------------------------- include/grub/misc.h | 29 ++++++++++++++++++++++++++ 6 files changed, 97 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f283eb01..1af3d4b9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-11-12 Vladimir Serbinenko + + Redirect all divisions to grub_divmod64. + 2013-11-12 Vladimir Serbinenko * grub-core/term/tparm.c (tparam_internal): Use unsigned divisions. diff --git a/configure.ac b/configure.ac index a0f17a2db..e59937774 100644 --- a/configure.ac +++ b/configure.ac @@ -831,7 +831,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 9d4c333b0..68e4828fd 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 af259d4f6..8b771a5d8 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -596,6 +596,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/include/grub/libgcc.h b/include/grub/libgcc.h index d101db473..fdc6611a0 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 20331f1c1..c62d4fbeb 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -453,6 +453,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 { -- 2.47.2