2023-01-11 14:58:12 +01:00
pub mod machine ;
2023-03-23 20:04:21 +01:00
pub mod error ;
2023-03-29 16:08:06 +02:00
pub mod instruction ;
2023-02-08 14:34:09 +01:00
pub mod mem_cmp ;
2023-02-15 17:20:10 +01:00
pub mod loader ;
2023-03-01 17:18:45 +01:00
pub mod interrupt ;
2023-03-13 22:52:27 +01:00
pub mod translationtable ;
pub mod mmu ;
2023-03-24 17:44:24 +01:00
pub mod register ;
2023-01-20 18:21:32 +01:00
2023-03-24 19:02:50 +01:00
/// Definition of global constants
2023-01-20 18:21:32 +01:00
pub mod global {
#![ allow(dead_code) ]
#![ allow(unused_variables) ]
// Instructions type:
// - R: Register / register
// - I: Immediate
// - U: Upper-Immediate
// - S: Store
// - B: Branch (conditional branches...)
// - J: Jump
// xlen = i64::MAX_VALUE on rv64 and i32::MAX_VALUE on rv32
/// Type: U
///
/// Load upper immediate
///
/// `LUI rd, imm31_12` => `rd <- imm31_12 << 12`
///
pub const RISCV_LUI : u8 = 0x37 ;
/// Type: U
///
/// Add upper immediate to PC
///
/// `AUIP rd, imm31_12` => `rd <- PC + imm31_12 << 12`
pub const RISCV_AUIPC : u8 = 0x17 ;
/// Type: J
///
/// Jump and link
///
/// `JAL rd, imm20(rs1)` => `rd <- pc + 4; pc <- rs1 + imm12`
pub const RISCV_JAL : u8 = 0x6f ;
/// type: J
///
/// Jump and link register
///
/// `JALR rd, imm12(rs1)` => `rd <- pc + 4; pc <- rs1 + imm12`
pub const RISCV_JALR : u8 = 0x67 ;
pub const RISCV_BR : u8 = 0x63 ;
/// Load instructions
///
/// See func3 to know the type of instruction (LD, LW, LH, LB, LWU, LHU, LBU)
pub const RISCV_LD : u8 = 0x3 ;
2023-03-24 19:02:50 +01:00
/// Store instructions
2023-01-20 18:21:32 +01:00
pub const RISCV_ST : u8 = 0x23 ;
2023-03-24 19:02:50 +01:00
/// immediate Arithmetic operations
2023-01-20 18:21:32 +01:00
pub const RISCV_OPI : u8 = 0x13 ;
2023-03-24 19:02:50 +01:00
/// Arithmetic operations
2023-01-20 18:21:32 +01:00
pub const RISCV_OP : u8 = 0x33 ;
/// Immediate arithmetic operations for rv64i
pub const RISCV_OPIW : u8 = 0x1b ;
2023-03-24 19:02:50 +01:00
/// Arithmetic operations for rv64i
2023-01-20 18:21:32 +01:00
pub const RISCV_OPW : u8 = 0x3b ;
/// Type: B
///
/// Branch equal
///
/// `BEQ rs1, rs2, imm12` => `if rs1 = rs2 then pc <- pc + imm12`
pub const RISCV_BR_BEQ : u8 = 0x0 ;
/// Type: B
///
/// Branch not equal
///
/// `BNE rs1, rs2, imm12` => `if rs1 != rs2 then pc <- pc + imm12`
pub const RISCV_BR_BNE : u8 = 0x1 ;
/// Type: B
///
/// Branch less than
///
/// `BLT rs1, rs2, imm12` => `if rs1 < rs2 then pc <- pc + imm12`
pub const RISCV_BR_BLT : u8 = 0x4 ;
/// Type: B
///
/// Branch greater than or equal
///
/// `BGE rs1, rs2, imm12` => `if rs1 >= rs2 then pc <- pc + imm12`
pub const RISCV_BR_BGE : u8 = 0x5 ;
/// Type: B
///
/// Branch less than unsigned
///
/// Same as BLT but for unsigned values
pub const RISCV_BR_BLTU : u8 = 0x6 ;
/// Type: B
///
/// Greater than or equal unsigned
///
/// Same as BGE but for unsigned values
pub const RISCV_BR_BGEU : u8 = 0x7 ;
/// Type: I
///
/// Load byte (8 bits word)
///
/// `LB rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LB : u8 = 0x0 ;
/// Type: I
///
/// Load halfword (16 bits word)
///
/// `LH rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LH : u8 = 0x1 ;
/// Type: I
///
/// Load word (32 bits word)
///
/// `LW rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LW : u8 = 0x2 ;
/// Type: I
///
/// Load doubleword (64-bits word)
///
/// `LD rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LD : u8 = 0x3 ;
/// Type: I
///
/// Load byte unsigned
///
/// `LBU rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LBU : u8 = 0x4 ;
/// Type: I
///
/// Load halfword unsigned
///
/// `LHU rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LHU : u8 = 0x5 ;
/// Type: I
///
/// Load word unsigned (64 bits word)
///
/// `LW rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LWU : u8 = 0x6 ;
/// Type: S
///
/// Store halfword (SH) (16 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 16 bits values are stored
///
/// `SH rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STH : u8 = 0x1 ;
/// Type: S
///
/// Store word (SW) (32 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 32 bits values are stored
///
/// `SW rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STW : u8 = 0x2 ;
/// Type: S
///
/// Store byte (SB) (8 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 8 bits values are stored
///
/// `SB rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STB : u8 = 0x0 ;
/// Type: S
///
/// Store doubleword (SD) (64 bits)
///
2023-02-01 16:39:40 +01:00
/// `SD rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
2023-01-20 18:21:32 +01:00
pub const RISCV_ST_STD : u8 = 0x3 ;
/// Type: I
///
/// Add immediate
///
/// `addi rd, rs1, imm12` => `rd <- rs1 + imm12`
pub const RISCV_OPI_ADDI : u8 = 0x0 ;
/// Type: I
///
/// Set less than immediate: set rd to 1 if rs1 < imm12, 0 otherwise
///
/// `SLT rd, rs1, imm12` => `rd <- rs1 < imm12 ? 1 : 0`
pub const RISCV_OPI_SLTI : u8 = 0x2 ;
/// Type: I
///
/// Set less than immediate unsigned : same than SLTI but for unsigned values
pub const RISCV_OPI_SLTIU : u8 = 0x3 ;
/// Type: I
///
/// XOR immediate instruction
///
/// `XORI rd, rs1, imm12` => `rd <- rs1 ^ imm12`
pub const RISCV_OPI_XORI : u8 = 0x4 ;
/// Type: I
///
/// OR immediate instruction
///
/// `ORI rd, rs1, imm12` => `rd <- rs1 | imm12`
pub const RISCV_OPI_ORI : u8 = 0x6 ;
/// Type: I
///
/// AND immediate instruction
///
/// `ANDI rd, rs1, imm12` => `rd <- rs1 & imm12`
pub const RISCV_OPI_ANDI : u8 = 0x7 ;
/// Type: I
///
/// Shift left logical immediate
///
/// `SLLI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SLLI : u8 = 0x1 ;
/// Shift right immediate, may be SRAI or SRLI
pub const RISCV_OPI_SRI : u8 = 0x5 ;
/// type: I
///
/// Shift right arithmetic immediate
///
/// `SRAI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SRI_SRAI : u8 = 0x20 ;
/// type: I
///
/// Shift right logical immediate
///
/// `SRLI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SRI_SRLI : u8 = 0x0 ;
/// Type: R
///
/// Add or sub (see RISCV_OP_ADD_ADD or RISCV_OP_ADD_SUB) depending of func7 value
pub const RISCV_OP_ADD : u8 = 0x0 ;
/// Type: R
///
/// Shift left logical, add a 0 on right of the word
///
/// `SLL rd, rs1, rs2` => `rs <- rs1 << rs2`
pub const RISCV_OP_SLL : u8 = 0x1 ;
/// Type: R
///
/// Set less than : set rd to 1 if rs1 < rs2, 0 otherwise
///
/// `SLT rd, rs1, rs2` => `rd <- rs1 < rs2 ? 1 : 0`
pub const RISCV_OP_SLT : u8 = 0x2 ;
/// Type: R
///
/// Set less than unsigned : same than SLT but for unsigned values
pub const RISCV_OP_SLTU : u8 = 0x3 ;
/// Type: R
///
/// XOR instruction
///
/// `XOR rd, rs1, rs2` => `rd <- rs1 ^ rs2`
pub const RISCV_OP_XOR : u8 = 0x4 ;
pub const RISCV_OP_SR : u8 = 0x5 ;
/// Type: R
///
/// OR instruction
///
/// `OR rd, rs1, rs2` => `rd <- rs1 | rs2`
pub const RISCV_OP_OR : u8 = 0x6 ;
/// Type: R
///
/// AND instruction
///
/// `AND rd, rs1, rs2` => `rd <- rs1 & rs2`
pub const RISCV_OP_AND : u8 = 0x7 ;
/// Type : R
///
/// Addition
///
/// `ADD rd, rs1, rs2` => `rd <- rs1 + rs2`
pub const RISCV_OP_ADD_ADD : u8 = 0x0 ;
/// Type: R
///
/// Substract
///
/// `SUB rd, rs1, rs2` => `rd <- rs1 - rs2`
pub const RISCV_OP_ADD_SUB : u8 = 0x20 ;
/// Type: R
///
/// Shift right logical, add a 0 at the left of the word (should not used for signed values in most cases)
///
/// `SRL rd, rs1, rs2` => `rd <- rs1 >> rs2`
pub const RISCV_OP_SR_SRL : u8 = 0x0 ;
/// Type: R
///
/// Shift right arithmetic, add a 1 at the left of the word(useful for signed values bacause it keep signed value)
///
/// `SRA rd, rs1, rs2` => `rd <- rs1 >> rs2`
pub const RISCV_OP_SR_SRA : u8 = 0x20 ;
// ECALL or EBREAK from base instructions
/// or instructions from Ricsr extension
pub const RISCV_SYSTEM : u8 = 0x73 ;
/// Type: I
///
/// Add immediate word (RV64I only)
///
/// `ADDIW rd, rs1, imm12` => `rd <- rs1 + imm12`
pub const RISCV_OPIW_ADDIW : u8 = 0x0 ;
/// Type: I
///
/// Shift right logical immediate word (RV64I only)
///
2023-02-04 18:16:52 +01:00
/// `SLLIW rd, rs1, imm12` => `rd <- rs1 >> shamt`
2023-01-20 18:21:32 +01:00
pub const RISCV_OPIW_SLLIW : u8 = 0x1 ;
/// Shift right immediate instructions (logical or arithmetic depend of func7)
pub const RISCV_OPIW_SRW : u8 = 0x5 ;
/// Type: I
///
/// Shift right logical immediate word (RV64I only)
///
2023-02-04 18:16:52 +01:00
/// `SRLIW rd, rs1, imm12` => `rd <- rs1 >> shamt`
2023-01-20 18:21:32 +01:00
///
/// Complete left bits by a zero, should be used with an unsigned value in most case
pub const RISCV_OPIW_SRW_SRLIW : u8 = 0x0 ;
/// Type: I
///
/// Shift right arithmetic immediate word (RV64I only)
///
2023-02-04 18:16:52 +01:00
/// `SRAIW rd, rs1, imm12` => `rd <- rs1 >> shamt`
2023-01-20 18:21:32 +01:00
///
/// Keep sign bit
pub const RISCV_OPIW_SRW_SRAIW : u8 = 0x20 ;
// ADD or SUB immediate instructions, depend of func7 value
pub const RISCV_OPW_ADDSUBW : u8 = 0x0 ;
/// Type: R
///
/// Shift left logical word (RV64I only)
///
/// `SLLW rd, rs1, rs2` => `rd <- rs1 << rs2`
pub const RISCV_OPW_SLLW : u8 = 0x1 ;
/// Shift right word instructions (logical or arithmetic depend of func3)
pub const RISCV_OPW_SRW : u8 = 0x5 ;
/// Type: R
///
/// Add word (rv64I only)
///
/// `ADDW rd, rs1, rs2` => `rd <- rs1 + rs2`
pub const RISCV_OPW_ADDSUBW_ADDW : u8 = 0x0 ;
/// Type: R
///
/// Subtract word (rv64I only)
///
/// `SUBW rd, rs1, rs2` => `rd <- rs1 - rs2`
pub const RISCV_OPW_ADDSUBW_SUBW : u8 = 0x20 ;
/// Type: R
///
/// Shift right logical word (rv64I only)
///
/// rd <- rs1 >> rs2
///
/// Complete left bits by a 0, should be used with an unsigned value
pub const RISCV_OPW_SRW_SRLW : u8 = 0x0 ;
/// Type: R
///
/// Shift right arithmetic word (rv64I only)
///
/// `SRAW rd, rs1, rs2` => `rd <- rs1 >> rs2`
///
/// Keep sign bit
pub const RISCV_OPW_SRW_SRAW : u8 = 0x20 ;
pub const RISCV_SYSTEM_ENV : u8 = 0x0 ;
pub const RISCV_SYSTEM_ENV_ECALL : u8 = 0x0 ;
pub const RISCV_SYSTEM_ENV_EBREAK : u8 = 0x1 ;
pub const RISCV_SYSTEM_CSRRS : u8 = 0x2 ;
pub const RISCV_SYSTEM_CSRRW : u8 = 0x1 ;
pub const RISCV_SYSTEM_CSRRC : u8 = 0x3 ;
pub const RISCV_SYSTEM_CSRRWI : u8 = 0x5 ;
pub const RISCV_SYSTEM_CSRRSI : u8 = 0x6 ;
pub const RISCV_SYSTEM_CSRRCI : u8 = 0x7 ;
pub const RISCV_FLW : u8 = 0x07 ;
pub const RISCV_FSW : u8 = 0x27 ;
pub const RISCV_FMADD : u8 = 0x43 ;
pub const RISCV_FMSUB : u8 = 0x47 ;
pub const RISCV_FNMSUB : u8 = 0x4b ;
pub const RISCV_FNMADD : u8 = 0x4f ;
2023-01-23 12:52:32 +01:00
2023-01-20 18:21:32 +01:00
/// Simple floating point extension
pub const RISCV_FP : u8 = 0x53 ;
2023-01-23 12:52:32 +01:00
/// Type: R
///
/// Simple precision floating point addition
///
/// `FADD.S rd, rs1, rs2` => `rd <- rs1 + rs2`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_ADD : u8 = 0x0 ;
2023-01-23 12:52:32 +01:00
/// Type: R
///
/// Simple precision floating point substraction
///
/// `FSUB.S rd, rs1, rs2` => `rd <- rs1 - rs2`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_SUB : u8 = 0x4 ;
2023-01-23 12:52:32 +01:00
/// Type: R
///
/// Simple precision floating point multiplication
///
/// `fmul.s rd, rs1, rs2` => `rd <- rs1 * rs2`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_MUL : u8 = 0x8 ;
2023-01-23 12:52:32 +01:00
/// Type : R
///
/// Simple precision floating point division
///
/// `fdiv.s rd, rs1, rs2` => `rd <- rs1 / rs2`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_DIV : u8 = 0xc ;
2023-01-23 12:52:32 +01:00
/// Type: R
///
/// Simple precision square root
///
/// `fsqrt.s rd, rs1` => `rd <- sqrt(rs1)`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_SQRT : u8 = 0x2c ;
2023-01-23 12:52:32 +01:00
/// FSGN instructions
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FSGN : u8 = 0x10 ;
2023-01-23 12:52:32 +01:00
// fmin or fmax instructions
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_MINMAX : u8 = 0x14 ;
2023-01-23 14:29:37 +01:00
/// fcvt.w instructions
///
/// convert fp to integer
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCVTW : u8 = 0x60 ;
2023-01-23 14:29:37 +01:00
/// fmv.x.w or fclass.s instruction
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FMVXFCLASS : u8 = 0x70 ;
2023-01-23 14:29:37 +01:00
/// floating points comparaison instructions
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCMP : u8 = 0x50 ;
pub const RISCV_FP_FEQS : u8 = 0x53 ;
2023-01-23 14:29:37 +01:00
/// fcvt.s instructions
///
/// Convert integer to fp
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCVTS : u8 = 0x68 ;
pub const RISCV_FP_FCVTDS : u8 = 0x21 ;
2023-01-23 12:52:32 +01:00
/// Type: R
///
/// Take all bits except sign bit from rs1. sign is rs2's sign bit
///
/// `fsgnj.s rd, rs1, rs2` => `rd <- {rs2[31], rs1[30:0]}`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FSGN_J : u8 = 0x0 ;
2023-01-23 12:52:32 +01:00
/// Type: R
///
/// Take all bits except sign bit from rs1, sign is opposite of rs2's sign bit
///
/// `fsgnjs.s rd, rs1, rs2` => `rd <- {rs2[31], rs[30:0]}`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FSGN_JN : u8 = 0x1 ;
2023-01-23 12:52:32 +01:00
/// Type: R
///
/// Take all bits except sign bit from rs1, sign is XOR of sign bit of rs1 and rs2
///
/// `fsgnjx.s rd, rs1, rs2` => `rd <- {rs1[31] ^ rs2[31], rs1[30:0]}`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FSGN_JX : u8 = 0x2 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// write the smaller number between rs1 and rs2 to rd
///
/// `fmin.s rd, rs1, rs2` => `rd <- min(rs1, rs2)`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_MINMAX_MIN : u8 = 0x0 ;
2023-01-23 14:29:37 +01:00
/// type: R
///
/// Write the larger number between rs1 and rs2 to rd
///
/// `fmax.s rd, rs1, rs2` => `rd <- max(rs1, rs2)`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_MINMAX_MAX : u8 = 0x1 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// Convert a floating point number in register to a signed 32-bit integer and write it in integer register
///
/// `fcvt.w.s rd, rs1` => `rd <- rs1_f32 as i32`
///
/// rd is integer register and rs1 is floating point register
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCVTW_W : u8 = 0x0 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// Convert a floating point number in register to a unsigned 32 bit integer and write it in integer register
///
/// `fcvt.wu.s rd, rs1` => `rd <- rs1_f32 as u32`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCVTW_WU : u8 = 0x1 ;
2023-01-23 14:29:37 +01:00
/// Type : R
///
/// Convert signed 32 bit integer in register to a floating point number and write it in fp register
///
/// `fcvt.s.w rd, rs1` => `rd <- rs1_s32 as f32`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCVTS_W : u8 = 0x0 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// Convert unsigned 32 bit integer in register to a floating point number and write it in fp register
///
/// `fcvt.s.wu rd, rs1` => `rd <- rs1_u32 as f32`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCVTS_WU : u8 = 0x1 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// Move floating point value in register to integer register, bits value aren't modified during the process
///
/// On rv64, the lower 32 bits of the integer register are transfered, for the upper 32 bits, values are filles with copies of the floating point number's sign bit
///
/// `fmv.x.w rd ,rs1` => `rd[31,0] <- rs1; rd[63:32] <- rs[31]`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FMVXFCLASS_FMVX : u8 = 0x0 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// examine the value given in fp register rs1 and writes to integer register rd a 10 bit mask that indicates the class of the fp number.
/// Format is described here:
///
/// | rd bit | meaning |
/// |--------|------------------------------------|
/// | 0 | rs1 is -infinite |
/// | 1 | rs1 is a negative normal number |
/// | 2 | rs1 is a negative subnormal number |
/// | 3 | rs1 is -0 |
/// | 4 | rs1 is +0 |
/// | 5 | rs1 is a positive subnormal number |
/// | 6 | rs1 is a positive normal number |
/// | 7 | rs1 is +infinite |
/// | 8 | rs1 is a signaling NaN |
/// | 9 | rs1 is a quiet NaN |
///
/// All others bit in rd are cleared
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FMVXFCLASS_FCLASS : u8 = 0x1 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// Quiet equal comparaison, NaN cause an invalid operation exception
///
/// `feq.s rd, rs1, rs2` => `rd <- rs1 == rs2`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCMP_FEQ : u8 = 2 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// Quiet less comparaison, NaN cause an invalid operation exception
///
/// `flt.s rd, rs1, rs2` => `rdf <- rs1 < rs2`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCMP_FLT : u8 = 1 ;
2023-01-23 14:29:37 +01:00
/// Type: R
///
/// Quiet less or equal comparaison, NaN cause an invalid operation exception
///
/// `fle.s rd, rs1, rs2` => `rd <- rs1 <= rs2`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FCMP_FLE : u8 = 0 ;
2023-01-23 14:29:37 +01:00
/// Type : R
///
/// Move floating point value in integer register to the fp register. Bits aren't modified in the transfer
///
/// On rv64, only the lower 32 bits in the integer register are transfered.
///
/// `fmv.w.x rd, rs1` => `rd <- rs1[31:0]`
2023-01-20 18:21:32 +01:00
pub const RISCV_FP_FMVW : u8 = 0x78 ;
/// Integer, multiplication and division extension
pub const RISCV_OP_M : u8 = 0x1 ;
/// Type: R
///
/// Multiply
///
/// `MUL rd, rs1, rs2` => `rd <- rs1 * rs2`
pub const RISCV_OP_M_MUL : u8 = 0x0 ;
/// Type: R
///
/// Multiply high signed signed
///
/// `MULH rd, rs1, rs2` => `rd <- (rs1 * rs2) >> xlen`
///
/// rs1 and rs2 signed
pub const RISCV_OP_M_MULH : u8 = 0x1 ;
/// Type: R
///
/// Multiply high signed unsigned
///
/// `MULHSU rd, rs1, rs2` => `rd <- (rs1 x rs2) >> xlen`
///
/// rs1 is signed and rs2 is unsigned
pub const RISCV_OP_M_MULHSU : u8 = 0x2 ;
/// Type: R
///
/// Multiply high unsigned unsigned
///
/// `MULHU rd, rs1, rs2` => `rd <- (rs1 × rs2) >> xlen`
///
/// rs1 and rs2 unsigned
pub const RISCV_OP_M_MULHU : u8 = 0x3 ;
/// Type: R
///
/// Divide signed
///
/// `DIV rd, rs1, rs2` => `rd <- r1 / rs2`
pub const RISCV_OP_M_DIV : u8 = 0x4 ;
/// Type: R
///
/// Divide unsigned
///
/// `DIVU rd, rs1, rs2` => `rd <- rs1 / rs2`
pub const RISCV_OP_M_DIVU : u8 = 0x5 ;
/// Type: R
///
/// Remainder signed
///
/// `REM rd, rs1, rs2` => `rd <- rs1 % rs2`
pub const RISCV_OP_M_REM : u8 = 0x6 ;
/// Type: R
///
/// Remaindder unsigned
///
/// `REMU rd, rs1, rs2` => `rd <- rs1 % rs2`
pub const RISCV_OP_M_REMU : u8 = 0x7 ;
/// Type: R
///
/// Multiply Word (rv64M only)
///
/// `MULW rd, rs1, rs2` => `rd <- rs1 * rs2`
pub const RISCV_OPW_M_MULW : u8 = 0x0 ;
/// Type: R
///
/// Divide signed word (RV64M only)
///
/// `DIVW rd, rs1, rs2` => `rd <- rs1 / rs2`
pub const RISCV_OPW_M_DIVW : u8 = 0x4 ;
/// Type: R
///
/// Divide unsigned word
///
/// `DIVUW rd, rs1, rs2` => `red <- rs1 / rs2`
pub const RISCV_OPW_M_DIVUW : u8 = 0x5 ;
/// Type: R
///
/// Remainder signed word (RV64M only)
///
/// `REMW rd, rs1, rs2` => `rd <- rs1 % rs2`
pub const RISCV_OPW_M_REMW : u8 = 0x6 ;
/// Type: R
///
/// Remainder unsigned word (RV64M only)
///
/// `REMUW rd, rs1, rs2` => `rd <- rs1 % rs2`
pub const RISCV_OPW_M_REMUW : u8 = 0x7 ;
/// Instruction from Zifencei extension
pub const RISCV_FENCE : u8 = 0x0f ;
/// Atomic instructions extension
pub const RISCV_ATOM : u8 = 0x2f ;
pub const RISCV_ATOM_LR : u8 = 0x2 ;
pub const RISCV_ATOM_SC : u8 = 0x3 ;
pub const RISCV_ATOM_SWAP : u8 = 0x1 ;
pub const RISCV_ATOM_ADD : u8 = 0 ;
pub const RISCV_ATOM_XOR : u8 = 0x4 ;
pub const RISCV_ATOM_AND : u8 = 0xc ;
pub const RISCV_ATOM_OR : u8 = 0x8 ;
pub const RISCV_ATOM_MIN : u8 = 0x10 ;
pub const RISCV_ATOM_MAX : u8 = 0x14 ;
pub const RISCV_ATOM_MINU : u8 = 0x18 ;
pub const RISCV_ATOM_MAXU : u8 = 0x1c ;
}