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*) -> u32n / d, and n % d into rem; d isn't 0 (the caller checked)
std::softint::udivmod64
fn udivmod64(n: u64, d: u64, rem: u64*) -> u64std::softint::sdivmod32
fn sdivmod32(n: i32, d: i32, rem: i32*) -> i32the 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*) -> i64std::softint::join
fn join(hi: u32, lo: u32) -> u64a 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) -> u32std::softint::shl64
fn shl64(x: u64, s: u32) -> u64x << 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) -> u64std::softint::ashr64
fn ashr64(x: i64, s: u32) -> i64std::softint::mul32x32
fn mul32x32(a: u32, b: u32) -> u64the 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) -> u64a * b, wrapping: the high halves only reach the result's upper 32 bits