ZEON256 ZEON256
← BACK

You can use const-generics with inline asm

ZEON256
ZEON256 2026-06-15
Low Level

Turns out you can use const-generis with inline asm in Rust!

Const Generics ASM

The code

Rust
#![no_std]

/// Q<N> is a fixed point integer where the bottom N bits are fractional
///
/// i.e the true value represented is
///
/// let val: f32 = (self.0 as f32) * f32::powi(2.0, -N);
///
#[derive(Clone, Copy, Debug)]
struct Q<const N: u32>(i16);

/// Multiply two fixed-point numbers together
fn multiply<const L: u32, const R: u32, const O: u32>(lhs: Q<L>, rhs: Q<R>) -> Q<O> {
    // product has L + R fractional digits
    let product = (lhs.0 as i32) * (rhs.0 as i32);

    // The returned value can only have `O` fractional digits.
    // Shift right to get rid of all of the extras, and use `ssat`
    // to saturate the 32-bit value to fit in 16 bits.
    let result: i32;
    unsafe {
        core::arch::asm!(
            "ssat {result}, #{bits}, {product}, asr #{shift}",
            product = in(reg) product,
            result = out(reg) result,
            bits = const { 16 },
            shift = const { L + R - O },
            options(nomem, nostack, pure)
        );
    }
    Q::<O>(result as i16)
}

#[unsafe(no_mangle)]
pub fn mul_impl(a: Q<15>, b: Q<7>) -> Q<9> {
    multiply(a, b)
}