From: Andrea Corallo Date: Mon, 10 Jun 2019 09:02:47 +0000 (+0200) Subject: add Bnegate support X-Git-Tag: emacs-28.0.90~2727^2~1497 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=7ce2c17a0fbde3203f311c6b91d8bb2ba77adeda;p=emacs.git add Bnegate support --- diff --git a/src/comp.c b/src/comp.c index d92e4822266..712fd01af07 100644 --- a/src/comp.c +++ b/src/comp.c @@ -634,6 +634,7 @@ compute_bblocks (ptrdiff_t bytestr_length, unsigned char *bytestr_data) break; case Bsub1: case Badd1: + case Bnegate: case Breturn: new_bb = true; break; @@ -997,8 +998,8 @@ compile_f (const char *f_name, ptrdiff_t bytestr_length, { /* (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM - ? make_fixnum (XFIXNUM (TOP) - 1) - : Fsub1 (TOP)) */ + ? make_fixnum (XFIXNUM (TOP) - 1) + : Fsub1 (TOP)) */ gcc_jit_block *sub1_inline_block = gcc_jit_function_new_block (comp.func, "inline_sub1"); @@ -1057,8 +1058,8 @@ compile_f (const char *f_name, ptrdiff_t bytestr_length, { /* (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_POSITIVE_FIXNUM - ? make_fixnum (XFIXNUM (TOP) + 1) - : Fadd (TOP)) */ + ? make_fixnum (XFIXNUM (TOP) + 1) + : Fadd (TOP)) */ gcc_jit_block *add1_inline_block = gcc_jit_function_new_block (comp.func, "inline_add1"); @@ -1131,7 +1132,59 @@ compile_f (const char *f_name, ptrdiff_t bytestr_length, EMIT_SCRATCH_CALL_N ("Fminus", 2); break; case Bnegate: - error ("Bnegate unsupported bytecode\n"); + { + + /* (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM + ? make_fixnum (- XFIXNUM (TOP)) + : Fminus (1, &TOP)) */ + + gcc_jit_block *negate_inline_block = + gcc_jit_function_new_block (comp.func, "inline_negate"); + gcc_jit_block *negate_fcall_block = + gcc_jit_function_new_block (comp.func, "fcall_negate"); + + gcc_jit_rvalue *tos_as_num = + comp_XFIXNUM (gcc_jit_lvalue_as_rvalue (TOS)); + + comp_emit_cond_jump ( + gcc_jit_context_new_binary_op ( + comp.ctxt, + NULL, + GCC_JIT_BINARY_OP_LOGICAL_AND, + comp.bool_type, + comp_cast (comp.bool_type, + comp_FIXNUMP (gcc_jit_lvalue_as_rvalue (TOS))), + gcc_jit_context_new_comparison (comp.ctxt, + NULL, + GCC_JIT_COMPARISON_NE, + tos_as_num, + comp.most_negative_fixnum)), + negate_inline_block, + negate_fcall_block); + + gcc_jit_rvalue *negate_inline_res = + gcc_jit_context_new_unary_op (comp.ctxt, + NULL, + GCC_JIT_UNARY_OP_MINUS, + comp.long_long_type, + tos_as_num); + + gcc_jit_block_add_assignment (negate_inline_block, + NULL, + TOS, + comp_make_fixnum (negate_inline_block, + negate_inline_res)); + basic_block_t bb_orig = *comp.bblock; + + comp.bblock->gcc_bb = negate_fcall_block; + EMIT_SCRATCH_CALL_N ("Fminus", 1); + *comp.bblock = bb_orig; + + gcc_jit_block_end_with_jump (negate_inline_block, NULL, + bb_map[pc].gcc_bb); + gcc_jit_block_end_with_jump (negate_fcall_block, NULL, + bb_map[pc].gcc_bb); + } break; case Bplus: EMIT_SCRATCH_CALL_N ("Fplus", 2); diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el index 06c7697be74..dc2c396392b 100644 --- a/test/src/comp-tests.el +++ b/test/src/comp-tests.el @@ -148,28 +148,42 @@ (ert-deftest comp-tests-fixnum () "Testing some fixnum inline operation." - (defun comp-tests-fixnum-1--f (x) + (defun comp-tests-fixnum-1-minus-f (x) + ;; Bsub1 (1- x)) - (defun comp-tests-fixnum-1+-f (x) + (defun comp-tests-fixnum-1-plus-f (x) + ;; Badd1 (1+ x)) - - (byte-compile #'comp-tests-fixnum-1--f) - (byte-compile #'comp-tests-fixnum-1+-f) - ;; (native-compile #'comp-tests-fixnum-1--f) - (native-compile #'comp-tests-fixnum-1+-f) - - (should (= (comp-tests-fixnum-1--f 10) 9)) - (should (= (comp-tests-fixnum-1--f most-negative-fixnum) + (defun comp-tests-fixnum-minus-f (x) + ;; Bnegate + (- x)) + + (byte-compile #'comp-tests-fixnum-1-minus-f) + (byte-compile #'comp-tests-fixnum-1-plus-f) + (byte-compile #'comp-tests-fixnum-minus-f) + (native-compile #'comp-tests-fixnum-1-minus-f) + (native-compile #'comp-tests-fixnum-1-plus-f) + (native-compile #'comp-tests-fixnum-minus-f) + + (should (= (comp-tests-fixnum-1-minus-f 10) 9)) + (should (= (comp-tests-fixnum-1-minus-f most-negative-fixnum) (1- most-negative-fixnum))) (should (equal (condition-case err - (comp-tests-fixnum-1--f 'a) + (comp-tests-fixnum-1-minus-f 'a) (error err)) '(wrong-type-argument number-or-marker-p a))) - (should (= (comp-tests-fixnum-1+-f 10) 11)) - (should (= (comp-tests-fixnum-1+-f most-positive-fixnum) + (should (= (comp-tests-fixnum-1-plus-f 10) 11)) + (should (= (comp-tests-fixnum-1-plus-f most-positive-fixnum) (1+ most-positive-fixnum))) (should (equal (condition-case err - (comp-tests-fixnum-1+-f 'a) + (comp-tests-fixnum-1-plus-f 'a) + (error err)) + '(wrong-type-argument number-or-marker-p a))) + (should (= (comp-tests-fixnum-minus-f 10) -10)) + (should (= (comp-tests-fixnum-minus-f most-negative-fixnum) + (- most-negative-fixnum))) + (should (equal (condition-case err + (comp-tests-fixnum-minus-f 'a) (error err)) '(wrong-type-argument number-or-marker-p a))))