* jit/jit-reg-alloc.h, jit/jit-reg-alloc.c: new register allocator
improved and extended to support stack registers.
+ * jit/jit-internal.h (struct _jit_builder):
+ * jit/jit-function.c (compile_block, jit_function_compile): add
+ some tracing.
+
+ * jit/jit-rules.h:
+ * jit/jit-rules-arm.c:
+ * jit/jit-rules-interp.c:
+ * jit/jit-rules-x86.c: add _jit_gen_exch_top and _jit_gen_spill_top
+ functions used by new allocator to handle stack registers. Add reg
+ argument to _jit_gen_spill_global and_jit_gen_load_global
+ functions.
+
2006-04-11 Aleksey Demakov <ademakov@gmail.com>
* jit/jit-insn.c (jit_insn_start_catcher): initialize
jit_insn_iter_t iter;
jit_insn_t insn;
+#ifdef _JIT_COMPILE_DEBUG
+ printf("Block: %d\n", func->builder->block_count++);
+#endif
+
/* Iterate over all blocks in the function */
jit_insn_iter_init(&iter, block);
while((insn = jit_insn_iter_next(&iter)) != 0)
{
+#ifdef _JIT_COMPILE_DEBUG
+ unsigned char *p1, *p2;
+ p1 = gen->posn.ptr;
+ printf("Insn %5d: 0x%04x - ", func->builder->insn_count++, insn->opcode);
+#endif
+
switch(insn->opcode)
{
case JIT_OP_NOP: break; /* Ignore NOP's */
if(insn->value1->has_global_register)
{
insn->value1->in_global_register = 1;
- _jit_gen_load_global(gen, insn->value1);
+ _jit_gen_load_global(gen, insn->value1->global_reg, insn->value1);
}
else
{
}
break;
}
+
+#ifdef _JIT_COMPILE_DEBUG
+ p2 = gen->posn.ptr;
+ printf("%d\n", p2 - p1);
+#endif
}
}
due to a lack of space in the current method cache page */
do
{
+#ifdef _JIT_COMPILE_DEBUG
+ printf("\n*** Start compilation ***\n\n");
+ func->builder->block_count = 0;
+ func->builder->insn_count = 0;
+#endif
+
/* Start function output to the cache */
start = _jit_cache_start_method
(cache, &(gen.posn), JIT_FUNCTION_ALIGNMENT, func);
extern "C" {
#endif
+/*
+#define _JIT_COMPILE_DEBUG 1
+*/
+
+
/*
* Determine what kind of Win32 system we are running on.
*/
/* Size of the outgoing parameter area in the frame */
jit_nint param_area_size;
+#ifdef _JIT_COMPILE_DEBUG
+ int block_count;
+ int insn_count;
+#endif
};
/*
regs->stack_count = 0;
regs->initial_stack_size = 0;
regs->current_stack_size = 0;
+ regs->num_exchanges = 0;
}
void
jit_cache_end_output();
}
-void _jit_gen_spill_global(jit_gencode_t gen, jit_value_t value)
+void _jit_gen_spill_global(jit_gencode_t gen, int reg, jit_value_t value)
{
/* TODO: Implement if ARM needs it. */
}
-void _jit_gen_load_global(jit_gencode_t gen, jit_value_t value)
+void _jit_gen_load_global(jit_gencode_t gen, int reg, jit_value_t value)
{
jit_cache_setup_output(32);
arm_load_membase(inst, _jit_reg_info[value->global_reg].cpu_reg,
jit_cache_end_output();
}
+void _jit_gen_exch_top(jit_gencode_t gen, int reg, int pop)
+{
+}
+
+void _jit_gen_spill_top(jit_gencode_t gen, int reg, jit_value_t value, int pop)
+{
+}
+
void _jit_gen_fix_value(jit_value_t value)
{
if(!(value->has_frame_offset) && !(value->is_constant))
* after it.
* @end deftypefun
@*/
-void _jit_gen_spill_global(jit_gencode_t gen, jit_value_t value)
+void _jit_gen_spill_global(jit_gencode_t gen, int reg, jit_value_t value)
{
/* Global registers are not used in the interpreted back end */
}
* slots into their global register copies.
* @end deftypefun
@*/
-void _jit_gen_load_global(jit_gencode_t gen, jit_value_t value)
+void _jit_gen_load_global(jit_gencode_t gen, int reg, jit_value_t value)
{
/* Global registers are not used in the interpreted back end */
}
+void _jit_gen_exch_top(jit_gencode_t gen, int reg, int pop)
+{
+}
+
+void _jit_gen_spill_top(jit_gencode_t gen, int reg, jit_value_t value, int pop)
+{
+}
+
/*@
* @deftypefun void _jit_gen_fix_value (jit_value_t value)
* Fix the position of a value within the local variable frame.
return top - reg;
}
+void
+_jit_gen_exch_top(jit_gencode_t gen, int reg, int pop)
+{
+ if(IS_FLOAT_REG(reg))
+ {
+ jit_cache_setup_output(2);
+ if(pop)
+ {
+ x86_fstp(inst, reg - X86_REG_ST0);
+ }
+ else
+ {
+ x86_fxch(inst, reg - X86_REG_ST0);
+ }
+ jit_cache_end_output();
+ }
+}
+
+void
+_jit_gen_spill_top(jit_gencode_t gen, int reg, jit_value_t value, int pop)
+{
+ int offset;
+ if(IS_FLOAT_REG(reg))
+ {
+ /* Fix the value in place within the local variable frame */
+ _jit_gen_fix_value(value);
+
+ /* Make sure that we have sufficient space */
+ jit_cache_setup_output(16);
+
+ /* Output an appropriate instruction to spill the value */
+ offset = (int)(value->frame_offset);
+
+ /* Spill the top of the floating-point register stack */
+ switch(jit_type_normalize(value->type)->kind)
+ {
+ case JIT_TYPE_FLOAT32:
+ {
+ x86_fst_membase(inst, X86_EBP, offset, 0, pop);
+ }
+ break;
+
+ case JIT_TYPE_FLOAT64:
+ {
+ x86_fst_membase(inst, X86_EBP, offset, 1, pop);
+ }
+ break;
+
+ case JIT_TYPE_NFLOAT:
+ {
+ x86_fst80_membase(inst, X86_EBP, offset);
+ if(!pop)
+ {
+ x86_fld80_membase(inst, X86_EBP, offset);
+ }
+ }
+ break;
+ }
+ }
+}
+
void
_jit_gen_load_value(jit_gencode_t gen, int reg, int other_reg, jit_value_t value)
{
jit_cache_end_output();
}
-void _jit_gen_spill_global(jit_gencode_t gen, jit_value_t value)
+void _jit_gen_spill_global(jit_gencode_t gen, int reg, jit_value_t value)
{
jit_cache_setup_output(16);
- _jit_gen_fix_value(value);
- x86_mov_membase_reg(inst, X86_EBP, value->frame_offset,
- _jit_reg_info[value->global_reg].cpu_reg, sizeof(void *));
+ if(value)
+ {
+ _jit_gen_fix_value(value);
+ x86_mov_membase_reg(inst,
+ X86_EBP, value->frame_offset,
+ _jit_reg_info[value->global_reg].cpu_reg, sizeof(void *));
+ }
+ else
+ {
+ x86_push_reg(inst, _jit_reg_info[reg].cpu_reg);
+ }
jit_cache_end_output();
}
-void _jit_gen_load_global(jit_gencode_t gen, jit_value_t value)
+void _jit_gen_load_global(jit_gencode_t gen, int reg, jit_value_t value)
{
jit_cache_setup_output(16);
- x86_mov_reg_membase(inst, _jit_reg_info[value->global_reg].cpu_reg,
- X86_EBP, value->frame_offset, sizeof(void *));
+ if(value)
+ {
+ x86_mov_reg_membase(inst,
+ _jit_reg_info[value->global_reg].cpu_reg,
+ X86_EBP, value->frame_offset, sizeof(void *));
+ }
+ else
+ {
+ x86_pop_reg(inst, _jit_reg_info[reg].cpu_reg);
+ }
jit_cache_end_output();
}
switch(insn->opcode)
{
#define JIT_INCLUDE_RULES
+#if _JIT_NEW_REG_ALLOC
+ #include "jit-rules-x86.inc"
+#else
#include "jit-rules-x86.slc"
+#endif
#undef JIT_INCLUDE_RULES
default:
int other_reg, int value_used);
void _jit_gen_load_value
(jit_gencode_t gen, int reg, int other_reg, jit_value_t value);
-void _jit_gen_spill_global(jit_gencode_t gen, jit_value_t value);
-void _jit_gen_load_global(jit_gencode_t gen, jit_value_t value);
+void _jit_gen_spill_global(jit_gencode_t gen, int reg, jit_value_t value);
+void _jit_gen_load_global(jit_gencode_t gen, int reg, jit_value_t value);
+void _jit_gen_exch_top(jit_gencode_t gen, int reg, int pop);
+void _jit_gen_spill_top(jit_gencode_t gen, int reg, jit_value_t value, int pop);
void _jit_gen_fix_value(jit_value_t value);
void _jit_gen_insn(jit_gencode_t gen, jit_function_t func,
jit_block_t block, jit_insn_t insn);