Repository: nexus-xyz/nexus-zkvm
File: vm/src/rv32/parse.rs (Rust)

Code before:
    assert_eq!(opcode(word), OPC_ALU);
    let res = match (funct3(word), funct7(word)) {
        (0b000, 0b0100000) => SUB,
        (0b000, 0b0000000) => ADD,
        (0b001, 0b0000000) => SLL,
        (0b010, 0b0000000) => SLT,
        (0b011, 0b0000000) => SLTU,
        (0b100, 0b0000000) => XOR,
        (0b101, 0b0000000) => SRL,
        (0b101, 0b0100000) => SRA,
        (0b110, 0b0000000) => OR,
        (0b111, 0b0000000) => AND,
        _ => return None,
    };
    Some(res)
}

fn aopi(word: u32) -> Option<AOP> {
    assert_eq!(opcode(word), OPC_ALUI);
    let res = match (funct3(word), funct7(word) /* imm[11:5] */) {
        (0b000, _ /* imm[11:5] can be any */) => ADD,
        (0b001, 0b0000000 /* shift amount is required to be small */) => SLL,
        (0b010, _ /* imm[11:5] can be any */) => SLT,
        (0b011, _ /* imm[11:5] can be any */) => SLTU,
        (0b100, _ /* imm[11:5] can be any */) => XOR,
        (0b101, 0b0000000 /* shift amount is required to be small */) => SRL,
        (0b101, 0b0100000 /* SRAI requires special value in imm[11:5] */) => SRA,
        (0b110, _ /* imm[11:5] can be any */) => OR,
        (0b111, _ /* imm[11:5] can be any */) => AND,
        _ => return None,
    };
    Some(res)
}

/// extract immediate from ALU instruction
pub fn immA(word: u32) -> u32 {
    match funct3(word) {
        0b001 | 0b101 => shamt(word),
        _ => immI(word),
    }
}

// instruction parsing by opcode

#[allow(clippy::unusual_byte_groupings)]
#[rustfmt::skip]
mod opcodes {
    pub const OPC_LUI   : u32 = 0b_011_0111;
    pub const OPC_AUIPC : u32 = 0b_001_0111;
    pub const OPC_JAL   : u32 = 0b_110_1111;
    pub const OPC_JALR  : u32 = 0b_110_0111;

Review comment (suggestion):
Also I'm confused by the "small" part, this value doesn't have anything to do with the shift amount, right? It's a fixed value to indicate the type of shift, I think.

Code after:
    assert_eq!(opcode(word), OPC_ALU);
    let res = match (funct3(word), funct7(word)) {
        (0b000, 0b0100000) => SUB,
        (0b000, 0b0000000) => ADD,
        (0b001, 0b0000000) => SLL,
        (0b010, 0b0000000) => SLT,
        (0b011, 0b0000000) => SLTU,
        (0b100, 0b0000000) => XOR,
        (0b101, 0b0000000) => SRL,
        (0b101, 0b0100000) => SRA,
        (0b110, 0b0000000) => OR,
        (0b111, 0b0000000) => AND,
        _ => return None,
    };
    Some(res)
}

fn aopi(word: u32) -> Option<AOP> {
    assert_eq!(opcode(word), OPC_ALUI);
    let res = match (funct3(word), funct7(word) /* imm[11:5] */) {
        (0b000, _ /* imm[11:5] can be any */) => ADD,
        (0b001, 0b0000000 /* SLLI requires special value in imm[11:5] */) => SLL,
        (0b010, _ /* imm[11:5] can be any */) => SLT,
        (0b011, _ /* imm[11:5] can be any */) => SLTU,
        (0b100, _ /* imm[11:5] can be any */) => XOR,
        (0b101, 0b0000000 /* SRLI requires special value in imm[11:5] */) => SRL,
        (0b101, 0b0100000 /* SRAI requires special value in imm[11:5] */) => SRA,
        (0b110, _ /* imm[11:5] can be any */) => OR,
        (0b111, _ /* imm[11:5] can be any */) => AND,
        _ => return None,
    };
    Some(res)
}

/// extract immediate from ALU instruction
pub fn immA(word: u32) -> u32 {
    match funct3(word) {
        0b001 | 0b101 => shamt(word),
        _ => immI(word),
    }
}

// instruction parsing by opcode

#[allow(clippy::unusual_byte_groupings)]
#[rustfmt::skip]
mod opcodes {
    pub const OPC_LUI   : u32 = 0b_011_0111;
    pub const OPC_AUIPC : u32 = 0b_001_0111;
    pub const OPC_JAL   : u32 = 0b_110_1111;
    pub const OPC_JALR  : u32 = 0b_110_0111;