use core::convert::TryFrom;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum Reg {
Zero = 0,
Ra = 1,
Sp = 2,
Gp = 3,
Tp = 4,
T0 = 5,
T1 = 6,
T2 = 7,
S0 = 8,
S1 = 9,
A0 = 10,
A1 = 11,
A2 = 12,
A3 = 13,
A4 = 14,
A5 = 15,
A6 = 16,
A7 = 17,
S2 = 18,
S3 = 19,
S4 = 20,
S5 = 21,
S6 = 22,
S7 = 23,
S8 = 24,
S9 = 25,
S10 = 26,
S11 = 27,
T3 = 28,
T4 = 29,
T5 = 30,
T6 = 31,
}
impl Default for Reg {
fn default() -> Reg {
Reg::Zero
}
}
#[allow(dead_code)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Instr {
Illegal,
Lb {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Lh {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Lw {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Ld {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Lbu {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Lhu {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Lwu {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Fence {
rd: Reg,
rs1: Reg,
successor: u8,
predecessor: u8,
fm: u8,
},
FenceI {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Addi {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Slli {
rd: Reg,
rs1: Reg,
imm5: u8,
},
Slti {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Sltiu {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Xori {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Srli {
rd: Reg,
rs1: Reg,
imm5: u8,
},
Srai {
rd: Reg,
rs1: Reg,
imm5: u8,
},
Ori {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Andi {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Auipc {
rd: Reg,
imm20: i32,
},
Sb {
rs1: Reg,
rs2: Reg,
imm12: i32,
},
Sh {
rs1: Reg,
rs2: Reg,
imm12: i32,
},
Sw {
rs1: Reg,
rs2: Reg,
imm12: i32,
},
Sd {
rs1: Reg,
rs2: Reg,
imm12: i32,
},
Add {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Sub {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Sll {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Slt {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Sltu {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Xor {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Srl {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Sra {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Or {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
And {
rd: Reg,
rs1: Reg,
rs2: Reg,
},
Lui {
rd: Reg,
imm20: i32,
},
Beq {
rs1: Reg,
rs2: Reg,
imm: i32,
},
Bne {
rs1: Reg,
rs2: Reg,
imm: i32,
},
Blt {
rs1: Reg,
rs2: Reg,
imm: i32,
},
Bge {
rs1: Reg,
rs2: Reg,
imm: i32,
},
Bltu {
rs1: Reg,
rs2: Reg,
imm: i32,
},
Bgeu {
rs1: Reg,
rs2: Reg,
imm: i32,
},
Jalr {
rd: Reg,
rs1: Reg,
imm12: i32,
},
Jal {
rd: Reg,
imm20: i32,
},
Ecall {
rd: Reg,
rs1: Reg,
},
Ebreak {
rd: Reg,
rs1: Reg,
},
Wfi {},
Mret {},
Csrrw {
rs1: Reg,
imm12: u32,
},
Csrrs {
rd: Reg,
rs1: Reg,
imm12: u32,
},
Csrrc {
rs1: Reg,
},
Csrrwi {
rd: Reg,
},
Csrrsi {
imm5: u8,
imm12: u32,
},
Csrrci {
imm5: u8,
imm12: u32,
},
Hint {
hint: (),
},
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct RegIndexError {
idx: u32,
}
impl TryFrom<u32> for Reg {
type Error = RegIndexError;
fn try_from(idx: u32) -> Result<Reg, Self::Error> {
let o_reg = match idx {
0 => Some(Reg::Zero),
1 => Some(Reg::Ra),
2 => Some(Reg::Sp),
3 => Some(Reg::Gp),
4 => Some(Reg::Tp),
5 => Some(Reg::T0),
6 => Some(Reg::T1),
7 => Some(Reg::T2),
8 => Some(Reg::S0),
9 => Some(Reg::S1),
10 => Some(Reg::A0),
11 => Some(Reg::A1),
12 => Some(Reg::A2),
13 => Some(Reg::A3),
14 => Some(Reg::A4),
15 => Some(Reg::A5),
16 => Some(Reg::A6),
17 => Some(Reg::A7),
18 => Some(Reg::S2),
19 => Some(Reg::S3),
20 => Some(Reg::S4),
21 => Some(Reg::S5),
22 => Some(Reg::S6),
23 => Some(Reg::S7),
24 => Some(Reg::S8),
25 => Some(Reg::S9),
26 => Some(Reg::S10),
27 => Some(Reg::S11),
28 => Some(Reg::T3),
29 => Some(Reg::T4),
30 => Some(Reg::T5),
31 => Some(Reg::T6),
_ => None,
};
if let Some(reg) = o_reg {
Ok(reg)
} else {
Err(RegIndexError { idx })
}
}
}