cvsuser 04/10/24 05:33:06
Modified: build_tools jit2h.pl
jit/i386 core.jit
src jit.c
Log:
JIT support for JITted functions that call external functions
Revision Changes Path
1.74 +4 -4 parrot/build_tools/jit2h.pl
Index: jit2h.pl
===================================================================
RCS file: /cvs/public/parrot/build_tools/jit2h.pl,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -r1.73 -r1.74
--- jit2h.pl 23 Oct 2004 13:21:35 -0000 1.73
+++ jit2h.pl 24 Oct 2004 12:33:04 -0000 1.74
@@ -1,6 +1,6 @@
#! perl -w
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: jit2h.pl,v 1.73 2004/10/23 13:21:35 leo Exp $
+# $Id: jit2h.pl,v 1.74 2004/10/24 12:33:04 leo Exp $
=head1 NAME
@@ -165,14 +165,14 @@
$asm =~ s/CUR_OPCODE/jit_info->cur_op/g;
$asm =~ s/cur_opcode/jit_info->cur_op/g;
$asm =~ s/MAP\[(\d)\]/MAP($1)/g;
- # XXX set extern if the code calls a function
- $extern = 1 if $asm =~ /call_func/;
+ # set extern if the code calls a function
+ $extern = -1 if $asm =~ /CALL_FUNCTION/;
unless ($jit_cpu) {
# no address of
$asm =~ s/&([INSP])REG/$1REG/g;
$asm =~ s/&CONST/CONST/g;
# Use the macro
- $asm =~
s/call_func\(\s*jit_info\s*,\s*\(void\*\)\s*(.*)\)/CALL("$1")/g;
+ $asm =~
s/CALL_FUNCTION\(\s*jit_info\s*,\s*\(void\*\)\s*(.*)\)/CALL("$1")/g;
# The ->u.(string|float) is unnecessary.
$asm =~ s/\)->u\.(\w+)/)/g;
$asm =~
s/CONST\((\d)\)\s*([><=!]=?)\s*CONST\((\d)\)/RCONST($1)->u.number $2
RCONST($3)->u.number/ if ($asm =~ /CONST.*CONST/);
1.64 +7 -6 parrot/jit/i386/core.jit
Index: core.jit
===================================================================
RCS file: /cvs/public/parrot/jit/i386/core.jit,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -r1.63 -r1.64
--- core.jit 23 Oct 2004 13:21:37 -0000 1.63
+++ core.jit 24 Oct 2004 12:33:05 -0000 1.64
@@ -1,12 +1,13 @@
;
; i386/core.jit
;
-; $Id: core.jit,v 1.63 2004/10/23 13:21:37 leo Exp $
+; $Id: core.jit,v 1.64 2004/10/24 12:33:05 leo Exp $
;
# TODO complete this
#define P_ARITH ((PREV_OP == dec_i) || (PREV_OP == inc_i) || (PREV_OP == sub_i_i_i))
+#define CALL_FUNCTION(j, f) call_func(j, f)
Parrot_end {
jit_emit_end(NATIVECODE);
@@ -1267,7 +1268,7 @@
Parrot_jit_emit_get_INTERP(jit_info->native_ptr, emit_ECX);
emitm_pushl_i(NATIVECODE, CONST(2)->u.string);
emitm_pushl_r(NATIVECODE, emit_ECX);
- call_func(jit_info, (void*) string_copy);
+ CALL_FUNCTION(jit_info, (void*) string_copy);
emitm_addb_i_r(NATIVECODE, 8, emit_ESP);
jit_emit_mov_MR_i(NATIVECODE, ROFFS_STR(1), emit_EAX );
}
@@ -1282,7 +1283,7 @@
push_<typ1>(1);
Parrot_jit_emit_get_INTERP(jit_info->native_ptr, emit_ECX);
emitm_pushl_r(NATIVECODE, emit_ECX);
- call_func(jit_info, (void*)string_compare);
+ CALL_FUNCTION(jit_info, (void*)string_compare);
emitm_addb_i_r(NATIVECODE, 12, emit_ESP);
jit_emit_test_r_i(NATIVECODE, emit_EAX);
jit_emit_jcc(jit_info, <op>, *INT_CONST[3]);
@@ -1299,7 +1300,7 @@
push_<typ1>(1);
Parrot_jit_emit_get_INTERP(jit_info->native_ptr, emit_ECX);
emitm_pushl_r(NATIVECODE, emit_ECX);
- call_func(jit_info, (void*)string_equal);
+ CALL_FUNCTION(jit_info, (void*)string_equal);
emitm_addb_i_r(NATIVECODE, 12, emit_ESP);
jit_emit_test_r_i(NATIVECODE, emit_EAX);
jit_emit_jcc(jit_info, <op>, *INT_CONST[3]);
@@ -1414,7 +1415,7 @@
push_<typ>(1);
Parrot_jit_emit_get_INTERP(jit_info->native_ptr, emit_ECX);
emitm_pushl_r(NATIVECODE, emit_ECX);
- call_func(jit_info, (void*)string_bool);
+ CALL_FUNCTION(jit_info, (void*)string_bool);
emitm_addb_i_r(NATIVECODE, 8, emit_ESP);
jit_emit_test_r_i(NATIVECODE, emit_EAX);
jit_emit_jcc(jit_info, <op>, *INT_CONST[2]);
@@ -1450,7 +1451,7 @@
push_<typ>(2);
Parrot_jit_emit_get_INTERP(jit_info->native_ptr, emit_ECX);
emitm_pushl_r(NATIVECODE, emit_ECX);
- call_func(jit_info, (void*)string_ord);
+ CALL_FUNCTION(jit_info, (void*)string_ord);
emitm_addb_i_r(NATIVECODE, 12, emit_ESP);
if (MAP[1]) {
jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
1.93 +63 -119 parrot/src/jit.c
Index: jit.c
===================================================================
RCS file: /cvs/public/parrot/src/jit.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -r1.92 -r1.93
--- jit.c 22 Oct 2004 09:57:42 -0000 1.92
+++ jit.c 24 Oct 2004 12:33:06 -0000 1.93
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: jit.c,v 1.92 2004/10/22 09:57:42 leo Exp $
+$Id: jit.c,v 1.93 2004/10/24 12:33:06 leo Exp $
=head1 NAME
@@ -48,25 +48,12 @@
# define ALLOCATE_REGISTERS_PER_SECTION 1
#endif
-#if ALLOCATE_REGISTERS_PER_SECTION
-# undef PRESERVED_INT_REGS
-# undef PRESERVED_FLOAT_REGS
-#endif
-
#ifndef PRESERVED_INT_REGS
-# if ALLOCATE_REGISTERS_PER_SECTION
-# define PRESERVED_INT_REGS INT_REGISTERS_TO_MAP
-# else
-# define PRESERVED_INT_REGS 0
-# endif
+# define PRESERVED_INT_REGS 0
#endif
#ifndef PRESERVED_FLOAT_REGS
-# if ALLOCATE_REGISTERS_PER_SECTION
-# define PRESERVED_FLOAT_REGS FLOAT_REGISTERS_TO_MAP
-# else
-# define PRESERVED_FLOAT_REGS 0
-# endif
+# define PRESERVED_FLOAT_REGS 0
#endif
#if defined __GNUC__ || defined __IBMC__
@@ -363,7 +350,8 @@
*/
#ifndef EXTCALL
-# define EXTCALL(op) op_jit[*(op)].extcall
+# define EXTCALL(op) (op_jit[*(op)].extcall >= 1)
+# define CALLS_C_CODE(op) (op_func[op].extcall == -1)
#endif
static void
@@ -966,6 +954,13 @@
*/
#if defined(Parrot_jit_emit_get_base_reg_no)
+# define JIT_USE_OFFS 1
+#else
+# define JIT_USE_OFFS 0
+#endif
+
+#if JIT_USE_OFFS
+
static size_t
reg_offs(Interp * interpreter, int typ, int i)
{
@@ -996,7 +991,7 @@
=item C<static void
Parrot_jit_load_registers(Parrot_jit_info_t *jit_info,
- Interp * interpreter)>
+ Interp * interpreter, int volatiles)>
Load registers for the current section from parrot to processor registers.
@@ -1005,22 +1000,27 @@
*/
-#if defined(Parrot_jit_emit_get_base_reg_no)
static void
Parrot_jit_load_registers(Parrot_jit_info_t *jit_info,
- Interp * interpreter)
+ Interp * interpreter, int volatiles)
{
Parrot_jit_optimizer_section_t *sect = jit_info->optimizer->cur_section;
Parrot_jit_register_usage_t *ru = sect->ru;
int i, typ;
+#if JIT_USE_OFFS
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;
+#else
+ void (*mov_f[4])(Interp *, int, char *)
+ = { Parrot_jit_emit_mov_rm, 0, 0, Parrot_jit_emit_mov_rm_n};
+ char *m;
+#endif
int lasts[] = { PRESERVED_INT_REGS, 0,0, PRESERVED_FLOAT_REGS };
char * maps[] = {0, 0, 0, 0};
int first = 1;
int base_reg = 0; /* -O3 warning */
- size_t offs;
maps[0] = jit_info->intval_map;
maps[3] = jit_info->floatval_map;
@@ -1030,15 +1030,22 @@
if (maps[typ]) {
for (i = ru[typ].registers_used-1; i >= 0; --i) {
int us = ru[typ].reg_usage[i];
- if ((i >= lasts[typ] && ru[typ].reg_dir[us]) ||
- (ru[typ].reg_dir[us] & PARROT_ARGDIR_IN)) {
+ int is_used = i >= lasts[typ] && ru[typ].reg_dir[us];
+ if ((is_used && volatiles) ||
+ (!volatiles &&
+ ((ru[typ].reg_dir[us] & PARROT_ARGDIR_IN)))) {
if (first) {
base_reg = Parrot_jit_emit_get_base_reg_no(
jit_info->native_ptr);
first = 0;
}
+#if JIT_USE_OFFS
offs = reg_offs(interpreter, typ, us);
(mov_f[typ])(interpreter, maps[typ][i], base_reg, offs);
+#else
+ m = reg_addr(interpreter, typ, us);
+ (mov_f[typ])(interpreter, maps[typ][i], m);
+#endif
}
}
}
@@ -1055,7 +1062,7 @@
=item C<static void
Parrot_jit_save_registers(Parrot_jit_info_t *jit_info,
- Interp * interpreter)>
+ Interp * interpreter, int volatiles)>
Save registers for the current section.
@@ -1065,18 +1072,24 @@
static void
Parrot_jit_save_registers(Parrot_jit_info_t *jit_info,
- Interp * interpreter)
+ Interp * interpreter, int volatiles)
{
Parrot_jit_optimizer_section_t *sect = jit_info->optimizer->cur_section;
Parrot_jit_register_usage_t *ru = sect->ru;
int i, typ;
+#if JIT_USE_OFFS
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;
+#else
+ void (*mov_f[4])(Interp * , char *, int)
+ = { Parrot_jit_emit_mov_mr, 0, 0, Parrot_jit_emit_mov_mr_n};
+ char *m;
+#endif
int lasts[] = { PRESERVED_INT_REGS, 0,0, PRESERVED_FLOAT_REGS };
char * maps[] = {0, 0, 0, 0};
int first = 1;
int base_reg = 0; /* -O3 warning */
- size_t offs;
maps[0] = jit_info->intval_map;
maps[3] = jit_info->floatval_map;
@@ -1084,109 +1097,26 @@
if (maps[typ])
for (i = 0; i < ru[typ].registers_used; ++i) {
int us = ru[typ].reg_usage[i];
- if ((i >= lasts[typ] && ru[typ].reg_dir[us]) ||
- ru[typ].reg_dir[us] & PARROT_ARGDIR_OUT) {
+ int is_used = i >= lasts[typ] && ru[typ].reg_dir[us];
+ if ((is_used && volatiles) ||
+ (!volatiles &&
+ (ru[typ].reg_dir[us] & PARROT_ARGDIR_OUT))) {
if (first) {
base_reg = Parrot_jit_emit_get_base_reg_no(
jit_info->native_ptr);
first = 0;
}
+#if JIT_USE_OFFS
offs = reg_offs(interpreter, typ, us);
(mov_f[typ])(interpreter, base_reg, offs, maps[typ][i]);
- }
- }
- }
-}
-
#else
-
-static void
-Parrot_jit_load_registers(Parrot_jit_info_t *jit_info,
- Interp * interpreter)
-{
- 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, char *)
- = { Parrot_jit_emit_mov_rm, 0, 0, Parrot_jit_emit_mov_rm_n};
- int lasts[] = { PRESERVED_INT_REGS, 0,0, PRESERVED_FLOAT_REGS };
- char * maps[] = {0, 0, 0, 0};
- maps[0] = jit_info->intval_map;
- maps[3] = jit_info->floatval_map;
-
-#if EXEC_CAPABLE
- if (jit_info->objfile) {
- mov_f[0] = Parrot_exec_emit_mov_rm;
- mov_f[3] = Parrot_exec_emit_mov_rm_n;
- }
-#endif
-
- for (typ = 0; typ < 4; typ++) {
- if (maps[typ]) {
- for (i = ru[typ].registers_used-1; i >= 0; --i) {
- int us = ru[typ].reg_usage[i];
- if ((i >= lasts[typ] && ru[typ].reg_dir[us]) ||
- (ru[typ].reg_dir[us] & PARROT_ARGDIR_IN)) {
- char *m = reg_addr(interpreter, typ, us);
- (mov_f[typ])(interpreter, maps[typ][i], m);
- }
- }
- }
- }
-
- /* The total size of the loads. This is used for branches to
- * the same section - these skip the load asm bytes */
- sect->load_size = jit_info->native_ptr -
- (jit_info->arena.start +
- jit_info->arena.op_map[jit_info->op_i].offset);
-}
-
-/*
-
-=item C<static void
-Parrot_jit_save_registers(Parrot_jit_info_t *jit_info,
- Interp * interpreter)>
-
-Save registers for the current section.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_save_registers(Parrot_jit_info_t *jit_info,
- Interp * interpreter)
-{
- 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 * , char *, int)
- = { Parrot_jit_emit_mov_mr, 0, 0, Parrot_jit_emit_mov_mr_n};
- int lasts[] = { PRESERVED_INT_REGS, 0,0, PRESERVED_FLOAT_REGS };
- char * maps[] = {0, 0, 0, 0};
- maps[0] = jit_info->intval_map;
- maps[3] = jit_info->floatval_map;
-
-#if EXEC_CAPABLE
- if (jit_info->objfile) {
- mov_f[0] = Parrot_exec_emit_mov_mr;
- mov_f[3] = Parrot_exec_emit_mov_mr_n;
- }
-#endif
-
- for (typ = 0; typ < 4; typ++) {
- if (maps[typ])
- for (i = 0; i < ru[typ].registers_used; ++i) {
- int us = ru[typ].reg_usage[i];
- if ((i >= lasts[typ] && ru[typ].reg_dir[us]) ||
- ru[typ].reg_dir[us] & PARROT_ARGDIR_OUT) {
- char *m = reg_addr(interpreter, typ, us);
+ m = reg_addr(interpreter, typ, us);
(mov_f[typ])(interpreter, m, maps[typ][i]);
+#endif
}
}
}
}
-#endif
/*
@@ -1365,7 +1295,7 @@
/* Load mapped registers for this section, if JIT */
if (!jit_seg && cur_section->isjit) {
- Parrot_jit_load_registers(jit_info, interpreter);
+ Parrot_jit_load_registers(jit_info, interpreter, 0);
}
/* The first opcode of each section doesn't have a previous one since
@@ -1407,7 +1337,14 @@
!cur_opcode_byte) &&
cur_section->isjit &&
!jit_seg) {
- Parrot_jit_save_registers(jit_info, interpreter);
+ Parrot_jit_save_registers(jit_info, interpreter, 0);
+ }
+ else if (CALLS_C_CODE(cur_opcode_byte)) {
+ /*
+ * a JITted function with a function call, we have to
+ * save volatile registers
+ */
+ Parrot_jit_save_registers(jit_info, interpreter, 1);
}
/* Generate native code for current op */
@@ -1416,6 +1353,13 @@
}
(op_func[cur_opcode_byte].fn) (jit_info, interpreter);
+ if (CALLS_C_CODE(cur_opcode_byte)) {
+ /*
+ * restore volatiles only - and TODO only if next
+ * whouldn't load registers anyway
+ */
+ Parrot_jit_load_registers(jit_info, interpreter, 1);
+ }
/* Update the previous opcode */
jit_info->prev_op = cur_op;
@@ -1445,7 +1389,7 @@
/* Save mapped registers back to the Parrot registers */
if (!jit_seg && cur_section->isjit)
- Parrot_jit_save_registers(jit_info, interpreter);
+ Parrot_jit_save_registers(jit_info, interpreter, 0);
/* update the offset for saved registers */
jit_info->arena.op_map[jit_info->op_i].offset =