From 79e36d90608a929c33b655c6fb6376f33f332e6f Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Wed, 30 Jan 2013 14:29:34 -0800 Subject: [PATCH] Improve how our printk calls do_div by using constants. The do_div code has a nice optimization in it when it is called with constants. The current highly generalized use of it defeats those optimizations and causes trouble on ARM, resulting in a complex and buggy code path. Since we only need to print in bases 8, 10, and 16, do a minor restructuring of the code so that we call do_div with constants. If you need base 2, print in base 16 and do it in your head. :-) This fixes an ongoing problem with ARM, will not harm X86, and will help PPC should we ever want to support it again. Plus, I don't have to ever try to understand the div64 assembly and where it's going wrong :-) Change-Id: I6a480011916eb0834e05c5bb10909d83330fe797 Signed-off-by: Ronald G. Minnich Reviewed-on: http://review.coreboot.org/2235 Tested-by: build bot (Jenkins) Reviewed-by: David Hendricks Reviewed-by: Stefan Reinauer --- src/console/vtxprintf.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/console/vtxprintf.c b/src/console/vtxprintf.c index 28c5a604e0..9de25845bd 100644 --- a/src/console/vtxprintf.c +++ b/src/console/vtxprintf.c @@ -69,8 +69,22 @@ static int number(void (*tx_byte)(unsigned char byte), i = 0; if (num == 0) tmp[i++]='0'; - else while (num != 0) - tmp[i++] = digits[do_div(num,base)]; + 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. + */ + 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 (i > precision) precision = i; size -= precision;