five32-instruction-set 0.1.0

Definitions for an implementation of the RISC-V instruction set.
Documentation
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<&ImmediateI> for i32 {
//     fn from(imm: &ImmediateI) -> Self {
//
//     }
// }


// Immediate    31      30        20 19             12    11 10         5 4          1       0
//              |-------|-----------|---------------|-------|------------|-----------|-------|
// Instr=K      | K[31] ->                 <- K[31] |  K[7] | K[30..25]  | K[11..8]  |  '0'  |
//
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)
    }
}

// Immediate    31      30        20 19             12    11 10         5 4          1       0
//              |-------|-----------|---------------|-------|------------|-----------|-------|
// Instr=K      | K[31] ->                         <- K[31] | K[30..25]  | K[11..8]  | K[7]  |
//
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)
    }
}

// Immediate    31      30        20 19             12    11 10         5 4          1       0
//              |-------|-----------|---------------|-------|------------|-----------|-------|
// Instr=K      | K[31] ->                         <- K[31] | K[30..25]  | K[24..21] | K[20] |
//
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)
    }
}

// Immediate    31      30        20 19             12    11 10         5 4          1       0
//              |-------|-----------|---------------|-------|------------|-----------|-------|
// Instr=K      |          <- K[31] |   K[19..12]   | K[20] | K[30..25]  | K[24..21] |  '0'  |
//
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)
    }
}

// Immediate    31      30        20 19             12    11 10         5 4          1       0
//              |-------|-----------|---------------|-------|------------|-----------|-------|
// Instr=K      |           K[31..12]               | '0' ->                          <- '0' |
//
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)
    }
}