Repository: nexus-xyz/nexus-zkvm
File: vm/src/circuit/riscv.rs (Rust)

Code before:
    cs.set_eq("J=2", "opcode=23"); // auipc
    cs.set_eq("J=3", "opcode=111"); // jal
    cs.set_eq("J=4", "opcode=103"); // jalr
    cs.nand("f3", "opcode=103");

    cs.mul("J=5", "opcode=99", "f3=0"); // beq
    cs.mul("J=6", "opcode=99", "f3=1"); // bne
    cs.mul("J=7", "opcode=99", "f3=4"); // blt
    cs.mul("J=8", "opcode=99", "f3=5"); // bge
    cs.mul("J=9", "opcode=99", "f3=6"); // bltu
    cs.mul("J=10", "opcode=99", "f3=7"); // bgeu

    cs.mul("J=11", "opcode=3", "f3=0"); // lb
    cs.mul("J=12", "opcode=3", "f3=1"); // lh
    cs.mul("J=13", "opcode=3", "f3=2"); // lw
    cs.mul("J=14", "opcode=3", "f3=4"); // lbu
    cs.mul("J=15", "opcode=3", "f3=5"); // lhu

    cs.mul("J=16", "opcode=35", "f3=0"); // sb
    cs.mul("J=17", "opcode=35", "f3=1"); // sh
    cs.mul("J=18", "opcode=35", "f3=2"); // sw

    cs.mul("J=19", "opcode=19", "f3=0"); // addi
    cs.set_var("J=20", 0); // subi does not exist
    cs.mul("J=21", "opcode=19", "f3=1"); // slli
    cs.nand("J=21", "f7"); // f7 == 0 if slli
    cs.mul("J=22", "opcode=19", "f3=2"); // slti
    cs.mul("J=23", "opcode=19", "f3=3"); // sltui
    cs.mul("J=24", "opcode=19", "f3=4"); // xori
    cs.mul("J=25", "opcode=19", "f3=5a"); // srli
    cs.nand("J=25", "f7"); // f7 == 0 if srli
    cs.mul("J=26", "opcode=19", "f3=5b"); // srai
    cs.nand("J=26", "f7-32"); // f7 == 32 if srai
    cs.mul("J=27", "opcode=19", "f3=6"); // ori
    cs.mul("J=28", "opcode=19", "f3=7"); // andi

    cs.mul("J=29", "opcode=51", "f3=0a"); // add
    cs.nand("J=29", "f7"); // f7 == 0 if add
    cs.mul("J=30", "opcode=51", "f3=0b"); // sub
    cs.nand("J=30", "f7-32"); // f7 == 32 if sub
    cs.mul("J=31", "opcode=51", "f3=1"); // sll
    cs.nand("J=31", "f7"); // f7 == 0 if sll
    cs.mul("J=32", "opcode=51", "f3=2"); // slt
    cs.nand("J=32", "f7"); // f7 == 0 if slt
    cs.mul("J=33", "opcode=51", "f3=3"); // sltu
    cs.nand("J=33", "f7"); // f7 == 0 if sltu
    cs.mul("J=34", "opcode=51", "f3=4"); // xor
    cs.nand("J=34", "f7"); // f7 == 0 if xor
    cs.mul("J=35", "opcode=51", "f3=5a"); // srl
    cs.nand("J=35", "f7"); // f7 == 0 if srl
    cs.mul("J=36", "opcode=51", "f3=5b"); // sra

Review comment (suggestion):
Similarly, we should document that this isn't actually `f7`, it's `imm[11:6]`, which coincides with `f7`.

Code after:
    cs.set_eq("J=2", "opcode=23"); // auipc
    cs.set_eq("J=3", "opcode=111"); // jal
    cs.set_eq("J=4", "opcode=103"); // jalr
    cs.nand("f3", "opcode=103");

    cs.mul("J=5", "opcode=99", "f3=0"); // beq
    cs.mul("J=6", "opcode=99", "f3=1"); // bne
    cs.mul("J=7", "opcode=99", "f3=4"); // blt
    cs.mul("J=8", "opcode=99", "f3=5"); // bge
    cs.mul("J=9", "opcode=99", "f3=6"); // bltu
    cs.mul("J=10", "opcode=99", "f3=7"); // bgeu

    cs.mul("J=11", "opcode=3", "f3=0"); // lb
    cs.mul("J=12", "opcode=3", "f3=1"); // lh
    cs.mul("J=13", "opcode=3", "f3=2"); // lw
    cs.mul("J=14", "opcode=3", "f3=4"); // lbu
    cs.mul("J=15", "opcode=3", "f3=5"); // lhu

    cs.mul("J=16", "opcode=35", "f3=0"); // sb
    cs.mul("J=17", "opcode=35", "f3=1"); // sh
    cs.mul("J=18", "opcode=35", "f3=2"); // sw

    cs.mul("J=19", "opcode=19", "f3=0"); // addi
    cs.set_var("J=20", 0); // subi does not exist
    cs.mul("J=21", "opcode=19", "f3=1"); // slli
    cs.nand("J=21", "f7"); // f7 (technicallly imm[11:5]) == 0 if slli
    cs.mul("J=22", "opcode=19", "f3=2"); // slti
    cs.mul("J=23", "opcode=19", "f3=3"); // sltui
    cs.mul("J=24", "opcode=19", "f3=4"); // xori
    cs.mul("J=25", "opcode=19", "f3=5a"); // srli
    cs.nand("J=25", "f7"); // f7 (technically imm[11:5]) == 0 if srli
    cs.mul("J=26", "opcode=19", "f3=5b"); // srai
    cs.nand("J=26", "f7-32"); // f7 (technically imm[11:5]) == 32 if srai
    cs.mul("J=27", "opcode=19", "f3=6"); // ori
    cs.mul("J=28", "opcode=19", "f3=7"); // andi

    cs.mul("J=29", "opcode=51", "f3=0a"); // add
    cs.nand("J=29", "f7"); // f7 == 0 if add
    cs.mul("J=30", "opcode=51", "f3=0b"); // sub
    cs.nand("J=30", "f7-32"); // f7 == 32 if sub
    cs.mul("J=31", "opcode=51", "f3=1"); // sll
    cs.nand("J=31", "f7"); // f7 == 0 if sll
    cs.mul("J=32", "opcode=51", "f3=2"); // slt
    cs.nand("J=32", "f7"); // f7 == 0 if slt
    cs.mul("J=33", "opcode=51", "f3=3"); // sltu
    cs.nand("J=33", "f7"); // f7 == 0 if sltu
    cs.mul("J=34", "opcode=51", "f3=4"); // xor
    cs.nand("J=34", "f7"); // f7 == 0 if xor
    cs.mul("J=35", "opcode=51", "f3=5a"); // srl
    cs.nand("J=35", "f7"); // f7 == 0 if srl
    cs.mul("J=36", "opcode=51", "f3=5b"); // sra