From 5362d5056d8384610d9c546ff00b3d606fcaae39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 4 Dec 2014 20:31:56 +0100 Subject: [PATCH] SDIV & SMOD fixed --- libevmjit/Arith256.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/libevmjit/Arith256.cpp b/libevmjit/Arith256.cpp index 95d11e3f3..10d3e3449 100644 --- a/libevmjit/Arith256.cpp +++ b/libevmjit/Arith256.cpp @@ -96,6 +96,29 @@ llvm::Value* Arith256::mulmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Valu return ternaryOp(m_mulmod, _arg1, _arg2, _arg3); } +namespace +{ + using s256 = boost::multiprecision::int256_t; + + inline s256 u2s(u256 _u) + { + static const bigint c_end = (bigint)1 << 256; + static const u256 c_send = (u256)1 << 255; + if (_u < c_send) + return (s256)_u; + else + return (s256)-(c_end - _u); + } + + inline u256 s2u(s256 _u) + { + static const bigint c_end = (bigint)1 << 256; + if (_u >= 0) + return (u256)_u; + else + return (u256)(c_end + _u); + } +} } } @@ -106,7 +129,6 @@ extern "C" { using namespace dev::eth::jit; - using s256 = boost::multiprecision::int256_t; EXPORT void arith_mul(i256* _arg1, i256* _arg2, i256* o_result) { @@ -133,14 +155,14 @@ extern "C" { auto arg1 = llvm2eth(*_arg1); auto arg2 = llvm2eth(*_arg2); - *o_result = eth2llvm(arg2 == 0 ? arg2 : (arg1.convert_to() / arg2.convert_to()).convert_to()); + *o_result = eth2llvm(arg2 == 0 ? arg2 : s2u(u2s(arg1) / u2s(arg2))); } EXPORT void arith_smod(i256* _arg1, i256* _arg2, i256* o_result) { auto arg1 = llvm2eth(*_arg1); auto arg2 = llvm2eth(*_arg2); - *o_result = eth2llvm(arg2 == 0 ? arg2 : (arg1.convert_to() % arg2.convert_to()).convert_to()); + *o_result = eth2llvm(arg2 == 0 ? arg2 : s2u(u2s(arg1) % u2s(arg2))); } EXPORT void arith_exp(i256* _arg1, i256* _arg2, i256* o_result)