cvsuser 02/11/18 02:11:40
Modified: include/parrot jit.h
jit/i386 core.jit jit_emit.h
. jit2h.pl jit_debug.c
Log:
JIT/i386: 370% faster mops_p.pasm
Revision Changes Path
1.22 +3 -2 parrot/include/parrot/jit.h
Index: jit.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/jit.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -w -r1.21 -r1.22
--- jit.h 16 Nov 2002 10:36:02 -0000 1.21
+++ jit.h 18 Nov 2002 10:11:36 -0000 1.22
@@ -1,7 +1,7 @@
/*
* jit.h
*
- * $Id: jit.h,v 1.21 2002/11/16 10:36:02 leo Exp $
+ * $Id: jit.h,v 1.22 2002/11/18 10:11:36 leo Exp $
*/
#ifndef JIT_H_GUARD
@@ -197,11 +197,12 @@
* jit_fn_t: A pointer to the function that emits code for the opcode
* or to the C funtion if the opcode is not jitted.
* extcall: If the opcode makes an external call to a C funtion.
+ * also used for vtable functions, extcall is #of vtable func
*/
typedef struct {
jit_fn_t fn;
- char extcall;
+ int extcall;
} Parrot_jit_fn_info_t;
extern Parrot_jit_fn_info_t op_jit[];
1.28 +6 -1 parrot/jit/i386/core.jit
Index: core.jit
===================================================================
RCS file: /cvs/public/parrot/jit/i386/core.jit,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -w -r1.27 -r1.28
--- core.jit 15 Nov 2002 13:43:24 -0000 1.27
+++ core.jit 18 Nov 2002 10:11:38 -0000 1.28
@@ -1,7 +1,7 @@
;
; i386/core.jit
;
-; $Id: core.jit,v 1.27 2002/11/15 13:43:24 leo Exp $
+; $Id: core.jit,v 1.28 2002/11/18 10:11:38 leo Exp $
;
# TODO complete this
@@ -43,6 +43,11 @@
emit_movl_m_r(NATIVECODE, emit_EAX, &INT_REG[2]);
emit_movl_r_m(NATIVECODE, emit_EAX, &INT_REG[1]);
}
+}
+
+Parrot_set_p_p {
+ emit_movl_m_r(NATIVECODE, emit_EAX, &PMC_REG[2]);
+ emit_movl_r_m(NATIVECODE, emit_EAX, &PMC_REG[1]);
}
Parrot_set_n_nc {
1.16 +91 -2 parrot/jit/i386/jit_emit.h
Index: jit_emit.h
===================================================================
RCS file: /cvs/public/parrot/jit/i386/jit_emit.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -w -r1.15 -r1.16
--- jit_emit.h 16 Nov 2002 10:36:08 -0000 1.15
+++ jit_emit.h 18 Nov 2002 10:11:38 -0000 1.16
@@ -3,9 +3,11 @@
*
* i386
*
- * $Id: jit_emit.h,v 1.15 2002/11/16 10:36:08 leo Exp $
+ * $Id: jit_emit.h,v 1.16 2002/11/18 10:11:38 leo Exp $
*/
+#include <assert.h>
+
/* Register codes */
#define emit_None 0
@@ -717,7 +719,7 @@
/* Short jump - 8 bit disp */
#define emitm_jxs(pc, code, disp) { \
- *((pc)++) = 0x70 | code; \
+ *((pc)++) = 0x70 | (code); \
*((pc)++) = (char)disp; }
/* Long jump - 32 bit disp */
@@ -992,6 +994,93 @@
Parrot_emit_jump_to_eax(jit_info, interpreter);
}
+#undef Parrot_jit_vtable1_op
+#undef Parrot_jit_vtable_ifp_op
+#undef Parrot_jit_vtable_unlessp_op
+
+/* emit a call to a vtable func
+ * $1->vtable(interp, $1)
+ */
+static void
+Parrot_jit_vtable1_op(Parrot_jit_info_t *jit_info,
+ struct Parrot_Interp * interpreter)
+{
+ int nvtable = op_jit[*jit_info->cur_op].extcall;
+ size_t offset;
+ op_info_t *op_info = &interpreter->op_info_table[*jit_info->cur_op];
+ int p1;
+
+ if (nvtable <= 1) {
+ Parrot_jit_normal_op(jit_info, interpreter);
+ return;
+ }
+ /* get the offset of the first vtable func */
+ offset = offsetof(struct _vtable, init);
+ offset += nvtable * sizeof(void *);
+ /* get first param $1 */
+ assert(op_info->types[1] == PARROT_ARG_P);
+ p1 = *(jit_info->cur_op + 1);
+ assert(p1 >= 0 && p1 < NUM_REGISTERS);
+ /* get $1 to EAX */
+ emit_movl_m_r(jit_info->native_ptr, emit_EAX,
+ &interpreter->ctx.pmc_reg.registers[p1]);
+ /* push $1 */
+ emit_pushl_r(jit_info->native_ptr, emit_EAX);
+ /* push interpreter */
+ emitm_pushl_i(jit_info->native_ptr, interpreter);
+ /* mov (eax), eax i.e. $1->vtable */
+ emitm_movl_m_r(jit_info->native_ptr, emit_EAX, emit_EAX, emit_None, 1, 0);
+ /* call *(offset)eax */
+ emitm_callm(jit_info->native_ptr, emit_EAX, emit_None, emit_None, offset);
+ emitm_addb_i_r(jit_info->native_ptr, 8, emit_ESP);
+}
+
+/* if_p_ic, unless_p_ic */
+static void
+Parrot_jit_vtable_if_unless_op(Parrot_jit_info_t *jit_info,
+ struct Parrot_Interp * interpreter, int unless)
+{
+ int ic = *(jit_info->cur_op + 2); /* branch offset */
+ char *jmp_ptr, *sav_ptr;
+
+ /* emit call vtable function i.e. get_bool, result eax */
+ Parrot_jit_vtable1_op(jit_info, interpreter);
+ /* test result */
+ emit_test_r_r(jit_info->native_ptr, emit_EAX, emit_EAX);
+ /* remember PC */
+ jmp_ptr = jit_info->native_ptr;
+ /* emit jump past code, dummy offset */
+ emitm_jxs(jit_info->native_ptr, unless ? emitm_jnz : emitm_jz, 0);
+ /* get branch offset to eax */
+ emitm_movl_i_r(jit_info->native_ptr,
+ jit_info->cur_op + ic * sizeof(opcode_t), emit_EAX);
+ /* TODO calc directly and jump
+ * (cur_op - code_start) + ic * 4 indexed EBP */
+ Parrot_emit_jump_to_eax(jit_info, interpreter);
+ /* fixup above jump */
+ sav_ptr = jit_info->native_ptr;
+ jit_info->native_ptr = jmp_ptr;
+ emitm_jxs(jit_info->native_ptr, unless ? emitm_jnz : emitm_jz,
+ (long)(sav_ptr - jmp_ptr) - 2);
+ /* restore PC */
+ jit_info->native_ptr = sav_ptr;
+}
+
+/* unless_p_ic */
+static void
+Parrot_jit_vtable_unlessp_op(Parrot_jit_info_t *jit_info,
+ struct Parrot_Interp * interpreter)
+{
+ Parrot_jit_vtable_if_unless_op(jit_info, interpreter, 1);
+}
+
+/* if_p_ic */
+static void
+Parrot_jit_vtable_ifp_op(Parrot_jit_info_t *jit_info,
+ struct Parrot_Interp * interpreter)
+{
+ Parrot_jit_vtable_if_unless_op(jit_info, interpreter, 0);
+}
void
Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
1.26 +61 -8 parrot/jit2h.pl
Index: jit2h.pl
===================================================================
RCS file: /cvs/public/parrot/jit2h.pl,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -w -r1.25 -r1.26
--- jit2h.pl 10 Oct 2002 12:22:27 -0000 1.25
+++ jit2h.pl 18 Nov 2002 10:11:40 -0000 1.26
@@ -2,7 +2,7 @@
#
# jit2h.pl
#
-# $Id: jit2h.pl,v 1.25 2002/10/10 12:22:27 leo Exp $
+# $Id: jit2h.pl,v 1.26 2002/11/18 10:11:40 leo Exp $
#
use strict;
@@ -77,6 +77,21 @@
return %ops;
}
+use Parrot::Vtable;
+my $vtable;
+sub vtable_num($) {
+ my $meth = shift;
+ unless ($vtable) {
+ $vtable = parse_vtable();
+ }
+ my $i = 0;
+ for my $entry (@{$vtable}) {
+ return $i if ($entry->[1] eq $meth);
+ $i++;
+ }
+ return 1;
+}
+
open JITCPU, ">$ARGV[0]" or die;
print JITCPU<<END_C;
@@ -93,6 +108,14 @@
#include<parrot/parrot.h>
#include"parrot/jit.h"
#define JIT_EMIT 1
+
+/*
+ *define default jit_funcs, if architecture doesn't have these optimizations
+ */
+#define Parrot_jit_vtable1_op Parrot_jit_normal_op
+#define Parrot_jit_vtable_ifp_op Parrot_jit_cpcf_op
+#define Parrot_jit_vtable_unlessp_op Parrot_jit_cpcf_op
+
#include"parrot/jit_emit.h"
#undef CONST
@@ -103,6 +126,7 @@
#define CONST(i) interpreter->code->const_table->constants[jit_info->cur_op[i]]
END_C
+
%core_ops = readjit("jit/$cpuarch/core.jit");
print JITCPU $header if ($header);
@@ -124,7 +148,36 @@
if (!defined $body) {
$precompiled = 1;
$extern = 1;
- if ($op->jump) {
+ my $opbody = $op->body;
+ # jitable vtable funcs:
+ # 1) $1->vtable->{vtable}(interp, $1)
+ if ($opbody =~ /
+ core.ops"\s+
+ {{\@1}}->vtable->
+ (\w+)
+ \(interpreter,
+ \s*
+ {{\@1}}
+ \);
+ \s+{{\+=\d}}/xm) {
+ $jit_func = "Parrot_jit_vtable1_op";
+ $extern = vtable_num($1);
+ print "$jit_func $extern\n";
+ }
+ elsif ($op->full_name eq 'if_p_ic') {
+ $jit_func = "Parrot_jit_vtable_ifp_op";
+ $opbody =~ /vtable->(\w+)/;
+ $extern = vtable_num($1);
+ print "$jit_func $extern\n";
+ }
+ elsif ($op->full_name eq 'unless_p_ic') {
+ $jit_func = "Parrot_jit_vtable_unlessp_op";
+ $opbody =~ /vtable->(\w+)/;
+ $extern = vtable_num($1);
+ print "$jit_func $extern\n";
+ }
+
+ elsif ($op->jump) {
$jit_func = "Parrot_jit_cpcf_op";
} else {
$jit_func = "Parrot_jit_normal_op";
1.2 +50 -5 parrot/jit_debug.c
Index: jit_debug.c
===================================================================
RCS file: /cvs/public/parrot/jit_debug.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- jit_debug.c 16 Nov 2002 15:12:17 -0000 1.1
+++ jit_debug.c 18 Nov 2002 10:11:40 -0000 1.2
@@ -1,7 +1,7 @@
/*
* jit_debug.c
*
- * $Id: jit_debug.c,v 1.1 2002/11/16 15:12:17 leo Exp $
+ * $Id: jit_debug.c,v 1.2 2002/11/18 10:11:40 leo Exp $
*
* write stabs file for jit code
* when debugging jit code with gdb, do:
@@ -17,6 +17,48 @@
void Parrot_jit_debug(struct Parrot_Interp* interpreter);
static void
+write_types(FILE *stabs)
+{
+ fprintf(stabs,
+".stabs \"int:t1=r1;0020000000000;0017777777777;\",128,0,0,0\n"
+".stabs \"char:t2=r2;0;127;\",128,0,0,0\n"
+".stabs \"long int:t3=r1;0020000000000;0017777777777;\",128,0,0,0\n"
+".stabs \"unsigned int:t4=r1;0000000000000;0037777777777;\",128,0,0,0\n"
+".stabs \"long unsigned int:t5=r1;0000000000000;0037777777777;\",128,0,0,0\n"
+".stabs \"long long
int:t6=r1;01000000000000000000000;07777777777777777777;\",128,0,0,0\n"
+".stabs \"long long unsigned
int:t7=r1;0000000000000;017777777777777777777;\",128,0,0,0\n"
+".stabs \"short int:t8=r8;-32768;32767;\",128,0,0,0\n"
+".stabs \"short unsigned int:t9=r9;0;65535;\",128,0,0,0\n"
+".stabs \"signed char:t10=r10;-128;127;\",128,0,0,0\n"
+".stabs \"unsigned char:t11=r11;0;255;\",128,0,0,0\n"
+".stabs \"float:t12=r1;4;0;\",128,0,0,0\n"
+".stabs \"double:t13=r1;8;0;\",128,0,0,0\n"
+ );
+#if INTVAL_SIZE == 4
+ fprintf(stabs, ".stabs \"Parrot_Int:t14=1\",128,0,0,0\n");
+#else
+ fprintf(stabs, ".stabs \"Parrot_Int:t14=6\",128,0,0,0\n");
+#endif
+#if NUMVAL_SIZE == 4
+ fprintf(stabs, ".stabs \"Parrot_Float:t15=12\",128,0,0,0\n");
+#else
+ fprintf(stabs, ".stabs \"Parrot_Float:t15=13\",128,0,0,0\n");
+#endif
+}
+
+static void
+write_vars(FILE *stabs, struct Parrot_Interp *interpreter)
+{
+ int i;
+ for (i = 0; i < NUM_REGISTERS; i++) {
+ fprintf(stabs, ".stabs \"I%d:b14\",38,0,0,%p\n", i,
+ (char*)&interpreter->ctx.int_reg.registers[i]);
+ fprintf(stabs, ".stabs \"N%d:b15\",38,0,0,%p\n", i,
+ (char*)&interpreter->ctx.num_reg.registers[i]);
+ }
+}
+
+static void
Parrot_jit_debug_stabs(struct Parrot_Interp *interpreter)
{
Parrot_jit_info_t *jit_info = interpreter->jit_info;
@@ -30,19 +72,19 @@
file = string_chopn(file, 3);
pasmfile = string_copy(interpreter, file);
pasmfile = string_append(interpreter, pasmfile,
- string_make(interpreter, "pasm", 4, 0, 0, 0),
+ string_make(interpreter, "pasm", 4, 0, BUFFER_external_FLAG, 0),
0);
stabsfile = string_copy(interpreter, file);
stabsfile = string_append(interpreter, stabsfile,
- string_make(interpreter, "stabs.s", 7, 0, 0, 0),
+ string_make(interpreter, "stabs.s", 7, 0, BUFFER_external_FLAG, 0),
0);
ofile = string_copy(interpreter, file);
ofile = string_append(interpreter, ofile,
- string_make(interpreter, "o", 4, 0, 0, 0),
+ string_make(interpreter, "o", 4, 0, BUFFER_external_FLAG, 0),
0);
stabsfile = string_copy(interpreter, file);
stabsfile = string_append(interpreter, stabsfile,
- string_make(interpreter, "stabs.s", 7, 0, 0, 0),
+ string_make(interpreter, "stabs.s", 7, 0, BUFFER_external_FLAG, 0),
0);
stabs = fopen(string_to_cstring(interpreter,stabsfile), "w");
if (stabs == NULL)
@@ -54,6 +96,8 @@
/* jit_func start addr */
fprintf(stabs, ".stabs \"jit_func:F(0,1)\",36,0,1,%p\n",
jit_info->arena.start);
+ write_types(stabs);
+ write_vars(stabs, interpreter);
/* we don't have line numbers yet, emit dummys, assuming there are
* no comments and spaces in source for testing
*/
@@ -69,6 +113,7 @@
line++;
}
}
+ /* eof */
fprintf(stabs, ".stabs \"\",36,0,1,%p\n",
(char *)jit_info->arena.start+ jit_info->arena.size);
fclose(stabs);