659 lines
20 KiB
Rust
659 lines
20 KiB
Rust
pub mod machine;
|
||
pub mod decode;
|
||
pub mod print;
|
||
pub mod mem_cmp;
|
||
|
||
|
||
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;
|
||
// Store instructions
|
||
pub const RISCV_ST: u8 = 0x23;
|
||
// immediate Arithmetic operations
|
||
pub const RISCV_OPI: u8 = 0x13;
|
||
// Arithmetic operations
|
||
pub const RISCV_OP: u8 = 0x33;
|
||
/// Immediate arithmetic operations for rv64i
|
||
pub const RISCV_OPIW: u8 = 0x1b;
|
||
// Arithmetic operations for rv64i
|
||
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)
|
||
///
|
||
/// `SD rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
|
||
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)
|
||
///
|
||
/// `SLLIW rd, rs1, imm12` => `rd <- rs1 >> shamt`
|
||
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)
|
||
///
|
||
/// `SRLIW rd, rs1, imm12` => `rd <- rs1 >> shamt`
|
||
///
|
||
/// 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)
|
||
///
|
||
/// `SRAIW rd, rs1, imm12` => `rd <- rs1 >> shamt`
|
||
///
|
||
/// 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;
|
||
|
||
/// Simple floating point extension
|
||
pub const RISCV_FP: u8 = 0x53;
|
||
|
||
/// Type: R
|
||
///
|
||
/// Simple precision floating point addition
|
||
///
|
||
/// `FADD.S rd, rs1, rs2` => `rd <- rs1 + rs2`
|
||
pub const RISCV_FP_ADD: u8 = 0x0;
|
||
/// Type: R
|
||
///
|
||
/// Simple precision floating point substraction
|
||
///
|
||
/// `FSUB.S rd, rs1, rs2` => `rd <- rs1 - rs2`
|
||
pub const RISCV_FP_SUB: u8 = 0x4;
|
||
/// Type: R
|
||
///
|
||
/// Simple precision floating point multiplication
|
||
///
|
||
/// `fmul.s rd, rs1, rs2` => `rd <- rs1 * rs2`
|
||
pub const RISCV_FP_MUL: u8 = 0x8;
|
||
/// Type : R
|
||
///
|
||
/// Simple precision floating point division
|
||
///
|
||
/// `fdiv.s rd, rs1, rs2` => `rd <- rs1 / rs2`
|
||
pub const RISCV_FP_DIV: u8 = 0xc;
|
||
/// Type: R
|
||
///
|
||
/// Simple precision square root
|
||
///
|
||
/// `fsqrt.s rd, rs1` => `rd <- sqrt(rs1)`
|
||
pub const RISCV_FP_SQRT: u8 = 0x2c;
|
||
/// FSGN instructions
|
||
pub const RISCV_FP_FSGN: u8 = 0x10;
|
||
// fmin or fmax instructions
|
||
pub const RISCV_FP_MINMAX: u8 = 0x14;
|
||
/// fcvt.w instructions
|
||
///
|
||
/// convert fp to integer
|
||
pub const RISCV_FP_FCVTW: u8 = 0x60;
|
||
/// fmv.x.w or fclass.s instruction
|
||
pub const RISCV_FP_FMVXFCLASS: u8 = 0x70;
|
||
/// floating points comparaison instructions
|
||
pub const RISCV_FP_FCMP: u8 = 0x50;
|
||
pub const RISCV_FP_FEQS: u8 = 0x53;
|
||
/// fcvt.s instructions
|
||
///
|
||
/// Convert integer to fp
|
||
pub const RISCV_FP_FCVTS: u8 = 0x68;
|
||
pub const RISCV_FP_FCVTDS: u8 = 0x21;
|
||
|
||
/// 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]}`
|
||
pub const RISCV_FP_FSGN_J: u8 = 0x0;
|
||
/// 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]}`
|
||
pub const RISCV_FP_FSGN_JN: u8 = 0x1;
|
||
/// 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]}`
|
||
pub const RISCV_FP_FSGN_JX: u8 = 0x2;
|
||
|
||
/// Type: R
|
||
///
|
||
/// write the smaller number between rs1 and rs2 to rd
|
||
///
|
||
/// `fmin.s rd, rs1, rs2` => `rd <- min(rs1, rs2)`
|
||
pub const RISCV_FP_MINMAX_MIN: u8 = 0x0;
|
||
/// type: R
|
||
///
|
||
/// Write the larger number between rs1 and rs2 to rd
|
||
///
|
||
/// `fmax.s rd, rs1, rs2` => `rd <- max(rs1, rs2)`
|
||
pub const RISCV_FP_MINMAX_MAX: u8 = 0x1;
|
||
|
||
/// 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
|
||
pub const RISCV_FP_FCVTW_W: u8 = 0x0;
|
||
/// 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`
|
||
pub const RISCV_FP_FCVTW_WU: u8 = 0x1;
|
||
|
||
/// 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`
|
||
pub const RISCV_FP_FCVTS_W: u8 = 0x0;
|
||
/// 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`
|
||
pub const RISCV_FP_FCVTS_WU: u8 = 0x1;
|
||
/// 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]`
|
||
pub const RISCV_FP_FMVXFCLASS_FMVX: u8 = 0x0;
|
||
/// 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
|
||
pub const RISCV_FP_FMVXFCLASS_FCLASS: u8 = 0x1;
|
||
|
||
/// Type: R
|
||
///
|
||
/// Quiet equal comparaison, NaN cause an invalid operation exception
|
||
///
|
||
/// `feq.s rd, rs1, rs2` => `rd <- rs1 == rs2`
|
||
pub const RISCV_FP_FCMP_FEQ: u8 = 2;
|
||
/// Type: R
|
||
///
|
||
/// Quiet less comparaison, NaN cause an invalid operation exception
|
||
///
|
||
/// `flt.s rd, rs1, rs2` => `rdf <- rs1 < rs2`
|
||
pub const RISCV_FP_FCMP_FLT: u8 = 1;
|
||
/// Type: R
|
||
///
|
||
/// Quiet less or equal comparaison, NaN cause an invalid operation exception
|
||
///
|
||
/// `fle.s rd, rs1, rs2` => `rd <- rs1 <= rs2`
|
||
pub const RISCV_FP_FCMP_FLE: u8 = 0;
|
||
|
||
/// 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]`
|
||
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;
|
||
|
||
} |