CHECK_STACK; \
gcc_jit_block_add_assignment (comp.block->gcc_bb, \
NULL, \
- (stack)->gcc_lval, \
+ stack->gcc_lval, \
gcc_jit_lvalue_as_rvalue(obj)); \
+ stack->type = -1; \
+ stack->sym_val = NULL; \
stack++; \
} while (0)
CHECK_STACK; \
gcc_jit_block_add_assignment (comp.block->gcc_bb, \
NULL, \
- (stack)->gcc_lval, \
+ stack->gcc_lval, \
(obj)); \
+ stack->type = -1; \
+ stack->sym_val = NULL; \
stack++; \
} while (0)
CHECK_STACK; \
gcc_jit_block_add_assignment (prologue_bb, \
NULL, \
- (stack)->gcc_lval, \
+ stack->gcc_lval, \
gcc_jit_param_as_rvalue(obj)); \
+ stack->type = -1; \
+ stack->sym_val = NULL; \
stack++; \
} while (0)
do { \
stack--; \
CHECK_STACK; \
- args[0] = gcc_jit_lvalue_as_rvalue ((stack)->gcc_lval); \
+ args[0] = gcc_jit_lvalue_as_rvalue (stack->gcc_lval); \
} while (0)
#define POP2 \
do { \
stack--; \
CHECK_STACK; \
- args[1] = gcc_jit_lvalue_as_rvalue ((stack)->gcc_lval); \
+ args[1] = gcc_jit_lvalue_as_rvalue (stack->gcc_lval); \
stack--; \
- args[0] = gcc_jit_lvalue_as_rvalue ((stack)->gcc_lval); \
+ args[0] = gcc_jit_lvalue_as_rvalue (stack->gcc_lval); \
} while (0)
#define POP3 \
do { \
stack--; \
CHECK_STACK; \
- args[2] = gcc_jit_lvalue_as_rvalue ((stack)->gcc_lval); \
+ args[2] = gcc_jit_lvalue_as_rvalue (stack->gcc_lval); \
stack--; \
- args[1] = gcc_jit_lvalue_as_rvalue ((stack)->gcc_lval); \
+ args[1] = gcc_jit_lvalue_as_rvalue (stack->gcc_lval); \
stack--; \
- args[0] = gcc_jit_lvalue_as_rvalue ((stack)->gcc_lval); \
+ args[0] = gcc_jit_lvalue_as_rvalue (stack->gcc_lval); \
} while (0)
/* Fetch the next byte from the bytecode stream. */
#define EMIT_CALL_N_REF(name, nargs) \
do { \
DISCARD (nargs); \
- res = emit_call_n_ref ((name), (nargs), (stack)->gcc_lval); \
+ res = emit_call_n_ref ((name), (nargs), stack->gcc_lval); \
PUSH_RVAL (res); \
} while (0)
/* Element of the meta stack. */
typedef struct {
gcc_jit_lvalue *gcc_lval;
+ enum Lisp_Type type; /* -1 if not set. */
+ char *sym_val;
} stack_el_t;
typedef struct {
docall:
{
ptrdiff_t nargs = op + 1;
- DISCARD (nargs);
- res = emit_call_n_ref ("Ffuncall", nargs, stack->gcc_lval);
+ pop (nargs, &stack, args);
+ if (stack->type == Lisp_Symbol &&
+ !strcmp (stack->sym_val, lisp_f_name))
+ {
+ /* Optimize self calls. */
+ res = gcc_jit_context_new_call (comp.ctxt,
+ NULL,
+ comp.func,
+ nargs - 1,
+ args + 1);
+ }
+ else
+ {
+ res = emit_call_n_ref ("Ffuncall", nargs, stack->gcc_lval);
+ }
PUSH_RVAL (res);
break;
}
gcc_jit_rvalue *c =
emit_lisp_obj_from_ptr (vectorp[op]);
PUSH_RVAL (c);
+ TOS.type = XTYPE (vectorp[op]);
+ if (TOS.type == Lisp_Symbol)
+ /* Store the symbol value for later use is used while
+ optimizing native and self calls. */
+ TOS.sym_val = (char *) SDATA (SYMBOL_NAME (vectorp[op]));
break;
}