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

Code before:
}

// parsing of arithmetic operations pg. 18-20

fn aop(word: u32) -> Option<AOP> {
    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]

Review comment (suggestion):
Wait now I'm confused the other way, this is `funct7` for `ADD` (and all the other non-shifts).

Code after:
}

// parsing of arithmetic operations pg. 18-20

fn aop(word: u32) -> Option<AOP> {
    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]