gcc_jit_function *bool_to_lisp_obj;
gcc_jit_function *add1;
gcc_jit_function *sub1;
+ gcc_jit_function *negate;
gcc_jit_function *car;
gcc_jit_function *cdr;
gcc_jit_function *setcar;
args);
}
+static gcc_jit_rvalue *
+emit_call_n_ref (const char *f_name, unsigned nargs,
+ gcc_jit_lvalue *base_arg)
+{
+ gcc_jit_rvalue *args[] =
+ { gcc_jit_context_new_rvalue_from_int(comp.ctxt,
+ comp.ptrdiff_type,
+ nargs),
+ gcc_jit_lvalue_get_address (base_arg, NULL) };
+ return emit_call (f_name, comp.lisp_obj_type, 2, args);
+}
+
/* Close current basic block emitting a conditional. */
INLINE static void
return gcc_jit_context_new_call (comp.ctxt, NULL, comp.sub1, 1, &n);
}
+static gcc_jit_rvalue *
+emit_negate (Lisp_Object insn)
+{
+ gcc_jit_rvalue *n = emit_mvar_val (SECOND (insn));
+ return gcc_jit_context_new_call (comp.ctxt, NULL, comp.negate, 1, &n);
+}
+
static gcc_jit_rvalue *
emit_consp (Lisp_Object insn)
{
gcc_jit_rvalue *predicate = gcc_jit_param_as_rvalue (param[1]);
gcc_jit_rvalue *x = gcc_jit_param_as_rvalue (param[2]);
- DECL_BLOCK (init_block, comp.check_type);
+ DECL_BLOCK (entry_block, comp.check_type);
DECL_BLOCK (ok_block, comp.check_type);
DECL_BLOCK (not_ok_block, comp.check_type);
- comp.block = init_block;
+ comp.block = entry_block;
comp.func = comp.check_type;
emit_cond_jump (ok, ok_block, not_ok_block);
for (int i = 0; i < 2; i++)
{
gcc_jit_rvalue *c = gcc_jit_param_as_rvalue (param);
- DECL_BLOCK (init_block, f);
+ DECL_BLOCK (entry_block, f);
DECL_BLOCK (is_cons_b, f);
DECL_BLOCK (not_a_cons_b, f);
- comp.block = init_block;
+ comp.block = entry_block;
comp.func = f;
emit_cond_jump (emit_CONSP (c), is_cons_b, not_a_cons_b);
2,
param,
0);
- DECL_BLOCK (init_block, *f_ref);
+ DECL_BLOCK (entry_block, *f_ref);
comp.func = *f_ref;
- comp.block = init_block;
+ comp.block = entry_block;
/* CHECK_CONS (cell); */
emit_CHECK_CONS (gcc_jit_param_as_rvalue (cell));
emit_XCONS (gcc_jit_param_as_rvalue (cell)) };
gcc_jit_block_add_eval (
- init_block,
+ entry_block,
NULL,
gcc_jit_context_new_call (comp.ctxt,
NULL,
gcc_jit_param_as_rvalue (new_el));
/* return newel; */
- gcc_jit_block_end_with_return (init_block,
+ gcc_jit_block_end_with_return (entry_block,
NULL,
gcc_jit_param_as_rvalue (new_el));
}
1,
¶m,
0);
- DECL_BLOCK (init_block, func[i]);
+ DECL_BLOCK (entry_block, func[i]);
DECL_BLOCK (inline_block, func[i]);
DECL_BLOCK (fcall_block, func[i]);
- comp.block = init_block;
+ comp.block = entry_block;
/* (FIXNUMP (n) && XFIXNUM (n) != MOST_POSITIVE_FIXNUM
? (XFIXNUM (n) + 1)
comp.sub1 = func[1];
}
+static void
+define_negate (void)
+{
+ gcc_jit_block *bb_orig = comp.block;
+
+ gcc_jit_param *param[] =
+ { gcc_jit_context_new_param (comp.ctxt,
+ NULL,
+ comp.lisp_obj_type,
+ "n") };
+
+ comp.func = comp.negate =
+ gcc_jit_context_new_function (comp.ctxt, NULL,
+ GCC_JIT_FUNCTION_ALWAYS_INLINE,
+ comp.lisp_obj_type,
+ "negate",
+ 1,
+ param,
+ 0);
+
+ DECL_BLOCK (entry_block, comp.negate);
+ DECL_BLOCK (inline_block, comp.negate);
+ DECL_BLOCK (fcall_block, comp.negate);
+
+ comp.block = entry_block;
+
+ /* (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM
+ ? make_fixnum (- XFIXNUM (TOP))
+ : Fminus (1, &TOP)) */
+
+ gcc_jit_lvalue *n = gcc_jit_param_as_lvalue (param[0]);
+ gcc_jit_rvalue *n_fixnum =
+ emit_XFIXNUM (gcc_jit_lvalue_as_rvalue (n));
+
+ emit_cond_jump (
+ gcc_jit_context_new_binary_op (
+ comp.ctxt,
+ NULL,
+ GCC_JIT_BINARY_OP_LOGICAL_AND,
+ comp.bool_type,
+ emit_cast (comp.bool_type,
+ emit_FIXNUMP (gcc_jit_lvalue_as_rvalue (n))),
+ gcc_jit_context_new_comparison (comp.ctxt,
+ NULL,
+ GCC_JIT_COMPARISON_NE,
+ n_fixnum,
+ comp.most_negative_fixnum)),
+ inline_block,
+ fcall_block);
+
+ comp.block = inline_block;
+ gcc_jit_rvalue *inline_res =
+ gcc_jit_context_new_unary_op (comp.ctxt,
+ NULL,
+ GCC_JIT_UNARY_OP_MINUS,
+ comp.emacs_int_type,
+ n_fixnum);
+
+ gcc_jit_block_end_with_return (inline_block,
+ NULL,
+ emit_make_fixnum (inline_res));
+
+ comp.block = fcall_block;
+ gcc_jit_rvalue *call_res = emit_call_n_ref ("Fminus", 1, n);
+ gcc_jit_block_end_with_return (fcall_block,
+ NULL,
+ call_res);
+ comp.block = bb_orig;
+}
+
/* Define a substitute for PSEUDOVECTORP as always inlined function. */
static void
param,
0);
- DECL_BLOCK (init_block, comp.pseudovectorp);
+ DECL_BLOCK (entry_block, comp.pseudovectorp);
DECL_BLOCK (ret_false_b, comp.pseudovectorp);
DECL_BLOCK (call_pseudovector_typep_b, comp.pseudovectorp);
- comp.block = init_block;
+ comp.block = entry_block;
comp.func = comp.pseudovectorp;
emit_cond_jump (emit_VECTORLIKEP (gcc_jit_param_as_rvalue (param[0])),
param,
0);
- DECL_BLOCK (init_block, comp.check_impure);
+ DECL_BLOCK (entry_block, comp.check_impure);
DECL_BLOCK (err_block, comp.check_impure);
DECL_BLOCK (ok_block, comp.check_impure);
- comp.block = init_block;
+ comp.block = entry_block;
comp.func = comp.check_impure;
emit_cond_jump (emit_PURE_P (gcc_jit_param_as_rvalue (param[0])), /* FIXME */
1,
¶m,
0);
- DECL_BLOCK (init_block, comp.bool_to_lisp_obj);
+ DECL_BLOCK (entry_block, comp.bool_to_lisp_obj);
DECL_BLOCK (ret_t_block, comp.bool_to_lisp_obj);
DECL_BLOCK (ret_nil_block, comp.bool_to_lisp_obj);
- comp.block = init_block;
+ comp.block = entry_block;
comp.func = comp.bool_to_lisp_obj;
emit_cond_jump (gcc_jit_param_as_rvalue (param),
register_emitter (QFconsp, emit_consp);
register_emitter (QFcar, emit_car);
register_emitter (QFcdr, emit_cdr);
+ register_emitter (Qnegate, emit_negate);
}
comp.ctxt = gcc_jit_context_acquire();
define_bool_to_lisp_obj ();
define_setcar_setcdr ();
define_add1_sub1 ();
+ define_negate ();
return Qt;
}
DEFSYM (QFconsp, "Fconsp");
DEFSYM (QFcar, "Fcar");
DEFSYM (QFcdr, "Fcdr");
+ DEFSYM (Qnegate, "negate");
defsubr (&Scomp_init_ctxt);
defsubr (&Scomp_release_ctxt);