[coreboot] New patch to review for coreboot: 3686a9c Eliminate do_div().

David Hendricks (dhendrix@chromium.org) gerrit at coreboot.org
Thu Mar 7 20:45:40 CET 2013


David Hendricks (dhendrix at 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 at 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 at chromium.org>
    Signed-off-by: David Hendricks <dhendrix at 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;



More information about the coreboot mailing list