five32-instruction-set 0.1.0

Definitions for an implementation of the RISC-V instruction set.
Documentation
use bitvec::prelude::*;

use crate::fields::*;

#[derive(Default, Debug, Eq, PartialEq)]
pub struct Raw(pub u32);

#[derive(Default, Debug, Eq, PartialEq)]
pub struct R {
    pub opcode: Opcode,
    pub func3: Func3,
    pub func7: Func7,
    pub rd: Rd,
    pub rs1: Rs1,
    pub rs2: Rs2
}

#[derive(Default, Debug, Eq, PartialEq)]
pub struct I {
    pub opcode: Opcode,
    pub func3: Func3,
    pub rd: Rd,
    pub rs1: Rs1,
    pub immediate: ImmediateI
}

#[derive(Default, Debug, Eq, PartialEq)]
pub struct S {
    pub opcode: Opcode,
    pub func3: Func3,
    pub rs1: Rs1,
    pub rs2: Rs2,
    pub immediate: ImmediateS
}

#[derive(Default, Debug, Eq, PartialEq)]
pub struct B {
    pub opcode: Opcode,
    pub func3: Func3,
    pub rs1: Rs1,
    pub rs2: Rs2,
    pub immediate: ImmediateB
}

#[derive(Default, Debug, Eq, PartialEq)]
pub struct U {
    pub opcode: Opcode,
    pub rd: Rd,
    pub immediate: ImmediateU
}

#[derive(Default, Debug, Eq, PartialEq)]
pub struct J {
    pub opcode: Opcode,
    pub rd: Rd,
    pub immediate: ImmediateJ
}

impl From<Word> for Raw {
    fn from(w: Word) -> Self {
        Self(w)
    }
}

impl From<Word> for U {
    fn from(w: Word) -> Self {
        let view = BitSlice::<_, Lsb0>::from_element(&w);
        Self {
            opcode:    Opcode::from(&view[0..=6]),
            rd:            Rd::from(&view[7..=11]),
            immediate:  ImmediateU::from(w),
        }
    }
}

impl From<Word> for S {
    fn from(w: Word) -> Self {
        let view = BitSlice::<_, Lsb0>::from_element(&w);
        Self {
            opcode:         Opcode::from(&view[0..=6]),
            func3:           Func3::from(&view[12..=14]),
            rs1:               Rs1::from(&view[15..=19]),
            rs2:               Rs2::from(&view[20..=24]),
            immediate:  ImmediateS::from(w)
        }
    }
}

impl From<Word> for R {
    fn from(w: Word) -> Self {
        let view = BitSlice::<_, Lsb0>::from_element(&w);
        Self {
            opcode: Opcode::from(&view[0..=6]),
            rd:         Rd::from(&view[7..=11]),
            func3:   Func3::from(&view[12..=14]),
            func7:   Func7::from(&view[25..=31]),
            rs1:       Rs1::from(&view[15..=19]),
            rs2:       Rs2::from(&view[20..=24]),
        }
    }
}

impl From<Word> for I {
    fn from(w: Word) -> Self {
        let view = BitSlice::<_, Lsb0>::from_element(&w);
        Self {
            opcode:          Opcode::from(&view[0..=6]),
            rd:                  Rd::from(&view[7..=11]),
            func3:            Func3::from(&view[12..=14]),
            rs1:                Rs1::from(&view[15..=19]),
            immediate:   ImmediateI::from(w),
        }
    }
}

impl From<Word> for B {
    fn from(w: Word) -> Self {
        let view = BitSlice::<_, Lsb0>::from_element(&w);
        Self {
            opcode:         Opcode::from(&view[0..=6]),
            func3:           Func3::from(&view[12..=14]),
            rs1:               Rs1::from(&view[15..=19]),
            rs2:               Rs2::from(&view[20..=24]),
            immediate:  ImmediateB::from(w),
        }
    }
}