mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-06-09 23:36:03 +09:00
SPL: tiny-printf: add "l" modifier
tiny-printf does not know about the "l" modifier so far, which breaks the crash dump on AArch64, because it uses %lx to print the registers. Add an easy way of handling longs correctly. Using a relatively decent compiler (GCC 5.3.0) this does _not_ increase the code size of tiny-printf.o for 32-bit builds (where long and int are actually the same), actually it looses three (ARM Thumb2) instructions from the actual SPL (numbers for orangepi_plus_defconfig): text data bss dec hex filename 758 0 0 758 2f6 spl/lib/tiny-printf.o before 18839 488 232 19559 4c67 spl/u-boot-spl before 758 0 0 758 2f6 spl/lib/tiny-printf.o after 18833 488 232 19553 4c61 spl/u-boot-spl after This adds some substantial amount of code to a 64-bit build, though: (taken after a later commit, which enables the ARM64 SPL build for sunxi) text data bss dec hex filename 1542 0 0 1542 606 spl/lib/tiny-printf.o before 25830 392 360 26582 67d6 spl/u-boot-spl before 1758 0 0 1758 6de spl/lib/tiny-printf.o after 26040 392 360 26792 68a8 spl/u-boot-spl after Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Jagan Teki <jagan@openedev.com>
This commit is contained in:
parent
aa9226f0ed
commit
a28e1d9831
|
@ -38,8 +38,8 @@ static void out_dgt(struct printf_info *info, char dgt)
|
||||||
info->zs = 1;
|
info->zs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void div_out(struct printf_info *info, unsigned int *num,
|
static void div_out(struct printf_info *info, unsigned long *num,
|
||||||
unsigned int div)
|
unsigned long div)
|
||||||
{
|
{
|
||||||
unsigned char dgt = 0;
|
unsigned char dgt = 0;
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ int _vprintf(struct printf_info *info, const char *fmt, va_list va)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
char *p;
|
char *p;
|
||||||
unsigned int num;
|
unsigned long num;
|
||||||
char buf[12];
|
char buf[12];
|
||||||
unsigned int div;
|
unsigned long div;
|
||||||
|
|
||||||
while ((ch = *(fmt++))) {
|
while ((ch = *(fmt++))) {
|
||||||
if (ch != '%') {
|
if (ch != '%') {
|
||||||
|
@ -66,6 +66,7 @@ int _vprintf(struct printf_info *info, const char *fmt, va_list va)
|
||||||
} else {
|
} else {
|
||||||
bool lz = false;
|
bool lz = false;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
bool islong = false;
|
||||||
|
|
||||||
ch = *(fmt++);
|
ch = *(fmt++);
|
||||||
if (ch == '0') {
|
if (ch == '0') {
|
||||||
|
@ -80,6 +81,11 @@ int _vprintf(struct printf_info *info, const char *fmt, va_list va)
|
||||||
ch = *fmt++;
|
ch = *fmt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ch == 'l') {
|
||||||
|
ch = *(fmt++);
|
||||||
|
islong = true;
|
||||||
|
}
|
||||||
|
|
||||||
info->bf = buf;
|
info->bf = buf;
|
||||||
p = info->bf;
|
p = info->bf;
|
||||||
info->zs = 0;
|
info->zs = 0;
|
||||||
|
@ -89,24 +95,43 @@ int _vprintf(struct printf_info *info, const char *fmt, va_list va)
|
||||||
goto abort;
|
goto abort;
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'd':
|
case 'd':
|
||||||
|
div = 1000000000;
|
||||||
|
if (islong) {
|
||||||
|
num = va_arg(va, unsigned long);
|
||||||
|
if (sizeof(long) > 4)
|
||||||
|
div *= div * 10;
|
||||||
|
} else {
|
||||||
num = va_arg(va, unsigned int);
|
num = va_arg(va, unsigned int);
|
||||||
if (ch == 'd' && (int)num < 0) {
|
}
|
||||||
|
|
||||||
|
if (ch == 'd') {
|
||||||
|
if (islong && (long)num < 0) {
|
||||||
|
num = -(long)num;
|
||||||
|
out(info, '-');
|
||||||
|
} else if (!islong && (int)num < 0) {
|
||||||
num = -(int)num;
|
num = -(int)num;
|
||||||
out(info, '-');
|
out(info, '-');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!num) {
|
if (!num) {
|
||||||
out_dgt(info, 0);
|
out_dgt(info, 0);
|
||||||
} else {
|
} else {
|
||||||
for (div = 1000000000; div; div /= 10)
|
for (; div; div /= 10)
|
||||||
div_out(info, &num, div);
|
div_out(info, &num, div);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
|
if (islong) {
|
||||||
|
num = va_arg(va, unsigned long);
|
||||||
|
div = 1UL << (sizeof(long) * 8 - 4);
|
||||||
|
} else {
|
||||||
num = va_arg(va, unsigned int);
|
num = va_arg(va, unsigned int);
|
||||||
|
div = 0x10000000;
|
||||||
|
}
|
||||||
if (!num) {
|
if (!num) {
|
||||||
out_dgt(info, 0);
|
out_dgt(info, 0);
|
||||||
} else {
|
} else {
|
||||||
for (div = 0x10000000; div; div /= 0x10)
|
for (; div; div /= 0x10)
|
||||||
div_out(info, &num, div);
|
div_out(info, &num, div);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user