Combine DUP and SWAP (#1254)

* Combine dup and swap flags.

* Add comments
This commit is contained in:
Linda Guiga 2023-10-18 17:32:43 -04:00 committed by GitHub
parent 29fdd3e372
commit 817e3e78e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 20 additions and 22 deletions

View File

@ -22,8 +22,7 @@ pub struct OpsColumnsView<T: Copy> {
pub jumpdest: T,
pub push0: T,
pub push: T,
pub dup: T,
pub swap: T,
pub dup_swap: T,
pub get_context: T,
pub set_context: T,
pub mstore_32bytes: T,

View File

@ -8,7 +8,7 @@ use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer
use crate::cpu::columns::{CpuColumnsView, COL_MAP};
use crate::cpu::kernel::aggregator::KERNEL;
const NATIVE_INSTRUCTIONS: [usize; 18] = [
const NATIVE_INSTRUCTIONS: [usize; 17] = [
COL_MAP.op.binary_op,
COL_MAP.op.ternary_op,
COL_MAP.op.fp254_op,
@ -24,8 +24,7 @@ const NATIVE_INSTRUCTIONS: [usize; 18] = [
COL_MAP.op.jumpdest,
COL_MAP.op.push0,
// not PUSH (need to increment by more than 1)
COL_MAP.op.dup,
COL_MAP.op.swap,
COL_MAP.op.dup_swap,
COL_MAP.op.get_context,
COL_MAP.op.set_context,
// not EXIT_KERNEL (performs a jump)

View File

@ -23,7 +23,7 @@ use crate::cpu::columns::{CpuColumnsView, COL_MAP};
/// behavior.
/// Note: invalid opcodes are not represented here. _Any_ opcode is permitted to decode to
/// `is_invalid`. The kernel then verifies that the opcode was _actually_ invalid.
const OPCODES: [(u8, usize, bool, usize); 17] = [
const OPCODES: [(u8, usize, bool, usize); 16] = [
// (start index of block, number of top bits to check (log2), kernel-only, flag column)
// ADD, MUL, SUB, DIV, MOD, LT, GT and BYTE flags are handled partly manually here, and partly through the Arithmetic table CTL.
// ADDMOD, MULMOD and SUBMOD flags are handled partly manually here, and partly through the Arithmetic table CTL.
@ -39,9 +39,8 @@ const OPCODES: [(u8, usize, bool, usize); 17] = [
(0x58, 0, false, COL_MAP.op.pc),
(0x5b, 0, false, COL_MAP.op.jumpdest),
(0x5f, 0, false, COL_MAP.op.push0),
(0x60, 5, false, COL_MAP.op.push), // 0x60-0x7f
(0x80, 4, false, COL_MAP.op.dup), // 0x80-0x8f
(0x90, 4, false, COL_MAP.op.swap), // 0x90-0x9f
(0x60, 5, false, COL_MAP.op.push), // 0x60-0x7f
(0x80, 5, false, COL_MAP.op.dup_swap), // 0x80-0x9f
(0xee, 0, true, COL_MAP.op.mstore_32bytes),
(0xf6, 0, true, COL_MAP.op.get_context),
(0xf7, 0, true, COL_MAP.op.set_context),

View File

@ -114,7 +114,8 @@ fn eval_packed_dup<P: PackedField>(
nv: &CpuColumnsView<P>,
yield_constr: &mut ConstraintConsumer<P>,
) {
let filter = lv.op.dup;
// DUP opcodes have 0 at the 5-th position, while SWAP opcodes have 1.
let filter = lv.op.dup_swap * (P::ONES - lv.opcode_bits[4]);
let write_channel = &lv.mem_channels[1];
let read_channel = &lv.mem_channels[2];
@ -139,8 +140,10 @@ fn eval_ext_circuit_dup<F: RichField + Extendable<D>, const D: usize>(
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
) {
let zero = builder.zero_extension();
let filter = lv.op.dup;
let one = builder.one_extension();
// DUP opcodes have 0 at the 5-th position, while SWAP opcodes have 1.
let mut filter = builder.sub_extension(one, lv.opcode_bits[4]);
filter = builder.mul_extension(lv.op.dup_swap, filter);
let write_channel = &lv.mem_channels[1];
let read_channel = &lv.mem_channels[2];
@ -187,7 +190,8 @@ fn eval_packed_swap<P: PackedField>(
) {
let n_plus_one = n + P::ONES;
let filter = lv.op.swap;
// DUP opcodes have 0 at the 5-th position, while SWAP opcodes have 1.
let filter = lv.op.dup_swap * lv.opcode_bits[4];
let in1_channel = &lv.mem_channels[0];
let in2_channel = &lv.mem_channels[1];
@ -215,7 +219,8 @@ fn eval_ext_circuit_swap<F: RichField + Extendable<D>, const D: usize>(
let one = builder.one_extension();
let n_plus_one = builder.add_extension(n, one);
let filter = lv.op.swap;
// DUP opcodes have 0 at the 5-th position, while SWAP opcodes have 1.
let filter = builder.mul_extension(lv.op.dup_swap, lv.opcode_bits[4]);
let in1_channel = &lv.mem_channels[0];
let in2_channel = &lv.mem_channels[1];

View File

@ -34,8 +34,7 @@ const SIMPLE_OPCODES: OpsColumnsView<Option<u32>> = OpsColumnsView {
jumpdest: G_JUMPDEST,
push0: G_BASE,
push: G_VERYLOW,
dup: G_VERYLOW,
swap: G_VERYLOW,
dup_swap: G_VERYLOW,
get_context: KERNEL_ONLY_INSTR,
set_context: KERNEL_ONLY_INSTR,
mstore_32bytes: KERNEL_ONLY_INSTR,

View File

@ -109,8 +109,7 @@ pub(crate) const STACK_BEHAVIORS: OpsColumnsView<Option<StackBehavior>> = OpsCol
disable_other_channels: true,
}),
push: None, // TODO
dup: None,
swap: None,
dup_swap: None,
get_context: Some(StackBehavior {
num_pops: 0,
pushes: true,

View File

@ -162,8 +162,7 @@ fn fill_op_flag<F: Field>(op: Operation, row: &mut CpuColumnsView<F>) {
*match op {
Operation::Push(0) => &mut flags.push0,
Operation::Push(1..) => &mut flags.push,
Operation::Dup(_) => &mut flags.dup,
Operation::Swap(_) => &mut flags.swap,
Operation::Dup(_) | Operation::Swap(_) => &mut flags.dup_swap,
Operation::Iszero | Operation::Eq => &mut flags.eq_iszero,
Operation::Not => &mut flags.not,
Operation::Syscall(_, _, _) => &mut flags.syscall,
@ -195,8 +194,7 @@ fn get_op_special_length(op: Operation) -> Option<usize> {
let behavior_opt = match op {
Operation::Push(0) => STACK_BEHAVIORS.push0,
Operation::Push(1..) => STACK_BEHAVIORS.push,
Operation::Dup(_) => STACK_BEHAVIORS.dup,
Operation::Swap(_) => STACK_BEHAVIORS.swap,
Operation::Dup(_) | Operation::Swap(_) => STACK_BEHAVIORS.dup_swap,
Operation::Iszero => IS_ZERO_STACK_BEHAVIOR,
Operation::Not => STACK_BEHAVIORS.not,
Operation::Syscall(_, _, _) => STACK_BEHAVIORS.syscall,