mod amo;
mod auipc;
mod branch;
mod c0;
mod c1;
mod c2;
mod jal;
mod jalr;
mod load;
mod lui;
mod misc_mem;
mod op;
mod op_imm;
mod store;
mod system;
use super::Error;
use crate::format::Size;
use crate::instruction::riscv;
#[inline(always)]
fn c_funct3(data: u32) -> u8 {
((data >> 13) & 0b111) as u8
}
#[inline(always)]
fn c_bit12(data: u32) -> u8 {
((data >> 12) & 0b1) as u8
}
#[inline(always)]
fn c_bits11_10(data: u32) -> u8 {
((data >> 10) & 0b11) as u8
}
#[inline(always)]
fn c_bits6_5(data: u32) -> u8 {
((data >> 5) & 0b11) as u8
}
pub struct RawInstruction {
pub data: u32,
pub size: Size,
}
impl RawInstruction {
pub fn new(data: u32, size: Size) -> RawInstruction {
RawInstruction { data, size }
}
}
trait Convert {
fn convert(data: u32) -> Result<RawInstruction, Error>;
}
macro_rules! embive_raw {
($inst:ty, $data:expr) => {{
use crate::instruction::embive::InstructionImpl;
let inst = <$inst>::from($data);
RawInstruction::new(inst.encode() | <$inst>::opcode() as u32, <$inst>::size())
}};
}
use embive_raw;
pub fn convert(data: u32) -> Result<RawInstruction, Error> {
match (data & 0b11) as u8 {
riscv::C0::OPCODE => riscv::C0::convert(data),
riscv::C1::OPCODE => riscv::C1::convert(data),
riscv::C2::OPCODE => riscv::C2::convert(data),
_ => match (data & 0b111_1111) as u8 {
riscv::Load::OPCODE => riscv::Load::convert(data),
riscv::MiscMem::OPCODE => riscv::MiscMem::convert(data),
riscv::OpImm::OPCODE => riscv::OpImm::convert(data),
riscv::Auipc::OPCODE => riscv::Auipc::convert(data),
riscv::Store::OPCODE => riscv::Store::convert(data),
riscv::Amo::OPCODE => riscv::Amo::convert(data),
riscv::Op::OPCODE => riscv::Op::convert(data),
riscv::Lui::OPCODE => riscv::Lui::convert(data),
riscv::Branch::OPCODE => riscv::Branch::convert(data),
riscv::Jalr::OPCODE => riscv::Jalr::convert(data),
riscv::Jal::OPCODE => riscv::Jal::convert(data),
riscv::System::OPCODE => riscv::System::convert(data),
_ => Err(Error::InvalidInstruction(data)),
},
}
}