Skip to content
volt
GitHub

std::softint

Integer arithmetic a core may not have in hardware, from 32-bit operations: a Cortex-M0 has no divide instruction and no 32x32->64 multiply, and no 32-bit core divides 64-bit numbers. Nothing here uses an operation it implements, so none of it ends up calling itself (std/bare.volt hands these to LLVM under the names it calls, __udivsi3 and the rest).

Source: std/softint.volt

Functions

std::softint::udivmod32

fn udivmod32(n: u32, d: u32, rem: u32*) -> u32

n / d, and n % d into rem; d isn't 0 (the caller checked)

std::softint::udivmod64

fn udivmod64(n: u64, d: u64, rem: u64*) -> u64

std::softint::sdivmod32

fn sdivmod32(n: i32, d: i32, rem: i32*) -> i32

the signed ones through the magnitudes, wrapping so the most negative number works too: the quotient truncates, the remainder takes the dividend's sign

std::softint::sdivmod64

fn sdivmod64(n: i64, d: i64, rem: i64*) -> i64

std::softint::join

fn join(hi: u32, lo: u32) -> u64

a u64 from its halves, and back, through its bytes (low half first: every core voltc targets is little-endian). Not by shifting: a debug build's x >> 32 is a call to lshr64 on a Cortex-M0

std::softint::high

fn high(x: u64) -> u32

std::softint::shl64

fn shl64(x: u64, s: u32) -> u64

x << s, x >> s and the arithmetic x >> s, for s in 0..63, through the halves

std::softint::lshr64

fn lshr64(x: u64, s: u32) -> u64

std::softint::ashr64

fn ashr64(x: i64, s: u32) -> i64

std::softint::mul32x32

fn mul32x32(a: u32, b: u32) -> u64

the whole 64-bit product of two u32s, from their 16-bit halves (each partial product fits in 32 bits). Wrapping ops, though nothing wraps: a debug build checks a u32 * for overflow through a 64-bit multiply, which is a call to mul64

std::softint::mul64

fn mul64(a: u64, b: u64) -> u64

a * b, wrapping: the high halves only reach the result's upper 32 bits