WORKING ASM FUNCTION CALLS

This commit is contained in:
2024-10-12 02:24:48 -04:00
parent de79445ede
commit cf9f3469ae
14 changed files with 376 additions and 287 deletions

View File

@@ -2,74 +2,59 @@ pub const fn u(x: i32) -> u32 {
unsafe { std::mem::transmute(x) }
}
pub const fn low_mask(high: u32, low: u32) -> u32 {
(2u32.unbounded_shl(high - low)).wrapping_sub(1)
pub const fn base_mask(len: u8) -> u32 {
(2 << len) - 1
}
pub const fn mask(high: u32, low: u32) -> u32 {
low_mask(high, low).unbounded_shl(low)
pub const fn mask(h: u8, l: u8) -> u32 {
base_mask(h - l) << l
}
pub const fn bits(x: i32, high: u32, low: u32) -> u32 {
let x = u(x);
x.unbounded_shr(low) & low_mask(high, low)
}
#[derive(Debug, Clone, Copy)]
pub struct Bits32<const H: u8, const L: u8>(u32);
#[derive(Debug, Clone, Copy)]
pub struct BitsI32<const H: u8, const L: u8>(u32);
pub const fn bit(x: i32, i: u32) -> u32 {
let x = u(x);
x.unbounded_shr(i) & 2u32 << i
}
pub const fn in_bit_range(x: i32, high: u32, low: u32) -> bool {
if x < 0 {
if high == low {
return false;
}
(bits(x, high - 1, low) | !mask(high - 1, low)) == u(x)
} else {
bits(x, high, low) << low == u(x)
impl<const H: u8, const L: u8> Bits32<H, L> {
pub const fn new(val: u32) -> Self {
let lsh = 31 - H;
let rsh = lsh + L;
debug_assert!(((val << lsh) >> rsh) == (val >> L));
Self(val)
}
pub const fn val(&self) -> u32 {
self.0
}
pub const fn bit(&self, i: u8) -> u32 {
(self.0 >> i) & 1
}
pub const fn bits(&self, h: u8, l: u8) -> u32 {
(self.0 >> l) & base_mask(h - l)
}
}
// use std::ops::{Add, Shl, Shr};
//
// pub const fn u(x: i32) -> u32 {
// unsafe { std::mem::transmute(x) }
// }
//
// pub const fn low_mask(high: u8, low: u8) -> u32 {
// (2u32.unbounded_shl(high - low)).wrapping_sub(1)
// }
//
// pub const fn mask(high: u8, low: u8) -> u32 {
// low_mask(high, low).unbounded_shl(low)
// }
//
// pub const fn bits(x: i32, high: u8, low: u8) -> u32 {
// let x = u(x);
// x.unbounded_shr(low) & low_mask(high, low)
// }
//
// pub const fn bit(x: i32, i: u32) -> u32 {
// let x = u(x);
// x.unbounded_shr(i) & 2u32 << i
// }
//
// pub const fn in_bit_range<T: Shl<u8, Output = T> + Shr<u8, Output = T>>(
// x: T,
// high: u8,
// low: u8,
// ) -> bool {
// if x < 0 {
// if high == low {
// return false;
// }
// (bits(x, high - 1, low) | !mask(high - 1, low)) == u(x)
// } else {
// bits(x, high, low) << low == u(x)
// }
// }
impl<const H: u8, const L: u8> BitsI32<H, L> {
pub const fn new(val: i32) -> Self {
let lsh = 31 - H;
let rsh = lsh + L;
assert!(((val << lsh) >> rsh) == (val >> L));
Self(u(val) & mask(H, L))
}
pub const fn tryy(val: i32) -> Option<Self> {
let lsh = 31 - H;
let rsh = lsh + L;
if ((val << lsh) >> rsh) == (val >> L) {
Some(Self(u(val) & mask(H, L)))
} else {
None
}
}
pub const fn to_u(self) -> Bits32<H, L> {
Bits32(self.0)
}
}
// I hate (love) rust https://github.com/rust-lang/rust-project-goals/issues/106
// pub struct Bits<
// T: Shl<u8, Output = T> + Shr<u8, Output = T>,
// const S: bool,
@@ -78,7 +63,7 @@ pub const fn in_bit_range(x: i32, high: u32, low: u32) -> bool {
// >(T);
// pub struct U32Bits<const H: u32, const L: u32>(u32);
//
// impl<T: Shl<u8, Output = T> + Shr<u8, Output = T> + Add<u8, Output = T>, const S: bool, const H: u8, const L: u8>
// impl<T: const Shl<u8, Output = T> + const Shr<u8, Output = T>, const S: bool, const H: u8, const L: u8>
// Bits<T, S, H, L>
// {
// pub const fn new(val: T) -> Self {
@@ -86,35 +71,3 @@ pub const fn in_bit_range(x: i32, high: u32, low: u32) -> bool {
// Self(val + L)
// }
// }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn get_bits() {
assert_eq!(bits(0b10111010, 5, 3), 0b111);
assert_eq!(bits(0b10111010, 7, 5), 0b101);
assert_eq!(bits(0b10111010, 2, 0), 0b010);
assert_eq!(bits(0b10111010, 7, 7), 0b1);
assert_eq!(bits(0b1, 0, 0), 0b1);
assert_eq!(bits(0b1, 1, 1), 0b0);
}
#[test]
fn range() {
assert!(!in_bit_range(0b00111100, 5, 3));
assert!(!in_bit_range(0b00111100, 4, 2));
assert!(in_bit_range(0b000111100, 5, 2));
assert!(in_bit_range(0b000000001, 0, 0));
assert!(in_bit_range(0b000001000, 3, 3));
assert!(!in_bit_range(-3, 1, 0));
assert!(!in_bit_range(-5, 2, 2));
assert!(!in_bit_range(-5, 4, 3));
assert!(in_bit_range(-1, 1, 0));
assert!(in_bit_range(-4, 2, 0));
assert!(in_bit_range(-5, 3, 2));
}
}