Author: leo
Date: Sun Feb 5 08:13:37 2006
New Revision: 11423
Modified:
trunk/compilers/imcc/jit.c
trunk/config/auto/jit.pm
trunk/include/parrot/jit.h
trunk/src/jit.c
trunk/src/jit/i386/jit_emit.h
Log:
JIT - use architecture specific info structure for x86
* x86 JIT changes
- setup jit_arch_info structure
- rearrange jit_emit.h WRT JIT_EMIT sections
* jit.c changes
- use jit_arch_info for register mapping, register move functions,
jit_begin, _dofixup, _cache_flush
- this needed some prototype changes to pass jit_info around instead
just optimizer
- remove function prototypes for stuff now in jit_arch_info
* disable imcc/jit.c totally - it's outdated
* disable JIT/ppc temporarly (others are off anyway)
Modified: trunk/compilers/imcc/jit.c
==============================================================================
--- trunk/compilers/imcc/jit.c (original)
+++ trunk/compilers/imcc/jit.c Sun Feb 5 08:13:37 2006
@@ -25,6 +25,15 @@
#include "pbc.h"
#ifdef HAS_JIT
+void
+allocate_jit(Interp *interpreter, IMC_Unit * unit)
+{
+ UNUSED(interpreter);
+ UNUSED(unit);
+}
+
+#ifdef DO_JIT_IMCC
+/* turned off for now - needs to be redone */
#define JIT_IMCC
#include "parrot/jit.h"
@@ -332,9 +341,9 @@ allocate_jit(Interp *interpreter, IMC_Un
}
}
-#else
+#endif /* DO_JIT_IMCC */
-#endif
+#endif /* HAS_JIT */
/*
* Local variables:
* c-indentation-style: bsd
Modified: trunk/config/auto/jit.pm
==============================================================================
--- trunk/config/auto/jit.pm (original)
+++ trunk/config/auto/jit.pm Sun Feb 5 08:13:37 2006
@@ -78,17 +78,14 @@ sub runstep
if $verbose;
# XXX disable all but i386, ppc
- if (-e "$jitbase/$cpuarch/core.jit" && ($cpuarch eq 'i386' || $cpuarch eq
'ppc')) {
- $jitcapable = 1;
+ my %working_jit = (
+ i386 => 1,
+ # ppc => 1, # needs jit_arch_info - coming soon
+ # all others are seriously b0rked
+ );
- # XXX disable sun4 - doesn't even build
- if (
- $cpuarch =~ /sun4|sparc64/
- && (1
- || $conf->data->get('intvalsize') >
$conf->data->get('ptrsize'))
- ) {
- $jitcapable = 0;
- }
+ if (-e "$jitbase/$cpuarch/core.jit" && $working_jit{$cpuarch}) {
+ $jitcapable = 1;
}
if (-e "$jitbase/$cpuarch/$jitarchname.s") {
Modified: trunk/include/parrot/jit.h
==============================================================================
--- trunk/include/parrot/jit.h (original)
+++ trunk/include/parrot/jit.h Sun Feb 5 08:13:37 2006
@@ -162,6 +162,15 @@ typedef struct {
INTVAL *slot_ptr;
} Parrot_jit_constant_pool_t;
+typedef enum {
+ JIT_CODE_FILE,
+ JIT_CODE_SUB,
+ JIT_CODE_SUB_REGS_ONLY,
+
+ /* size */
+ JIT_CODE_TYPES
+} enum_jit_code_type;
+
/* Parrot_jit_info_t
* All the information needed to jit the bytecode will be here.
*
@@ -183,9 +192,8 @@ typedef struct {
Parrot_jit_arena_t arena;
Parrot_jit_optimizer_t *optimizer;
Parrot_jit_constant_pool_t *constant_pool;
- char *intval_map;
- char *floatval_map;
- struct jit_arch_info_t *arch_info;
+ enum_jit_code_type code_type;
+ const struct jit_arch_info_t *arch_info;
# if EXEC_CAPABLE
Parrot_exec_objfile_t *objfile;
# else
@@ -218,12 +226,6 @@ extern Parrot_jit_fn_info_t op_exec[];
void Parrot_jit_newfixup(Parrot_jit_info_t *jit_info);
-void Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- Interp *interpreter);
-
-void Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
- Interp *interpreter);
-
void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
Interp *interpreter);
@@ -256,15 +258,6 @@ void Parrot_jit_emit_mov_rm_n_offs(
void Parrot_jit_emit_mov_rm_offs(
Interp *, int dst_reg, int base_reg, size_t offs);
-typedef enum {
- JIT_CODE_FILE,
- JIT_CODE_SUB,
- JIT_CODE_SUB_REGS_ONLY,
-
- /* size */
- JIT_CODE_TYPES
-} enum_jit_code_type;
-
/*
* interface to architecture specific details
*/
@@ -302,13 +295,13 @@ typedef struct jit_arch_info_t {
/* flush caches */
jit_arch_f jit_flush_cache;
/* register mapping info */
- jit_arch_regs regs[JIT_CODE_TYPES];
+ const jit_arch_regs regs[JIT_CODE_TYPES];
} jit_arch_info;
/*
* return the jit_arch_info for the given JIT_CODE type
*/
-jit_arch_info * Parrot_jit_init(Interp *, enum_jit_code_type);
+const jit_arch_info * Parrot_jit_init(Interp *);
/*
* interface to create JIT code
Modified: trunk/src/jit.c
==============================================================================
--- trunk/src/jit.c (original)
+++ trunk/src/jit.c Sun Feb 5 08:13:37 2006
@@ -38,28 +38,10 @@ extern int jit_op_count(void);
* s. jit/$jitcpuarch/jit_emit.h for the meaning of these defs
*/
-#ifndef INT_REGISTERS_TO_MAP
-# define INT_REGISTERS_TO_MAP 0
- char *intval_map = 0;
-#endif
-
-#ifndef FLOAT_REGISTERS_TO_MAP
-# define FLOAT_REGISTERS_TO_MAP 0
- char *floatval_map = 0;
-#endif
-
#ifndef ALLOCATE_REGISTERS_PER_SECTION
# define ALLOCATE_REGISTERS_PER_SECTION 1
#endif
-#ifndef PRESERVED_INT_REGS
-# define PRESERVED_INT_REGS 0
-#endif
-
-#ifndef PRESERVED_FLOAT_REGS
-# define PRESERVED_FLOAT_REGS 0
-#endif
-
#if defined __GNUC__ || defined __IBMC__
void Parrot_jit_debug(Interp* interpreter);
#endif
@@ -568,7 +550,8 @@ make_branch_targets(Interp *interpreter,
=item C<static void
sort_registers(Interp *interpreter,
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)>
+ Parrot_jit_info_t *jit_info,
+ opcode_t * code_start)>
Sorts the Parrot registers prior to mapping them to actual hardware registers.
@@ -578,13 +561,20 @@ Sorts the Parrot registers prior to mapp
static void
sort_registers(Interp *interpreter,
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)
+ Parrot_jit_info_t *jit_info,
+ opcode_t * code_start)
{
+ Parrot_jit_optimizer_t *optimizer;
Parrot_jit_optimizer_section_ptr cur_section, next, prev;
- int i, any, k, typ;
+ int i, any, k, typ, code_type;
int max_count, max_i = 0;
- int to_map[] = { INT_REGISTERS_TO_MAP, 0, 0, FLOAT_REGISTERS_TO_MAP };
+ int to_map[] = { 0, 0, 0, 0 };
+
+ code_type = jit_info->code_type;
+ to_map[0] = jit_info->arch_info->regs[code_type].n_mapped_I;
+ to_map[3] = jit_info->arch_info->regs[code_type].n_mapped_F;
+ optimizer = jit_info->optimizer;
/* Start from the first section */
cur_section = optimizer->sections;
@@ -668,7 +658,7 @@ sort_registers(Interp *interpreter,
=item C<static void
assign_registers(Interp *interpreter,
- Parrot_jit_optimizer_t *optimizer,
+ Parrot_jit_info_t *jit_info,
Parrot_jit_optimizer_section_ptr cur_section,
opcode_t * code_start, int from_imcc)>
@@ -715,18 +705,22 @@ complicate the allocation code a bit.
static void
assign_registers(Interp *interpreter,
- Parrot_jit_optimizer_t *optimizer,
+ Parrot_jit_info_t *jit_info,
Parrot_jit_optimizer_section_ptr cur_section,
opcode_t * code_start, int from_imcc)
{
char *map;
+ Parrot_jit_optimizer_t *optimizer;
op_info_t *op_info;
- int i, op_arg, typ, n;
+ int i, op_arg, typ, n, code_type;
opcode_t * cur_op;
- char * maps[] = {0, 0, 0, 0};
- maps[0] = intval_map;
- maps[3] = floatval_map;
+ const char * maps[] = {0, 0, 0, 0};
+ code_type = jit_info->code_type;
+ maps[0] = jit_info->arch_info->regs[code_type].map_I;
+ maps[3] = jit_info->arch_info->regs[code_type].map_F;
+
+ optimizer = jit_info->optimizer;
map = optimizer->map_branch;
/* For each opcode in this section */
cur_op = cur_section->begin;
@@ -773,7 +767,7 @@ assign_registers(Interp *interpreter,
=item C<static void
map_registers(Interp *interpreter,
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)>
+ Parrot_jit_info_t *jit_info, opcode_t * code_start)>
Maps the most used Parrot registers to hardware registers.
@@ -783,17 +777,20 @@ Maps the most used Parrot registers to h
static void
map_registers(Interp *interpreter,
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)
+ Parrot_jit_info_t *jit_info,
+ opcode_t * code_start)
{
+ Parrot_jit_optimizer_t *optimizer;
Parrot_jit_optimizer_section_ptr cur_section;
+ optimizer = jit_info->optimizer;
/* Start from the first section */
cur_section = optimizer->sections;
/* While there is section */
while (cur_section) {
- assign_registers(interpreter, optimizer, cur_section, code_start, 0);
+ assign_registers(interpreter, jit_info, cur_section, code_start, 0);
/* Move to the next section */
cur_section = cur_section->next;
@@ -901,6 +898,7 @@ debug_sections(Interp *interpreter,
=item C<static Parrot_jit_optimizer_t *
optimize_jit(Interp *interpreter,
+ Parrot_jit_info_t *jit_info,
opcode_t *code_start, opcode_t *code_end)>
Called by C<parrot_build_asm()> to run the optimizer.
@@ -909,15 +907,17 @@ Called by C<parrot_build_asm()> to run t
*/
-static Parrot_jit_optimizer_t *
+static void
optimize_jit(Interp *interpreter,
- opcode_t *code_start, opcode_t *code_end)
+ Parrot_jit_info_t *jit_info,
+ opcode_t *code_start, opcode_t *code_end)
{
Parrot_jit_optimizer_t *optimizer;
/* Allocate space for the optimizer */
- optimizer = (Parrot_jit_optimizer_t *)
- mem_sys_allocate_zeroed(sizeof(Parrot_jit_optimizer_t));
+ jit_info->optimizer =
+ optimizer = (Parrot_jit_optimizer_t *)
+ mem_sys_allocate_zeroed(sizeof(Parrot_jit_optimizer_t));
/* Look, which opcodes might branch */
make_branch_list(interpreter, optimizer, code_start, code_end);
@@ -934,22 +934,21 @@ optimize_jit(Interp *interpreter,
#if JIT_DEBUG > 2
debug_sections(interpreter, optimizer, code_start);
#endif
- sort_registers(interpreter, optimizer, code_start);
- map_registers(interpreter, optimizer, code_start);
+ sort_registers(interpreter, jit_info, code_start);
+ map_registers(interpreter, jit_info, code_start);
#if JIT_DEBUG
debug_sections(interpreter, optimizer, code_start);
#endif
-
- return optimizer;
}
/*
=item C<static Parrot_jit_optimizer_t *
optimize_imcc_jit(Interp *interpreter,
- opcode_t *code_start, opcode_t *code_end,
- struct PackFile_Segment *jit_seg)>
+ Parrot_jit_info_t *jit_info,
+ opcode_t *code_start, opcode_t *code_end,
+ struct PackFile_Segment *jit_seg)>
Generate optimizer stuff from the C<_JIT> section in the packfile.
@@ -957,8 +956,9 @@ Generate optimizer stuff from the C<_JIT
*/
-static Parrot_jit_optimizer_t *
+static void
optimize_imcc_jit(Interp *interpreter,
+ Parrot_jit_info_t *jit_info,
opcode_t *code_start, opcode_t *code_end,
struct PackFile_Segment *jit_seg)
{
@@ -972,8 +972,9 @@ optimize_imcc_jit(Interp *interpreter,
opcode_t *cur_op;
/* Allocate space for the optimizer */
- optimizer = (Parrot_jit_optimizer_t *)
- mem_sys_allocate_zeroed(sizeof(Parrot_jit_optimizer_t));
+ jit_info->optimizer =
+ optimizer = (Parrot_jit_optimizer_t *)
+ mem_sys_allocate_zeroed(sizeof(Parrot_jit_optimizer_t));
/*
* TODO: pass the whole map_branch in the PBC
* this would save two runs through all the opcode
@@ -1020,13 +1021,12 @@ optimize_imcc_jit(Interp *interpreter,
ADD_OP_VAR_PART(interpreter, interpreter->code, cur_op, n);
cur_op += n;
}
- assign_registers(interpreter, optimizer, section, code_start, 1);
+ assign_registers(interpreter, jit_info, section, code_start, 1);
}
insert_fixup_targets(interpreter, branch, code_end - code_start);
#if JIT_DEBUG
debug_sections(interpreter, optimizer, code_start);
#endif
- return optimizer;
}
/*
@@ -1078,16 +1078,22 @@ Parrot_jit_load_registers(Parrot_jit_inf
Parrot_jit_optimizer_section_t *sect = jit_info->optimizer->cur_section;
Parrot_jit_register_usage_t *ru = sect->ru;
int i, typ;
- void (*mov_f[4])(Interp *, int, int, size_t)
- = { Parrot_jit_emit_mov_rm_offs, 0, 0, Parrot_jit_emit_mov_rm_n_offs};
size_t offs;
int base_reg = 0; /* -O3 warning */
- int lasts[] = { PRESERVED_INT_REGS, 0,0, PRESERVED_FLOAT_REGS };
- char * maps[] = {0, 0, 0, 0};
+ int lasts[] = { 0, 0, 0, 0 };
+ const char * maps[] = {0, 0, 0, 0};
int first = 1;
-
- maps[0] = jit_info->intval_map;
- maps[3] = jit_info->floatval_map;
+ int code_type;
+ const jit_arch_info *arch_info;
+ const jit_arch_regs *reg_info;
+
+ arch_info = jit_info->arch_info;
+ code_type = jit_info->code_type;
+ reg_info = arch_info->regs + code_type;
+ maps[0] = reg_info->map_I;
+ maps[3] = reg_info->map_F;
+ lasts[0] = reg_info->n_preserved_I;
+ lasts[3] = reg_info->n_preserved_F;
for (typ = 0; typ < 4; typ++) {
if (maps[typ]) {
@@ -1095,7 +1101,7 @@ Parrot_jit_load_registers(Parrot_jit_inf
int us = ru[typ].reg_usage[i];
int is_used = i >= lasts[typ] && ru[typ].reg_dir[us];
if ((is_used && volatiles) ||
- (!volatiles &&
+ (!volatiles &&
((ru[typ].reg_dir[us] & PARROT_ARGDIR_IN)))) {
if (first) {
base_reg = Parrot_jit_emit_get_base_reg_no(
@@ -1103,7 +1109,13 @@ Parrot_jit_load_registers(Parrot_jit_inf
first = 0;
}
offs = reg_offs(interpreter, typ, us);
- (mov_f[typ])(interpreter, maps[typ][i], base_reg, offs);
+ if (typ == 3)
+ (arch_info->mov_RM_n)(jit_info,
+ maps[typ][i], base_reg, offs);
+ else
+ (arch_info->mov_RM_i)(jit_info,
+ maps[typ][i], base_reg, offs);
+
}
}
}
@@ -1137,16 +1149,23 @@ Parrot_jit_save_registers(Parrot_jit_inf
Parrot_jit_optimizer_section_t *sect = jit_info->optimizer->cur_section;
Parrot_jit_register_usage_t *ru = sect->ru;
int i, typ;
- void (*mov_f[4])(Interp * ,int, size_t, int)
- = { Parrot_jit_emit_mov_mr_offs, 0, 0, Parrot_jit_emit_mov_mr_n_offs};
size_t offs;
int base_reg = 0; /* -O3 warning */
- int lasts[] = { PRESERVED_INT_REGS, 0,0, PRESERVED_FLOAT_REGS };
- char * maps[] = {0, 0, 0, 0};
+ int lasts[] = { 0, 0, 0, 0 };
+ const char * maps[] = {0, 0, 0, 0};
int first = 1;
+ int code_type;
+ const jit_arch_info *arch_info;
+ const jit_arch_regs *reg_info;
+
+ arch_info = jit_info->arch_info;
+ code_type = jit_info->code_type;
+ reg_info = arch_info->regs + code_type;
+ maps[0] = reg_info->map_I;
+ maps[3] = reg_info->map_F;
+ lasts[0] = reg_info->n_preserved_I;
+ lasts[3] = reg_info->n_preserved_F;
- maps[0] = jit_info->intval_map;
- maps[3] = jit_info->floatval_map;
for (typ = 0; typ < 4; typ++) {
if (maps[typ])
for (i = 0; i < ru[typ].registers_used; ++i) {
@@ -1162,7 +1181,13 @@ Parrot_jit_save_registers(Parrot_jit_inf
}
offs = reg_offs(interpreter, typ, us);
- (mov_f[typ])(interpreter, base_reg, offs, maps[typ][i]);
+ if (typ == 3)
+ (arch_info->mov_MR_n)(jit_info,
+ base_reg, offs, maps[typ][i]);
+ else
+ (arch_info->mov_MR_i)(jit_info,
+ base_reg, offs, maps[typ][i]);
+
}
}
}
@@ -1305,10 +1330,14 @@ parrot_build_asm(Interp *interpreter,
#endif
op_info_t *op_info;
int n;
+ const jit_arch_info *arch_info;
jit_info = interpreter->code->jit_info =
mem_sys_allocate(sizeof(Parrot_jit_info_t));
+ jit_info->code_type = jit_type;
+ arch_info = jit_info->arch_info = Parrot_jit_init(interpreter);
+
jit_info->objfile = NULL;
#if EXEC_CAPABLE
if (objfile) {
@@ -1340,15 +1369,9 @@ parrot_build_asm(Interp *interpreter,
jit_seg = NULL;
#endif
if (jit_seg)
- jit_info->optimizer =
- optimize_imcc_jit(interpreter, code_start, code_end, jit_seg);
+ optimize_imcc_jit(interpreter, jit_info, code_start, code_end,
jit_seg);
else
- jit_info->optimizer =
- optimize_jit(interpreter, code_start, code_end);
-
- /* Attach the register map to the jit_info structure */
- jit_info->intval_map = intval_map;
- jit_info->floatval_map = floatval_map;
+ optimize_jit(interpreter, jit_info, code_start, code_end);
/* Byte code size in opcode_t's */
jit_info->arena.map_size = (code_end - code_start) + 1;
@@ -1385,7 +1408,7 @@ parrot_build_asm(Interp *interpreter,
* function. So we have to generate an appropriate function
* prologue, that makes all this look like a normal function ;)
*/
- Parrot_jit_begin(jit_info, interpreter);
+ (arch_info->regs[jit_type].jit_begin)(jit_info, interpreter);
/*
* the function epilog can basically be anywhere, that's done
* by the Parrot_end opcode somewhere in core.jit
@@ -1550,7 +1573,7 @@ parrot_build_asm(Interp *interpreter,
*/
CONTEXT(interpreter->ctx)->n_regs_used = n_regs_used;
/* Do fixups before converting offsets */
- Parrot_jit_dofixup(jit_info, interpreter);
+ (arch_info->jit_dofixup)(jit_info, interpreter);
/* Convert offsets to pointers */
if (!objfile)
@@ -1580,6 +1603,9 @@ parrot_build_asm(Interp *interpreter,
* allocation functions as e.g. mem_close_executable()
*/
+ if (arch_info->jit_flush_cache)
+ (arch_info->jit_flush_cache)(jit_info, interpreter);
+
#ifdef PARROT_ARM
arm_sync_d_i_cache(jit_info->arena.start, jit_info->native_ptr);
#endif
Modified: trunk/src/jit/i386/jit_emit.h
==============================================================================
--- trunk/src/jit/i386/jit_emit.h (original)
+++ trunk/src/jit/i386/jit_emit.h Sun Feb 5 08:13:37 2006
@@ -75,7 +75,6 @@ extern UINTVAL ld(UINTVAL);
# define INT_REGISTERS_TO_MAP 4
-#if JIT_EMIT
/* Scratch register. */
@@ -2765,11 +2764,10 @@ Parrot_jit_vtable_newp_ic_op(Parrot_jit_
}
# endif /* JIT_CGP */
-#endif /* JIT_EMIT */
-#if JIT_EMIT > 1
+#if JIT_EMIT == 0
-void
+static void
Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
Interp * interpreter)
{
@@ -2813,95 +2811,6 @@ Parrot_jit_dofixup(Parrot_jit_info_t *ji
static int control_word = 0x27f;
-# ifndef JIT_CGP
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- Interp * interpreter)
-{
- /* the generated code gets called as:
- * (jit_code)(interpreter, pc)
- * jumping to pc is the same code as used in Parrot_jit_cpcf_op()
- */
-
- /* Maintain the stack frame pointer for the sake of gdb */
- jit_emit_stack_frame_enter(jit_info->native_ptr);
- emitm_fldcw(jit_info->native_ptr, &control_word);
- /* stack:
- * 12 pc
- * 8 interpreter
- * 4 retaddr
- * 0 ebp <----- ebp
- * -4 ebx .. preserved regs
- * -8 esi ..
- * -12 edi ..
- * -16 interpreter
- */
-
- /* Save all callee-saved registers (cdecl)
- */
- emitm_pushl_r(jit_info->native_ptr, emit_EBX);
- emitm_pushl_r(jit_info->native_ptr, emit_ESI);
- emitm_pushl_r(jit_info->native_ptr, emit_EDI);
-
- /* Cheat on op function calls by writing the interpreter arg on the stack
- * just once. If an op function ever modifies the interpreter argument on
- * the stack this will stop working !!! */
-
- /* get the interpreter from stack: mov 8(%ebp), %eax */
- emitm_movl_m_r(jit_info->native_ptr, emit_EAX, emit_EBP, emit_None, 1, 8);
- emitm_pushl_r(jit_info->native_ptr, emit_EAX);
-
- /* get the pc from stack: mov 12(%ebp), %eax */
- emitm_movl_m_r(jit_info->native_ptr, emit_EAX, emit_EBP, emit_None, 1, 12);
-
- /* jump to restart pos or first op */
- Parrot_emit_jump_to_eax(jit_info, interpreter);
-}
-# endif
-
-
-
-void
-Parrot_jit_emit_mov_mr_n_offs(Interp *interpreter,
- int base_reg, size_t offs, int src_reg)
-{
- emitm_fld(((Parrot_jit_info_t *)(interpreter->code->jit_info))->native_ptr,
- src_reg);
- jit_emit_fstore_mb_n(((Parrot_jit_info_t *)(interpreter->code->jit_info))->
- native_ptr, base_reg, offs);
-}
-
-void
-Parrot_jit_emit_mov_mr_offs(Interp *interpreter,
- int base_reg, size_t offs, int src_reg)
-{
- emitm_movl_r_m(((Parrot_jit_info_t
*)(interpreter->code->jit_info))->native_ptr,
- src_reg, base_reg, emit_None, 1, offs);
-}
-
-void
-Parrot_jit_emit_mov_rm_n_offs(Interp *interpreter,
- int dst_reg, int base_reg, size_t offs)
-{
- jit_emit_fload_mb_n(((Parrot_jit_info_t *)(interpreter->code->jit_info))->
- native_ptr, base_reg, offs);
- emitm_fstp(((Parrot_jit_info_t
*)(interpreter->code->jit_info))->native_ptr,
- (dst_reg+1));
-}
-
-void
-Parrot_jit_emit_mov_rm_offs(Interp *interpreter,
- int dst_reg, int base_reg, size_t offs)
-{
- emitm_movl_m_r(((Parrot_jit_info_t
*)(interpreter->code->jit_info))->native_ptr,
- dst_reg, base_reg, emit_None, 1, offs);
-}
-
-static void
-Parrot_jit_emit_finit(Parrot_jit_info_t *jit_info)
-{
- jit_emit_finit(jit_info->native_ptr);
-}
# ifdef JIT_CGP
# include <parrot/oplib/core_ops_cgp.h>
@@ -2936,7 +2845,7 @@ Parrot_jit_emit_finit(Parrot_jit_info_t
*
*/
-void
+static void
Parrot_jit_begin(Parrot_jit_info_t *jit_info,
Interp * interpreter)
{
@@ -2979,6 +2888,106 @@ Parrot_jit_begin(Parrot_jit_info_t *jit_
/* code_start: */
}
+#else /* JIT_CGP */
+static void
+Parrot_jit_begin(Parrot_jit_info_t *jit_info,
+ Interp * interpreter)
+{
+ /* the generated code gets called as:
+ * (jit_code)(interpreter, pc)
+ * jumping to pc is the same code as used in Parrot_jit_cpcf_op()
+ */
+
+ /* Maintain the stack frame pointer for the sake of gdb */
+ jit_emit_stack_frame_enter(jit_info->native_ptr);
+ emitm_fldcw(jit_info->native_ptr, &control_word);
+ /* stack:
+ * 12 pc
+ * 8 interpreter
+ * 4 retaddr
+ * 0 ebp <----- ebp
+ * -4 ebx .. preserved regs
+ * -8 esi ..
+ * -12 edi ..
+ * -16 interpreter
+ */
+
+ /* Save all callee-saved registers (cdecl)
+ */
+ emitm_pushl_r(jit_info->native_ptr, emit_EBX);
+ emitm_pushl_r(jit_info->native_ptr, emit_ESI);
+ emitm_pushl_r(jit_info->native_ptr, emit_EDI);
+
+ /* Cheat on op function calls by writing the interpreter arg on the stack
+ * just once. If an op function ever modifies the interpreter argument on
+ * the stack this will stop working !!! */
+
+ /* get the interpreter from stack: mov 8(%ebp), %eax */
+ emitm_movl_m_r(jit_info->native_ptr, emit_EAX, emit_EBP, emit_None, 1, 8);
+ emitm_pushl_r(jit_info->native_ptr, emit_EAX);
+
+ /* get the pc from stack: mov 12(%ebp), %eax */
+ emitm_movl_m_r(jit_info->native_ptr, emit_EAX, emit_EBP, emit_None, 1, 12);
+
+ /* jump to restart pos or first op */
+ Parrot_emit_jump_to_eax(jit_info, interpreter);
+}
+
+#endif /* JIT_CGP */
+
+static void
+Parrot_jit_begin_sub(Parrot_jit_info_t *jit_info,
+ Interp * interpreter)
+{
+}
+
+
+static void
+jit_mov_mr_n_offs(Parrot_jit_info_t *jit_info,
+ int base_reg, INTVAL offs, int src_reg)
+{
+ emitm_fld(jit_info->native_ptr, src_reg);
+ jit_emit_fstore_mb_n(jit_info->native_ptr, base_reg, offs);
+}
+
+static void
+jit_mov_mr_offs(Parrot_jit_info_t *jit_info,
+ int base_reg, INTVAL offs, int src_reg)
+{
+ emitm_movl_r_m(jit_info->native_ptr,
+ src_reg, base_reg, emit_None, 1, offs);
+}
+
+static void
+jit_mov_rm_n_offs(Parrot_jit_info_t *jit_info,
+ int dst_reg, int base_reg, INTVAL offs)
+{
+ jit_emit_fload_mb_n(jit_info->native_ptr, base_reg, offs);
+ emitm_fstp(jit_info->native_ptr, (dst_reg+1));
+}
+
+static void
+jit_mov_rm_offs(Parrot_jit_info_t *jit_info,
+ int dst_reg, int base_reg, INTVAL offs)
+{
+ emitm_movl_m_r(jit_info->native_ptr,
+ dst_reg, base_reg, emit_None, 1, offs);
+}
+
+#endif
+
+#if JIT_EMIT == 2
+/* generate code just once */
+
+static void
+Parrot_jit_emit_finit(Parrot_jit_info_t *jit_info)
+{
+ jit_emit_finit(jit_info->native_ptr);
+}
+
+
+
+# ifdef JIT_CGP
/*
* XXX needs some fixing
* s. t/sub/pmc_{8,9}.t: the 2 print in tail call without that 'end'
@@ -3076,8 +3085,6 @@ Parrot_jit_normal_op(Parrot_jit_info_t *
# endif /* JIT_CGP */
-static void Parrot_end_jit(Parrot_jit_info_t *, Interp * );
-
void
Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
Interp * interpreter)
@@ -3087,6 +3094,10 @@ Parrot_jit_cpcf_op(Parrot_jit_info_t *ji
}
+/* autogened inside core.ops */
+static void
+Parrot_end_jit(Parrot_jit_info_t *jit_info, Interp * interpreter);
+
# undef Parrot_jit_restart_op
void
Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
@@ -3111,6 +3122,7 @@ Parrot_jit_restart_op(Parrot_jit_info_t
jit_info->native_ptr = sav_ptr;
Parrot_emit_jump_to_eax(jit_info, interpreter);
}
+
/*
* params are put rigth to left on the stack
* parrot registers are counted left to right
@@ -3455,10 +3467,11 @@ preg:
return (jit_f)D2FPTR(jit_info.arena.start);
}
-#endif /* JIT_EMIT */
+#endif
+
#if JIT_EMIT == 0
+
# define REQUIRES_CONSTANT_POOL 0
-/* # define INT_REGISTERS_TO_MAP 4 definition at top */
/*
* examples/pir/mandel.pir and t/op/jitn_14 show rounding problems
* due to keeping intermediate results in FP registers
@@ -3471,7 +3484,6 @@ preg:
*/
# define FLOAT_REGISTERS_TO_MAP 4
-# ifndef JIT_IMCC
/*
* register usage
* %edi, %esi ... mapped, preserved
@@ -3479,33 +3491,58 @@ preg:
* %ebx ... base pointer for register access, preserved
* %eax ... scratch, return value register
*/
-char intval_map[] =
- /* Note: don't change order of these */
- { emit_EDI, emit_ESI, emit_EDX, emit_ECX };
-/* ST(0) is used as a scratch register,
- * using more then 4 registers breaks C<time N0>
- */
-char floatval_map[] = { 1,2,3,4 };
-# endif
+static const char intval_map[] =
+ { emit_EDI, emit_ESI, emit_EDX, emit_ECX };
+static const char floatval_map[] =
+ { 1,2,3,4 }; /* ST(1) .. (ST(4) */
-/* of these registers that much (from 0 < n) are callee saved, i.e. are
- * not changed around external calls
- */
+static const char intval_map_sub[] =
+ { emit_EDX, emit_ECX, emit_EBX, emit_EDI, emit_ESI };
-# define PRESERVED_INT_REGS 2
+static const jit_arch_info arch_info = {
+ jit_mov_rm_offs,
+ jit_mov_rm_n_offs,
+ jit_mov_mr_offs,
+ jit_mov_mr_n_offs,
+ Parrot_jit_dofixup,
+ (jit_arch_f)0, /* no cache flush needed */
+ {
+ {
+ Parrot_jit_begin, /* emit code prologue */
+ 4, /* 4 mapped ints */
+ 2, /* first 2 are preserved */
+ intval_map,
+ 4, /* 4 mapped float regs */
+ 0, /* ABI sez it's not preserved */
+ floatval_map
+ },
+ {
+ Parrot_jit_begin_sub, /* emit code prologue */
+ 4, /* 4 mapped ints */
+ 2, /* first 2 are *non*preserved */
+ intval_map_sub,
+ 4, /* 4 mapped float regs */
+ 0, /* ABI sez it's not preserved */
+ floatval_map
+ },{
+ Parrot_jit_begin_sub, /* emit code prologue */
+ 4, /* 4 mapped ints */
+ 2, /* first 2 are *non*preserved */
+ intval_map_sub,
+ 4, /* 4 mapped float regs */
+ 0, /* ABI sez it's not preserved */
+ floatval_map
+ }
+ }
+};
-/* XXX
- * this 4 floatvals are currently assumed to be callee saved,
- * what is strictly not true conforming to the ABI
- * but currently, we don't have external functions, which
- * globber these regs
- * to be save the following line should be enabled:
- *
- *
- */
-# define PRESERVED_FLOAT_REGS 0
+const jit_arch_info *
+Parrot_jit_init(Interp *interpreter)
+{
+ return &arch_info;
+}
/*
* if jit_emit_noop is defined, it does align a jump target
@@ -3543,8 +3580,9 @@ char floatval_map[] = { 1,2,3,4 };
# define INTERP_BP_OFFS -16
# endif
+#endif /* JIT_EMIT */
-#endif /* JIT_EMIT */
+# undef INT_REGISTERS_TO_MAP
#endif /* PARROT_I386_JIT_EMIT_H_GUARD */
/*