David Hendricks (dhendrix@chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2606
-gerrit
commit 3686a9c6ab7e57052bb88b294f5d09cf41efaa59 Author: David Hendricks dhendrix@chromium.org Date: Wed Mar 6 20:43:55 2013 -0800
Eliminate do_div().
This eliminates the use of do_div() in favor of using libgcc wrapper functions.
This was tested by building and booting on Google Snow (ARMv7) and Qemu (x86). printk()s which use division in vtxprintf() look good.
Change-Id: Icad001d84a3c05bfbf77098f3d644816280b4a4d Signed-off-by: Gabe Black gabeblack@chromium.org Signed-off-by: David Hendricks dhendrix@chromium.org --- src/arch/armv7/Makefile.inc | 2 +- src/arch/armv7/lib/Makefile.inc | 2 -- src/arch/x86/include/div64.h | 30 ------------------------------ src/console/vtxprintf.c | 28 ++++++++++++++-------------- 4 files changed, 15 insertions(+), 47 deletions(-)
diff --git a/src/arch/armv7/Makefile.inc b/src/arch/armv7/Makefile.inc index 0595ae2..8f9915f 100644 --- a/src/arch/armv7/Makefile.inc +++ b/src/arch/armv7/Makefile.inc @@ -124,7 +124,7 @@ endif $(objgenerated)/coreboot_ram.o: $(stages_o) $$(ramstage-objs) $(LIBGCC_FILE_NAME) @printf " CC $(subst $(obj)/,,$(@))\n" ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y) - $(LD) -m -m armelf_linux_eabi -r -o $@ --wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3 --wrap __uidiv --wrap __do_div64 --start-group $(ramstage-objs) $(LIBGCC_FILE_NAME) --end-group + $(LD) -m -m armelf_linux_eabi -r -o $@ --wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3 --wrap __uidiv --start-group $(ramstage-objs) $(LIBGCC_FILE_NAME) --end-group else $(CC) $(CFLAGS) -nostdlib -r -o $@ -Wl,--start-group $(stages_o) $(ramstage-objs) $(LIBGCC_FILE_NAME) -Wl,--end-group endif diff --git a/src/arch/armv7/lib/Makefile.inc b/src/arch/armv7/lib/Makefile.inc index 0e81c99..0da3b0b 100644 --- a/src/arch/armv7/lib/Makefile.inc +++ b/src/arch/armv7/lib/Makefile.inc @@ -8,12 +8,10 @@ bootblock-y += div64.S romstage-y += cache_v7.c romstage-y += cache-cp15.c romstage-y += div0.c -romstage-y += div64.S romstage-y += syslib.c romstage-$(CONFIG_EARLY_CONSOLE) += early_console.c
ramstage-y += div0.c -ramstage-y += div64.S #ramstage-y += interrupts.c #ramstage-y += memcpy.S #ramstage-y += memset.S diff --git a/src/arch/x86/include/div64.h b/src/arch/x86/include/div64.h deleted file mode 100644 index bbc9921..0000000 --- a/src/arch/x86/include/div64.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __I386_DIV64 -#define __I386_DIV64 - -/* - * do_div() is NOT a C function. It wants to return - * two values (the quotient and the remainder), but - * since that doesn't work very well in C, what it - * does is: - * - * - modifies the 64-bit dividend _in_place_ - * - returns the 32-bit remainder - * - * This ends up being the most efficient "calling - * convention" on x86. - */ -#define do_div(n,base) ({ \ - unsigned long __upper, __low, __high, __mod, __base; \ - __base = (base); \ - asm("":"=a" (__low), "=d" (__high):"A" (n)); \ - __upper = __high; \ - if (__high) { \ - __upper = __high % (__base); \ - __high = __high / (__base); \ - } \ - asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \ - asm("":"=A" (n):"a" (__low),"d" (__high)); \ - __mod; \ -}) - -#endif diff --git a/src/console/vtxprintf.c b/src/console/vtxprintf.c index 9de2584..0146805 100644 --- a/src/console/vtxprintf.c +++ b/src/console/vtxprintf.c @@ -5,7 +5,6 @@ */
#include <string.h> -#include <div64.h> #include <console/console.h> #include <console/vtxprintf.h>
@@ -70,20 +69,21 @@ static int number(void (*tx_byte)(unsigned char byte), if (num == 0) tmp[i++]='0'; else while (num != 0){ - /* there are some nice optimizations in the - * Macros-From-Hell that form the div64 code - * *IF* you call it with a constant. - * We're firmware, we only do bases - * 8, 10, and 16. Let's be smart. - * This greatly helps ARM, reduces the - * code footprint at compile time, and does not hurt x86. + /* + * We're firmware, we only do bases 8, 10, and 16. Let's be + * smart. This greatly helps ARM, reduces the code footprint + * at compile time, and does not hurt x86. */ - if (base == 10) - tmp[i++] = digits[do_div(num,10)]; - else if (base == 8) - tmp[i++] = digits[do_div(num,8)]; - else /* sorry, you're out of choices */ - tmp[i++] = digits[do_div(num,16)]; + if (base == 10) { + tmp[i++] = digits[num % 10]; + num /= 10; + } else if (base == 8) { + tmp[i++] = digits[num % 8]; + num /= 8; + } else { /* sorry, you're out of choices */ + tmp[i++] = digits[num % 16]; + num /= 16; + } } if (i > precision) precision = i;