Skip to content

feat(printk): add %ll support for printing 64-bit values on 32-bit architectures #346

@josecm

Description

@josecm

Summary

printk should support the %ll length modifier to correctly print 64-bit values (unsigned long long / uint64_t) on 32-bit architectures.

Current behaviour

The %ll modifier is silently parsed but ignored in src/lib/printk.c:

if (*fmt_it == 'l') {
    fmt_it++;
    flags = flags | F_LONG;
    if (*fmt_it == 'l') {
        fmt_it++;
    } // ignore long long
}

vprintd then calls va_arg(*args, unsigned long) (32-bit on 32-bit targets) instead of va_arg(*args, unsigned long long) (64-bit). This silently truncates the high 32 bits and misaligns the va_list for any subsequent arguments.

Desired behaviour

%llx/%llu/%lld should correctly read and print a full 64-bit value on all targets.

Implementation notes

  • Add a F_LONG_LONG flag and set it when ll is parsed
  • Pop unsigned long long from va_list when the flag is set
  • Promote intermediate arithmetic in vprintd to unsigned long long

Note that promoting to unsigned long long requires 64-bit division, which on 32-bit architectures is a software operation (e.g. __aeabi_uldivmod on ARM, __udivdi3/__umoddi3 on other ABIs). This runtime support needs to be available in the build (either via libgcc or a custom implementation) before this change can land.

Affected architectures

All 32-bit targets: ARMv8 AArch32, RISC-V 32, RH850, TriCore

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions