#![no_std]
mod compressed;
mod instruction;
pub mod types;
use types::*;
pub use instruction::Instruction;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum DecodingError {
Custom,
Reserved,
Unknown,
Truncated,
Unimplemented,
}
type DecodingResult = Result<Instruction, DecodingError>;
pub fn instruction_length(i: u16) -> usize {
if i & 0b11 != 0b11 {
2
} else if i & 0b11100 != 0b11100 {
4
} else if i & 0b111111 == 0b011111 {
6
} else if i & 0b1111111 == 0b011111 {
8
} else {
10 + 2 * ((i >> 12) & 0b111) as usize
}
}
pub fn decode(i: u32) -> DecodingResult {
match i & 0b11 {
0b00 => compressed::decode_q00(i),
0b01 => compressed::decode_q01(i),
0b10 => compressed::decode_q10(i),
0b11 => match (i >> 2) & 0b11111 {
0b00000 => decode_load(i),
0b00001 => match (i >> 12) & 0b111 {
0b010 => Ok(Instruction::Flw(IType(i))),
_ => Err(DecodingError::Unknown),
},
0b00010 => Err(DecodingError::Custom),
0b00011 => decode_misc_mem(i),
0b00100 => decode_op_imm(i),
0b00101 => Ok(Instruction::Auipc(UType(i))),
0b00110 => decode_op_imm32(i),
0b00111 => Err(DecodingError::Reserved), 0b01000 => decode_store(i),
0b01001 => match (i >> 12) & 0b111 {
0b010 => Ok(Instruction::Fsw(SType(i))),
_ => Err(DecodingError::Unknown),
},
0b01010 => Err(DecodingError::Custom),
0b01011 => decode_amo(i),
0b01100 => decode_op(i),
0b01101 => Ok(Instruction::Lui(UType(i))),
0b01110 => decode_op32(i),
0b01111 => Err(DecodingError::Reserved), 0b10000 => match (i >> 25) & 0b11 {
0b00 => Ok(Instruction::Fmadds(R4Type(i))),
_ => Err(DecodingError::Unknown),
},
0b10001 => match (i >> 25) & 0b11 {
0b00 => Ok(Instruction::Fmsubs(R4Type(i))),
_ => Err(DecodingError::Unknown),
},
0b10010 => match (i >> 25) & 0b11 {
0b00 => Ok(Instruction::Fnmsubs(R4Type(i))),
_ => Err(DecodingError::Unknown),
},
0b10011 => match (i >> 25) & 0b11 {
0b00 => Ok(Instruction::Fnmadds(R4Type(i))),
_ => Err(DecodingError::Unknown),
},
0b10100 => decode_opfp(i), 0b10101 => Err(DecodingError::Reserved),
0b10110 => Err(DecodingError::Custom),
0b10111 => Err(DecodingError::Reserved), 0b11000 => decode_branch(i),
0b11001 => Ok(Instruction::Jalr(IType(i))),
0b11010 => Err(DecodingError::Reserved),
0b11011 => Ok(Instruction::Jal(JType(i))),
0b11100 => decode_system(i),
0b11101 => Err(DecodingError::Reserved),
0b11110 => Err(DecodingError::Custom),
0b11111 => Err(DecodingError::Reserved), _ => unreachable!(),
},
_ => unreachable!(),
}
}
fn decode_opfp(i: u32) -> Result<Instruction, DecodingError> {
match (i >> 25) & 0b1111111 {
0b0000000 => Ok(Instruction::Fadds(RType(i))),
0b0000100 => Ok(Instruction::Fsubs(RType(i))),
0b0001000 => Ok(Instruction::Fmuls(RType(i))),
0b0001100 => Ok(Instruction::Fdivs(RType(i))),
0b0101100 if i >> 20 & 0b11111 == 0 => Ok(Instruction::Fsqrts(RType(i))),
0b0010000 => match i >> 12 & 0b111 {
0b000 => Ok(Instruction::Fsgnjs(RType(i))),
0b001 => Ok(Instruction::Fsgnjns(RType(i))),
0b010 => Ok(Instruction::Fsgnjxs(RType(i))),
_ => Err(DecodingError::Unknown),
},
0b0010100 => match i >> 12 & 0b111 {
0b000 => Ok(Instruction::Fmins(RType(i))),
0b001 => Ok(Instruction::Fmaxs(RType(i))),
_ => Err(DecodingError::Unknown),
},
0b1100000 => match i >> 20 & 0b11111 {
0b00000 => Ok(Instruction::Fcvtws(RType(i))),
0b00001 => Ok(Instruction::Fcvtwus(RType(i))),
_ => Err(DecodingError::Unknown),
},
0b1110000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0 => {
Ok(Instruction::Fmvxw(RType(i)))
}
0b1010000 => match i >> 12 & 0b111 {
0b010 => Ok(Instruction::Feqs(RType(i))),
0b001 => Ok(Instruction::Flts(RType(i))),
0b000 => Ok(Instruction::Fles(RType(i))),
_ => Err(DecodingError::Unknown),
},
0b1110000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0b001 => {
Ok(Instruction::Fclasss(RType(i)))
}
0b1101000 if i >> 20 & 0b11111 == 0 => Ok(Instruction::Fcvtsw(RType(i))),
0b1101000 if i >> 20 & 0b11111 == 1 => Ok(Instruction::Fcvtswu(RType(i))),
0b1111000 if i >> 20 & 0b11111 == 0 && i >> 12 & 0b111 == 0 => {
Ok(Instruction::Fmvwx(RType(i)))
}
_ => Err(DecodingError::Unknown),
}
}
fn decode_load(i: u32) -> DecodingResult {
match (i >> 12) & 0b111 {
0b000 => Ok(Instruction::Lb(IType(i))),
0b001 => Ok(Instruction::Lh(IType(i))),
0b010 => Ok(Instruction::Lw(IType(i))),
0b011 => Ok(Instruction::Ld(IType(i))),
0b100 => Ok(Instruction::Lbu(IType(i))),
0b101 => Ok(Instruction::Lhu(IType(i))),
0b110 => Ok(Instruction::Lwu(IType(i))),
0b111 => Err(DecodingError::Reserved),
_ => unreachable!(),
}
}
fn decode_misc_mem(i: u32) -> DecodingResult {
if i == 0b001000000001111 {
Ok(Instruction::FenceI)
} else if i & 0xf00fff80 == 0 {
Ok(Instruction::Fence(FenceType(i)))
} else {
Err(DecodingError::Reserved)
}
}
fn decode_op_imm(i: u32) -> DecodingResult {
match (i >> 12) & 0b111 {
0b000 => Ok(Instruction::Addi(IType(i))),
0b001 => match i >> 26 {
0 => Ok(Instruction::Slli(ShiftType(i))),
_ => Err(DecodingError::Unknown),
},
0b010 => Ok(Instruction::Slti(IType(i))),
0b011 => Ok(Instruction::Sltiu(IType(i))),
0b100 => Ok(Instruction::Xori(IType(i))),
0b101 => match i >> 26 {
0b000000 => Ok(Instruction::Srli(ShiftType(i))),
0b010000 => Ok(Instruction::Srai(ShiftType(i))),
_ => Err(DecodingError::Unknown),
},
0b110 => Ok(Instruction::Ori(IType(i))),
0b111 => Ok(Instruction::Andi(IType(i))),
_ => unreachable!(),
}
}
fn decode_op_imm32(i: u32) -> DecodingResult {
match (i >> 25, (i >> 12) & 0b111) {
(_, 0b000) => Ok(Instruction::Addiw(IType(i))),
(0b0000000, 0b001) => Ok(Instruction::Slliw(ShiftType(i))),
(0b0000000, 0b101) => Ok(Instruction::Srliw(ShiftType(i))),
(0b0100000, 0b101) => Ok(Instruction::Sraiw(ShiftType(i))),
_ => Err(DecodingError::Unknown),
}
}
fn decode_store(i: u32) -> DecodingResult {
match (i >> 12) & 0b111 {
0b000 => Ok(Instruction::Sb(SType(i))),
0b001 => Ok(Instruction::Sh(SType(i))),
0b010 => Ok(Instruction::Sw(SType(i))),
0b011 => Ok(Instruction::Sd(SType(i))),
_ => Err(DecodingError::Unknown),
}
}
fn decode_op(i: u32) -> DecodingResult {
match (i >> 25, (i >> 12) & 0b111) {
(0b0000000, 0b000) => Ok(Instruction::Add(RType(i))),
(0b0100000, 0b000) => Ok(Instruction::Sub(RType(i))),
(0b0000000, 0b001) => Ok(Instruction::Sll(RType(i))),
(0b0000000, 0b010) => Ok(Instruction::Slt(RType(i))),
(0b0000000, 0b011) => Ok(Instruction::Sltu(RType(i))),
(0b0000000, 0b100) => Ok(Instruction::Xor(RType(i))),
(0b0000000, 0b101) => Ok(Instruction::Srl(RType(i))),
(0b0100000, 0b101) => Ok(Instruction::Sra(RType(i))),
(0b0000000, 0b110) => Ok(Instruction::Or(RType(i))),
(0b0000000, 0b111) => Ok(Instruction::And(RType(i))),
(0b0000001, 0b000) => Ok(Instruction::Mul(RType(i))),
(0b0000001, 0b001) => Ok(Instruction::Mulh(RType(i))),
(0b0000001, 0b010) => Ok(Instruction::Mulhsu(RType(i))),
(0b0000001, 0b011) => Ok(Instruction::Mulhu(RType(i))),
(0b0000001, 0b100) => Ok(Instruction::Div(RType(i))),
(0b0000001, 0b101) => Ok(Instruction::Divu(RType(i))),
(0b0000001, 0b110) => Ok(Instruction::Rem(RType(i))),
(0b0000001, 0b111) => Ok(Instruction::Remu(RType(i))),
_ => Err(DecodingError::Unknown),
}
}
fn decode_op32(i: u32) -> DecodingResult {
match (i >> 25, (i >> 12) & 0b111) {
(0b0000000, 0b000) => Ok(Instruction::Addw(RType(i))),
(0b0100000, 0b000) => Ok(Instruction::Subw(RType(i))),
(0b0000000, 0b001) => Ok(Instruction::Sllw(RType(i))),
(0b0000000, 0b101) => Ok(Instruction::Srlw(RType(i))),
(0b0100000, 0b101) => Ok(Instruction::Sraw(RType(i))),
(0b0000001, 0b000) => Ok(Instruction::Mulw(RType(i))),
(0b0000001, 0b100) => Ok(Instruction::Divw(RType(i))),
(0b0000001, 0b101) => Ok(Instruction::Divuw(RType(i))),
(0b0000001, 0b110) => Ok(Instruction::Remw(RType(i))),
(0b0000001, 0b111) => Ok(Instruction::Remuw(RType(i))),
_ => Err(DecodingError::Unknown),
}
}
fn decode_branch(i: u32) -> DecodingResult {
match (i >> 12) & 0b111 {
0b000 => Ok(Instruction::Beq(BType(i))),
0b001 => Ok(Instruction::Bne(BType(i))),
0b010 => Err(DecodingError::Unknown),
0b011 => Err(DecodingError::Unknown),
0b100 => Ok(Instruction::Blt(BType(i))),
0b101 => Ok(Instruction::Bge(BType(i))),
0b110 => Ok(Instruction::Bltu(BType(i))),
0b111 => Ok(Instruction::Bgeu(BType(i))),
_ => unreachable!(),
}
}
fn decode_system(i: u32) -> DecodingResult {
match i {
0b000000000000_00000_000_00000_1110011 => return Ok(Instruction::Ecall),
0b000000000001_00000_000_00000_1110011 => return Ok(Instruction::Ebreak),
0b0000000_00010_00000_000_00000_1110011 => return Ok(Instruction::Uret),
0b0001000_00010_00000_000_00000_1110011 => return Ok(Instruction::Sret),
0b0011000_00010_00000_000_00000_1110011 => return Ok(Instruction::Mret),
0b0001000_00101_00000_000_00000_1110011 => return Ok(Instruction::Wfi),
_ => {}
}
match (i >> 12) & 0b111 {
0b001 => return Ok(Instruction::Csrrw(CsrType(i))),
0b010 => return Ok(Instruction::Csrrs(CsrType(i))),
0b011 => return Ok(Instruction::Csrrc(CsrType(i))),
0b101 => return Ok(Instruction::Csrrwi(CsrIType(i))),
0b110 => return Ok(Instruction::Csrrsi(CsrIType(i))),
0b111 => return Ok(Instruction::Csrrci(CsrIType(i))),
_ => {}
}
const SFENCE_VMA_MASK: u32 = 0b1111111_00000_00000_111_11111_1111111;
const SFENCE_VMA_VALUE: u32 = 0b0001001_00000_00000_000_00000_1110011;
if i & SFENCE_VMA_MASK == SFENCE_VMA_VALUE {
return Ok(Instruction::SfenceVma(RType(i)));
}
Err(DecodingError::Unknown)
}
fn decode_amo(i: u32) -> DecodingResult {
match (i >> 27, (i >> 12) & 0b111) {
(0b00010, 0b010) => Ok(Instruction::LrW(RType(i))),
(0b00011, 0b010) => Ok(Instruction::ScW(RType(i))),
(0b00001, 0b010) => Ok(Instruction::AmoswapW(RType(i))),
(0b00000, 0b010) => Ok(Instruction::AmoaddW(RType(i))),
(0b00100, 0b010) => Ok(Instruction::AmoxorW(RType(i))),
(0b01100, 0b010) => Ok(Instruction::AmoandW(RType(i))),
(0b01000, 0b010) => Ok(Instruction::AmoorW(RType(i))),
(0b10000, 0b010) => Ok(Instruction::AmominW(RType(i))),
(0b10100, 0b010) => Ok(Instruction::AmomaxW(RType(i))),
(0b11000, 0b010) => Ok(Instruction::AmominuW(RType(i))),
(0b11100, 0b010) => Ok(Instruction::AmomaxuW(RType(i))),
(0b00010, 0b011) => Ok(Instruction::LrD(RType(i))),
(0b00011, 0b011) => Ok(Instruction::ScD(RType(i))),
(0b00001, 0b011) => Ok(Instruction::AmoswapD(RType(i))),
(0b00000, 0b011) => Ok(Instruction::AmoaddD(RType(i))),
(0b00100, 0b011) => Ok(Instruction::AmoxorD(RType(i))),
(0b01100, 0b011) => Ok(Instruction::AmoandD(RType(i))),
(0b01000, 0b011) => Ok(Instruction::AmoorD(RType(i))),
(0b10000, 0b011) => Ok(Instruction::AmominD(RType(i))),
(0b10100, 0b011) => Ok(Instruction::AmomaxD(RType(i))),
(0b11000, 0b011) => Ok(Instruction::AmominuD(RType(i))),
(0b11100, 0b011) => Ok(Instruction::AmomaxuD(RType(i))),
_ => Err(DecodingError::Unknown),
}
}
#[cfg(test)]
mod tests {
use super::*;
use Instruction::*;
#[test]
fn decoding() {
assert_eq!(decode(0x00001a37).unwrap(), Lui(UType(0x00001a37))); assert_eq!(decode(0x800002b7).unwrap(), Lui(UType(0x800002b7))); assert_eq!(decode(0x212120b7).unwrap(), Lui(UType(0x212120b7))); assert_eq!(decode(0xffffe517).unwrap(), Auipc(UType(0xffffe517))); assert_eq!(decode(0xfffff797).unwrap(), Auipc(UType(0xfffff797))); assert_eq!(decode(0xfffff797).unwrap(), Auipc(UType(0xfffff797))); assert_eq!(decode(0xfe1ff06f).unwrap(), Jal(JType(0xfe1ff06f))); assert_eq!(decode(0x0000006f).unwrap(), Jal(JType(0x0000006f))); assert_eq!(decode(0xf89ff06f).unwrap(), Jal(JType(0xf89ff06f))); assert_eq!(decode(0x00008067).unwrap(), Jalr(IType(0x00008067))); assert_eq!(decode(0x00008067).unwrap(), Jalr(IType(0x00008067))); assert_eq!(decode(0x000f0067).unwrap(), Jalr(IType(0x000f0067))); }
#[test]
fn load() {
assert_eq!(decode(0x02008283).unwrap(), Lb(IType(0x02008283))); assert_eq!(decode(0x00708283).unwrap(), Lb(IType(0x00708283))); assert_eq!(decode(0x00108f03).unwrap(), Lb(IType(0x00108f03))); assert_eq!(decode(0x00411f03).unwrap(), Lh(IType(0x00411f03))); assert_eq!(decode(0x00611f03).unwrap(), Lh(IType(0x00611f03))); assert_eq!(decode(0x00811f03).unwrap(), Lh(IType(0x00811f03))); assert_eq!(decode(0x02052403).unwrap(), Lw(IType(0x02052403))); assert_eq!(decode(0x03452683).unwrap(), Lw(IType(0x03452683))); assert_eq!(decode(0x0006a703).unwrap(), Lw(IType(0x0006a703))); assert_eq!(decode(0x0006c783).unwrap(), Lbu(IType(0x0006c783))); assert_eq!(decode(0x0006c703).unwrap(), Lbu(IType(0x0006c703))); assert_eq!(decode(0x0007c683).unwrap(), Lbu(IType(0x0007c683))); assert_eq!(decode(0x0060df03).unwrap(), Lhu(IType(0x0060df03))); assert_eq!(decode(0xffe0df03).unwrap(), Lhu(IType(0xffe0df03))); assert_eq!(decode(0x0002d303).unwrap(), Lhu(IType(0x0002d303))); assert_eq!(decode(0x00346303).unwrap(), Lwu(IType(0x00346303))); assert_eq!(decode(0x0080ef03).unwrap(), Lwu(IType(0x0080ef03))); assert_eq!(decode(0x0000ef03).unwrap(), Lwu(IType(0x0000ef03))); assert_eq!(decode(0x01853683).unwrap(), Ld(IType(0x01853683))); assert_eq!(decode(0x02013c03).unwrap(), Ld(IType(0x02013c03))); assert_eq!(decode(0x0007b703).unwrap(), Ld(IType(0x0007b703))); }
#[test]
fn misc_mem() {
assert_eq!(decode(0x0310000f).unwrap(), Fence(FenceType(0x0310000f))); assert_eq!(decode(0x0820000f).unwrap(), Fence(FenceType(0x0820000f))); assert_eq!(decode(0x0ff0000f).unwrap(), Fence(FenceType(0x0ff0000f))); assert_eq!(decode(0x0000100f).unwrap(), FenceI); }
#[test]
fn op_imm() {
assert_eq!(decode(0x00200793).unwrap(), Addi(IType(0x00200793))); assert_eq!(decode(0x00000013).unwrap(), Addi(IType(0x00000013))); assert_eq!(decode(0x00000013).unwrap(), Addi(IType(0x00000013))); assert_eq!(decode(0x00381813).unwrap(), Slli(ShiftType(0x00381813))); assert_eq!(decode(0x01059793).unwrap(), Slli(ShiftType(0x01059793))); assert_eq!(decode(0x03079793).unwrap(), Slli(ShiftType(0x03079793))); assert_eq!(decode(0x0010af13).unwrap(), Slti(IType(0x0010af13))); assert_eq!(decode(0x7ff0af13).unwrap(), Slti(IType(0x7ff0af13))); assert_eq!(decode(0x8000af13).unwrap(), Slti(IType(0x8000af13))); assert_eq!(decode(0x0017b613).unwrap(), Sltiu(IType(0x0017b613))); assert_eq!(decode(0xfff0bf13).unwrap(), Sltiu(IType(0xfff0bf13))); assert_eq!(decode(0x0017b613).unwrap(), Sltiu(IType(0x0017b613))); assert_eq!(decode(0xfff6c693).unwrap(), Xori(IType(0xfff6c693))); assert_eq!(decode(0x999ac093).unwrap(), Xori(IType(0x999ac093))); assert_eq!(decode(0xfff6c693).unwrap(), Xori(IType(0xfff6c693))); assert_eq!(decode(0x00c7d793).unwrap(), Srli(ShiftType(0x00c7d793))); assert_eq!(decode(0x0207d793).unwrap(), Srli(ShiftType(0x0207d793))); assert_eq!(decode(0x00c7d793).unwrap(), Srli(ShiftType(0x00c7d793))); assert_eq!(decode(0x40e0df13).unwrap(), Srai(ShiftType(0x40e0df13))); assert_eq!(decode(0x41f55893).unwrap(), Srai(ShiftType(0x41f55893))); assert_eq!(decode(0x40e0df13).unwrap(), Srai(ShiftType(0x40e0df13))); assert_eq!(decode(0x00156513).unwrap(), Ori(IType(0x00156513))); assert_eq!(decode(0x04076713).unwrap(), Ori(IType(0x04076713))); assert_eq!(decode(0x5391e193).unwrap(), Ori(IType(0x5391e193))); assert_eq!(decode(0xff867693).unwrap(), Andi(IType(0xff867693))); assert_eq!(decode(0x08077693).unwrap(), Andi(IType(0x08077693))); assert_eq!(decode(0x04077693).unwrap(), Andi(IType(0x04077693))); }
#[test]
fn op_imm32() {
assert_eq!(decode(0x0010009b).unwrap(), Addiw(IType(0x0010009b))); assert_eq!(decode(0xfff0809b).unwrap(), Addiw(IType(0xfff0809b))); assert_eq!(decode(0xfff0809b).unwrap(), Addiw(IType(0xfff0809b))); assert_eq!(decode(0x0057979b).unwrap(), Slliw(ShiftType(0x0057979b))); assert_eq!(decode(0x0057979b).unwrap(), Slliw(ShiftType(0x0057979b))); assert_eq!(decode(0x00e09f1b).unwrap(), Slliw(ShiftType(0x00e09f1b))); assert_eq!(decode(0x0017d61b).unwrap(), Srliw(ShiftType(0x0017d61b))); assert_eq!(decode(0x01f0df1b).unwrap(), Srliw(ShiftType(0x01f0df1b))); assert_eq!(decode(0x0017d61b).unwrap(), Srliw(ShiftType(0x0017d61b))); assert_eq!(decode(0x41f0df1b).unwrap(), Sraiw(ShiftType(0x41f0df1b))); assert_eq!(decode(0x4000df1b).unwrap(), Sraiw(ShiftType(0x4000df1b))); assert_eq!(decode(0x4070d09b).unwrap(), Sraiw(ShiftType(0x4070d09b))); }
#[test]
fn store() {
assert_eq!(decode(0x00e78023).unwrap(), Sb(SType(0x00e78023))); assert_eq!(decode(0x001101a3).unwrap(), Sb(SType(0x001101a3))); assert_eq!(decode(0xfee78fa3).unwrap(), Sb(SType(0xfee78fa3))); assert_eq!(decode(0xfe209d23).unwrap(), Sh(SType(0xfe209d23))); assert_eq!(decode(0x00111223).unwrap(), Sh(SType(0x00111223))); assert_eq!(decode(0x00111523).unwrap(), Sh(SType(0x00111523))); assert_eq!(decode(0x05612c23).unwrap(), Sw(SType(0x05612c23))); assert_eq!(decode(0x01b12e23).unwrap(), Sw(SType(0x01b12e23))); assert_eq!(decode(0x01052223).unwrap(), Sw(SType(0x01052223))); assert_eq!(decode(0x0b613823).unwrap(), Sd(SType(0x0b613823))); assert_eq!(decode(0x09213823).unwrap(), Sd(SType(0x09213823))); assert_eq!(decode(0x00f6b423).unwrap(), Sd(SType(0x00f6b423))); }
#[test]
fn op() {
assert_eq!(decode(0x00c58633).unwrap(), Add(RType(0x00c58633))); assert_eq!(decode(0x00d506b3).unwrap(), Add(RType(0x00d506b3))); assert_eq!(decode(0x00a70533).unwrap(), Add(RType(0x00a70533))); assert_eq!(decode(0x40b50533).unwrap(), Sub(RType(0x40b50533))); assert_eq!(decode(0x40e78533).unwrap(), Sub(RType(0x40e78533))); assert_eq!(decode(0x41060633).unwrap(), Sub(RType(0x41060633))); assert_eq!(decode(0x00209f33).unwrap(), Sll(RType(0x00209f33))); assert_eq!(decode(0x00209f33).unwrap(), Sll(RType(0x00209f33))); assert_eq!(decode(0x00209f33).unwrap(), Sll(RType(0x00209f33))); assert_eq!(decode(0x0020af33).unwrap(), Slt(RType(0x0020af33))); assert_eq!(decode(0x0020af33).unwrap(), Slt(RType(0x0020af33))); assert_eq!(decode(0x0020af33).unwrap(), Slt(RType(0x0020af33))); assert_eq!(decode(0x0020bf33).unwrap(), Sltu(RType(0x0020bf33))); assert_eq!(decode(0x0020bf33).unwrap(), Sltu(RType(0x0020bf33))); assert_eq!(decode(0x000030b3).unwrap(), Sltu(RType(0x000030b3))); assert_eq!(decode(0x00f647b3).unwrap(), Xor(RType(0x00f647b3))); assert_eq!(decode(0x0020cf33).unwrap(), Xor(RType(0x0020cf33))); assert_eq!(decode(0x0020c133).unwrap(), Xor(RType(0x0020c133))); assert_eq!(decode(0x0020d0b3).unwrap(), Srl(RType(0x0020d0b3))); assert_eq!(decode(0x0020df33).unwrap(), Srl(RType(0x0020df33))); assert_eq!(decode(0x0020df33).unwrap(), Srl(RType(0x0020df33))); assert_eq!(decode(0x4020df33).unwrap(), Sra(RType(0x4020df33))); assert_eq!(decode(0x400050b3).unwrap(), Sra(RType(0x400050b3))); assert_eq!(decode(0x4020d133).unwrap(), Sra(RType(0x4020d133))); assert_eq!(decode(0x00b7e5b3).unwrap(), Or(RType(0x00b7e5b3))); assert_eq!(decode(0x00f665b3).unwrap(), Or(RType(0x00f665b3))); assert_eq!(decode(0x00b7e7b3).unwrap(), Or(RType(0x00b7e7b3))); assert_eq!(decode(0x00d57533).unwrap(), And(RType(0x00d57533))); assert_eq!(decode(0x00b7f733).unwrap(), And(RType(0x00b7f733))); assert_eq!(decode(0x00c7f733).unwrap(), And(RType(0x00c7f733))); assert_eq!(decode(0x021080b3).unwrap(), Mul(RType(0x021080b3))); assert_eq!(decode(0x02208f33).unwrap(), Mul(RType(0x02208f33))); assert_eq!(decode(0x02208133).unwrap(), Mul(RType(0x02208133))); assert_eq!(decode(0x02209133).unwrap(), Mulh(RType(0x02209133))); assert_eq!(decode(0x02209f33).unwrap(), Mulh(RType(0x02209f33))); assert_eq!(decode(0x02209f33).unwrap(), Mulh(RType(0x02209f33))); assert_eq!(decode(0x0220a133).unwrap(), Mulhsu(RType(0x0220a133))); assert_eq!(decode(0x0220af33).unwrap(), Mulhsu(RType(0x0220af33))); assert_eq!(decode(0x0220af33).unwrap(), Mulhsu(RType(0x0220af33))); assert_eq!(decode(0x0220bf33).unwrap(), Mulhu(RType(0x0220bf33))); assert_eq!(decode(0x0220bf33).unwrap(), Mulhu(RType(0x0220bf33))); assert_eq!(decode(0x0220bf33).unwrap(), Mulhu(RType(0x0220bf33))); assert_eq!(decode(0x0220cf33).unwrap(), Div(RType(0x0220cf33))); assert_eq!(decode(0x0220cf33).unwrap(), Div(RType(0x0220cf33))); assert_eq!(decode(0x0220cf33).unwrap(), Div(RType(0x0220cf33))); assert_eq!(decode(0x0220df33).unwrap(), Divu(RType(0x0220df33))); assert_eq!(decode(0x0220df33).unwrap(), Divu(RType(0x0220df33))); assert_eq!(decode(0x0220df33).unwrap(), Divu(RType(0x0220df33))); assert_eq!(decode(0x0220ef33).unwrap(), Rem(RType(0x0220ef33))); assert_eq!(decode(0x0220ef33).unwrap(), Rem(RType(0x0220ef33))); assert_eq!(decode(0x0220ef33).unwrap(), Rem(RType(0x0220ef33))); assert_eq!(decode(0x0220ff33).unwrap(), Remu(RType(0x0220ff33))); assert_eq!(decode(0x0220ff33).unwrap(), Remu(RType(0x0220ff33))); assert_eq!(decode(0x0220ff33).unwrap(), Remu(RType(0x0220ff33))); }
#[test]
fn op32() {
assert_eq!(decode(0x00c687bb).unwrap(), Addw(RType(0x00c687bb))); assert_eq!(decode(0x00c687bb).unwrap(), Addw(RType(0x00c687bb))); assert_eq!(decode(0x00208f3b).unwrap(), Addw(RType(0x00208f3b))); assert_eq!(decode(0x40e5053b).unwrap(), Subw(RType(0x40e5053b))); assert_eq!(decode(0x40e5053b).unwrap(), Subw(RType(0x40e5053b))); assert_eq!(decode(0x40e5053b).unwrap(), Subw(RType(0x40e5053b))); assert_eq!(decode(0x001090bb).unwrap(), Sllw(RType(0x001090bb))); assert_eq!(decode(0x00209f3b).unwrap(), Sllw(RType(0x00209f3b))); assert_eq!(decode(0x00209f3b).unwrap(), Sllw(RType(0x00209f3b))); assert_eq!(decode(0x0020df3b).unwrap(), Srlw(RType(0x0020df3b))); assert_eq!(decode(0x0020df3b).unwrap(), Srlw(RType(0x0020df3b))); assert_eq!(decode(0x0020d13b).unwrap(), Srlw(RType(0x0020d13b))); assert_eq!(decode(0x4020df3b).unwrap(), Sraw(RType(0x4020df3b))); assert_eq!(decode(0x4020df3b).unwrap(), Sraw(RType(0x4020df3b))); assert_eq!(decode(0x4020df3b).unwrap(), Sraw(RType(0x4020df3b))); assert_eq!(decode(0x02208f3b).unwrap(), Mulw(RType(0x02208f3b))); assert_eq!(decode(0x02208f3b).unwrap(), Mulw(RType(0x02208f3b))); assert_eq!(decode(0x02208f3b).unwrap(), Mulw(RType(0x02208f3b))); assert_eq!(decode(0x0220cf3b).unwrap(), Divw(RType(0x0220cf3b))); assert_eq!(decode(0x0220cf3b).unwrap(), Divw(RType(0x0220cf3b))); assert_eq!(decode(0x0220cf3b).unwrap(), Divw(RType(0x0220cf3b))); assert_eq!(decode(0x0220df3b).unwrap(), Divuw(RType(0x0220df3b))); assert_eq!(decode(0x0220df3b).unwrap(), Divuw(RType(0x0220df3b))); assert_eq!(decode(0x0220df3b).unwrap(), Divuw(RType(0x0220df3b))); assert_eq!(decode(0x0220ef3b).unwrap(), Remw(RType(0x0220ef3b))); assert_eq!(decode(0x0220ef3b).unwrap(), Remw(RType(0x0220ef3b))); assert_eq!(decode(0x0220ef3b).unwrap(), Remw(RType(0x0220ef3b))); assert_eq!(decode(0x0220ff3b).unwrap(), Remuw(RType(0x0220ff3b))); assert_eq!(decode(0x0220ff3b).unwrap(), Remuw(RType(0x0220ff3b))); assert_eq!(decode(0x0220ff3b).unwrap(), Remuw(RType(0x0220ff3b))); }
#[test]
fn branch() {
assert_eq!(decode(0x10e78463).unwrap(), Beq(BType(0x10e78463))); assert_eq!(decode(0x00050a63).unwrap(), Beq(BType(0x00050a63))); assert_eq!(decode(0x1b5a0463).unwrap(), Beq(BType(0x1b5a0463))); assert_eq!(decode(0xfe5210e3).unwrap(), Bne(BType(0xfe5210e3))); assert_eq!(decode(0x00e79a63).unwrap(), Bne(BType(0x00e79a63))); assert_eq!(decode(0x25df1863).unwrap(), Bne(BType(0x25df1863))); assert_eq!(decode(0x1220c063).unwrap(), Blt(BType(0x1220c063))); assert_eq!(decode(0x00054863).unwrap(), Blt(BType(0x00054863))); assert_eq!(decode(0xfe20cee3).unwrap(), Blt(BType(0xfe20cee3))); assert_eq!(decode(0x000f5463).unwrap(), Bge(BType(0x000f5463))); assert_eq!(decode(0x0020d663).unwrap(), Bge(BType(0x0020d663))); assert_eq!(decode(0x0620d463).unwrap(), Bge(BType(0x0620d463))); assert_eq!(decode(0xfec7ece3).unwrap(), Bltu(BType(0xfec7ece3))); assert_eq!(decode(0xfec7ece3).unwrap(), Bltu(BType(0xfec7ece3))); assert_eq!(decode(0x0020e663).unwrap(), Bltu(BType(0x0020e663))); assert_eq!(decode(0x00f5f463).unwrap(), Bgeu(BType(0x00f5f463))); assert_eq!(decode(0x00f5f463).unwrap(), Bgeu(BType(0x00f5f463))); assert_eq!(decode(0xfec572e3).unwrap(), Bgeu(BType(0xfec572e3))); }
#[test]
fn system() {
assert_eq!(decode(0x00000073).unwrap(), Ecall); assert_eq!(decode(0x10200073).unwrap(), Sret); assert_eq!(decode(0x30200073).unwrap(), Mret); assert_eq!(decode(0x10500073).unwrap(), Wfi); assert_eq!(decode(0x10569073).unwrap(), Csrrw(CsrType(0x10569073))); assert_eq!(decode(0x18079073).unwrap(), Csrrw(CsrType(0x18079073))); assert_eq!(decode(0x10551073).unwrap(), Csrrw(CsrType(0x10551073))); assert_eq!(decode(0x1007a073).unwrap(), Csrrs(CsrType(0x1007a073))); assert_eq!(decode(0x1006a073).unwrap(), Csrrs(CsrType(0x1006a073))); assert_eq!(decode(0x1004b073).unwrap(), Csrrc(CsrType(0x1004b073))); assert_eq!(decode(0x100db073).unwrap(), Csrrc(CsrType(0x100db073))); assert_eq!(decode(0x1006b073).unwrap(), Csrrc(CsrType(0x1006b073))); assert_eq!(decode(0x14005073).unwrap(), Csrrwi(CsrIType(0x14005073))); assert_eq!(decode(0x10016073).unwrap(), Csrrsi(CsrIType(0x10016073))); assert_eq!(decode(0x100176f3).unwrap(), Csrrci(CsrIType(0x100176f3))); assert_eq!(decode(0x10017773).unwrap(), Csrrci(CsrIType(0x10017773))); }
#[test]
fn float() {
assert_eq!(decode(0x0004a787).unwrap(), Flw(IType(0x0004a787))); assert_eq!(decode(0x1e872687).unwrap(), Flw(IType(0x1e872687))); assert_eq!(decode(0x1e472707).unwrap(), Flw(IType(0x1e472707))); assert_eq!(decode(0x00aa2027).unwrap(), Fsw(SType(0x00aa2027))); assert_eq!(decode(0x00f4a027).unwrap(), Fsw(SType(0x00f4a027))); assert_eq!(decode(0x00fba827).unwrap(), Fsw(SType(0x00fba827))); assert_eq!(decode(0xd19b1543).unwrap(), Fmadds(R4Type(0xd19b1543))); assert_eq!(decode(0x114f8bc3).unwrap(), Fmadds(R4Type(0x114f8bc3))); assert_eq!(decode(0x08cf53c3).unwrap(), Fmadds(R4Type(0x08cf53c3))); assert_eq!(decode(0x3166dd47).unwrap(), Fmsubs(R4Type(0x3166dd47))); assert_eq!(decode(0x50077347).unwrap(), Fmsubs(R4Type(0x50077347))); assert_eq!(decode(0xb903e1c7).unwrap(), Fmsubs(R4Type(0xb903e1c7))); assert_eq!(decode(0xc9cd48cb).unwrap(), Fnmsubs(R4Type(0xc9cd48cb))); assert_eq!(decode(0xa1ee44cb).unwrap(), Fnmsubs(R4Type(0xa1ee44cb))); assert_eq!(decode(0xf8db734b).unwrap(), Fnmsubs(R4Type(0xf8db734b))); assert_eq!(decode(0x19613e4f).unwrap(), Fnmadds(R4Type(0x19613e4f))); assert_eq!(decode(0xc944cfcf).unwrap(), Fnmadds(R4Type(0xc944cfcf))); assert_eq!(decode(0x191506cf).unwrap(), Fnmadds(R4Type(0x191506cf))); assert_eq!(decode(0x0127f553).unwrap(), Fadds(RType(0x0127f553))); assert_eq!(decode(0x01257553).unwrap(), Fadds(RType(0x01257553))); assert_eq!(decode(0x0135f9d3).unwrap(), Fadds(RType(0x0135f9d3))); assert_eq!(decode(0x0897f7d3).unwrap(), Fsubs(RType(0x0897f7d3))); assert_eq!(decode(0x0957f7d3).unwrap(), Fsubs(RType(0x0957f7d3))); assert_eq!(decode(0x0935f753).unwrap(), Fsubs(RType(0x0935f753))); assert_eq!(decode(0x10f97953).unwrap(), Fmuls(RType(0x10f97953))); assert_eq!(decode(0x1187f7d3).unwrap(), Fmuls(RType(0x1187f7d3))); assert_eq!(decode(0x116b7553).unwrap(), Fmuls(RType(0x116b7553))); assert_eq!(decode(0x1947f553).unwrap(), Fdivs(RType(0x1947f553))); assert_eq!(decode(0x18a7f553).unwrap(), Fdivs(RType(0x18a7f553))); assert_eq!(decode(0x18f777d3).unwrap(), Fdivs(RType(0x18f777d3))); assert_eq!(decode(0x58057553).unwrap(), Fsqrts(RType(0x58057553))); assert_eq!(decode(0x580e35d3).unwrap(), Fsqrts(RType(0x580e35d3))); assert_eq!(decode(0x5808c0d3).unwrap(), Fsqrts(RType(0x5808c0d3))); assert_eq!(decode(0x21ca0ed3).unwrap(), Fsgnjs(RType(0x21ca0ed3))); assert_eq!(decode(0x20d103d3).unwrap(), Fsgnjs(RType(0x20d103d3))); assert_eq!(decode(0x209c0d53).unwrap(), Fsgnjs(RType(0x209c0d53))); assert_eq!(decode(0x21dd1b53).unwrap(), Fsgnjns(RType(0x21dd1b53))); assert_eq!(decode(0x20971153).unwrap(), Fsgnjns(RType(0x20971153))); assert_eq!(decode(0x211d1953).unwrap(), Fsgnjns(RType(0x211d1953))); assert_eq!(decode(0x20eb2153).unwrap(), Fsgnjxs(RType(0x20eb2153))); assert_eq!(decode(0x219fa7d3).unwrap(), Fsgnjxs(RType(0x219fa7d3))); assert_eq!(decode(0x215baad3).unwrap(), Fsgnjxs(RType(0x215baad3))); assert_eq!(decode(0x286b82d3).unwrap(), Fmins(RType(0x286b82d3))); assert_eq!(decode(0x29ac88d3).unwrap(), Fmins(RType(0x29ac88d3))); assert_eq!(decode(0x29728c53).unwrap(), Fmins(RType(0x29728c53))); assert_eq!(decode(0x29441153).unwrap(), Fmaxs(RType(0x29441153))); assert_eq!(decode(0x29689fd3).unwrap(), Fmaxs(RType(0x29689fd3))); assert_eq!(decode(0x286a1fd3).unwrap(), Fmaxs(RType(0x286a1fd3))); assert_eq!(decode(0xc0056553).unwrap(), Fcvtws(RType(0xc0056553))); assert_eq!(decode(0xc006fad3).unwrap(), Fcvtws(RType(0xc006fad3))); assert_eq!(decode(0xc00fa8d3).unwrap(), Fcvtws(RType(0xc00fa8d3))); assert_eq!(decode(0xc014cb53).unwrap(), Fcvtwus(RType(0xc014cb53))); assert_eq!(decode(0xc01698d3).unwrap(), Fcvtwus(RType(0xc01698d3))); assert_eq!(decode(0xc01e5dd3).unwrap(), Fcvtwus(RType(0xc01e5dd3))); assert_eq!(decode(0xe00482d3).unwrap(), Fmvxw(RType(0xe00482d3))); assert_eq!(decode(0xe00d86d3).unwrap(), Fmvxw(RType(0xe00d86d3))); assert_eq!(decode(0xe0088053).unwrap(), Fmvxw(RType(0xe0088053))); assert_eq!(decode(0xa0742153).unwrap(), Feqs(RType(0xa0742153))); assert_eq!(decode(0xa0a0a153).unwrap(), Feqs(RType(0xa0a0a153))); assert_eq!(decode(0xa1aba853).unwrap(), Feqs(RType(0xa1aba853))); assert_eq!(decode(0xa0651953).unwrap(), Flts(RType(0xa0651953))); assert_eq!(decode(0xa0ab9f53).unwrap(), Flts(RType(0xa0ab9f53))); assert_eq!(decode(0xa19595d3).unwrap(), Flts(RType(0xa19595d3))); assert_eq!(decode(0xa1ff8d53).unwrap(), Fles(RType(0xa1ff8d53))); assert_eq!(decode(0xa0f40653).unwrap(), Fles(RType(0xa0f40653))); assert_eq!(decode(0xa1ab0c53).unwrap(), Fles(RType(0xa1ab0c53))); assert_eq!(decode(0xe00a1e53).unwrap(), Fclasss(RType(0xe00a1e53))); assert_eq!(decode(0xe00f1c53).unwrap(), Fclasss(RType(0xe00f1c53))); assert_eq!(decode(0xe00e9d53).unwrap(), Fclasss(RType(0xe00e9d53))); assert_eq!(decode(0xd009d7d3).unwrap(), Fcvtsw(RType(0xd009d7d3))); assert_eq!(decode(0xd001a953).unwrap(), Fcvtsw(RType(0xd001a953))); assert_eq!(decode(0xd00507d3).unwrap(), Fcvtsw(RType(0xd00507d3))); assert_eq!(decode(0xd01c27d3).unwrap(), Fcvtswu(RType(0xd01c27d3))); assert_eq!(decode(0xd019edd3).unwrap(), Fcvtswu(RType(0xd019edd3))); assert_eq!(decode(0xd012c3d3).unwrap(), Fcvtswu(RType(0xd012c3d3))); assert_eq!(decode(0xf0000e53).unwrap(), Fmvwx(RType(0xf0000e53))); assert_eq!(decode(0xf0098053).unwrap(), Fmvwx(RType(0xf0098053))); assert_eq!(decode(0xf00081d3).unwrap(), Fmvwx(RType(0xf00081d3))); }
#[test]
fn amo() {
assert_eq!(decode(0x08b6a72f).unwrap(), AmoswapW(RType(0x08b6a72f))); assert_eq!(decode(0x00b6a72f).unwrap(), AmoaddW(RType(0x00b6a72f))); assert_eq!(decode(0x20b6a72f).unwrap(), AmoxorW(RType(0x20b6a72f))); assert_eq!(decode(0x60b6a72f).unwrap(), AmoandW(RType(0x60b6a72f))); assert_eq!(decode(0x40b6a72f).unwrap(), AmoorW(RType(0x40b6a72f))); assert_eq!(decode(0x80b6a72f).unwrap(), AmominW(RType(0x80b6a72f))); assert_eq!(decode(0xa0b6a72f).unwrap(), AmomaxW(RType(0xa0b6a72f))); assert_eq!(decode(0xc0b6a72f).unwrap(), AmominuW(RType(0xc0b6a72f))); assert_eq!(decode(0xe0b6a72f).unwrap(), AmomaxuW(RType(0xe0b6a72f))); assert_eq!(decode(0x100525af).unwrap(), LrW(RType(0x100525af))); assert_eq!(decode(0x180525af).unwrap(), ScW(RType(0x180525af))); assert_eq!(decode(0x08b6b72f).unwrap(), AmoswapD(RType(0x08b6b72f))); assert_eq!(decode(0x00b6b72f).unwrap(), AmoaddD(RType(0x00b6b72f))); assert_eq!(decode(0x20b6b72f).unwrap(), AmoxorD(RType(0x20b6b72f))); assert_eq!(decode(0x60b6b72f).unwrap(), AmoandD(RType(0x60b6b72f))); assert_eq!(decode(0x40b6b72f).unwrap(), AmoorD(RType(0x40b6b72f))); assert_eq!(decode(0x80b6b72f).unwrap(), AmominD(RType(0x80b6b72f))); assert_eq!(decode(0xa0b6b72f).unwrap(), AmomaxD(RType(0xa0b6b72f))); assert_eq!(decode(0xc0b6b72f).unwrap(), AmominuD(RType(0xc0b6b72f))); assert_eq!(decode(0xe0b6b72f).unwrap(), AmomaxuD(RType(0xe0b6b72f))); assert_eq!(decode(0x1005372f).unwrap(), LrD(RType(0x1005372f))); assert_eq!(decode(0x180535af).unwrap(), ScD(RType(0x180535af))); }
}