ab_riscv_primitives/instructions/rv32/
m.rs1#[cfg(test)]
4mod tests;
5pub mod zmmul;
6
7use crate::hart::HartConfig;
8use crate::instructions::rv32::m::zmmul::Rv32ZmmulInstruction;
9use crate::instructions::{ImplementedExtension, Instruction, IsaExtension};
10use crate::registers::general_purpose::Register;
11use ab_riscv_macros::instruction;
12use core::fmt;
13
14#[instruction(inherit = [Rv32ZmmulInstruction])]
16#[derive(Debug, Clone, Copy)]
17#[derive_const(PartialEq, Eq)]
18#[rustfmt::skip]
19pub enum Rv32MInstruction<Hart>
20where
21 Hart: HartConfig,
22{
23 Div { rd: Hart::Reg, rs1: Hart::Reg, rs2: Hart::Reg },
24 Divu { rd: Hart::Reg, rs1: Hart::Reg, rs2: Hart::Reg },
25 Rem { rd: Hart::Reg, rs1: Hart::Reg, rs2: Hart::Reg },
26 Remu { rd: Hart::Reg, rs1: Hart::Reg, rs2: Hart::Reg },
27}
28
29#[instruction]
30const impl<Reg, Hart> Instruction for Rv32MInstruction<Hart>
31where
32 Reg: [const] Register<Type = u32>,
33 Hart: [const] HartConfig<Reg = Reg>,
34{
35 const OWN_ISA_EXTENSIONS: &'static [IsaExtension] = &[IsaExtension::new("m", 2, 0)];
36
37 const ALIGNMENT: u8 = align_of::<u32>() as u8;
38
39 type Hart = Hart;
40
41 #[inline(always)]
42 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
43 fn try_decode(instruction: u32) -> Option<Self> {
44 let opcode = (instruction & 0b111_1111) as u8;
45 let rd_bits = ((instruction >> 7) & 0x1f) as u8;
46 let funct3 = ((instruction >> 12) & 0b111) as u8;
47 let rs1_bits = ((instruction >> 15) & 0x1f) as u8;
48 let rs2_bits = ((instruction >> 20) & 0x1f) as u8;
49 let funct7 = ((instruction >> 25) & 0b111_1111) as u8;
50
51 match opcode {
52 0b011_0011 => {
54 let rd = Reg::from_bits(rd_bits)?;
55 let rs1 = Reg::from_bits(rs1_bits)?;
56 let rs2 = Reg::from_bits(rs2_bits)?;
57 match (funct3, funct7) {
58 (0b100, 0b000_0001) => Some(Self::Div { rd, rs1, rs2 }),
59 (0b101, 0b000_0001) => Some(Self::Divu { rd, rs1, rs2 }),
60 (0b110, 0b000_0001) => Some(Self::Rem { rd, rs1, rs2 }),
61 (0b111, 0b000_0001) => Some(Self::Remu { rd, rs1, rs2 }),
62 _ => None,
63 }
64 }
65 _ => None,
66 }
67 }
68
69 #[inline(always)]
70 fn size(&self) -> u8 {
71 size_of::<u32>() as u8
72 }
73}
74
75#[instruction]
76impl<Reg, Hart> fmt::Display for Rv32MInstruction<Hart>
77where
78 Reg: fmt::Display + Copy,
79 Hart: HartConfig<Reg = Reg>,
80{
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 match self {
83 Self::Div { rd, rs1, rs2 } => write!(f, "div {rd}, {rs1}, {rs2}"),
84 Self::Divu { rd, rs1, rs2 } => write!(f, "divu {rd}, {rs1}, {rs2}"),
85 Self::Rem { rd, rs1, rs2 } => write!(f, "rem {rd}, {rs1}, {rs2}"),
86 Self::Remu { rd, rs1, rs2 } => write!(f, "remu {rd}, {rs1}, {rs2}"),
87 }
88 }
89}