Skip to content

Commit

Permalink
Load string indices with inline asm to save space.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dirbaio committed Oct 28, 2024
1 parent 55524c8 commit 786534e
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion macros/src/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,27 @@ pub(crate) fn interned_string(
let var_item = static_variable(&var_name, string, tag, prefix);
quote!({
#var_item
&#var_name as *const u8 as u16

// defmt string indices are 16 bits, which can be loaded with a single `movw`.
// However, the compiler doesn't know that, so it generates `movw+movt` or `ldr rX, [pc, #offs]`
// because it sees we're loading an address of a symbol, which could be any 32bit value.
// This wastes space, so we load the value with asm manually to avoid this.
#[cfg(target_arch = "arm")]
{
let res: u16;
unsafe { ::core::arch::asm!(
"movw {res}, #:lower16:{y}",
res = lateout(reg) res,
y = sym #var_name,
options(pure, nomem, nostack, preserves_flags)
)};
res
}

#[cfg(not(target_arch = "arm"))]
{
&#var_name as *const u8 as u16
}
})
};

Expand Down

0 comments on commit 786534e

Please sign in to comment.