From 9f7a8121503774c2aa667ba388b4741669e619ea Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Thu, 13 Jun 2024 11:13:01 -0300 Subject: [PATCH 01/15] impl mul --- programs/mul.zasm | 15 +++++++++++++++ programs/mul_zero.zasm | 13 +++++++++++++ src/lib.rs | 3 ++- src/op_handlers/mod.rs | 1 + src/op_handlers/mul.rs | 21 +++++++++++++++++++++ tests/integration_test.rs | 14 ++++++++++++++ 6 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 programs/mul.zasm create mode 100644 programs/mul_zero.zasm create mode 100644 src/op_handlers/mul.rs diff --git a/programs/mul.zasm b/programs/mul.zasm new file mode 100644 index 00000000..d72e4c06 --- /dev/null +++ b/programs/mul.zasm @@ -0,0 +1,15 @@ + .text + .file "mul.zasm" + .globl __entry +__entry: +.func_begin0: + add 3, r0, r1 + add 2, r0, r2 + mul r1, r2, r1, r0 + mul 1, r1, r1, r0 + sstore r0, r1 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/programs/mul_zero.zasm b/programs/mul_zero.zasm new file mode 100644 index 00000000..6fdfbf26 --- /dev/null +++ b/programs/mul_zero.zasm @@ -0,0 +1,13 @@ + .text + .file "mul_zero.zasm" + .globl __entry +__entry: +.func_begin0: + add 1, r0, r1 + mul r1, r0, r1, r0 + sstore r0, r1 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/src/lib.rs b/src/lib.rs index 68871888..3a1041fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod state; mod value; use op_handlers::add::_add; +use op_handlers::mul::_mul; use op_handlers::sub::_sub; pub use opcode::Opcode; use state::VMState; @@ -41,7 +42,7 @@ pub fn run_program(bin_path: &str) -> U256 { _add(&mut vm, opcode); } Variant::Sub(_) => _sub(&mut vm, opcode), - Variant::Mul(_) => todo!(), + Variant::Mul(_) => _mul(&mut vm, opcode), Variant::Div(_) => todo!(), Variant::Jump(_) => todo!(), Variant::Context(_) => todo!(), diff --git a/src/op_handlers/mod.rs b/src/op_handlers/mod.rs index 42f1cf02..9f1ed19e 100644 --- a/src/op_handlers/mod.rs +++ b/src/op_handlers/mod.rs @@ -1,2 +1,3 @@ pub mod add; pub mod sub; +pub mod mul; diff --git a/src/op_handlers/mul.rs b/src/op_handlers/mul.rs new file mode 100644 index 00000000..15b81015 --- /dev/null +++ b/src/op_handlers/mul.rs @@ -0,0 +1,21 @@ +use crate::address_operands::{address_operands_read, address_operands_store}; +use crate::{opcode::Opcode, state::VMState}; + +fn _mul_reg_only(vm: &mut VMState, opcode: Opcode) { + // src0 * src1 -> dst0 + let src0 = vm.get_register(opcode.src0_index); + let src1 = vm.get_register(opcode.src1_index); + vm.set_register(opcode.dst0_index, src0 * src1); +} + +fn _mul_imm16_only(vm: &mut VMState, opcode: Opcode) { + // imm0 * src0 -> dst0 + let src1 = vm.get_register(opcode.src1_index); + vm.set_register(opcode.dst0_index, src1 * opcode.imm0); +} + +pub fn _mul(vm: &mut VMState, opcode: Opcode) { + let (src0, src1) = address_operands_read(vm, &opcode); + let res = src0 * src1; + address_operands_store(vm, &opcode, res); +} diff --git a/tests/integration_test.rs b/tests/integration_test.rs index ec1b2be1..95610ce5 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -50,3 +50,17 @@ fn test_sub_and_add() { let result = run_program(&bin_path); assert_eq!(result, U256::from_dec_str("1").unwrap()); } + +#[test] +fn test_mul_asm() { + let bin_path = make_bin_path_asm("mul"); + let result = run_program(&bin_path); + assert_eq!(result, U256::from_dec_str("6").unwrap()); +} + +#[test] +fn test_mul_zero_asm() { + let bin_path = make_bin_path_asm("mul_zero"); + let result = run_program(&bin_path); + assert_eq!(result, U256::from_dec_str("0").unwrap()); +} From 0f03c65c4ab3f77de1b1c557865e1e9adb596aba Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Thu, 13 Jun 2024 16:22:46 -0300 Subject: [PATCH 02/15] add div --- programs/div_quotient.zasm | 14 ++++++++++++++ programs/div_remainder.zasm | 14 ++++++++++++++ programs/div_zero.zasm | 13 +++++++++++++ src/lib.rs | 3 ++- src/op_handlers/div.rs | 8 ++++++++ src/op_handlers/mod.rs | 3 ++- src/op_handlers/mul.rs | 13 ------------- tests/integration_test.rs | 23 +++++++++++++++++++++++ 8 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 programs/div_quotient.zasm create mode 100644 programs/div_remainder.zasm create mode 100644 programs/div_zero.zasm create mode 100644 src/op_handlers/div.rs diff --git a/programs/div_quotient.zasm b/programs/div_quotient.zasm new file mode 100644 index 00000000..fb5669b4 --- /dev/null +++ b/programs/div_quotient.zasm @@ -0,0 +1,14 @@ + .text + .file "div_quotient.zasm" + .globl __entry +__entry: +.func_begin0: + add 25, r0, r1 + add 6, r0, r2 + div r1, r2, r3, r4 + sstore r0, r3 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/programs/div_remainder.zasm b/programs/div_remainder.zasm new file mode 100644 index 00000000..d32bbaa9 --- /dev/null +++ b/programs/div_remainder.zasm @@ -0,0 +1,14 @@ + .text + .file "div_remainder.zasm" + .globl __entry +__entry: +.func_begin0: + add 25, r0, r1 + add 6, r0, r2 + div r1, r2, r3, r4 + sstore r0, r4 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/programs/div_zero.zasm b/programs/div_zero.zasm new file mode 100644 index 00000000..b854b26c --- /dev/null +++ b/programs/div_zero.zasm @@ -0,0 +1,13 @@ + .text + .file "div_zero.zasm" + .globl __entry +__entry: +.func_begin0: + add 1, r0, r1 + div r1, r0, r3, r4 + sstore r0, r3 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/src/lib.rs b/src/lib.rs index 3a1041fc..d008f962 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod state; mod value; use op_handlers::add::_add; +use op_handlers::div::_div; use op_handlers::mul::_mul; use op_handlers::sub::_sub; pub use opcode::Opcode; @@ -43,7 +44,7 @@ pub fn run_program(bin_path: &str) -> U256 { } Variant::Sub(_) => _sub(&mut vm, opcode), Variant::Mul(_) => _mul(&mut vm, opcode), - Variant::Div(_) => todo!(), + Variant::Div(_) => _div(&mut vm, opcode), Variant::Jump(_) => todo!(), Variant::Context(_) => todo!(), Variant::Shift(_) => todo!(), diff --git a/src/op_handlers/div.rs b/src/op_handlers/div.rs new file mode 100644 index 00000000..94532ce5 --- /dev/null +++ b/src/op_handlers/div.rs @@ -0,0 +1,8 @@ +use crate::address_operands::address_operands_read; +use crate::{opcode::Opcode, state::VMState}; + +pub fn _div(vm: &mut VMState, opcode: Opcode) { + let (src0, src1) = address_operands_read(vm, &opcode); + vm.set_register(opcode.dst0_index, src0 / src1); + vm.set_register(opcode.dst1_index, src0 % src1); +} diff --git a/src/op_handlers/mod.rs b/src/op_handlers/mod.rs index 9f1ed19e..3907206d 100644 --- a/src/op_handlers/mod.rs +++ b/src/op_handlers/mod.rs @@ -1,3 +1,4 @@ pub mod add; -pub mod sub; +pub mod div; pub mod mul; +pub mod sub; diff --git a/src/op_handlers/mul.rs b/src/op_handlers/mul.rs index 15b81015..e9d1ba50 100644 --- a/src/op_handlers/mul.rs +++ b/src/op_handlers/mul.rs @@ -1,19 +1,6 @@ use crate::address_operands::{address_operands_read, address_operands_store}; use crate::{opcode::Opcode, state::VMState}; -fn _mul_reg_only(vm: &mut VMState, opcode: Opcode) { - // src0 * src1 -> dst0 - let src0 = vm.get_register(opcode.src0_index); - let src1 = vm.get_register(opcode.src1_index); - vm.set_register(opcode.dst0_index, src0 * src1); -} - -fn _mul_imm16_only(vm: &mut VMState, opcode: Opcode) { - // imm0 * src0 -> dst0 - let src1 = vm.get_register(opcode.src1_index); - vm.set_register(opcode.dst0_index, src1 * opcode.imm0); -} - pub fn _mul(vm: &mut VMState, opcode: Opcode) { let (src0, src1) = address_operands_read(vm, &opcode); let res = src0 * src1; diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 95610ce5..81d91816 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -64,3 +64,26 @@ fn test_mul_zero_asm() { let result = run_program(&bin_path); assert_eq!(result, U256::from_dec_str("0").unwrap()); } + +#[test] +fn test_div_asm() { + // for this test we need to run two identical programs + // that only differ in their return values + + let first_bin_path = make_bin_path_asm("div_quotient"); + let quotient_result = run_program(&first_bin_path); + + let second_bin_path = make_bin_path_asm("div_remainder"); + let remainder_result = run_program(&second_bin_path); + + // 25 / 6 = 4 remainder 1 + assert_eq!(quotient_result, U256::from_dec_str("4").unwrap()); + assert_eq!(remainder_result, U256::from_dec_str("1").unwrap()); +} + +#[test] +#[should_panic] +fn test_div_zero_asm() { + let bin_path = make_bin_path_asm("div_zero"); + run_program(&bin_path); +} From fa70cc6ec92b8dedcddc7bf335df4272ef3735c4 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Thu, 13 Jun 2024 16:43:04 -0300 Subject: [PATCH 03/15] refactor makefile and programs dir --- Makefile | 12 ++++++------ programs/{ => add}/add.yul | 0 programs/{ => add}/add.zasm | 0 programs/{ => add}/add2.yul | 0 .../{ => add}/add_and_sub_with_conditionals.zasm | 0 programs/{ => add}/add_code_page.zasm | 0 programs/{ => add}/add_conditional.zasm | 0 programs/{ => add}/add_conditional_eq.zasm | 0 programs/{ => add}/add_conditional_gt.zasm | 0 programs/{ => add}/add_conditional_lt.zasm | 0 programs/{ => add}/add_conditional_not_eq.zasm | 0 programs/{ => add}/add_conditional_not_gt.zasm | 0 programs/{ => add}/add_conditional_not_lt.zasm | 0 programs/{ => add}/add_registers.zasm | 0 programs/{ => add}/add_stack_out_of_bounds.zasm | 0 programs/{ => add}/add_stack_with_pop.zasm | 0 .../{ => add}/add_stack_with_pop_out_of_bounds.zasm | 0 programs/{ => add}/add_stack_with_push.zasm | 0 programs/{ => div}/div_quotient.zasm | 0 programs/{ => div}/div_remainder.zasm | 0 programs/{ => div}/div_zero.zasm | 0 programs/{ => mul}/mul.zasm | 0 programs/{ => mul}/mul_zero.zasm | 0 programs/{ => sub}/sub_and_add.zasm | 0 programs/{ => sub}/sub_should_be_zero.zasm | 0 programs/{ => sub}/sub_simple.zasm | 0 26 files changed, 6 insertions(+), 6 deletions(-) rename programs/{ => add}/add.yul (100%) rename programs/{ => add}/add.zasm (100%) rename programs/{ => add}/add2.yul (100%) rename programs/{ => add}/add_and_sub_with_conditionals.zasm (100%) rename programs/{ => add}/add_code_page.zasm (100%) rename programs/{ => add}/add_conditional.zasm (100%) rename programs/{ => add}/add_conditional_eq.zasm (100%) rename programs/{ => add}/add_conditional_gt.zasm (100%) rename programs/{ => add}/add_conditional_lt.zasm (100%) rename programs/{ => add}/add_conditional_not_eq.zasm (100%) rename programs/{ => add}/add_conditional_not_gt.zasm (100%) rename programs/{ => add}/add_conditional_not_lt.zasm (100%) rename programs/{ => add}/add_registers.zasm (100%) rename programs/{ => add}/add_stack_out_of_bounds.zasm (100%) rename programs/{ => add}/add_stack_with_pop.zasm (100%) rename programs/{ => add}/add_stack_with_pop_out_of_bounds.zasm (100%) rename programs/{ => add}/add_stack_with_push.zasm (100%) rename programs/{ => div}/div_quotient.zasm (100%) rename programs/{ => div}/div_remainder.zasm (100%) rename programs/{ => div}/div_zero.zasm (100%) rename programs/{ => mul}/mul.zasm (100%) rename programs/{ => mul}/mul_zero.zasm (100%) rename programs/{ => sub}/sub_and_add.zasm (100%) rename programs/{ => sub}/sub_should_be_zero.zasm (100%) rename programs/{ => sub}/sub_simple.zasm (100%) diff --git a/Makefile b/Makefile index 949765ab..439f9425 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,10 @@ PROGRAMS_DIR=./programs ZKSOLC_YUL_FLAGS=--asm --bin --yul --overwrite ZKSOLC_ASM_FLAGS=--zkasm --bin --overwrite -YUL_PROGRAMS = $(wildcard $(PROGRAMS_DIR)/*.yul) -ASM_PROGRAMS = $(wildcard $(PROGRAMS_DIR)/*.zasm) -ARTIFACTS_YUL = $(patsubst $(PROGRAMS_DIR)/%.yul, $(ARTIFACTS_DIR)/%.artifacts.yul, $(YUL_PROGRAMS)) -ARTIFACTS_ASM = $(patsubst $(PROGRAMS_DIR)/%.zasm, $(ARTIFACTS_DIR)/%.artifacts.zasm, $(ASM_PROGRAMS)) +YUL_PROGRAMS := $(shell find $(PROGRAMS_DIR) -type f -name "*.yul") +ASM_PROGRAMS := $(shell find $(PROGRAMS_DIR) -type f -name "*.zasm") +ARTIFACTS_YUL := $(patsubst $(PROGRAMS_DIR)/%.yul, $(ARTIFACTS_DIR)/%.artifacts.yul, $(YUL_PROGRAMS)) +ARTIFACTS_ASM := $(patsubst $(PROGRAMS_DIR)/%.zasm, $(ARTIFACTS_DIR)/%.artifacts.zasm, $(ASM_PROGRAMS)) compile-programs-asm: $(ARTIFACTS_ASM) compile-programs-yul: $(ARTIFACTS_YUL) @@ -16,10 +16,10 @@ compile-programs-yul: $(ARTIFACTS_YUL) compile-programs: clean compile-programs-asm compile-programs-yul $(ARTIFACTS_DIR)/%.artifacts.yul: $(PROGRAMS_DIR)/%.yul - zksolc $(ZKSOLC_YUL_FLAGS) $< -o $@ --debug-output-dir $@ + zksolc $(ZKSOLC_YUL_FLAGS) $< -o $(ARTIFACTS_DIR)/$(@F) --debug-output-dir $(ARTIFACTS_DIR)/$(@F) $(ARTIFACTS_DIR)/%.artifacts.zasm: $(PROGRAMS_DIR)/%.zasm - zksolc $(ZKSOLC_ASM_FLAGS) $< -o $@ --debug-output-dir $@ + zksolc $(ZKSOLC_ASM_FLAGS) $< -o $(ARTIFACTS_DIR)/$(@F) --debug-output-dir $(ARTIFACTS_DIR)/$(@F) clean: -rm -rf $(ARTIFACTS_DIR) diff --git a/programs/add.yul b/programs/add/add.yul similarity index 100% rename from programs/add.yul rename to programs/add/add.yul diff --git a/programs/add.zasm b/programs/add/add.zasm similarity index 100% rename from programs/add.zasm rename to programs/add/add.zasm diff --git a/programs/add2.yul b/programs/add/add2.yul similarity index 100% rename from programs/add2.yul rename to programs/add/add2.yul diff --git a/programs/add_and_sub_with_conditionals.zasm b/programs/add/add_and_sub_with_conditionals.zasm similarity index 100% rename from programs/add_and_sub_with_conditionals.zasm rename to programs/add/add_and_sub_with_conditionals.zasm diff --git a/programs/add_code_page.zasm b/programs/add/add_code_page.zasm similarity index 100% rename from programs/add_code_page.zasm rename to programs/add/add_code_page.zasm diff --git a/programs/add_conditional.zasm b/programs/add/add_conditional.zasm similarity index 100% rename from programs/add_conditional.zasm rename to programs/add/add_conditional.zasm diff --git a/programs/add_conditional_eq.zasm b/programs/add/add_conditional_eq.zasm similarity index 100% rename from programs/add_conditional_eq.zasm rename to programs/add/add_conditional_eq.zasm diff --git a/programs/add_conditional_gt.zasm b/programs/add/add_conditional_gt.zasm similarity index 100% rename from programs/add_conditional_gt.zasm rename to programs/add/add_conditional_gt.zasm diff --git a/programs/add_conditional_lt.zasm b/programs/add/add_conditional_lt.zasm similarity index 100% rename from programs/add_conditional_lt.zasm rename to programs/add/add_conditional_lt.zasm diff --git a/programs/add_conditional_not_eq.zasm b/programs/add/add_conditional_not_eq.zasm similarity index 100% rename from programs/add_conditional_not_eq.zasm rename to programs/add/add_conditional_not_eq.zasm diff --git a/programs/add_conditional_not_gt.zasm b/programs/add/add_conditional_not_gt.zasm similarity index 100% rename from programs/add_conditional_not_gt.zasm rename to programs/add/add_conditional_not_gt.zasm diff --git a/programs/add_conditional_not_lt.zasm b/programs/add/add_conditional_not_lt.zasm similarity index 100% rename from programs/add_conditional_not_lt.zasm rename to programs/add/add_conditional_not_lt.zasm diff --git a/programs/add_registers.zasm b/programs/add/add_registers.zasm similarity index 100% rename from programs/add_registers.zasm rename to programs/add/add_registers.zasm diff --git a/programs/add_stack_out_of_bounds.zasm b/programs/add/add_stack_out_of_bounds.zasm similarity index 100% rename from programs/add_stack_out_of_bounds.zasm rename to programs/add/add_stack_out_of_bounds.zasm diff --git a/programs/add_stack_with_pop.zasm b/programs/add/add_stack_with_pop.zasm similarity index 100% rename from programs/add_stack_with_pop.zasm rename to programs/add/add_stack_with_pop.zasm diff --git a/programs/add_stack_with_pop_out_of_bounds.zasm b/programs/add/add_stack_with_pop_out_of_bounds.zasm similarity index 100% rename from programs/add_stack_with_pop_out_of_bounds.zasm rename to programs/add/add_stack_with_pop_out_of_bounds.zasm diff --git a/programs/add_stack_with_push.zasm b/programs/add/add_stack_with_push.zasm similarity index 100% rename from programs/add_stack_with_push.zasm rename to programs/add/add_stack_with_push.zasm diff --git a/programs/div_quotient.zasm b/programs/div/div_quotient.zasm similarity index 100% rename from programs/div_quotient.zasm rename to programs/div/div_quotient.zasm diff --git a/programs/div_remainder.zasm b/programs/div/div_remainder.zasm similarity index 100% rename from programs/div_remainder.zasm rename to programs/div/div_remainder.zasm diff --git a/programs/div_zero.zasm b/programs/div/div_zero.zasm similarity index 100% rename from programs/div_zero.zasm rename to programs/div/div_zero.zasm diff --git a/programs/mul.zasm b/programs/mul/mul.zasm similarity index 100% rename from programs/mul.zasm rename to programs/mul/mul.zasm diff --git a/programs/mul_zero.zasm b/programs/mul/mul_zero.zasm similarity index 100% rename from programs/mul_zero.zasm rename to programs/mul/mul_zero.zasm diff --git a/programs/sub_and_add.zasm b/programs/sub/sub_and_add.zasm similarity index 100% rename from programs/sub_and_add.zasm rename to programs/sub/sub_and_add.zasm diff --git a/programs/sub_should_be_zero.zasm b/programs/sub/sub_should_be_zero.zasm similarity index 100% rename from programs/sub_should_be_zero.zasm rename to programs/sub/sub_should_be_zero.zasm diff --git a/programs/sub_simple.zasm b/programs/sub/sub_simple.zasm similarity index 100% rename from programs/sub_simple.zasm rename to programs/sub/sub_simple.zasm From 56bf594d1557a0aaefd1b12677fef28054772378 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Thu, 13 Jun 2024 16:54:24 -0300 Subject: [PATCH 04/15] add missing flag for test --- tests/integration_test.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 95533dc3..8b7c6105 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -45,6 +45,7 @@ fn test_add_stack_with_push() { } #[test] +#[should_panic] fn test_add_stack_out_of_bounds() { let bin_path = make_bin_path_asm("add_stack_out_of_bounds"); run_program(&bin_path); From e39b8f5d3325af52689a48fc40db1084a79898ec Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Fri, 14 Jun 2024 12:57:51 -0300 Subject: [PATCH 05/15] add flag setting for mul --- programs/{ => add}/add_sets_gt_flag.zasm | 0 programs/{ => add}/add_sets_overflow.zasm | 2 +- .../add_sub_do_not_modify_flags.zasm | 0 programs/div/{div_quotient.zasm => div.zasm} | 2 +- programs/div/div_remainder.zasm | 14 -- programs/div/div_zero.zasm | 2 +- programs/mul/mul_big.zasm | 13 ++ programs/mul/mul_sets_overflow.zasm | 14 ++ programs/{ => sub}/sub_flags_r1_r2.zasm | 0 src/address_operands.rs | 68 ++++++-- src/op_handlers/add.rs | 2 +- src/op_handlers/div.rs | 6 +- src/op_handlers/mul.rs | 23 ++- src/op_handlers/sub.rs | 2 +- tests/integration_test.rs | 161 +++++++++++------- 15 files changed, 205 insertions(+), 104 deletions(-) rename programs/{ => add}/add_sets_gt_flag.zasm (100%) rename programs/{ => add}/add_sets_overflow.zasm (84%) rename programs/{ => add}/add_sub_do_not_modify_flags.zasm (100%) rename programs/div/{div_quotient.zasm => div.zasm} (85%) delete mode 100644 programs/div/div_remainder.zasm create mode 100644 programs/mul/mul_big.zasm create mode 100644 programs/mul/mul_sets_overflow.zasm rename programs/{ => sub}/sub_flags_r1_r2.zasm (100%) diff --git a/programs/add_sets_gt_flag.zasm b/programs/add/add_sets_gt_flag.zasm similarity index 100% rename from programs/add_sets_gt_flag.zasm rename to programs/add/add_sets_gt_flag.zasm diff --git a/programs/add_sets_overflow.zasm b/programs/add/add_sets_overflow.zasm similarity index 84% rename from programs/add_sets_overflow.zasm rename to programs/add/add_sets_overflow.zasm index 44527450..35520dd0 100644 --- a/programs/add_sets_overflow.zasm +++ b/programs/add/add_sets_overflow.zasm @@ -1,5 +1,5 @@ .text - .file "add_sets_overflow.zasm" + .file "mul_sets_overflow.zasm" .globl __entry __entry: diff --git a/programs/add_sub_do_not_modify_flags.zasm b/programs/add/add_sub_do_not_modify_flags.zasm similarity index 100% rename from programs/add_sub_do_not_modify_flags.zasm rename to programs/add/add_sub_do_not_modify_flags.zasm diff --git a/programs/div/div_quotient.zasm b/programs/div/div.zasm similarity index 85% rename from programs/div/div_quotient.zasm rename to programs/div/div.zasm index fb5669b4..3ecc5e75 100644 --- a/programs/div/div_quotient.zasm +++ b/programs/div/div.zasm @@ -1,5 +1,5 @@ .text - .file "div_quotient.zasm" + .file "div.zasm" .globl __entry __entry: .func_begin0: diff --git a/programs/div/div_remainder.zasm b/programs/div/div_remainder.zasm deleted file mode 100644 index d32bbaa9..00000000 --- a/programs/div/div_remainder.zasm +++ /dev/null @@ -1,14 +0,0 @@ - .text - .file "div_remainder.zasm" - .globl __entry -__entry: -.func_begin0: - add 25, r0, r1 - add 6, r0, r2 - div r1, r2, r3, r4 - sstore r0, r4 - ret -.func_end0: - - .note.GNU-stack - .rodata diff --git a/programs/div/div_zero.zasm b/programs/div/div_zero.zasm index b854b26c..94067ffe 100644 --- a/programs/div/div_zero.zasm +++ b/programs/div/div_zero.zasm @@ -5,7 +5,7 @@ __entry: .func_begin0: add 1, r0, r1 div r1, r0, r3, r4 - sstore r0, r3 + sstore r0, r0 ret .func_end0: diff --git a/programs/mul/mul_big.zasm b/programs/mul/mul_big.zasm new file mode 100644 index 00000000..a9e67b70 --- /dev/null +++ b/programs/mul/mul_big.zasm @@ -0,0 +1,13 @@ + .text + .file "mul_big.zasm" + .globl __entry +__entry: +.func_begin0: + ; test sets r1 = 2**(256) - 1, r2 = 1 + mul r1, r2, r3, r4 + sstore r0, r1 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/programs/mul/mul_sets_overflow.zasm b/programs/mul/mul_sets_overflow.zasm new file mode 100644 index 00000000..8bdfabab --- /dev/null +++ b/programs/mul/mul_sets_overflow.zasm @@ -0,0 +1,14 @@ + .text + .file "add_sets_overflow.zasm" + .globl __entry +__entry: + +.func_begin0: + ; test sets r1 = 2**(256) - 1, r2 = 2**(256) - 1 + mul! r1, r2, r3, r4 + sstore r0, r1 + ret + +.func_end0: + .note.GNU-stack + .rodata diff --git a/programs/sub_flags_r1_r2.zasm b/programs/sub/sub_flags_r1_r2.zasm similarity index 100% rename from programs/sub_flags_r1_r2.zasm rename to programs/sub/sub_flags_r1_r2.zasm diff --git a/src/address_operands.rs b/src/address_operands.rs index 63efb9e2..f71ec15f 100644 --- a/src/address_operands.rs +++ b/src/address_operands.rs @@ -72,25 +72,57 @@ pub fn address_operands_read(vm: &mut VMState, opcode: &Opcode) -> (U256, U256) } } } -fn only_reg_write(vm: &mut VMState, opcode: &Opcode, res: U256) { - vm.set_register(opcode.dst0_index, res); + +/// The first operand is used most of the times +/// the second operand is used only for div and mul +enum OutputOperandPosition { + First, + Second, } -fn reg_and_imm_write(vm: &mut VMState, opcode: &Opcode) -> U256 { - let dst0 = vm.get_register(opcode.dst0_index); - let offset = opcode.imm1; +fn only_reg_write( + vm: &mut VMState, + opcode: &Opcode, + output_op_pos: OutputOperandPosition, + res: U256, +) { + match output_op_pos { + OutputOperandPosition::First => vm.set_register(opcode.dst0_index, res), + OutputOperandPosition::Second => vm.set_register(opcode.dst1_index, res), + } +} - dst0 + U256::from(offset) +fn reg_and_imm_write( + vm: &mut VMState, + output_op_pos: OutputOperandPosition, + opcode: &Opcode, +) -> U256 { + match output_op_pos { + OutputOperandPosition::First => { + let dst0 = vm.get_register(opcode.dst0_index); + let offset = opcode.imm1; + let res = dst0 + U256::from(offset); + vm.set_register(opcode.dst0_index, res); + res + } + OutputOperandPosition::Second => { + let dst1 = vm.get_register(opcode.dst1_index); + let offset = opcode.imm1; + let res = dst1 + U256::from(offset); + vm.set_register(opcode.dst1_index, res); + res + } + } } -pub fn address_operands_store(vm: &mut VMState, opcode: &Opcode, res: U256) { +pub fn address_operands_store(vm: &mut VMState, opcode: &Opcode, res: (U256, Option)) { match opcode.dst0_operand_type { Operand::RegOnly => { - only_reg_write(vm, opcode, res); + only_reg_write(vm, opcode, OutputOperandPosition::First, res.0); } Operand::RegOrImm(variant) => match variant { RegOrImmFlags::UseRegOnly => { - only_reg_write(vm, opcode, res); + only_reg_write(vm, opcode, OutputOperandPosition::First, res.0); } RegOrImmFlags::UseImm16Only => { panic!("dest cannot be imm16 only"); @@ -99,38 +131,38 @@ pub fn address_operands_store(vm: &mut VMState, opcode: &Opcode, res: U256) { Operand::Full(variant) => { match variant { ImmMemHandlerFlags::UseRegOnly => { - only_reg_write(vm, opcode, res); + only_reg_write(vm, opcode, OutputOperandPosition::First, res.0); } ImmMemHandlerFlags::UseStackWithPushPop => { // stack+=[src0 + offset] + src1 - let src0 = reg_and_imm_write(vm, opcode); + let src0 = reg_and_imm_write(vm, OutputOperandPosition::First, opcode); vm.current_frame.stack.fill_with_zeros(src0 + 1); vm.current_frame.stack.store_with_offset( 1, TaggedValue { - value: res, + value: res.0, is_pointer: false, }, ); } ImmMemHandlerFlags::UseStackWithOffset => { // stack[src0 + offset] + src1 - let src0 = reg_and_imm_write(vm, opcode); + let src0 = reg_and_imm_write(vm, OutputOperandPosition::First, opcode); vm.current_frame.stack.store_with_offset( src0.as_usize(), TaggedValue { - value: res, + value: res.0, is_pointer: false, }, ); } ImmMemHandlerFlags::UseAbsoluteOnStack => { // stack=[src0 + offset] + src1 - let src0 = reg_and_imm_write(vm, opcode); + let src0 = reg_and_imm_write(vm, OutputOperandPosition::First, opcode); vm.current_frame.stack.store_absolute( src0.as_usize(), TaggedValue { - value: res, + value: res.0, is_pointer: false, }, ); @@ -144,4 +176,8 @@ pub fn address_operands_store(vm: &mut VMState, opcode: &Opcode, res: U256) { } } } + if let Some(res) = res.1 { + // Second operand can only be a register + only_reg_write(vm, opcode, OutputOperandPosition::Second, res); + } } diff --git a/src/op_handlers/add.rs b/src/op_handlers/add.rs index 8d6e810f..897f5801 100644 --- a/src/op_handlers/add.rs +++ b/src/op_handlers/add.rs @@ -27,5 +27,5 @@ pub fn _add(vm: &mut VMState, opcode: &Opcode) { // Gt is set if both of lt_of and eq are cleared. vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; } - address_operands_store(vm, opcode, res); + address_operands_store(vm, opcode, (res, None)); } diff --git a/src/op_handlers/div.rs b/src/op_handlers/div.rs index 162429c3..3b2f5532 100644 --- a/src/op_handlers/div.rs +++ b/src/op_handlers/div.rs @@ -1,8 +1,8 @@ -use crate::address_operands::address_operands_read; +use crate::address_operands::{address_operands_read, address_operands_store}; use crate::{opcode::Opcode, state::VMState}; pub fn _div(vm: &mut VMState, opcode: &Opcode) { let (src0, src1) = address_operands_read(vm, &opcode); - vm.set_register(opcode.dst0_index, src0 / src1); - vm.set_register(opcode.dst1_index, src0 % src1); + let (quotient, remainder) = src0.div_mod(src1); + address_operands_store(vm, &opcode, (quotient, Some(remainder))); } diff --git a/src/op_handlers/mul.rs b/src/op_handlers/mul.rs index 038a1186..3a1db6de 100644 --- a/src/op_handlers/mul.rs +++ b/src/op_handlers/mul.rs @@ -1,8 +1,27 @@ +use u256::U256; + use crate::address_operands::{address_operands_read, address_operands_store}; use crate::{opcode::Opcode, state::VMState}; pub fn _mul(vm: &mut VMState, opcode: &Opcode) { let (src0, src1) = address_operands_read(vm, &opcode); - let res = src0 * src1; - address_operands_store(vm, &opcode, res); + + let max = U256::max_value(); + let low_mask = U256::from(max.low_u128()); + let high_mask = !low_mask & max; + + let (res, overflow) = src0.overflowing_mul(src1); + if opcode.alters_vm_flags { + // If overflow, set the flag. + // otherwise keep the current value. + vm.flag_lt_of |= overflow; + // Set eq if res == 0 + vm.flag_eq |= res.is_zero(); + // Gt is set if both of lt_of and eq are cleared. + vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; + } + + let low_bits = res & low_mask; + let high_bits = res & high_mask; + address_operands_store(vm, &opcode, (low_bits, Some(high_bits))); } diff --git a/src/op_handlers/sub.rs b/src/op_handlers/sub.rs index 7a27bec7..7a73e41f 100644 --- a/src/op_handlers/sub.rs +++ b/src/op_handlers/sub.rs @@ -13,5 +13,5 @@ pub fn _sub(vm: &mut VMState, opcode: &Opcode) { // Gt is set if both of lt_of and eq are cleared. vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; } - address_operands_store(vm, opcode, res); + address_operands_store(vm, opcode, (res, None)); } diff --git a/tests/integration_test.rs b/tests/integration_test.rs index fde0353b..679c1dd0 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -141,58 +141,6 @@ fn test_add_does_not_run_if_gt_is_not_set() { assert_eq!(result, U256::from_dec_str("0").unwrap()); } -#[test] -fn test_sub_and_add() { - let bin_path = make_bin_path_asm("sub_and_add"); - let (result, _) = run_program(&bin_path); - assert_eq!(result, U256::from_dec_str("1").unwrap()); -} - -#[test] -fn test_mul_asm() { - let bin_path = make_bin_path_asm("mul"); - let (result, _) = run_program(&bin_path); - assert_eq!(result, U256::from_dec_str("6").unwrap()); -} - -#[test] -fn test_mul_zero_asm() { - let bin_path = make_bin_path_asm("mul_zero"); - let (result, _) = run_program(&bin_path); - assert_eq!(result, U256::from_dec_str("0").unwrap()); -} - -#[test] -fn test_div_asm() { - // for this test we need to run two identical programs - // that only differ in their return values - - let first_bin_path = make_bin_path_asm("div_quotient"); - let (quotient_result, _) = run_program(&first_bin_path); - - let second_bin_path = make_bin_path_asm("div_remainder"); - let (remainder_result, _) = run_program(&second_bin_path); - - // 25 / 6 = 4 remainder 1 - assert_eq!(quotient_result, U256::from_dec_str("4").unwrap()); - assert_eq!(remainder_result, U256::from_dec_str("1").unwrap()); -} - -#[test] -#[should_panic] -fn test_div_zero_asm() { - let bin_path = make_bin_path_asm("div_zero"); - run_program(&bin_path); -} - -#[test] -fn test_more_complex_program_with_conditionals() { - let bin_path = make_bin_path_asm("add_and_sub_with_conditionals"); - let vm_with_custom_flags = VMState::new_with_flag_state(false, true, false); - let (result, _final_vm_state) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); - assert_eq!(result, U256::from_dec_str("10").unwrap()); -} - #[test] fn test_add_sets_overflow_flag() { let bin_path = make_bin_path_asm("add_sets_overflow"); @@ -236,6 +184,26 @@ fn test_add_sets_gt_flag_keeps_other_flags_clear() { assert!(result == U256::from(2)); } +#[test] +fn test_add_does_not_modify_set_flags() { + let bin_path = make_bin_path_asm("add_sub_do_not_modify_flags"); + // Trigger overflow on first add, so this sets the lt_of flag. Then a + // non-overflowing add should leave the flag set. + let r1 = U256::MAX; + let r2 = fake_rand().into(); + let r3 = U256::from(1_usize); + let r4 = U256::from(1_usize); + let mut registers: [U256; 15] = [U256::zero(); 15]; + registers[0] = r1; + registers[1] = r2; + registers[2] = r3; + registers[3] = r4; + let vm_with_custom_flags = VMState::new_with_registers(registers); + let (_result, final_vm_state) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); + assert!(final_vm_state.flag_lt_of); + assert!(final_vm_state.flag_eq); +} + #[test] fn test_sub_flags_r1_rs_keeps_other_flags_clear() { let bin_path = make_bin_path_asm("sub_flags_r1_r2"); @@ -282,21 +250,86 @@ fn test_sub_sets_gt_flag_keeps_other_flags_clear() { } #[test] -fn test_add_does_not_modify_set_flags() { - let bin_path = make_bin_path_asm("add_sub_do_not_modify_flags"); - // Trigger overflow on first add, so this sets the lt_of flag. Then a - // non-overflowing add should leave the flag set. +fn test_sub_and_add() { + let bin_path = make_bin_path_asm("sub_and_add"); + let (result, _) = run_program(&bin_path); + assert_eq!(result, U256::from_dec_str("1").unwrap()); +} + +#[test] +fn test_mul_asm() { + let bin_path = make_bin_path_asm("mul"); + let (result, _) = run_program(&bin_path); + assert_eq!(result, U256::from_dec_str("6").unwrap()); +} + +#[test] +fn test_mul_big_asm() { + let bin_path = make_bin_path_asm("mul_big"); let r1 = U256::MAX; - let r2 = fake_rand().into(); - let r3 = U256::from(1_usize); - let r4 = U256::from(1_usize); + let r2 = U256::from(1); let mut registers: [U256; 15] = [U256::zero(); 15]; registers[0] = r1; registers[1] = r2; - registers[2] = r3; - registers[3] = r4; let vm_with_custom_flags = VMState::new_with_registers(registers); - let (_result, final_vm_state) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); - assert!(final_vm_state.flag_lt_of); - assert!(final_vm_state.flag_eq); + + let (_, vm) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); + + let low = vm.get_register(3); + let high = vm.get_register(4); + + let max = U256::max_value(); + let expected_low = U256::from(max.low_u128()); + let expected_high = !low & max; + + assert_eq!(low, expected_low); + assert_eq!(high, expected_high); +} + +#[test] +fn test_mul_zero_asm() { + let bin_path = make_bin_path_asm("mul_zero"); + let (result, _) = run_program(&bin_path); + assert_eq!(result, U256::from_dec_str("0").unwrap()); +} + +#[test] +fn test_mul_sets_overflow_flag() { + let bin_path = make_bin_path_asm("mul_sets_overflow"); + let r1 = U256::MAX; + let r2 = U256::MAX; + let mut registers: [U256; 15] = [U256::zero(); 15]; + registers[0] = r1; + registers[1] = r2; + + let vm_with_custom_flags = VMState::new_with_registers(registers); + let (_, vm) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); + assert!(vm.flag_lt_of); +} + +#[test] +fn test_div_asm() { + let bin_path = make_bin_path_asm("div"); + let (_, vm) = run_program(&bin_path); + let quotient_result = vm.get_register(3); + let remainder_result = vm.get_register(4); + + // 25 / 6 = 4 remainder 1 + assert_eq!(quotient_result, U256::from_dec_str("4").unwrap()); + assert_eq!(remainder_result, U256::from_dec_str("1").unwrap()); +} + +#[test] +#[should_panic] +fn test_div_zero_asm() { + let bin_path = make_bin_path_asm("div_zero"); + run_program(&bin_path); +} + +#[test] +fn test_more_complex_program_with_conditionals() { + let bin_path = make_bin_path_asm("add_and_sub_with_conditionals"); + let vm_with_custom_flags = VMState::new_with_flag_state(false, true, false); + let (result, _final_vm_state) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); + assert_eq!(result, U256::from_dec_str("10").unwrap()); } From 7ffeacee9706a421000354723e74d226028654d2 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Fri, 14 Jun 2024 17:38:14 -0300 Subject: [PATCH 06/15] fix mul not following spec --- programs/mul/mul.zasm | 4 ++-- programs/mul/mul_big.zasm | 2 +- src/op_handlers/div.rs | 10 ++++++++++ src/op_handlers/mul.rs | 32 ++++++++++++++++++++------------ tests/integration_test.rs | 18 +++++++++--------- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/programs/mul/mul.zasm b/programs/mul/mul.zasm index d72e4c06..a70fc6ac 100644 --- a/programs/mul/mul.zasm +++ b/programs/mul/mul.zasm @@ -6,8 +6,8 @@ __entry: add 3, r0, r1 add 2, r0, r2 mul r1, r2, r1, r0 - mul 1, r1, r1, r0 - sstore r0, r1 + mul 1, r1, r3, r4 + sstore r0, r3 ret .func_end0: diff --git a/programs/mul/mul_big.zasm b/programs/mul/mul_big.zasm index a9e67b70..35d65eb8 100644 --- a/programs/mul/mul_big.zasm +++ b/programs/mul/mul_big.zasm @@ -3,7 +3,7 @@ .globl __entry __entry: .func_begin0: - ; test sets r1 = 2**(256) - 1, r2 = 1 + ; test sets r1 = 2**(256) - 1, r2 = 2**(256) mul r1, r2, r3, r4 sstore r0, r1 ret diff --git a/src/op_handlers/div.rs b/src/op_handlers/div.rs index 3b2f5532..59d3ea47 100644 --- a/src/op_handlers/div.rs +++ b/src/op_handlers/div.rs @@ -4,5 +4,15 @@ use crate::{opcode::Opcode, state::VMState}; pub fn _div(vm: &mut VMState, opcode: &Opcode) { let (src0, src1) = address_operands_read(vm, &opcode); let (quotient, remainder) = src0.div_mod(src1); + if opcode.alters_vm_flags { + // If overflow, set the flag. + // otherwise keep the current value. + // vm.flag_lt_of |= overflow; + // Set eq if res == 0 + // vm.flag_eq |= quotient.is_zero(); + // Gt is set if both of lt_of and eq are cleared. + vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; + } + address_operands_store(vm, &opcode, (quotient, Some(remainder))); } diff --git a/src/op_handlers/mul.rs b/src/op_handlers/mul.rs index 3a1db6de..5d6a4221 100644 --- a/src/op_handlers/mul.rs +++ b/src/op_handlers/mul.rs @@ -1,27 +1,35 @@ -use u256::U256; +use u256::{U256, U512}; use crate::address_operands::{address_operands_read, address_operands_store}; use crate::{opcode::Opcode, state::VMState}; pub fn _mul(vm: &mut VMState, opcode: &Opcode) { let (src0, src1) = address_operands_read(vm, &opcode); + let src0 = U512::from(src0); + let src1 = U512::from(src1); + let res = src0 * src1; - let max = U256::max_value(); - let low_mask = U256::from(max.low_u128()); - let high_mask = !low_mask & max; + let u256_mask = U512::from(U256::MAX); + let low_bits = res & u256_mask; + let high_bits = res >> 256 & u256_mask; - let (res, overflow) = src0.overflowing_mul(src1); if opcode.alters_vm_flags { - // If overflow, set the flag. - // otherwise keep the current value. + // Lt overflow, is set if + // src0 * src1 >= 2^256 + let overflow = res >= U512::from(U256::MAX); vm.flag_lt_of |= overflow; - // Set eq if res == 0 - vm.flag_eq |= res.is_zero(); + // Eq is set if res_low == 0 + vm.flag_eq |= low_bits.is_zero(); // Gt is set if both of lt_of and eq are cleared. vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; } - let low_bits = res & low_mask; - let high_bits = res & high_mask; - address_operands_store(vm, &opcode, (low_bits, Some(high_bits))); + address_operands_store( + vm, + &opcode, + ( + low_bits.try_into().unwrap(), + Some(high_bits.try_into().unwrap()), + ), + ); } diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 679c1dd0..aa6e4eb4 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -259,15 +259,19 @@ fn test_sub_and_add() { #[test] fn test_mul_asm() { let bin_path = make_bin_path_asm("mul"); - let (result, _) = run_program(&bin_path); - assert_eq!(result, U256::from_dec_str("6").unwrap()); + let (_, vm) = run_program(&bin_path); + let low = vm.get_register(3); + let high = vm.get_register(4); + + assert_eq!(low, U256::from_dec_str("6").unwrap()); + assert_eq!(high, U256::zero()); } #[test] fn test_mul_big_asm() { let bin_path = make_bin_path_asm("mul_big"); let r1 = U256::MAX; - let r2 = U256::from(1); + let r2 = U256::from(2); let mut registers: [U256; 15] = [U256::zero(); 15]; registers[0] = r1; registers[1] = r2; @@ -278,12 +282,8 @@ fn test_mul_big_asm() { let low = vm.get_register(3); let high = vm.get_register(4); - let max = U256::max_value(); - let expected_low = U256::from(max.low_u128()); - let expected_high = !low & max; - - assert_eq!(low, expected_low); - assert_eq!(high, expected_high); + assert_eq!(low, U256::MAX - 1); + assert_eq!(high, U256::from(1)); // multiply by 2 == shift left by 1 } #[test] From 30d6ed28d46695d22db2dd7c171e18f88f45e214 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Fri, 14 Jun 2024 19:13:53 -0300 Subject: [PATCH 07/15] impl div set flags --- src/op_handlers/div.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/op_handlers/div.rs b/src/op_handlers/div.rs index 59d3ea47..a252666b 100644 --- a/src/op_handlers/div.rs +++ b/src/op_handlers/div.rs @@ -5,13 +5,12 @@ pub fn _div(vm: &mut VMState, opcode: &Opcode) { let (src0, src1) = address_operands_read(vm, &opcode); let (quotient, remainder) = src0.div_mod(src1); if opcode.alters_vm_flags { - // If overflow, set the flag. - // otherwise keep the current value. - // vm.flag_lt_of |= overflow; - // Set eq if res == 0 - // vm.flag_eq |= quotient.is_zero(); - // Gt is set if both of lt_of and eq are cleared. - vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; + // Lt overflow is cleared + vm.flag_lt_of = false; + // Eq is set if quotient is not zero + vm.flag_eq = !quotient.is_zero(); + // Gt is set if the remainder is not zero + vm.flag_gt = !remainder.is_zero(); } address_operands_store(vm, &opcode, (quotient, Some(remainder))); From e671111f2849c714fbbc8c213b130a15f0f24d46 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Fri, 14 Jun 2024 19:42:21 -0300 Subject: [PATCH 08/15] div set flags test --- programs/div/div_set_eq_flag.zasm | 15 +++++++++++++++ programs/div/div_set_gt_flag.zasm | 15 +++++++++++++++ tests/integration_test.rs | 17 +++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 programs/div/div_set_eq_flag.zasm create mode 100644 programs/div/div_set_gt_flag.zasm diff --git a/programs/div/div_set_eq_flag.zasm b/programs/div/div_set_eq_flag.zasm new file mode 100644 index 00000000..e05ec1fb --- /dev/null +++ b/programs/div/div_set_eq_flag.zasm @@ -0,0 +1,15 @@ + .text + .file "div_set_eq_flag.zasm" + .globl __entry +__entry: +.func_begin0: + ; EQ is set if the quotient is not zero + add 25, r0, r1 + add 6, r0, r2 + div! r1, r2, r3, r4 + sstore r0, r3 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/programs/div/div_set_gt_flag.zasm b/programs/div/div_set_gt_flag.zasm new file mode 100644 index 00000000..873903e6 --- /dev/null +++ b/programs/div/div_set_gt_flag.zasm @@ -0,0 +1,15 @@ + .text + .file "div_set_gt_flag.zasm" + .globl __entry +__entry: +.func_begin0: + ; GT is set if the reminder is not zero. + add 25, r0, r1 + add 6, r0, r2 + div! r1, r2, r3, r4 + sstore r0, r3 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/tests/integration_test.rs b/tests/integration_test.rs index aa6e4eb4..9e472374 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -326,6 +326,23 @@ fn test_div_zero_asm() { run_program(&bin_path); } +#[test] +fn test_div_set_eq_flag() { + let bin_path = make_bin_path_asm("div_set_eq_flag"); + let (_, vm) = run_program(&bin_path); + + assert!(vm.flag_eq); +} + +#[test] +fn test_div_set_gt_flag() { + let bin_path = make_bin_path_asm("div_set_gt_flag"); + run_program(&bin_path); + let (_, vm) = run_program(&bin_path); + + assert!(vm.flag_gt); +} + #[test] fn test_more_complex_program_with_conditionals() { let bin_path = make_bin_path_asm("add_and_sub_with_conditionals"); From acdfe78301b95fb3ba3609d249e796d79fc01138 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 18 Jun 2024 10:01:00 -0300 Subject: [PATCH 09/15] more tests --- programs/div/div_codepage.zasm | 20 ++++++++++++++++++ programs/div/div_stack.zasm | 19 +++++++++++++++++ programs/mul/mul_codepage.zasm | 21 +++++++++++++++++++ programs/mul/mul_stack.zasm | 22 ++++++++++++++++++++ tests/integration_test.rs | 38 ++++++++++++++++++++++++++++++++++ 5 files changed, 120 insertions(+) create mode 100644 programs/div/div_codepage.zasm create mode 100644 programs/div/div_stack.zasm create mode 100644 programs/mul/mul_codepage.zasm create mode 100644 programs/mul/mul_stack.zasm diff --git a/programs/div/div_codepage.zasm b/programs/div/div_codepage.zasm new file mode 100644 index 00000000..3308c3c8 --- /dev/null +++ b/programs/div/div_codepage.zasm @@ -0,0 +1,20 @@ + .text + .file "div_codepage.zasm" + .globl __entry + +.rodata +datavar: + .cell 42 + .cell 3 +.text + +__entry: +.func_begin0: + add 3, r0, r1 + div @datavar[0], r1, r3, r4 + sstore r0, r0 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/programs/div/div_stack.zasm b/programs/div/div_stack.zasm new file mode 100644 index 00000000..c6de787c --- /dev/null +++ b/programs/div/div_stack.zasm @@ -0,0 +1,19 @@ + .text + .file "div_stack.zasm" + .globl __entry +__entry: + +.func_begin0: + add 3, r0, r2 + ; grow stack + add 1, r0, stack+=[1] + ; set stack values + add 42, r0, stack=[0] + ; divide stack of absolute index 0 + div stack=[0],r2, r3, r4 + sstore r0, r0 + ret + +.func_end0: + .note.GNU-stack + .rodata diff --git a/programs/mul/mul_codepage.zasm b/programs/mul/mul_codepage.zasm new file mode 100644 index 00000000..7d1a0c69 --- /dev/null +++ b/programs/mul/mul_codepage.zasm @@ -0,0 +1,21 @@ + .text + .file "mul_codepage.zasm" + .globl __entry + +.rodata +datavar: + .cell 42 + .cell 3 +.text + +__entry: +.func_begin0: + add 1, r0, r1 + mul @datavar[0], r1, r1, r0 + mul @datavar[1], r1, r1, r0 + sstore r0, r1 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/programs/mul/mul_stack.zasm b/programs/mul/mul_stack.zasm new file mode 100644 index 00000000..7597d821 --- /dev/null +++ b/programs/mul/mul_stack.zasm @@ -0,0 +1,22 @@ + .text + .file "mul_stack.zasm" + .globl __entry +__entry: + +.func_begin0: + add 1, r0, r2 + ; grow stack + add 1, r0, stack+=[2] + ; set stack values + add 2, r0, stack=[0] + add 3, r0, stack=[1] + ; multiply by stack of absolute index 0 + mul stack=[0],r2, r1, r0 + ; pop stack and multiply by the topmost value + mul stack-=[2],r1, r1, r0 + sstore r0, r1 + ret + +.func_end0: + .note.GNU-stack + .rodata diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 9e472374..c57a3813 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -293,6 +293,13 @@ fn test_mul_zero_asm() { assert_eq!(result, U256::from_dec_str("0").unwrap()); } +#[test] +fn test_mul_codepage() { + let bin_path = make_bin_path_asm("mul_codepage"); + let (result, _) = run_program(&bin_path); + assert_eq!(result, U256::from_dec_str("126").unwrap()); +} + #[test] fn test_mul_sets_overflow_flag() { let bin_path = make_bin_path_asm("mul_sets_overflow"); @@ -307,6 +314,13 @@ fn test_mul_sets_overflow_flag() { assert!(vm.flag_lt_of); } +#[test] +fn test_mul_stack() { + let bin_path = make_bin_path_asm("mul_stack"); + let (result, _) = run_program(&bin_path); + assert_eq!(result, U256::from_dec_str("6").unwrap()); +} + #[test] fn test_div_asm() { let bin_path = make_bin_path_asm("div"); @@ -343,6 +357,30 @@ fn test_div_set_gt_flag() { assert!(vm.flag_gt); } +#[test] +fn test_div_codepage() { + let bin_path = make_bin_path_asm("div_codepage"); + let (_, vm) = run_program(&bin_path); + let quotient_result = vm.get_register(3); + let remainder_result = vm.get_register(4); + + // 42 / 3 = 14 remainder 0 + assert_eq!(quotient_result, U256::from_dec_str("14").unwrap()); + assert_eq!(remainder_result, U256::from_dec_str("0").unwrap()); +} + +#[test] +fn test_div_stack() { + let bin_path = make_bin_path_asm("div_stack"); + let (_, vm) = run_program(&bin_path); + let quotient_result = vm.get_register(3); + let remainder_result = vm.get_register(4); + + // 25 / 6 = 4 remainder 1 + assert_eq!(quotient_result, U256::from_dec_str("14").unwrap()); + assert_eq!(remainder_result, U256::from_dec_str("0").unwrap()); +} + #[test] fn test_more_complex_program_with_conditionals() { let bin_path = make_bin_path_asm("add_and_sub_with_conditionals"); From 838ec3699fed378dfd057d56c450e27e03c439fa Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 18 Jun 2024 10:09:30 -0300 Subject: [PATCH 10/15] clippy --- src/op_handlers/div.rs | 4 ++-- src/op_handlers/mul.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/op_handlers/div.rs b/src/op_handlers/div.rs index a252666b..e61d6383 100644 --- a/src/op_handlers/div.rs +++ b/src/op_handlers/div.rs @@ -2,7 +2,7 @@ use crate::address_operands::{address_operands_read, address_operands_store}; use crate::{opcode::Opcode, state::VMState}; pub fn _div(vm: &mut VMState, opcode: &Opcode) { - let (src0, src1) = address_operands_read(vm, &opcode); + let (src0, src1) = address_operands_read(vm, opcode); let (quotient, remainder) = src0.div_mod(src1); if opcode.alters_vm_flags { // Lt overflow is cleared @@ -13,5 +13,5 @@ pub fn _div(vm: &mut VMState, opcode: &Opcode) { vm.flag_gt = !remainder.is_zero(); } - address_operands_store(vm, &opcode, (quotient, Some(remainder))); + address_operands_store(vm, opcode, (quotient, Some(remainder))); } diff --git a/src/op_handlers/mul.rs b/src/op_handlers/mul.rs index 5d6a4221..eaf205b9 100644 --- a/src/op_handlers/mul.rs +++ b/src/op_handlers/mul.rs @@ -4,7 +4,7 @@ use crate::address_operands::{address_operands_read, address_operands_store}; use crate::{opcode::Opcode, state::VMState}; pub fn _mul(vm: &mut VMState, opcode: &Opcode) { - let (src0, src1) = address_operands_read(vm, &opcode); + let (src0, src1) = address_operands_read(vm, opcode); let src0 = U512::from(src0); let src1 = U512::from(src1); let res = src0 * src1; @@ -26,7 +26,7 @@ pub fn _mul(vm: &mut VMState, opcode: &Opcode) { address_operands_store( vm, - &opcode, + opcode, ( low_bits.try_into().unwrap(), Some(high_bits.try_into().unwrap()), From 02ca9a9146806e8cf1eb908b9542a72b2ee4780e Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 18 Jun 2024 10:49:10 -0300 Subject: [PATCH 11/15] add mul conditional test --- programs/div/div_conditional.zasm | 14 ++++++++++++++ programs/mul/mul_conditional_gt.zasm | 14 ++++++++++++++ tests/integration_test.rs | 18 ++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 programs/div/div_conditional.zasm create mode 100644 programs/mul/mul_conditional_gt.zasm diff --git a/programs/div/div_conditional.zasm b/programs/div/div_conditional.zasm new file mode 100644 index 00000000..3ecc5e75 --- /dev/null +++ b/programs/div/div_conditional.zasm @@ -0,0 +1,14 @@ + .text + .file "div.zasm" + .globl __entry +__entry: +.func_begin0: + add 25, r0, r1 + add 6, r0, r2 + div r1, r2, r3, r4 + sstore r0, r3 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/programs/mul/mul_conditional_gt.zasm b/programs/mul/mul_conditional_gt.zasm new file mode 100644 index 00000000..adcfaaa4 --- /dev/null +++ b/programs/mul/mul_conditional_gt.zasm @@ -0,0 +1,14 @@ + .text + .file "mul_conditional_gt.zasm" + .globl __entry +__entry: +.func_begin0: + add 3, r0, r1 + add 14, r0, r2 + mul.gt r1, r2, r3, r4 + sstore r0, r3 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/tests/integration_test.rs b/tests/integration_test.rs index c57a3813..4081426e 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -321,6 +321,24 @@ fn test_mul_stack() { assert_eq!(result, U256::from_dec_str("6").unwrap()); } +#[test] +fn test_mul_conditional_gt_set() { + let bin_path = make_bin_path_asm("mul_conditional_gt"); + + let vm_with_custom_flags = VMState::new_with_flag_state(false, false, true); + let (result, _) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); + assert_eq!(result, U256::from_dec_str("42").unwrap()); +} + +#[test] +fn test_mul_conditional_gt_not_set() { + let bin_path = make_bin_path_asm("mul_conditional_gt"); + + let vm_with_custom_flags = VMState::new_with_flag_state(false, false, false); + let (result, _) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); + assert_eq!(result, U256::from_dec_str("0").unwrap()); +} + #[test] fn test_div_asm() { let bin_path = make_bin_path_asm("div"); From 552140f0329376f6430972a8bf149b7c003cf0d6 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 18 Jun 2024 11:06:52 -0300 Subject: [PATCH 12/15] add div conditional tests --- programs/div/div_conditional_gt.zasm | 16 +++++++++++++++ tests/integration_test.rs | 29 +++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 programs/div/div_conditional_gt.zasm diff --git a/programs/div/div_conditional_gt.zasm b/programs/div/div_conditional_gt.zasm new file mode 100644 index 00000000..b488c63a --- /dev/null +++ b/programs/div/div_conditional_gt.zasm @@ -0,0 +1,16 @@ + .text + .file "div_conditional_gt.zasm" + .globl __entry +__entry: +.func_begin0: + add 1, r0, r3 + add 1, r0, r4 + add 42, r0, r1 + add 3, r0, r2 + div.gt r1, r2, r3, r4 + sstore r0, r3 + ret +.func_end0: + + .note.GNU-stack + .rodata diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 4081426e..583b0275 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -394,11 +394,38 @@ fn test_div_stack() { let quotient_result = vm.get_register(3); let remainder_result = vm.get_register(4); - // 25 / 6 = 4 remainder 1 + // 42 / 3 = 14 remainder 0 assert_eq!(quotient_result, U256::from_dec_str("14").unwrap()); assert_eq!(remainder_result, U256::from_dec_str("0").unwrap()); } +#[test] +fn test_div_conditional_gt_set() { + let bin_path = make_bin_path_asm("div_conditional_gt"); + + let vm_with_custom_flags = VMState::new_with_flag_state(false, false, true); + let (_, vm) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); + let quotient_result = vm.get_register(3); + let remainder_result = vm.get_register(4); + + assert_eq!(quotient_result, U256::from_dec_str("14").unwrap()); + assert_eq!(remainder_result, U256::from_dec_str("0").unwrap()); +} + +#[test] +fn test_div_conditional_gt_not_set() { + let bin_path = make_bin_path_asm("div_conditional_gt"); + + let vm_with_custom_flags = VMState::new_with_flag_state(false, false, false); + let (_, vm) = run_program_with_custom_state(&bin_path, vm_with_custom_flags); + let quotient_result = vm.get_register(3); + let remainder_result = vm.get_register(4); + + // program sets registers 3 and 4 at the beginning, and only changes them if the conditional is met + assert_eq!(quotient_result, U256::from_dec_str("1").unwrap()); + assert_eq!(remainder_result, U256::from_dec_str("1").unwrap()); +} + #[test] fn test_more_complex_program_with_conditionals() { let bin_path = make_bin_path_asm("add_and_sub_with_conditionals"); From a5f9d4e59b54723bb4493faf977f05a04bf304ca Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 18 Jun 2024 17:34:53 -0300 Subject: [PATCH 13/15] wrap address_operands --- src/address_operands.rs | 10 +++++++++- src/op_handlers/add.rs | 2 +- src/op_handlers/div.rs | 4 ++-- src/op_handlers/mul.rs | 9 +++------ src/op_handlers/sub.rs | 2 +- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/address_operands.rs b/src/address_operands.rs index f71ec15f..b85d9b9a 100644 --- a/src/address_operands.rs +++ b/src/address_operands.rs @@ -115,7 +115,15 @@ fn reg_and_imm_write( } } -pub fn address_operands_store(vm: &mut VMState, opcode: &Opcode, res: (U256, Option)) { +pub fn address_operands_store(vm: &mut VMState, opcode: &Opcode, res: U256) { + address_operands(vm, opcode, (res, None)) +} + +pub fn address_operands_div_mul(vm: &mut VMState, opcode: &Opcode, res: (U256, U256)) { + address_operands(vm, opcode, (res.0, Some(res.1))) +} + +fn address_operands(vm: &mut VMState, opcode: &Opcode, res: (U256, Option)) { match opcode.dst0_operand_type { Operand::RegOnly => { only_reg_write(vm, opcode, OutputOperandPosition::First, res.0); diff --git a/src/op_handlers/add.rs b/src/op_handlers/add.rs index 897f5801..8d6e810f 100644 --- a/src/op_handlers/add.rs +++ b/src/op_handlers/add.rs @@ -27,5 +27,5 @@ pub fn _add(vm: &mut VMState, opcode: &Opcode) { // Gt is set if both of lt_of and eq are cleared. vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; } - address_operands_store(vm, opcode, (res, None)); + address_operands_store(vm, opcode, res); } diff --git a/src/op_handlers/div.rs b/src/op_handlers/div.rs index e61d6383..2971beec 100644 --- a/src/op_handlers/div.rs +++ b/src/op_handlers/div.rs @@ -1,4 +1,4 @@ -use crate::address_operands::{address_operands_read, address_operands_store}; +use crate::address_operands::{address_operands_div_mul, address_operands_read}; use crate::{opcode::Opcode, state::VMState}; pub fn _div(vm: &mut VMState, opcode: &Opcode) { @@ -13,5 +13,5 @@ pub fn _div(vm: &mut VMState, opcode: &Opcode) { vm.flag_gt = !remainder.is_zero(); } - address_operands_store(vm, opcode, (quotient, Some(remainder))); + address_operands_div_mul(vm, opcode, (quotient, remainder)); } diff --git a/src/op_handlers/mul.rs b/src/op_handlers/mul.rs index eaf205b9..24c65a49 100644 --- a/src/op_handlers/mul.rs +++ b/src/op_handlers/mul.rs @@ -1,6 +1,6 @@ use u256::{U256, U512}; -use crate::address_operands::{address_operands_read, address_operands_store}; +use crate::address_operands::{address_operands_div_mul, address_operands_read}; use crate::{opcode::Opcode, state::VMState}; pub fn _mul(vm: &mut VMState, opcode: &Opcode) { @@ -24,12 +24,9 @@ pub fn _mul(vm: &mut VMState, opcode: &Opcode) { vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; } - address_operands_store( + address_operands_div_mul( vm, opcode, - ( - low_bits.try_into().unwrap(), - Some(high_bits.try_into().unwrap()), - ), + (low_bits.try_into().unwrap(), high_bits.try_into().unwrap()), ); } diff --git a/src/op_handlers/sub.rs b/src/op_handlers/sub.rs index 7a73e41f..7a27bec7 100644 --- a/src/op_handlers/sub.rs +++ b/src/op_handlers/sub.rs @@ -13,5 +13,5 @@ pub fn _sub(vm: &mut VMState, opcode: &Opcode) { // Gt is set if both of lt_of and eq are cleared. vm.flag_gt |= !vm.flag_lt_of && !vm.flag_eq; } - address_operands_store(vm, opcode, (res, None)); + address_operands_store(vm, opcode, res); } From d3288220a5cfcb096e20ff093168f8625b810697 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Wed, 19 Jun 2024 11:13:59 -0300 Subject: [PATCH 14/15] justify unwrap --- src/op_handlers/mul.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/op_handlers/mul.rs b/src/op_handlers/mul.rs index 24c65a49..5fd8a946 100644 --- a/src/op_handlers/mul.rs +++ b/src/op_handlers/mul.rs @@ -27,6 +27,6 @@ pub fn _mul(vm: &mut VMState, opcode: &Opcode) { address_operands_div_mul( vm, opcode, - (low_bits.try_into().unwrap(), high_bits.try_into().unwrap()), + (low_bits.try_into().unwrap(), high_bits.try_into().unwrap()), // safe to unwrap, as we have applied the mask ); } From 31f251c89faab5efc24d704d91b4204bad0b80a9 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Wed, 19 Jun 2024 14:47:10 -0300 Subject: [PATCH 15/15] remove makefile changes --- Makefile | 12 ++++++------ programs/{add => }/add.yul | 0 programs/{add => }/add.zasm | 0 programs/{add => }/add2.yul | 0 .../{add => }/add_and_sub_with_conditionals.zasm | 0 programs/{add => }/add_code_page.zasm | 0 programs/{add => }/add_conditional.zasm | 0 programs/{add => }/add_conditional_eq.zasm | 0 programs/{add => }/add_conditional_gt.zasm | 0 programs/{add => }/add_conditional_lt.zasm | 0 programs/{add => }/add_conditional_not_eq.zasm | 0 programs/{add => }/add_conditional_not_gt.zasm | 0 programs/{add => }/add_conditional_not_lt.zasm | 0 programs/{add => }/add_registers.zasm | 0 programs/{add => }/add_sets_gt_flag.zasm | 0 programs/{add => }/add_sets_overflow.zasm | 0 programs/{add => }/add_stack_out_of_bounds.zasm | 0 programs/{add => }/add_stack_with_pop.zasm | 0 .../{add => }/add_stack_with_pop_out_of_bounds.zasm | 0 programs/{add => }/add_stack_with_push.zasm | 0 programs/{add => }/add_sub_do_not_modify_flags.zasm | 0 programs/{div => }/div.zasm | 0 programs/{div => }/div_codepage.zasm | 0 programs/{div => }/div_conditional.zasm | 0 programs/{div => }/div_conditional_gt.zasm | 0 programs/{div => }/div_set_eq_flag.zasm | 0 programs/{div => }/div_set_gt_flag.zasm | 0 programs/{div => }/div_stack.zasm | 0 programs/{div => }/div_zero.zasm | 0 programs/{mul => }/mul.zasm | 0 programs/{mul => }/mul_big.zasm | 0 programs/{mul => }/mul_codepage.zasm | 0 programs/{mul => }/mul_conditional_gt.zasm | 0 programs/{mul => }/mul_sets_overflow.zasm | 0 programs/{mul => }/mul_stack.zasm | 0 programs/{mul => }/mul_zero.zasm | 0 programs/{sub => }/sub_and_add.zasm | 0 programs/{sub => }/sub_flags_r1_r2.zasm | 0 programs/{sub => }/sub_should_be_zero.zasm | 0 programs/{sub => }/sub_simple.zasm | 0 40 files changed, 6 insertions(+), 6 deletions(-) rename programs/{add => }/add.yul (100%) rename programs/{add => }/add.zasm (100%) rename programs/{add => }/add2.yul (100%) rename programs/{add => }/add_and_sub_with_conditionals.zasm (100%) rename programs/{add => }/add_code_page.zasm (100%) rename programs/{add => }/add_conditional.zasm (100%) rename programs/{add => }/add_conditional_eq.zasm (100%) rename programs/{add => }/add_conditional_gt.zasm (100%) rename programs/{add => }/add_conditional_lt.zasm (100%) rename programs/{add => }/add_conditional_not_eq.zasm (100%) rename programs/{add => }/add_conditional_not_gt.zasm (100%) rename programs/{add => }/add_conditional_not_lt.zasm (100%) rename programs/{add => }/add_registers.zasm (100%) rename programs/{add => }/add_sets_gt_flag.zasm (100%) rename programs/{add => }/add_sets_overflow.zasm (100%) rename programs/{add => }/add_stack_out_of_bounds.zasm (100%) rename programs/{add => }/add_stack_with_pop.zasm (100%) rename programs/{add => }/add_stack_with_pop_out_of_bounds.zasm (100%) rename programs/{add => }/add_stack_with_push.zasm (100%) rename programs/{add => }/add_sub_do_not_modify_flags.zasm (100%) rename programs/{div => }/div.zasm (100%) rename programs/{div => }/div_codepage.zasm (100%) rename programs/{div => }/div_conditional.zasm (100%) rename programs/{div => }/div_conditional_gt.zasm (100%) rename programs/{div => }/div_set_eq_flag.zasm (100%) rename programs/{div => }/div_set_gt_flag.zasm (100%) rename programs/{div => }/div_stack.zasm (100%) rename programs/{div => }/div_zero.zasm (100%) rename programs/{mul => }/mul.zasm (100%) rename programs/{mul => }/mul_big.zasm (100%) rename programs/{mul => }/mul_codepage.zasm (100%) rename programs/{mul => }/mul_conditional_gt.zasm (100%) rename programs/{mul => }/mul_sets_overflow.zasm (100%) rename programs/{mul => }/mul_stack.zasm (100%) rename programs/{mul => }/mul_zero.zasm (100%) rename programs/{sub => }/sub_and_add.zasm (100%) rename programs/{sub => }/sub_flags_r1_r2.zasm (100%) rename programs/{sub => }/sub_should_be_zero.zasm (100%) rename programs/{sub => }/sub_simple.zasm (100%) diff --git a/Makefile b/Makefile index 439f9425..949765ab 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,10 @@ PROGRAMS_DIR=./programs ZKSOLC_YUL_FLAGS=--asm --bin --yul --overwrite ZKSOLC_ASM_FLAGS=--zkasm --bin --overwrite -YUL_PROGRAMS := $(shell find $(PROGRAMS_DIR) -type f -name "*.yul") -ASM_PROGRAMS := $(shell find $(PROGRAMS_DIR) -type f -name "*.zasm") -ARTIFACTS_YUL := $(patsubst $(PROGRAMS_DIR)/%.yul, $(ARTIFACTS_DIR)/%.artifacts.yul, $(YUL_PROGRAMS)) -ARTIFACTS_ASM := $(patsubst $(PROGRAMS_DIR)/%.zasm, $(ARTIFACTS_DIR)/%.artifacts.zasm, $(ASM_PROGRAMS)) +YUL_PROGRAMS = $(wildcard $(PROGRAMS_DIR)/*.yul) +ASM_PROGRAMS = $(wildcard $(PROGRAMS_DIR)/*.zasm) +ARTIFACTS_YUL = $(patsubst $(PROGRAMS_DIR)/%.yul, $(ARTIFACTS_DIR)/%.artifacts.yul, $(YUL_PROGRAMS)) +ARTIFACTS_ASM = $(patsubst $(PROGRAMS_DIR)/%.zasm, $(ARTIFACTS_DIR)/%.artifacts.zasm, $(ASM_PROGRAMS)) compile-programs-asm: $(ARTIFACTS_ASM) compile-programs-yul: $(ARTIFACTS_YUL) @@ -16,10 +16,10 @@ compile-programs-yul: $(ARTIFACTS_YUL) compile-programs: clean compile-programs-asm compile-programs-yul $(ARTIFACTS_DIR)/%.artifacts.yul: $(PROGRAMS_DIR)/%.yul - zksolc $(ZKSOLC_YUL_FLAGS) $< -o $(ARTIFACTS_DIR)/$(@F) --debug-output-dir $(ARTIFACTS_DIR)/$(@F) + zksolc $(ZKSOLC_YUL_FLAGS) $< -o $@ --debug-output-dir $@ $(ARTIFACTS_DIR)/%.artifacts.zasm: $(PROGRAMS_DIR)/%.zasm - zksolc $(ZKSOLC_ASM_FLAGS) $< -o $(ARTIFACTS_DIR)/$(@F) --debug-output-dir $(ARTIFACTS_DIR)/$(@F) + zksolc $(ZKSOLC_ASM_FLAGS) $< -o $@ --debug-output-dir $@ clean: -rm -rf $(ARTIFACTS_DIR) diff --git a/programs/add/add.yul b/programs/add.yul similarity index 100% rename from programs/add/add.yul rename to programs/add.yul diff --git a/programs/add/add.zasm b/programs/add.zasm similarity index 100% rename from programs/add/add.zasm rename to programs/add.zasm diff --git a/programs/add/add2.yul b/programs/add2.yul similarity index 100% rename from programs/add/add2.yul rename to programs/add2.yul diff --git a/programs/add/add_and_sub_with_conditionals.zasm b/programs/add_and_sub_with_conditionals.zasm similarity index 100% rename from programs/add/add_and_sub_with_conditionals.zasm rename to programs/add_and_sub_with_conditionals.zasm diff --git a/programs/add/add_code_page.zasm b/programs/add_code_page.zasm similarity index 100% rename from programs/add/add_code_page.zasm rename to programs/add_code_page.zasm diff --git a/programs/add/add_conditional.zasm b/programs/add_conditional.zasm similarity index 100% rename from programs/add/add_conditional.zasm rename to programs/add_conditional.zasm diff --git a/programs/add/add_conditional_eq.zasm b/programs/add_conditional_eq.zasm similarity index 100% rename from programs/add/add_conditional_eq.zasm rename to programs/add_conditional_eq.zasm diff --git a/programs/add/add_conditional_gt.zasm b/programs/add_conditional_gt.zasm similarity index 100% rename from programs/add/add_conditional_gt.zasm rename to programs/add_conditional_gt.zasm diff --git a/programs/add/add_conditional_lt.zasm b/programs/add_conditional_lt.zasm similarity index 100% rename from programs/add/add_conditional_lt.zasm rename to programs/add_conditional_lt.zasm diff --git a/programs/add/add_conditional_not_eq.zasm b/programs/add_conditional_not_eq.zasm similarity index 100% rename from programs/add/add_conditional_not_eq.zasm rename to programs/add_conditional_not_eq.zasm diff --git a/programs/add/add_conditional_not_gt.zasm b/programs/add_conditional_not_gt.zasm similarity index 100% rename from programs/add/add_conditional_not_gt.zasm rename to programs/add_conditional_not_gt.zasm diff --git a/programs/add/add_conditional_not_lt.zasm b/programs/add_conditional_not_lt.zasm similarity index 100% rename from programs/add/add_conditional_not_lt.zasm rename to programs/add_conditional_not_lt.zasm diff --git a/programs/add/add_registers.zasm b/programs/add_registers.zasm similarity index 100% rename from programs/add/add_registers.zasm rename to programs/add_registers.zasm diff --git a/programs/add/add_sets_gt_flag.zasm b/programs/add_sets_gt_flag.zasm similarity index 100% rename from programs/add/add_sets_gt_flag.zasm rename to programs/add_sets_gt_flag.zasm diff --git a/programs/add/add_sets_overflow.zasm b/programs/add_sets_overflow.zasm similarity index 100% rename from programs/add/add_sets_overflow.zasm rename to programs/add_sets_overflow.zasm diff --git a/programs/add/add_stack_out_of_bounds.zasm b/programs/add_stack_out_of_bounds.zasm similarity index 100% rename from programs/add/add_stack_out_of_bounds.zasm rename to programs/add_stack_out_of_bounds.zasm diff --git a/programs/add/add_stack_with_pop.zasm b/programs/add_stack_with_pop.zasm similarity index 100% rename from programs/add/add_stack_with_pop.zasm rename to programs/add_stack_with_pop.zasm diff --git a/programs/add/add_stack_with_pop_out_of_bounds.zasm b/programs/add_stack_with_pop_out_of_bounds.zasm similarity index 100% rename from programs/add/add_stack_with_pop_out_of_bounds.zasm rename to programs/add_stack_with_pop_out_of_bounds.zasm diff --git a/programs/add/add_stack_with_push.zasm b/programs/add_stack_with_push.zasm similarity index 100% rename from programs/add/add_stack_with_push.zasm rename to programs/add_stack_with_push.zasm diff --git a/programs/add/add_sub_do_not_modify_flags.zasm b/programs/add_sub_do_not_modify_flags.zasm similarity index 100% rename from programs/add/add_sub_do_not_modify_flags.zasm rename to programs/add_sub_do_not_modify_flags.zasm diff --git a/programs/div/div.zasm b/programs/div.zasm similarity index 100% rename from programs/div/div.zasm rename to programs/div.zasm diff --git a/programs/div/div_codepage.zasm b/programs/div_codepage.zasm similarity index 100% rename from programs/div/div_codepage.zasm rename to programs/div_codepage.zasm diff --git a/programs/div/div_conditional.zasm b/programs/div_conditional.zasm similarity index 100% rename from programs/div/div_conditional.zasm rename to programs/div_conditional.zasm diff --git a/programs/div/div_conditional_gt.zasm b/programs/div_conditional_gt.zasm similarity index 100% rename from programs/div/div_conditional_gt.zasm rename to programs/div_conditional_gt.zasm diff --git a/programs/div/div_set_eq_flag.zasm b/programs/div_set_eq_flag.zasm similarity index 100% rename from programs/div/div_set_eq_flag.zasm rename to programs/div_set_eq_flag.zasm diff --git a/programs/div/div_set_gt_flag.zasm b/programs/div_set_gt_flag.zasm similarity index 100% rename from programs/div/div_set_gt_flag.zasm rename to programs/div_set_gt_flag.zasm diff --git a/programs/div/div_stack.zasm b/programs/div_stack.zasm similarity index 100% rename from programs/div/div_stack.zasm rename to programs/div_stack.zasm diff --git a/programs/div/div_zero.zasm b/programs/div_zero.zasm similarity index 100% rename from programs/div/div_zero.zasm rename to programs/div_zero.zasm diff --git a/programs/mul/mul.zasm b/programs/mul.zasm similarity index 100% rename from programs/mul/mul.zasm rename to programs/mul.zasm diff --git a/programs/mul/mul_big.zasm b/programs/mul_big.zasm similarity index 100% rename from programs/mul/mul_big.zasm rename to programs/mul_big.zasm diff --git a/programs/mul/mul_codepage.zasm b/programs/mul_codepage.zasm similarity index 100% rename from programs/mul/mul_codepage.zasm rename to programs/mul_codepage.zasm diff --git a/programs/mul/mul_conditional_gt.zasm b/programs/mul_conditional_gt.zasm similarity index 100% rename from programs/mul/mul_conditional_gt.zasm rename to programs/mul_conditional_gt.zasm diff --git a/programs/mul/mul_sets_overflow.zasm b/programs/mul_sets_overflow.zasm similarity index 100% rename from programs/mul/mul_sets_overflow.zasm rename to programs/mul_sets_overflow.zasm diff --git a/programs/mul/mul_stack.zasm b/programs/mul_stack.zasm similarity index 100% rename from programs/mul/mul_stack.zasm rename to programs/mul_stack.zasm diff --git a/programs/mul/mul_zero.zasm b/programs/mul_zero.zasm similarity index 100% rename from programs/mul/mul_zero.zasm rename to programs/mul_zero.zasm diff --git a/programs/sub/sub_and_add.zasm b/programs/sub_and_add.zasm similarity index 100% rename from programs/sub/sub_and_add.zasm rename to programs/sub_and_add.zasm diff --git a/programs/sub/sub_flags_r1_r2.zasm b/programs/sub_flags_r1_r2.zasm similarity index 100% rename from programs/sub/sub_flags_r1_r2.zasm rename to programs/sub_flags_r1_r2.zasm diff --git a/programs/sub/sub_should_be_zero.zasm b/programs/sub_should_be_zero.zasm similarity index 100% rename from programs/sub/sub_should_be_zero.zasm rename to programs/sub_should_be_zero.zasm diff --git a/programs/sub/sub_simple.zasm b/programs/sub_simple.zasm similarity index 100% rename from programs/sub/sub_simple.zasm rename to programs/sub_simple.zasm