From 74d68ea4254789a6e49560a698bf320ca4e58eb1 Mon Sep 17 00:00:00 2001 From: andri lim Date: Mon, 12 Aug 2019 17:39:29 +0700 Subject: [PATCH] fixes #72, simplify SDIV implementation --- nimbus/vm/interpreter/opcodes_impl.nim | 8 +-- tests/test_op_arith.nim | 89 +++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/nimbus/vm/interpreter/opcodes_impl.nim b/nimbus/vm/interpreter/opcodes_impl.nim index bb53848b5..9ce17783f 100644 --- a/nimbus/vm/interpreter/opcodes_impl.nim +++ b/nimbus/vm/interpreter/opcodes_impl.nim @@ -49,17 +49,13 @@ op sdiv, inline = true, lhs, rhs: ## 0x05, Signed division var r: UInt256 if rhs != 0: - const min = (1.u256 shl 255) - 1.u256 var a = lhs var b = rhs var signA, signB: bool extractSign(a, signA) extractSign(b, signB) - if a == min and b == not zero(UInt256): - r = min - else: - r = a div b - setSign(r, signA xor signB) + r = a div b + setSign(r, signA xor signB) push(r) op modulo, inline = true, lhs, rhs: diff --git a/tests/test_op_arith.nim b/tests/test_op_arith.nim index c70c8afd3..c8372ada9 100644 --- a/tests/test_op_arith.nim +++ b/tests/test_op_arith.nim @@ -195,7 +195,7 @@ suite "Arithmetic Opcodes": SDIV stack: "0x0000000000000000000000000000000000000000000000000000000000000001" - assembler: # SDIV OP + assembler: # SDIV OP, SDIV by zero should be zero title: "SDIV_3" code: PUSH1 "0x00" @@ -211,6 +211,93 @@ suite "Arithmetic Opcodes": success: false stack: "0xFF" + assembler: # -2^255 SDIV -1 = -2^255 (special case in yellow paper) + title: "SDIV_5" + code: + PUSH32 "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" # -1 + PUSH32 "0x8000000000000000000000000000000000000000000000000000000000000000" # -2^255 == low(int256) + SDIV + stack: "0x8000000000000000000000000000000000000000000000000000000000000000" # -2^255 == low(int256) + + assembler: # -2^255 SDIV 1 = -2^255 + title: "SDIV_6" + code: + PUSH32 "0x0000000000000000000000000000000000000000000000000000000000000001" # 1 + PUSH32 "0x8000000000000000000000000000000000000000000000000000000000000000" # -2^255 == low(int256) + SDIV + stack: "0x8000000000000000000000000000000000000000000000000000000000000000" # -2^255 == low(int256) + + assembler: # -2 SDIV 2 = -1 + title: "SDIV_7" + code: + PUSH32 "0x0000000000000000000000000000000000000000000000000000000000000002" # 2 + PUSH32 "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" # -2 + SDIV + stack: "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" # -1 + + assembler: # 4 SDIV -2 = -2 + title: "SDIV_8" + code: + PUSH32 "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" # -2 + PUSH32 "0x0000000000000000000000000000000000000000000000000000000000000004" # 4 + SDIV + stack: "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" # -2 + + assembler: # -4 SDIV 2 = -2 + title: "SDIV_9" + code: + PUSH32 "0x0000000000000000000000000000000000000000000000000000000000000002" # -4 + PUSH32 "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC" # 2 + SDIV + stack: "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" # -2 + + assembler: # -1 SDIV 2 = 0 + title: "SDIV_10" + code: + PUSH32 "0x0000000000000000000000000000000000000000000000000000000000000002" # 2 + PUSH32 "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" # -1 + SDIV + stack: "0x00" # 0 + + assembler: # low(int256) SDIV low(int256) = 1 + title: "SDIV_11" + code: + PUSH32 "0x8000000000000000000000000000000000000000000000000000000000000000" # low(int256) + PUSH32 "0x8000000000000000000000000000000000000000000000000000000000000000" # low(int256) + SDIV + stack: "0x01" # 1 + + assembler: # low(int256) SDIV 2 + title: "SDIV_12" + code: + PUSH32 "0x0000000000000000000000000000000000000000000000000000000000000002" # 2 + PUSH32 "0x8000000000000000000000000000000000000000000000000000000000000000" # low(int256) + SDIV + stack: "0xC000000000000000000000000000000000000000000000000000000000000000" # negative half low(int256) + + assembler: # low(int256) SDIV -2 + title: "SDIV_13" + code: + PUSH32 "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" # -2 + PUSH32 "0x8000000000000000000000000000000000000000000000000000000000000000" # low(int256) + SDIV + stack: "0x4000000000000000000000000000000000000000000000000000000000000000" # positive version of SDIV_12 + + assembler: + title: "SDIV_14" + code: + PUSH1 "0x01" # 1 + PUSH1 "0x7F" # 127 + SHL # 1 shl 127 (move the bit to the center or 128th position) + + PUSH1 "0x01" # 1 + PUSH1 "0xFF" # 255 + SHL # 1 shl 255 (create low(int256)) + + SDIV + stack: "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000" # half of the hi bits are set + fork: constantinople + assembler: # SUB OP title: "SUB_1" code: