Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mul and div opcodes #26

Merged
merged 18 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion programs/add_sets_overflow.zasm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.text
.file "add_sets_overflow.zasm"
.file "mul_sets_overflow.zasm"
.globl __entry
__entry:

Expand Down
14 changes: 14 additions & 0 deletions programs/div.zasm
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions programs/div_codepage.zasm
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions programs/div_conditional.zasm
Original file line number Diff line number Diff line change
@@ -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
16 changes: 16 additions & 0 deletions programs/div_conditional_gt.zasm
Original file line number Diff line number Diff line change
@@ -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
15 changes: 15 additions & 0 deletions programs/div_set_eq_flag.zasm
Original file line number Diff line number Diff line change
@@ -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
15 changes: 15 additions & 0 deletions programs/div_set_gt_flag.zasm
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions programs/div_stack.zasm
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions programs/div_zero.zasm
Original file line number Diff line number Diff line change
@@ -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, r0
ret
.func_end0:

.note.GNU-stack
.rodata
15 changes: 15 additions & 0 deletions programs/mul.zasm
Original file line number Diff line number Diff line change
@@ -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, r3, r4
sstore r0, r3
ret
.func_end0:

.note.GNU-stack
.rodata
13 changes: 13 additions & 0 deletions programs/mul_big.zasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.text
.file "mul_big.zasm"
.globl __entry
__entry:
.func_begin0:
; test sets r1 = 2**(256) - 1, r2 = 2**(256)
mul r1, r2, r3, r4
sstore r0, r1
ret
.func_end0:

.note.GNU-stack
.rodata
21 changes: 21 additions & 0 deletions programs/mul_codepage.zasm
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions programs/mul_conditional_gt.zasm
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions programs/mul_sets_overflow.zasm
Original file line number Diff line number Diff line change
@@ -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
22 changes: 22 additions & 0 deletions programs/mul_stack.zasm
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions programs/mul_zero.zasm
Original file line number Diff line number Diff line change
@@ -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
74 changes: 59 additions & 15 deletions src/address_operands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,25 +72,65 @@ 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) {
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<U256>)) {
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");
Expand All @@ -99,38 +139,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,
},
);
Expand All @@ -144,4 +184,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);
}
}
Loading