use bitvec::field::BitField;
use bitvec::order::Lsb0;
use bitvec::slice::BitSlice;
use bitvec::view::BitView;
pub type Word = u32;
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct ImmediateI(pub u32);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct ImmediateS(pub u32);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct ImmediateB(pub u32);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct ImmediateU(pub u32);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct ImmediateJ(pub u32);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Rd(pub u8);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Rs1(pub u8);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Rs2(pub u8);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Opcode(pub u8);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Func3(pub u8);
#[derive(Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Func7(pub u8);
impl From<&BitSlice<Word, Lsb0>> for Rd {
fn from(bs: &BitSlice<Word, Lsb0>) -> Self {
assert_eq!(bs.len(), 5);
Self(bs.load())
}
}
impl From<&BitSlice<Word, Lsb0>> for Func7 {
fn from(bs: &BitSlice<Word, Lsb0>) -> Self {
assert_eq!(bs.len(), 7);
Self(bs.load())
}
}
impl From<&BitSlice<Word, Lsb0>> for Func3 {
fn from(bs: &BitSlice<Word, Lsb0>) -> Self {
assert_eq!(bs.len(), 3);
Self(bs.load())
}
}
impl From<&BitSlice<Word, Lsb0>> for Opcode {
fn from(bs: &BitSlice<Word, Lsb0>) -> Self {
assert_eq!(bs.len(), 7);
Self(bs.load())
}
}
impl From<&BitSlice<Word, Lsb0>> for Rs1 {
fn from(bs: &BitSlice<Word, Lsb0>) -> Self {
assert_eq!(bs.len(), 5);
Self(bs.load())
}
}
impl From<&BitSlice<Word, Lsb0>> for Rs2 {
fn from(bs: &BitSlice<Word, Lsb0>) -> Self {
assert_eq!(bs.len(), 5);
Self(bs.load())
}
}
impl From<Word> for ImmediateB {
fn from(w: Word) -> Self {
let src = w.view_bits::<Lsb0>();
let mut data = 0u32;
let dst = data.view_bits_mut::<Lsb0>();
dst.set(11, src[7]);
dst[1..5].copy_from_bitslice(&src[8..=11]);
dst[5..11].copy_from_bitslice(&src[25..=30]);
for i in 12..=31 {
dst.set(i, src[31]);
}
Self(data)
}
}
impl From<Word> for ImmediateS {
fn from(w: Word) -> Self {
let src = w.view_bits::<Lsb0>();
let mut data = 0u32;
let dst = data.view_bits_mut::<Lsb0>();
dst.set(0, src[7]);
dst[1..=4].copy_from_bitslice(&src[8..=11]);
dst[5..=10].copy_from_bitslice(&src[25..=30]);
for i in 11..=31 {
dst.set(i, src[31]);
}
Self(data)
}
}
impl From<Word> for ImmediateI {
fn from(w: Word) -> Self {
let src = w.view_bits::<Lsb0>();
let mut data = 0u32;
let dst = data.view_bits_mut::<Lsb0>();
dst.set(0, src[20]);
dst[1..=4].copy_from_bitslice(&src[21..=24]);
dst[5..=10].copy_from_bitslice(&src[25..=30]);
for i in 11..=31 {
dst.set(i, src[31]);
}
Self(data)
}
}
impl From<Word> for ImmediateJ {
fn from(w: Word) -> Self {
let src = w.view_bits::<Lsb0>();
let mut data = 0u32;
let dst = data.view_bits_mut::<Lsb0>();
dst[1..5].copy_from_bitslice(&src[21..25]);
dst[5..11].copy_from_bitslice(&src[25..31]);
dst.set(11, src[20]);
dst[12..20].copy_from_bitslice(&src[12..20]);
for i in 20..32 {
dst.set(i, src[31]);
}
Self(data)
}
}
impl From<Word> for ImmediateU {
fn from(w: Word) -> Self {
let src = w.view_bits::<Lsb0>();
let mut data = 0u32;
data.view_bits_mut::<Lsb0>()[12..=31].copy_from_bitslice(&src[12..=31]);
Self(data)
}
}