From 458dc58b59125a99b2020635bcc5452e486a190a Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Mon, 27 Nov 2017 12:56:50 +0100 Subject: [PATCH] Improve multiplication in vm This patch improves the ecma_integers_values multiplication by checking if the multiplier or multiplicand is power of 2. If it is it uses right shift instead of multiplication. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu --- jerry-core/ecma/base/ecma-helpers-number.c | 25 ++++++++++++++++++++++ jerry-core/ecma/base/ecma-helpers.h | 1 + jerry-core/vm/vm.c | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/jerry-core/ecma/base/ecma-helpers-number.c b/jerry-core/ecma/base/ecma-helpers-number.c index 19db451e3..ea43c5071 100644 --- a/jerry-core/ecma/base/ecma-helpers-number.c +++ b/jerry-core/ecma/base/ecma-helpers-number.c @@ -653,6 +653,31 @@ ecma_number_calc_remainder (ecma_number_t left_num, /**< left operand */ return r; } /* ecma_number_calc_remainder */ +/** + * ECMA-integer number multiplication. + * + * @return number - result of multiplication. + */ +inline ecma_value_t __attr_always_inline___ +ecma_integer_multiply (ecma_integer_value_t left_integer, /**< left operand */ + ecma_integer_value_t right_integer) /**< right operand */ +{ +#if defined (__GNUC__) || defined (__clang__) + /* Check if left_integer is power of 2 */ + if (unlikely ((left_integer & (left_integer - 1)) == 0)) + { + /* Right shift right_integer with log2 (left_integer) */ + return ecma_make_integer_value (right_integer << (__builtin_ctz ((unsigned int) left_integer))); + } + else if (unlikely ((right_integer & (right_integer - 1)) == 0)) + { + /* Right shift left_integer with log2 (right_integer) */ + return ecma_make_integer_value (left_integer << (__builtin_ctz ((unsigned int) right_integer))); + } +#endif /* defined (__GNUC__) || defined (__clang__) */ + return ecma_make_integer_value (left_integer * right_integer); +} /* ecma_integer_multiply */ + /** * @} * @} diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index a1783849c..520b3d1e7 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -243,6 +243,7 @@ ecma_number_t ecma_number_get_prev (ecma_number_t num); ecma_number_t ecma_number_get_next (ecma_number_t num); ecma_number_t ecma_number_trunc (ecma_number_t num); ecma_number_t ecma_number_calc_remainder (ecma_number_t left_num, ecma_number_t right_num); +ecma_value_t ecma_integer_multiply (ecma_integer_value_t left_integer, ecma_integer_value_t right_integer); lit_utf8_size_t ecma_number_to_decimal (ecma_number_t num, lit_utf8_byte_t *out_digits_p, int32_t *out_decimal_exp_p); lit_utf8_size_t ecma_number_to_binary_floating_point_number (ecma_number_t num, lit_utf8_byte_t *out_digits_p, diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index d1cac7bef..3dd634615 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -1793,7 +1793,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ && left_value != 0 && right_value != 0) { - result = ecma_make_integer_value (left_integer * right_integer); + result = ecma_integer_multiply (left_integer, right_integer); break; }