[svn:parrot] r41356 - in trunk: . compilers/imcc compilers/pirc/src config/auto config/auto/frames config/auto/jit config/gen/makefiles docs docs/book/draft docs/dev include/parrot lib/Parrot/Configure/Options lib/Parrot/Configure/Options/Conf lib/Parrot/Configure/Step src src/interp src/jit/alpha src/jit/amd64 src/jit/arm src/jit/hppa src/jit/i386 src/jit/ia64 src/jit/mips src/jit/ppc src/jit/skeleton src/jit/sun4 src/runcore t/steps/auto tools/build
bacek at svn.parrot.org
bacek at svn.parrot.org
Sat Sep 19 08:10:20 UTC 2009
Author: bacek
Date: Sat Sep 19 08:10:11 2009
New Revision: 41356
URL: https://trac.parrot.org/parrot/changeset/41356
Log:
Merge branch 'kill_jit' back to trunk.
Added:
trunk/config/auto/frames/
trunk/config/auto/frames.pm
trunk/config/auto/frames/test_exec_cygwin_c.in
- copied, changed from r41354, trunk/config/auto/jit/test_exec_cygwin_c.in
trunk/config/auto/frames/test_exec_linux_c.in
- copied, changed from r41354, trunk/config/auto/jit/test_exec_linux_c.in
trunk/config/auto/frames/test_exec_openbsd_c.in
- copied, changed from r41354, trunk/config/auto/jit/test_exec_openbsd_c.in
trunk/src/frame_builder.c
trunk/src/frame_builder.h
- copied, changed from r41354, trunk/src/jit/i386/jit_emit.h
trunk/t/steps/auto/frames-01.t
Deleted:
trunk/config/auto/jit/test_c.in
trunk/config/auto/jit/test_exec_cygwin_c.in
trunk/config/auto/jit/test_exec_linux_c.in
trunk/config/auto/jit/test_exec_openbsd_c.in
trunk/docs/dev/jit_i386.pod
trunk/docs/jit.pod
trunk/docs/native_exec.pod
trunk/include/parrot/exec.h
trunk/src/exec.c
trunk/src/exec_save.c
trunk/src/exec_save.h
trunk/src/exec_start.c
trunk/src/jit.c
trunk/src/jit.h
trunk/src/jit/alpha/core.jit
trunk/src/jit/alpha/jit_defs.c
trunk/src/jit/alpha/jit_emit.h
trunk/src/jit/amd64/core.jit
trunk/src/jit/amd64/jit_defs.c
trunk/src/jit/amd64/jit_emit.h
trunk/src/jit/arm/core.jit
trunk/src/jit/arm/exec_dep.c
trunk/src/jit/arm/exec_dep.h
trunk/src/jit/arm/jit_defs.c
trunk/src/jit/arm/jit_emit.h
trunk/src/jit/hppa/core.jit
trunk/src/jit/hppa/jit_defs.c
trunk/src/jit/hppa/jit_emit.h
trunk/src/jit/i386/core.jit
trunk/src/jit/i386/exec_dep.c
trunk/src/jit/i386/exec_dep.h
trunk/src/jit/i386/jit_defs.c
trunk/src/jit/i386/jit_emit.h
trunk/src/jit/ia64/core.jit
trunk/src/jit/ia64/jit_defs.c
trunk/src/jit/ia64/jit_emit.h
trunk/src/jit/mips/core.jit
trunk/src/jit/mips/jit_defs.c
trunk/src/jit/mips/jit_emit.h
trunk/src/jit/ppc/asm.s
trunk/src/jit/ppc/core.jit
trunk/src/jit/ppc/exec_dep.c
trunk/src/jit/ppc/exec_dep.h
trunk/src/jit/ppc/jit_defs.c
trunk/src/jit/ppc/jit_emit.h
trunk/src/jit/ppc/ppc-linux.s
trunk/src/jit/skeleton/jit_defs.c
trunk/src/jit/skeleton/jit_emit.h
trunk/src/jit/sun4/core.jit
trunk/src/jit/sun4/jit_defs.c
trunk/src/jit/sun4/jit_emit.h
trunk/src/jit_debug.c
trunk/src/jit_debug_xcoff.c
trunk/tools/build/jit2c.pl
Modified:
trunk/Configure.pl
trunk/MANIFEST
trunk/compilers/imcc/main.c
trunk/compilers/imcc/pbc.c
trunk/compilers/imcc/pbc.h
trunk/compilers/pirc/src/bcgen.c
trunk/compilers/pirc/src/bcgen.h
trunk/config/auto/jit.pm
trunk/config/gen/makefiles/root.in
trunk/docs/book/draft/appc_command_line_options.pod
trunk/docs/debug.pod
trunk/docs/dev/events.pod
trunk/docs/parrot.pod
trunk/docs/porting_intro.pod
trunk/docs/running.pod
trunk/docs/tests.pod
trunk/include/parrot/interpreter.h
trunk/include/parrot/packfile.h
trunk/include/parrot/runcore_api.h
trunk/lib/Parrot/Configure/Options/Conf.pm
trunk/lib/Parrot/Configure/Options/Conf/Shared.pm
trunk/lib/Parrot/Configure/Step/List.pm
trunk/src/embed.c
trunk/src/interp/inter_create.c
trunk/src/packfile.c
trunk/src/runcore/cores.c
trunk/src/runcore/main.c
trunk/t/steps/auto/jit-01.t
trunk/tools/build/nativecall.pl
Modified: trunk/Configure.pl
==============================================================================
--- trunk/Configure.pl Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/Configure.pl Sat Sep 19 08:10:11 2009 (r41356)
@@ -351,6 +351,10 @@
Use JIT system.
+=item C<--buildframes>
+
+Dynamically build NCI call frames.
+
=item C<--execcapable>
Use JIT to emit a native executable.
@@ -617,6 +621,7 @@
auto::isreg
auto::arch
auto::jit
+ auto::frames
auto::cpu
auto::funcptr
auto::cgoto
Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/MANIFEST Sat Sep 19 08:10:11 2009 (r41356)
@@ -1,7 +1,7 @@
# ex: set ro:
# $Id$
#
-# generated by tools/dev/mk_manifest_and_skip.pl Wed Sep 16 06:03:11 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Sat Sep 19 03:26:22 2009 UT
#
# See below for documentation on the format of this file.
#
@@ -232,6 +232,10 @@
config/auto/env/test_setenv_c.in []
config/auto/env/test_unsetenv_c.in []
config/auto/format.pm []
+config/auto/frames.pm []
+config/auto/frames/test_exec_cygwin_c.in []
+config/auto/frames/test_exec_linux_c.in []
+config/auto/frames/test_exec_openbsd_c.in []
config/auto/funcptr.pm []
config/auto/funcptr/test_c.in []
config/auto/gc.pm []
@@ -255,10 +259,6 @@
config/auto/isreg.pm []
config/auto/isreg/test_c.in []
config/auto/jit.pm []
-config/auto/jit/test_c.in []
-config/auto/jit/test_exec_cygwin_c.in []
-config/auto/jit/test_exec_linux_c.in []
-config/auto/jit/test_exec_openbsd_c.in []
config/auto/memalign.pm []
config/auto/memalign/test2_c.in []
config/auto/memalign/test_c.in []
@@ -457,7 +457,6 @@
docs/dev/events.pod []
docs/dev/headerizer.pod []
docs/dev/infant.pod []
-docs/dev/jit_i386.pod []
docs/dev/longopt.pod []
docs/dev/optimizer.pod []
docs/dev/parrot_api.pod []
@@ -474,10 +473,8 @@
docs/imcc/imcfaq.pod []
docs/imcc/operation.pod []
docs/intro.pod [main]doc
-docs/jit.pod []
docs/memory_internals.pod []
docs/multidispatch.pod []
-docs/native_exec.pod []
docs/optable.pod []
docs/overview.pod []
docs/parrot.pod []
@@ -968,7 +965,6 @@
include/parrot/enums.h [main]include
include/parrot/events.h [main]include
include/parrot/exceptions.h [main]include
-include/parrot/exec.h [main]include
include/parrot/exit.h [main]include
include/parrot/extend.h [main]include
include/parrot/gc_api.h [main]include
@@ -1272,12 +1268,10 @@
src/embed.c []
src/events.c []
src/exceptions.c []
-src/exec.c []
-src/exec_save.c []
-src/exec_save.h []
-src/exec_start.c []
src/exit.c []
src/extend.c []
+src/frame_builder.c []
+src/frame_builder.h []
src/gc/alloc_memory.c []
src/gc/alloc_resources.c []
src/gc/api.c []
@@ -1309,47 +1303,6 @@
src/io/unix.c []
src/io/utf8.c []
src/io/win32.c []
-src/jit.c []
-src/jit.h []
-src/jit/alpha/core.jit []
-src/jit/alpha/jit_defs.c []
-src/jit/alpha/jit_emit.h []
-src/jit/amd64/core.jit []
-src/jit/amd64/jit_defs.c []
-src/jit/amd64/jit_emit.h []
-src/jit/arm/core.jit []
-src/jit/arm/exec_dep.c []
-src/jit/arm/exec_dep.h []
-src/jit/arm/jit_defs.c []
-src/jit/arm/jit_emit.h []
-src/jit/hppa/core.jit []
-src/jit/hppa/jit_defs.c []
-src/jit/hppa/jit_emit.h []
-src/jit/i386/core.jit []
-src/jit/i386/exec_dep.c []
-src/jit/i386/exec_dep.h []
-src/jit/i386/jit_defs.c []
-src/jit/i386/jit_emit.h []
-src/jit/ia64/core.jit []
-src/jit/ia64/jit_defs.c []
-src/jit/ia64/jit_emit.h []
-src/jit/mips/core.jit []
-src/jit/mips/jit_defs.c []
-src/jit/mips/jit_emit.h []
-src/jit/ppc/asm.s []
-src/jit/ppc/core.jit []
-src/jit/ppc/exec_dep.c []
-src/jit/ppc/exec_dep.h []
-src/jit/ppc/jit_defs.c []
-src/jit/ppc/jit_emit.h []
-src/jit/ppc/ppc-linux.s []
-src/jit/skeleton/jit_defs.c []
-src/jit/skeleton/jit_emit.h []
-src/jit/sun4/core.jit []
-src/jit/sun4/jit_defs.c []
-src/jit/sun4/jit_emit.h []
-src/jit_debug.c []
-src/jit_debug_xcoff.c []
src/key.c []
src/libnci_test.def []
src/library.c []
@@ -1969,6 +1922,7 @@
t/steps/auto/ctags-01.t [test]
t/steps/auto/env-01.t [test]
t/steps/auto/format-01.t [test]
+t/steps/auto/frames-01.t [test]
t/steps/auto/funcptr-01.t [test]
t/steps/auto/gc-01.t [test]
t/steps/auto/gcc-01.t [test]
@@ -2114,7 +2068,6 @@
tools/build/c2str.pl []
tools/build/fixup_gen_file.pl []
tools/build/headerizer.pl []
-tools/build/jit2c.pl []
tools/build/nativecall.pl []
tools/build/ops2c.pl [devel]
tools/build/ops2pm.pl []
Modified: trunk/compilers/imcc/main.c
==============================================================================
--- trunk/compilers/imcc/main.c Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/compilers/imcc/main.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -897,16 +897,8 @@
if (STREQ(ext, ".pbc"))
SET_STATE_WRITE_PBC(interp);
else if (STREQ(ext, PARROT_OBJ_EXT)) {
-#if EXEC_CAPABLE
- SET_STATE_LOAD_PBC(interp);
- SET_STATE_RUN_PBC(interp);
- UNSET_STATE_WRITE_PBC(interp);
- *obj_file = 1;
- Parrot_set_run_core(interp, PARROT_EXEC_CORE);
-#else
UNUSED(obj_file);
IMCC_fatal_standalone(interp, 1, "main: can't produce object file");
-#endif
}
}
}
Modified: trunk/compilers/imcc/pbc.c
==============================================================================
--- trunk/compilers/imcc/pbc.c Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/compilers/imcc/pbc.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -179,10 +179,6 @@
__attribute__nonnull__(1)
__attribute__nonnull__(2);
-PARROT_WARN_UNUSED_RESULT
-static int old_blocks(PARROT_INTERP)
- __attribute__nonnull__(1);
-
static void store_fixup(PARROT_INTERP,
ARGIN(const SymReg *r),
int pc,
@@ -270,8 +266,6 @@
#define ASSERT_ARGS_mk_multi_sig __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(r)
-#define ASSERT_ARGS_old_blocks __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp)
#define ASSERT_ARGS_store_fixup __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(r)
@@ -287,14 +281,6 @@
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
-#ifdef HAS_JIT
-
-PARROT_WARN_UNUSED_RESULT
-static int old_blocks(PARROT_INTERP)
- __attribute__nonnull__(1);
-
-#endif /* HAS_JIT */
-
/*
=item C<static void imcc_globals_destroy(PARROT_INTERP, int ex, void *param)>
@@ -482,84 +468,6 @@
return 0;
}
-
-#ifdef HAS_JIT
-
-/*
-
-=item C<static int old_blocks(PARROT_INTERP)>
-
-Gets the size/line of bytecode in ops at this point.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-static int
-old_blocks(PARROT_INTERP)
-{
- ASSERT_ARGS(old_blocks)
- const subs_t *s;
- size_t size = 0;
-
- for (s = IMCC_INFO(interp)->globals->cs->subs; s; s = s->prev) {
- size += s->n_basic_blocks;
- }
-
- return size;
-}
-
-
-/*
-
-=item C<opcode_t * make_jit_info(PARROT_INTERP, const IMC_Unit *unit)>
-
-Creates JIT information for this compilation unit.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-opcode_t *
-make_jit_info(PARROT_INTERP, ARGIN(const IMC_Unit *unit))
-{
- ASSERT_ARGS(make_jit_info)
- const size_t old = old_blocks(interp);
- const size_t size = unit->n_basic_blocks + old;
-
- if (!IMCC_INFO(interp)->globals->cs->jit_info) {
- const size_t len = strlen(IMCC_INFO(interp)->globals->cs->seg->base.name) + 5;
- char * const name = mem_allocate_n_typed(len, char);
-
- snprintf(name, len, "%s_JIT",
- IMCC_INFO(interp)->globals->cs->seg->base.name);
-
- IMCC_INFO(interp)->globals->cs->jit_info =
- PackFile_Segment_new_seg(interp,
- interp->code->base.dir, PF_UNKNOWN_SEG, name, 1);
-
- mem_sys_free(name);
- }
-
- /* store current size */
- IMCC_INFO(interp)->globals->cs->subs->n_basic_blocks = unit->n_basic_blocks;
-
- /* offset of block start and end, 4 * registers_used */
- IMCC_INFO(interp)->globals->cs->jit_info->data =
- mem_realloc_n_typed(IMCC_INFO(interp)->globals->cs->jit_info->data,
- size * 4, opcode_t);
-
- IMCC_INFO(interp)->globals->cs->jit_info->size = size * 4;
-
- return IMCC_INFO(interp)->globals->cs->jit_info->data + old * 4;
-}
-
-#endif /* HAS_JIT */
-
-
/*
=item C<static void make_new_sub(PARROT_INTERP, IMC_Unit *unit)>
Modified: trunk/compilers/imcc/pbc.h
==============================================================================
--- trunk/compilers/imcc/pbc.h Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/compilers/imcc/pbc.h Sat Sep 19 08:10:11 2009 (r41356)
@@ -48,12 +48,6 @@
__attribute__nonnull__(1)
__attribute__nonnull__(2);
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-opcode_t * make_jit_info(PARROT_INTERP, ARGIN(const IMC_Unit *unit))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
#define ASSERT_ARGS_e_pbc_close __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp)
#define ASSERT_ARGS_e_pbc_emit __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -77,9 +71,6 @@
#define ASSERT_ARGS_IMCC_string_from_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(r)
-#define ASSERT_ARGS_make_jit_info __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp) \
- || PARROT_ASSERT_ARG(unit)
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: compilers/imcc/pbc.c */
Modified: trunk/compilers/pirc/src/bcgen.c
==============================================================================
--- trunk/compilers/pirc/src/bcgen.c Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/compilers/pirc/src/bcgen.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -1060,58 +1060,6 @@
return pmc_new(bc->interp, type);
}
-
-#if 0
-
-/*
-
-=item C<opcode_t * make_jit_info(PARROT_INTERP, const struct _IMC_Unit *unit)>
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-opcode_t *
-make_jit_info(PARROT_INTERP, ARGIN(const struct _IMC_Unit *unit))
-{
- ASSERT_ARGS(make_jit_info)
- const size_t old = old_blocks(interp);
- const size_t size = unit->n_basic_blocks + old;
-
- if (!IMCC_INFO(interp)->globals->cs->jit_info) {
- const size_t len =
- strlen(IMCC_INFO(interp)->globals->cs->seg->base.name) + 5;
- char * const name = mem_allocate_n_typed(len, char);
-
- snprintf(name, len, "%s_JIT",
- IMCC_INFO(interp)->globals->cs->seg->base.name);
-
- IMCC_INFO(interp)->globals->cs->jit_info =
- PackFile_Segment_new_seg(interp,
- interp->code->base.dir, PF_UNKNOWN_SEG, name, 1);
-
- mem_sys_free(name);
- }
-
- /* store current size */
- IMCC_INFO(interp)->globals->cs->subs->n_basic_blocks = unit->n_basic_blocks;
-
- /* offset of block start and end, 4 * registers_used */
- IMCC_INFO(interp)->globals->cs->jit_info->data =
- mem_realloc_n_typed(IMCC_INFO(interp)->globals->cs->jit_info->data,
- size * 4, opcode_t);
-
- IMCC_INFO(interp)->globals->cs->jit_info->size = size * 4;
-
- return IMCC_INFO(interp)->globals->cs->jit_info->data + old * 4;
-}
-
-#endif /* HAS_JIT */
-
-
-
/*
=item C<int add_sub_pmc(bytecode * const bc, sub_info * const info, int needlex,
Modified: trunk/compilers/pirc/src/bcgen.h
==============================================================================
--- trunk/compilers/pirc/src/bcgen.h Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/compilers/pirc/src/bcgen.h Sat Sep 19 08:10:11 2009 (r41356)
@@ -165,12 +165,6 @@
STRING * get_string_const(ARGIN(bytecode * const bc), unsigned index)
__attribute__nonnull__(1);
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-opcode_t * make_jit_info(PARROT_INTERP, ARGIN(const struct _IMC_Unit *unit))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
PARROT_CANNOT_RETURN_NULL
bytecode * new_bytecode(PARROT_INTERP, ARGIN(char const * const filename))
__attribute__nonnull__(1)
@@ -226,9 +220,6 @@
PARROT_ASSERT_ARG(bc)
#define ASSERT_ARGS_get_string_const __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(bc)
-#define ASSERT_ARGS_make_jit_info __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp) \
- || PARROT_ASSERT_ARG(unit)
#define ASSERT_ARGS_new_bytecode __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(filename)
Added: trunk/config/auto/frames.pm
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/config/auto/frames.pm Sat Sep 19 08:10:11 2009 (r41356)
@@ -0,0 +1,101 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+config/auto/frmes
+
+=head1 DESCRIPTION
+
+Determines whether the current platform is capable of building NCI call
+frames dynamically. Use the C<--buildframes> option to override the
+default value for your CPU architecture and operating system.
+
+=cut
+
+package auto::frames;
+
+use strict;
+use warnings;
+
+use base qw(Parrot::Configure::Step);
+
+sub _init {
+ my $self = shift;
+ my %data;
+ $data{description} = q{Determine call frame building capability};
+ $data{result} = q{};
+ return \%data;
+}
+
+sub runstep {
+ my ( $self, $conf ) = @_;
+
+ my $can_build_call_frames;
+
+ my $osname = $conf->data->get('osname');
+ my $cpuarch = $conf->data->get('cpuarch');
+ my $nvsize = $conf->data->get('nvsize');
+
+ if (defined $conf->options->get('buildframes')) {
+ $can_build_call_frames = $conf->options->get('buildframes');
+ }
+ else {
+ $can_build_call_frames = ($nvsize == 8 && $cpuarch eq 'i386'
+ && $osname ne 'darwin');
+ }
+
+ if ( $can_build_call_frames ) {
+ $conf->data->set(
+ cc_build_call_frames => '-DCAN_BUILD_CALL_FRAMES',
+ );
+ }
+ else {
+ $conf->data->set(
+ cc_build_call_frames => '',
+ );
+ }
+
+ if ( $can_build_call_frames ) {
+ # test for executable malloced memory
+ if ( -e "config/auto/frames/test_exec_${osname}_c.in" ) {
+ $conf->cc_gen("config/auto/frames/test_exec_${osname}_c.in");
+ eval { $conf->cc_build(); };
+ if ($@) {
+ $conf->data->set( has_exec_protect => 0 );
+ }
+ else {
+ my $exec_protect_test = (
+ $conf->cc_run(0) !~ /ok/ && $conf->cc_run(1) =~ /ok/
+ );
+ _handle_exec_protect($conf, $exec_protect_test);
+ }
+ $conf->cc_clean();
+ }
+ else {
+ $conf->data->set( has_exec_protect => 0 );
+ }
+ }
+
+ $self->set_result($can_build_call_frames?'yes':'no');
+ return 1;
+}
+
+sub _handle_exec_protect {
+ my ($conf, $exec_protect_test) = @_;
+ if ($exec_protect_test) {
+ $conf->data->set( has_exec_protect => 1 );
+ }
+ else {
+ $conf->data->set( has_exec_protect => 0 );
+ }
+}
+
+1;
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
Copied and modified: trunk/config/auto/frames/test_exec_cygwin_c.in (from r41354, trunk/config/auto/jit/test_exec_cygwin_c.in)
==============================================================================
Copied and modified: trunk/config/auto/frames/test_exec_linux_c.in (from r41354, trunk/config/auto/jit/test_exec_linux_c.in)
==============================================================================
Copied and modified: trunk/config/auto/frames/test_exec_openbsd_c.in (from r41354, trunk/config/auto/jit/test_exec_openbsd_c.in)
==============================================================================
Modified: trunk/config/auto/jit.pm
==============================================================================
--- trunk/config/auto/jit.pm Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/config/auto/jit.pm Sat Sep 19 08:10:11 2009 (r41356)
@@ -23,227 +23,39 @@
use warnings;
use base qw(Parrot::Configure::Step);
-use Parrot::Configure::Utils qw(copy_if_diff);
sub _init {
my $self = shift;
my %data;
$data{description} = q{Determine JIT capability};
$data{result} = q{};
- $data{jit_is_working} = {
- i386 => 1,
- ppc => 1,
- };
- $data{jitbase_default} = 'src/jit'; # base path for jit sources
- # jitcpuarch_platforms: Those which should be examined for possibility of
- # exec capability.
- $data{jitcpuarch_platforms} = { map { $_ => 1 } qw( i386 ppc arm ) };
- # execcapable_oses: Those which should have exec capability.
- $data{execcapable_oses} = { map { $_ => 1 }
- qw( openbsd freebsd netbsd linux darwin cygwin MSWin32 )
- };
return \%data;
}
sub runstep {
my ( $self, $conf ) = @_;
- my $verbose = $conf->options->get('verbose');
- $verbose and print "\n";
+ my $osname = $conf->data->get('osname');
+ my $cpuarch = $conf->data->get('cpuarch');
- my $cpuarch = $conf->data->get('cpuarch');
- my $osname = $conf->data->get('osname');
- my $nvsize = $conf->data->get('nvsize');
-
- my $jitbase = $self->{jitbase_default}; # base path for jit sources
-
- my $corejit = "$jitbase/$cpuarch/core.jit";
- print( qq{-e $corejit = },
- -e $corejit ? 'yes' : 'no', "\n" )
- if $verbose;
-
- my $jitcapable =
- $self->_check_jitcapability($corejit, $cpuarch, $osname, $nvsize);
-
- my $jitarchname = "$cpuarch-$osname";
- _handle_asm( {
- conf => $conf,
- jitbase => $jitbase,
- cpuarch => $cpuarch,
- jitarchname => $jitarchname,
- } );
-
- # let developers override the default JIT capability
- $jitcapable = $conf->options->get('jitcapable')
- if defined $conf->options->get('jitcapable');
-
- if (! $jitcapable) {
- $conf->data->set(
- jitarchname => 'nojit',
- jitcpuarch => $cpuarch,
- jitcpu => $cpuarch,
- jitosname => $osname,
- jitcapable => 0,
- execcapable => 0,
- cc_hasjit => '',
- TEMP_jit_o => '',
- TEMP_exec_h => '',
- TEMP_exec_o => '',
- TEMP_exec_dep => '',
- );
- $self->set_result('no');
- return 1;
- }
-
- my ( $jitcpuarch, $jitosname ) = split( /-/, $jitarchname );
$conf->data->set(
- jitarchname => $jitarchname,
- jitcpuarch => $jitcpuarch,
- jitcpu => uc($jitcpuarch),
- jitosname => uc($jitosname),
- jitcapable => 1,
- cc_hasjit => " -DHAS_JIT -D\U$jitcpuarch",
- TEMP_jit_o =>
-'$(SRC_DIR)/jit$(O) $(SRC_DIR)/jit_cpu$(O) $(SRC_DIR)/jit_debug$(O) $(SRC_DIR)/jit_debug_xcoff$(O) $(SRC_DIR)/jit_defs$(O)'
+ jitarchname => 'nojit',
+ jitcpuarch => $cpuarch,
+ jitcpu => $cpuarch,
+ jitosname => $osname,
+ jitcapable => 0,
+ execcapable => 0,
+ cc_hasjit => '',
+ TEMP_jit_o => '',
+ TEMP_exec_h => '',
+ TEMP_exec_o => '',
+ TEMP_exec_dep => '',
+ asmfun_o => '',
);
-
- my $execcapable = $self->_first_probe_for_exec(
- $jitcpuarch, $osname);
- $execcapable = $conf->options->get('execcapable')
- if defined $conf->options->get('execcapable');
- _handle_execcapable($conf, $execcapable);
-
- # test for executable malloced memory
- if ( -e "config/auto/jit/test_exec_${osname}_c.in" ) {
- print " (has_exec_protect " if $verbose;
- $conf->cc_gen("config/auto/jit/test_exec_${osname}_c.in");
- eval { $conf->cc_build(); };
- if ($@) {
- print " $@) " if $verbose;
- }
- else {
- my $exec_protect_test = (
- $conf->cc_run(0) !~ /ok/ && $conf->cc_run(1) =~ /ok/
- );
- _handle_exec_protect($conf, $exec_protect_test, $verbose);
- }
- $conf->cc_clean();
- }
-
- # RT #43146 use executable memory for this test if needed
- #
- # test for some instructions
- if ( $jitcpuarch eq 'i386' ) {
- $conf->cc_gen('config/auto/jit/test_c.in');
- eval { $conf->cc_build(); };
- unless ( $@ || $conf->cc_run() !~ /ok/ ) {
- $conf->data->set( jit_i386 => 'fcomip' );
- }
- $conf->cc_clean();
- }
- $self->set_result('yes');
- return 1;
-}
-
-#################### INTERNAL SUBROUTINES ####################
-
-sub _check_jitcapability {
- my $self = shift;
- my ($corejit, $cpuarch, $osname, $nvsize) = @_;
- my $jitcapable = 0;
- if ( -e $corejit ) {
-
- # Just because there is a "$jitbase/$cpuarch/core.jit" file,
- # doesn't mean the JIT is working on that platform.
- # So build JIT per default only on platforms where JIT in known
- # to work. Building JIT on other platform most likely breaks the build.
- # Developer can always call: Configure.pl --jitcapable
- # This was discussed in RT #43145 (which has been resolved).
- if ( $self->{jit_is_working}->{$cpuarch} ) {
- $jitcapable = 1;
- }
-
- # Can only jit double. For long double see patch in TT #352.
- # float not yet planned.
- if ( $nvsize != 8 ) {
- $jitcapable = 0;
- }
-
- # Another exception
- if ( $cpuarch eq 'i386' && $osname eq 'darwin' ) {
- $jitcapable = 0;
- }
- }
- return $jitcapable;
-}
-
-sub _handle_asm {
- my $arg = shift;
- my $sjit = "$arg->{jitbase}/$arg->{cpuarch}/$arg->{jitarchname}.s";
- my $asm = "$arg->{jitbase}/$arg->{cpuarch}/asm.s";
- if ( -e $sjit ) {
- copy_if_diff( $sjit, "src/asmfun.S" );
- $arg->{conf}->data->set( asmfun_o => 'src/asmfun$(O)' );
- }
- elsif ( -e $asm ) {
- copy_if_diff( $asm, "src/asmfun.S" );
- $arg->{conf}->data->set( asmfun_o => 'src/asmfun$(O)' );
- }
- else {
- $arg->{conf}->data->set( asmfun_o => '' );
- }
-}
-
-sub _first_probe_for_exec {
- my $self = shift;
- my ($jitcpuarch, $osname) = @_;
- my $execcapable = 0;
- if ( $self->{jitcpuarch_platforms}->{$jitcpuarch} ) {
- $execcapable = 1;
- unless ( $self->{execcapable_oses}->{$osname} ) {
- $execcapable = 0;
- }
- }
- return $execcapable;
-}
-
-sub _handle_execcapable {
- my ($conf, $execcapable) = @_;
- if ($execcapable) {
- my $cpuarch = $conf->data->get('cpuarch');
- $conf->data->set(
- TEMP_exec_h =>
-'$(SRC_DIR)/jit.h $(INC_DIR)/exec.h $(SRC_DIR)/exec_dep.h $(SRC_DIR)/exec_save.h',
- TEMP_exec_o =>
- '$(SRC_DIR)/exec$(O) $(SRC_DIR)/exec_cpu$(O) $(SRC_DIR)/exec_dep$(O) $(SRC_DIR)/exec_save$(O)',
- TEMP_exec_dep =>
- "\$(SRC_DIR)/exec_dep.c : \$(SRC_DIR)/jit/$cpuarch/exec_dep.c\n"
- . "\t\$(CP) \$(SRC_DIR)/jit/$cpuarch/exec_dep.c \$(SRC_DIR)/exec_dep.c",
- execcapable => 1
- );
- }
- else {
- $conf->data->set(
- TEMP_exec_h => '',
- TEMP_exec_o => '',
- TEMP_exec_dep => '',
- execcapable => 0,
- );
- }
+ $self->set_result('no');
return 1;
}
-sub _handle_exec_protect {
- my ($conf, $exec_protect_test, $verbose) = @_;
- if ($exec_protect_test) {
- $conf->data->set( has_exec_protect => 1 );
- print "yes) " if $verbose;
- }
- else {
- print "no) " if $verbose;
- }
-}
-
1;
# Local Variables:
Deleted: trunk/config/auto/jit/test_c.in
==============================================================================
--- trunk/config/auto/jit/test_c.in Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,53 +0,0 @@
-/*
-Copyright (C) 2002-2009, Parrot Foundation.
-$Id$
-
-test for the fcomip float instruction
-*/
-
-#include <stdio.h>
-
-/*
- * c equiv:
- int t(int i, int j) {
- return (double)i == (double)j;
-}
-*/
-
-/* this code leaves one op on the fp stack, but this shouldn't harm */
-
-char code[] = {
- 0x55, /* pushl %ebp */
- 0x89, 0xE5, /* movl %esp,%ebp */
- 0x83, 0xEC, 0x18, /* subl $24,%esp */
- 0xDB, 0x45, 0x08, /* fildl 8(%ebp) */
- 0xDB, 0x45, 0x0C, /* fildl 12(%ebp)*/
- 0xDF, 0xE9, /* fucomip */
- 0x0F, 0x94, 0xC0, /* sete %al */
- 0x31, 0xD2, /* xorl %edx,%edx */
- 0x88, 0xC2, /* movb %al,%dl */
- 0x89, 0xD0, /* movl %edx,%eax */
- 0x89, 0xEC, /* movl %ebp,%esp */
- 0x5D, /* popl %ebp */
- 0xC3 /* ret */
-};
-
-typedef int (*pf)(int, int);
-
-int
-main()
-{
- pf t = (pf) code;
- if (t(10, 10) && !t(10, 20))
- puts("ok");
- else
- return 1;
- return 0;
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/config/auto/jit/test_exec_cygwin_c.in
==============================================================================
--- trunk/config/auto/jit/test_exec_cygwin_c.in Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,76 +0,0 @@
-/*
-Copyright (C) 2008-2009, Parrot Foundation.
-$Id$
-
-test for exec privs
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <limits.h>
-#include <errno.h>
-#include <malloc.h>
-#include <unistd.h>
-#include <string.h>
-#ifndef PAGE_SIZE
-# define PAGE_SIZE getpagesize()
-#endif
-#
-
-/*
- * c equiv:
- int t() {
- return 1;
-}
-*/
-
-char code[] = {
- 0xB8, 0x01, 0, 0, 0, /* movl $1, %eax */
- 0xC3 /* ret */
-};
-
-typedef int (*pf)(void);
-
-int
-main(int argc, char *argv[])
-{
- pf t;
- char *p;
- int rc;
- int prot = PROT_READ;
-
- if (argc != 2) {
- fprintf(stderr, "usage: test 0 | 1\n");
- exit(1);
- }
-
- if (atoi(argv[1]))
- prot |= PROT_EXEC;
-
- p = memalign(PAGE_SIZE, PAGE_SIZE);
- memcpy(p, code, sizeof (code));
-
- t = (pf) p;
- rc = mprotect(p, PAGE_SIZE, prot);
-
- if (rc) {
- fprintf(stderr, "p = %p PAGE_SIZE = %d (0x%x)\n", p,
- PAGE_SIZE, PAGE_SIZE);
- perror("failure");
- }
-
- if (t() == 1)
- puts("ok");
- else
- return 1;
-
- return 0;
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/config/auto/jit/test_exec_linux_c.in
==============================================================================
--- trunk/config/auto/jit/test_exec_linux_c.in Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,71 +0,0 @@
-/*
-Copyright (C) 2004-2009, Parrot Foundation.
-$Id$
-
-test for exec privs
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <limits.h>
-#include <errno.h>
-#include <malloc.h>
-#include <unistd.h>
-#ifndef PAGE_SIZE
-# define PAGE_SIZE getpagesize()
-#endif
-
-/*
- * c equiv:
- int t() {
- return 1;
-}
-*/
-
-char code[] = {
- 0xB8, 0x01, 0, 0, 0, /* movl $1, %eax */
- 0xC3 /* ret */
-};
-
-typedef int (*pf)(void);
-
-int
-main(int argc, char *argv[])
-{
- pf t;
- char *p;
- int rc;
- int prot = PROT_READ;
-
- if (argc != 2) {
- fprintf(stderr, "usage: test 0 | 1\n");
- exit(1);
- }
- if (atoi(argv[1]))
- prot |= PROT_EXEC;
-
- p = memalign(PAGE_SIZE, sizeof (code));
- memcpy(p, code, sizeof (code));
- t = (pf) p;
- rc = mprotect(p, PAGE_SIZE, prot);
- if (rc) {
- fprintf(stderr, "p = %p PAGE_SIZE = %d (0x%x)\n", p,
- PAGE_SIZE, PAGE_SIZE);
- perror("failure");
- }
-
- if (t() == 1)
- puts("ok");
- else
- return 1;
-
- return 0;
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/config/auto/jit/test_exec_openbsd_c.in
==============================================================================
--- trunk/config/auto/jit/test_exec_openbsd_c.in Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,71 +0,0 @@
-/*
-Copyright (C) 2004-2009, Parrot Foundation.
-$Id$
-
-test for exec privs
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <limits.h>
-#include <errno.h>
-#include <malloc.h>
-#include <unistd.h>
-#ifndef PAGE_SIZE
-# define PAGE_SIZE sysconf(_SC_PAGESIZE)
-#endif
-
-/*
- * c equiv:
- int t() {
- return 1;
-}
-*/
-
-char code[] = {
- 0xB8, 0x01, 0, 0, 0, /* movl $1, %eax */
- 0xC3 /* ret */
-};
-
-typedef int (*pf)(void);
-
-int
-main(int argc, char *argv[])
-{
- pf t;
- char *p;
- int rc;
- int prot = PROT_READ;
-
- if (argc != 2) {
- fprintf(stderr, "usage: test 0 | 1\n");
- exit(1);
- }
- if (atoi(argv[1]))
- prot |= PROT_EXEC;
-
- p = malloc(PAGE_SIZE);
- memcpy(p, code, sizeof (code));
- t = (pf) p;
- rc = mprotect(p, PAGE_SIZE, prot);
- if (rc) {
- fprintf(stderr, "p = %p PAGE_SIZE = %d (0x%x)\n", p,
- PAGE_SIZE, PAGE_SIZE);
- perror("failure");
- }
-
- if (t() == 1)
- puts("ok");
- else
- return 1;
-
- return 0;
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Modified: trunk/config/gen/makefiles/root.in
==============================================================================
--- trunk/config/gen/makefiles/root.in Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/config/gen/makefiles/root.in Sat Sep 19 08:10:11 2009 (r41356)
@@ -103,7 +103,7 @@
CC_INC := @cc_inc@
C_LIBS := @libs@
CC_SHARED := @cc_shared@
-CFLAGS := $(CC_INC) @ccflags@ @cc_debug@ @ccwarn@ @cc_hasjit@ @cg_flag@ @gc_flag@ @clock_best@ $(CC_SHARED)
+CFLAGS := $(CC_INC) @ccflags@ @cc_build_call_frames@ @cc_debug@ @ccwarn@ @cg_flag@ @gc_flag@ @clock_best@ $(CC_SHARED)
LINK_DYNAMIC := @link_dynamic@
LINK := @link@
LINKFLAGS := @linkflags@ @link_debug@ @ld_debug@
@@ -111,7 +111,6 @@
LDFLAGS := @ldflags@ @ld_debug@
RECONFIGURE := $(PERL) tools/dev/reconfigure.pl
INNO_SETUP := iscc
-JIT_BUILD_TOOL := $(BUILD_TOOLS_DIR)/jit2c.pl
TEMPDIR := @tempdir@
#IF(darwin):export MACOSX_DEPLOYMENT_TARGET := @osx_version@
@@ -247,12 +246,9 @@
$(SRC_DIR)/core_ops.c \
$(SRC_DIR)/nci.c \
$(SRC_DIR)/core_ops_switch.c \
- $(SRC_DIR)/jit_cpu.c \
$(SRC_DIR)/parrot_config.c \
$(SRC_DIR)/null_config.c \
$(SRC_DIR)/install_config.c \
- $(SRC_DIR)/exec_cpu.c \
- $(SRC_DIR)/jit_defs.c \
$(SRC_DIR)/extend_vtable.c
GEN_MODULES := \
@@ -322,14 +318,11 @@
$(LIBRARY_DIR)/libpcre.pbc \
$(LIBRARY_DIR)/postgres.pbc
-# the dependencies of $(SRC_DIR)/jit_emit.h are done explicitly
-# including this file in GEN_HEADERS causes unnecessary recompile of all
FLUID_FILES_1 := \
$(GEN_OPSFILES) \
$(GEN_HEADERS) \
$(GEN_SOURCES) \
$(GEN_MODULES) \
- $(SRC_DIR)/jit_emit.h
FLUID_FILES_2 := \
$(GEN_LIBRARY) \
@@ -446,6 +439,7 @@
$(SRC_DIR)/longopt$(O) \
$(SRC_DIR)/misc$(O) \
$(SRC_DIR)/multidispatch$(O) \
+ $(SRC_DIR)/frame_builder$(O) \
$(SRC_DIR)/nci$(O) \
$(SRC_DIR)/oo$(O) \
$(SRC_DIR)/packfile$(O) \
@@ -470,11 +464,8 @@
\
$(PF_DIR)/pf_items$(O) \
\
- @asmfun_o@ \
@TEMP_cg_o@ \
- @TEMP_exec_o@ \
@TEMP_atomic_o@ \
- @TEMP_jit_o@ \
@TEMP_gc_o@ \
#IF(platform_asm): $(SRC_DIR)/platform_asm$(O) \
@@ -627,6 +618,7 @@
$(SRC_DIR)/key.str \
$(SRC_DIR)/library.str \
$(SRC_DIR)/multidispatch.str \
+ $(SRC_DIR)/frame_builder.str \
$(SRC_DIR)/nci.str \
$(SRC_DIR)/packfile.str \
$(SRC_DIR)/pmc.str \
@@ -1067,30 +1059,9 @@
$(SRC_DIR)/library$(O) : $(GENERAL_H_FILES)
-$(SRC_DIR)/jit$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/jit_emit.h $(SRC_DIR)/pmc/pmc_sub.h $(SRC_DIR)/pmc/pmc_managedstruct.h
-
-$(SRC_DIR)/jit_debug$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/debug.str
-
-$(SRC_DIR)/jit_debug_xcoff$(O) : $(GENERAL_H_FILES)
-
-$(SRC_DIR)/jit_cpu$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/jit_emit.h
-
-$(SRC_DIR)/exec$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
-
-$(SRC_DIR)/exec_dep$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h $(SRC_DIR)/pmc/managedstruct.c
-
-$(SRC_DIR)/exec_cpu$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
-
-$(SRC_DIR)/jit_defs$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h \
- $(SRC_DIR)/pmc/pmc_fixedintegerarray.h $(SRC_DIR)/pmc/pmc_unmanagedstruct.h $(SRC_DIR)/pmc/pmc_pointer.h
-
$(INC_DIR)/extend_vtable.h $(SRC_DIR)/extend_vtable.c $(SRC_DIR)/vtable.h : src/vtable.tbl $(BUILD_TOOLS_DIR)/vtable_extend.pl lib/Parrot/Vtable.pm
$(PERL) $(BUILD_TOOLS_DIR)/vtable_extend.pl
-$(SRC_DIR)/exec_start$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@
-
-$(SRC_DIR)/exec_save$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@
-
$(SRC_DIR)/key$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/key.str $(SRC_DIR)/pmc/pmc_key.h
$(SRC_DIR)/gc/mark_sweep$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/gc/gc_private.h
@@ -1208,10 +1179,13 @@
$(SRC_DIR)/exit$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/exit.c
$(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str \
+ $(SRC_DIR)/frame_builder$(O) \
$(SRC_DIR)/pmc/pmc_managedstruct.h \
$(SRC_DIR)/pmc/pmc_nci.h \
$(SRC_DIR)/pmc/pmc_pointer.h
+$(SRC_DIR)/frame_builder$(O) : $(SRC_DIR)/frame_builder.h $(GENERAL_H_FILES) $(SRC_DIR)/frame_builder.c $(SRC_DIR)/frame_builder.str
+
$(SRC_DIR)/vtables$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/vtables.c
$(SRC_DIR)/gc/system$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/gc/gc_private.h
@@ -1282,21 +1256,6 @@
$(INC_DIR)/vtable.h : src/vtable.tbl $(BUILD_TOOLS_DIR)/vtable_h.pl lib/Parrot/Vtable.pm
$(PERL) $(BUILD_TOOLS_DIR)/vtable_h.pl
-$(SRC_DIR)/jit_emit.h : $(SRC_DIR)/jit/@jitcpuarch@/jit_emit.h
- $(CP) $(SRC_DIR)/jit/@jitcpuarch@/jit_emit.h $(SRC_DIR)/jit_emit.h
-$(SRC_DIR)/exec_dep.h : $(SRC_DIR)/jit/@jitcpuarch@/exec_dep.h
- $(CP) $(SRC_DIR)/jit/@jitcpuarch@/exec_dep.h $(SRC_DIR)/exec_dep.h
-$(SRC_DIR)/jit_cpu.c : lib/Parrot/OpLib/core.pm $(SRC_DIR)/jit_emit.h \
- $(SRC_DIR)/jit/@jitcpuarch@/core.jit $(JIT_BUILD_TOOL)
- $(PERL) $(JIT_BUILD_TOOL) @jitcpuarch@ $(SRC_DIR)/jit_cpu.c
-$(SRC_DIR)/jit_defs.c : $(SRC_DIR)/jit/@jitcpuarch@/jit_emit.h \
- $(SRC_DIR)/jit/@jitcpuarch@/jit_defs.c
- $(CP) $(SRC_DIR)/jit/@jitcpuarch@/jit_defs.c $(SRC_DIR)/jit_defs.c
-$(SRC_DIR)/exec_cpu.c : lib/Parrot/OpLib/core.pm $(SRC_DIR)/jit_emit.h \
- $(SRC_DIR)/jit/@jitcpuarch@/core.jit @TEMP_exec_h@ $(SRC_DIR)/exec_dep.h $(JIT_BUILD_TOOL)
- $(PERL) $(JIT_BUILD_TOOL) @jitcpuarch@ $(SRC_DIR)/exec_cpu.c
- at TEMP_exec_dep@
-
# imcc file dependencies
#
# The .flag files are needed because we keep some derived files in SVN,
@@ -1672,7 +1631,6 @@
$(SRC_DIR)/null_config$(O) \
$(SRC_DIR)/parrot_config$(O) \
$(SRC_DIR)/install_config$(O) \
- $(SRC_DIR)/exec_start$(O) \
$(SRC_DIR)/nci_test$(O) \
$(LIBNCI_TEST_SO) \
$(SRC_DIR)/glut_callbacks$(O) \
@@ -1708,12 +1666,6 @@
$(SRC_DIR)/null_config$(O) \
$(SRC_DIR)/parrot_config$(O) \
$(SRC_DIR)/install_config$(O) \
- $(SRC_DIR)/asmfun.s \
- $(SRC_DIR)/jit_emit.h \
- $(SRC_DIR)/jit_cpu.c \
- $(SRC_DIR)/exec_cpu.c \
- $(SRC_DIR)/jit_defs.c \
- $(SRC_DIR)/exec_start$(O) \
install_config.fpmc \
$(SRC_DIR)/nci_test$(O) \
$(LIBNCI_TEST_SO) \
@@ -1884,7 +1836,7 @@
sunlint :
rm -f *.ln
- $(SUNLINT) $(CC_INC) @cc_hasjit@ "-Isrc/pmc" $(SUNLINTOPTS) $(LINTABLE_CFILES)
+ $(SUNLINT) $(CC_INC) "-Isrc/pmc" $(SUNLINTOPTS) $(LINTABLE_CFILES)
BSD_LINT_FLAGS := -a -aa -b -c -e -h -n -p -r -u -x -z -F -H -V
@@ -2044,7 +1996,7 @@
splint-all : $(PARROT)
$(MKPATH) $(SPLINT_TMP)
- $(SPLINT) $(CC_INC) @cc_hasjit@ "-Isrc/pmc" "-Icompilers/ast" $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) \
+ $(SPLINT) $(CC_INC) "-Isrc/pmc" "-Icompilers/ast" $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) \
$(SPLINT_SOURCE) \
$(SPLINT) $(CC_INC) $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) $(IMCC_DIR)/main.c
@@ -2055,7 +2007,7 @@
splint : all
$(MKPATH) $(SPLINT_TMP)
- $(SPLINT) $(CC_INC) @cc_hasjit@ "-Isrc/pmc" "-Icompilers/ast" $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) \
+ $(SPLINT) $(CC_INC) "-Isrc/pmc" "-Icompilers/ast" $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) \
+partial -DNDEBUG \
$(SPLINT_SOURCE) \
| grep -v 'Source code error generation point'
@@ -2081,7 +2033,6 @@
#IF(cg_flag): cover-testC \
cover-testf \
#IF(cg_flag): cover-testg \
-#IF(jitcapable): cover-testj \
cover-testr \
cover-testS \
cover-src \
@@ -2202,8 +2153,8 @@
#
###############################################################################
-exec : $(SRC_DIR)/exec_start$(O) $(SRC_DIR)/parrot_config$(O) $(LIBPARROT)
- $(LINK) @ld_out@$(EXEC)$(EXE) $(EXEC)$(O) $(SRC_DIR)/exec_start$(O) $(SRC_DIR)/parrot_config$(O) @rpath_blib@ $(ALL_PARROT_LIBS) $(LINKFLAGS)
+exec : $(SRC_DIR)/parrot_config$(O) $(LIBPARROT)
+ $(LINK) @ld_out@$(EXEC)$(EXE) $(EXEC)$(O) $(SRC_DIR)/parrot_config$(O) @rpath_blib@ $(ALL_PARROT_LIBS) $(LINKFLAGS)
###### OS depend targets ##########
Modified: trunk/docs/book/draft/appc_command_line_options.pod
==============================================================================
--- trunk/docs/book/draft/appc_command_line_options.pod Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/docs/book/draft/appc_command_line_options.pod Sat Sep 19 08:10:11 2009 (r41356)
@@ -152,11 +152,6 @@
to check various optimizations when you run Parrot with the C<-Op>
switch.
-If the extension is F<.o> or equivalent, Parrot generates an object
-file from the JITed program code, which can be used to create a
-standalone executable program. This isn't available on all platforms
-yet; see F<PLATFORMS> for which platforms support this.
-
=item -r,--run-pbc
Immediately execute bytecode. This is the default unless C<-o> is
@@ -269,31 +264,14 @@
Run the I<computed goto core> (CGoto).
-=item -R jit
-
-Run with the I<JIT core> if available.
-
=item -R cgp
Run with the I<CGoto-Prederefed> core.
-=item -R cgp-jit
-
-Run with the I<CGoto-Prederefed with jit> core.
-
=item -R switch
Run with the I<Switched core>.
-=item -R switch-jit
-
-Run with the I<Switched core with jit>.
-
-=item -R exec
-
-Run with the I<exec core>
-(uses JIT at compile time to generate native code)
-
=item -R gcdebug
Performs a full GC run before every op dispatch
Modified: trunk/docs/debug.pod
==============================================================================
--- trunk/docs/debug.pod Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/docs/debug.pod Sat Sep 19 08:10:11 2009 (r41356)
@@ -80,76 +80,6 @@
One possible tool is C<parrot_debugger>, the Parrot Debugger.
See F<docs/debugger.pod> for details on it.
-=head2 stabs
-
-If you are running on a jit-capable machine, you can also try using C<gdb> by
-having the JIT compiler generate C<stabs> metadata and then stepping through
-the code with C<gdb> as if it were any other language.
-
-To use this, you'll want to use C<parrot> to generate your bytecode (.pbc
-file). It is not strictly necessary, but you'll get more information into the
-bytecode this way.
-
-Let's say your file is named C<test.pasm>. (Note: these instructions will also
-work if you use C<test.pir> everywhere C<test.pasm> occurs.)
-
-Step 1: Generate the .pbc file with extra debugging information.
-
- shell> parrot -d -o test.pbc test.pasm
-
-Step 2: Start up C<parrot> under C<gdb>
-
- % gdb parrot
-
-or
-
- % emacs &
- (in emacs) M-x gdb
- (in emacs) type "parrot" so it says "gdb parrot"
-
-Step 3: Set a breakpoint on runops_jit
-
- gdb> b runops_jit
-
-Step 4: Run your program under C<gdb> with JIT and debugging on
-
- gdb> run -R jit -D4 test.pbc
-
-Step 5: C<gdb> will stop at the beginning of runops_jit. Step through the lines
-until just before the JITed code is executed (the line will be something like
-C<(jit_code)(interpreter,pc)>.
-
- gdb> n
- gdb> n
- .
- .
- .
-
-Step 6: load in the debugging information from the symbol file that the jit
-just generated.
-
- gdb> add-symbol-file test.o 0
-
-Step 7: Step into the JITed code
-
- gdb> s
-
-At this point, you can step through the instructions, or print out the
-various Parrot registers. FIXME: C<gdb> will know about I0-I31,
-N0-N31, S0-S31, and P0-P31.
-
-
-WARNING: Stepping too far
-
-One thing to watch out for is that C<gdb> gets confused when attempting to step
-over certain instructions. The only ones that I have noticed having problems is
-keyed operations. With my version of C<gdb>, if I do 'n' to step over the
-instruction, C<gdb> will start running and only stop when the entire parrot
-program has finished. To work around this, do 'si' twice just before executing
-any keyed op. For some reason, C<gdb> can then figure out when it's supposed to
-stop next. If you know of a better technique, please let the mailing list know
-(C<parrot-dev at lists.parrot.org>).
-
=head1 PIR CODE GENERATION
The C<parrot> binary has a bunch of debugging flags for spewing out information
Modified: trunk/docs/dev/events.pod
==============================================================================
--- trunk/docs/dev/events.pod Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/docs/dev/events.pod Sat Sep 19 08:10:11 2009 (r41356)
@@ -82,15 +82,13 @@
handler replaces backward branches in the opcode image with the
B<check_events__> opcode.
-The JIT core doesn't handle events yet.
-
After all events are popped off and handled, the opcode dispatch table is
restored to its original, and the B<check_events__> reexecutes the same
instruction again, which is now the real one and thus normal execution flow
continues.
This scheme has zero overhead in the absence of scheduled events for all cores
-except switched and JIT.
+except switched.
=head1 Missing
Deleted: trunk/docs/dev/jit_i386.pod
==============================================================================
--- trunk/docs/dev/jit_i386.pod Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,299 +0,0 @@
-# Copyright (C) 2001-2006, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-docs/dev/jit_i386.pod - Parrot JIT (i386/gcc)
-
-=head1 ABSTRACT
-
-This PDD describes the i386 gcc JIT implementation.
-
-=head1 DESCRIPTION
-
-JIT i386/gcc is a combination of unrolled assembly instructions and the
-Computed Goto Predereferenced (CGP) run loop. For branch instructions the
-function implementation in the standard core is called.
-
-Another difference of JIT/i386 is that most vtable functions are JITed
-instructions which use register mappings.
-
-For a better understanding of the control flow between these basically 3 run
-loop cores, an example shows the gory details.
-
-=head1 EXAMPLE
-
-Given the following PASM program, the righthand three columns show where each
-opcode gets executed:
-
- PASM JIT ops Normal CGP ops
-
-=begin PASM
- # (call cgp_core) (jmp back)
-
- set I0, 10 # set_i_ic
- print I0 # (call) print_i
- print "\n" # print_sc
- new P1, 'ResizableIntegerArray'
- local_branch P0, inc # (call) local_branch_p_ic cpu_ret
- end # (jmp) HALT end (ret)
- # end (ret)
- inc:
- inc I0 # inc_i
- new P0, 'String' # new_p_sc
- set P0, I0 # set_p_i
- print P0 # (call) print_p
- print "\n" # print_sc
- local_return P1 # (call) local_return_p cpu_ret
-
-=end PASM
-
-=head2 Startup sequence
-
-In B<runops_jit> a prederefed copy of the opcode stream is built by
-B<init_prederef>. Then B<build_asm> generates the assembler code sequence as
-usual. This generated code (shown as B<runops_jit> in B<ddd>) is then executed.
-
-Generate minimal stack frame, save %ebx
-
- 0x812c510 <jit_func>: push %ebp
- 0x812c511 <jit_func+1>: mov %esp,%ebp
- 0x812c513 <jit_func+3>: push %ebx
-
-Get the program counter to %ebx
-
- 0x812c514 <jit_func+4>: mov 0xc(%ebp),%ebx
-
-Push B<interpreter> and B<(opcode_t*) 1> and call B<cgp_core>
-
- 0x812c517 <jit_func+7>: push $0x8113db8
- 0x812c51c <jit_func+12>: push $0x1
- 0x812c521 <jit_func+17>: mov $0x1,%eax
- 0x812c526 <jit_func+22>: call 0x80b5830 <cgp_core>
-
-In B<cgp_core> all callee saved registers are saved.
-
- 0x80b5830 <cgp_core>: push %ebp
- 0x80b5831 <cgp_core+1>: mov %esp,%ebp
- 0x80b5833 <cgp_core+3>: sub $0xdc,%esp
- 0x80b5839 <cgp_core+9>: lea 0x8(%ebp),%eax
- 0x80b583c <cgp_core+12>: push %edi
- 0x80b583d <cgp_core+13>: push %esi
- 0x80b583e <cgp_core+14>: push %ebx
-
-In B<%eax> the init flag is set to B<-1>
-
- 0x80b583f <cgp_core+15>: mov %eax,0xfffffff
-
-The parameter B<*cur_op> (the program counter) is put into B<%esi> and ...
-
- 0x80b5842 <cgp_core+18>: mov 0x8(%ebp),%esi
- 0x80b5845 <cgp_core+21>: test %esi,%esi
- 0x80b5847 <cgp_core+23>: jne 0x80b5853 <cgp_core+35>
- 0x80b5849 <cgp_core+25>: mov $0x810ca60,%eax
- 0x80b584e <cgp_core+30>: jmp 0x80bb470 <cgp_core+23616>
-
-... compared to B<1>
-
- 0x80b5853 <cgp_core+35>: cmp $0x1,%esi
- 0x80b5856 <cgp_core+38>: jne 0x80b5860 <cgp_core+48>
-
-If true, the program jumps to the return address of above function call, i.e.
-it jumps back again to JIT code.
-
- 0x80b5858 <cgp_core+40>: jmp *0x4(%ebp)
-
-Back again in JIT code, the init flag is checked
-
- 0x812c52b <jit_func+27>: test %eax,%eax
- 0x812c52d <jit_func+29>: jne 0x812c536 <jit_func+38>
-
-... and if zero, the function would be left.
-
- [ 0x812c52f <jit_func+31>: pop %ebx ]
- [ 0x812c531 <jit_func+33>: mov %ebp,%esp ]
- [ 0x812c533 <jit_func+35>: pop %ebp ]
- [ 0x812c535 <jit_func+37>: ret ]
-
-When coming from the init sequence, program flow continues by checking the
-B<resume_offset> and jumping to the desired instruction
-
- 0x812c536 <jit_func+38>: mov %ebx,%eax
- 0x812c538 <jit_func+40>: sub $0x400140c0,%eax
- 0x812c53e <jit_func+46>: mov $0x812c4a8,%edx
- 0x812c543 <jit_func+51>: jmp *(%edx,%eax,1)
-
-B<set I0, 10> and save_registers
-
- 0x812c546 <jit_func+54>: mov $0xa,%ebx
- 0x812c54b <jit_func+59>: mov %ebx,0x8113db8
-
-Now non-JITed code follows -- get the address from the prederefed op_func_table
-and call it:
-
- 0x812c551 <jit_func+65>: mov $0x812ac0c,%esi
- 0x812c556 <jit_func+70>: call *(%esi)
-
- inline op print(in INT) {
- printf(INTVAL_FMT, (INTVAL)$1);
- goto NEXT();
- }
-
-where the B<goto NEXT()> is a simple:
-
- 0x80b5b49 <cgp_core+793>: jmp *(%esi)
-
- op print(in STR) {
- ...
- goto NEXT();
- }
-
-As the last instruction of the non-JITed code sequence is a branch, this is not
-executed in CGP, but the opcode:
-
- inline op cpu_ret() {
- #ifdef __GNUC__
- # ifdef I386
- asm("ret")
-
-is executed. This opcode is patched into the prederefed code stream by
-Parrot_jit_normal_op at the end of a non-JITed code sequence. This returns to
-JIT code again, where the next instruction gets called as a function in the
-standard core ...
-
- 0x812c558 <jit_func+72>: push $0x8113db8
- 0x812c55d <jit_func+77>: push $0x400140dc
- 0x812c562 <jit_func+82>: call 0x805be60 <Parrot_bsr_ic>
- 0x812c567 <jit_func+87>: add $0x8,%esp
-
-... and from the return result in B<%eax>, the new code position in JIT is
-calculated and gets jumped to:
-
- 0x812c56a <jit_func+90>: sub $0x400140c0,%eax
- 0x812c570 <jit_func+96>: mov $0x812c4a8,%edx
- 0x812c575 <jit_func+101>: jmp *(%edx,%eax,1)
-
-Now in the subroutine B<inc>:
-
- 0x812c580 <jit_func+112>: mov 0x8113db8,%ebx
- 0x812c586 <jit_func+118>: inc %ebx
-
-Save register and arguments and call B<pmc_new_noinit>:
-
- 0x812c587 <jit_func+119>: push %edx
- 0x812c588 <jit_func+120>: push $0x11
- 0x812c58d <jit_func+125>: push $0x8113db8
- 0x812c592 <jit_func+130>: call 0x806fc60 <pmc_new_noinit>
-
-put the PMC* into Parrot's register:
-
- 0x812c597 <jit_func+135>: mov %eax,0x8113fb8
-
-and prepare arguments for a VTABLE call:
-
- 0x812c59d <jit_func+141>: push %eax
- 0x812c59e <jit_func+142>: push $0x8113db8
- 0x812c5a3 <jit_func+147>: mov 0x10(%eax),%eax
- 0x812c5a6 <jit_func+150>: call *0x18(%eax)
- 0x812c5a9 <jit_func+153>: add $0x10,%esp
- 0x812c5ac <jit_func+156>: pop %edx
-
-and another one:
-
- 0x812c5ae <jit_func+158>: push %edx
-
-Here, with the mapped register in B<%ebx>, push B<I0>, the PMC and the
-interpreter:
-
- 0x812c5af <jit_func+159>: push %ebx
- 0x812c5b0 <jit_func+160>: mov 0x8113fb8,%eax
- 0x812c5b6 <jit_func+166>: push %eax
- 0x812c5b7 <jit_func+167>: push $0x8113db8
-
-and call the vtable:
-
- 0x812c5bc <jit_func+172>: mov 0x10(%eax),%eax
- 0x812c5bf <jit_func+175>: call *0xdc(%eax)
- 0x812c5c5 <jit_func+181>: add $0xc,%esp
- 0x812c5c8 <jit_func+184>: pop %edx
-
-As this ends the JITed section, used registers are saved back to Parrot's
-register:
-
- 0x812c5ca <jit_func+186>: mov %ebx,0x8113db8
-
-and again the code in B<cgp_core> gets called:
-
- 0x812c5d0 <jit_func+192>: mov $0x812ac48,%esi
- 0x812c5d5 <jit_func+197>: call *(%esi)
-
-which after executing the B<print> returns back here in JIT, where the B<ret>
-is called:
-
- 0x812c5d7 <jit_func+199>: push $0x8113db8
- 0x812c5dc <jit_func+204>: push $0x40014118
- 0x812c5e1 <jit_func+209>: call 0x805d5e0 <Parrot_ret>
- 0x812c5e6 <jit_func+214>: add $0x8,%esp
-
-From the returned PC a JIT address is calculated, which gets executed:
-
- 0x812c5e9 <jit_func+217>: sub $0x400140c0,%eax
- 0x812c5ef <jit_func+223>: mov $0x812c4a8,%edx
- 0x812c5f4 <jit_func+228>: jmp *(%edx,%eax,1)
-
-Now at the B<end> opcode, the CGP code for HALT() gets jumped to:
-
- 0x812c578 <jit_func+104>: mov $0x80b5877,%esi
- 0x812c57d <jit_func+109>: jmp *%esi
-
-which is:
-
- inline op end() {
- HALT();
- }
-
-or, set return result:
-
- 0x80b8b6f <cgp_core+13119>: xor %eax,%eax
- ...
-
-and clean up stack frame and ret:
-
- 0x80bb470 <cgp_core+23616>: lea 0xffffff18(%ebp),%esp
- 0x80bb476 <cgp_core+23622>: pop %ebx
- 0x80bb477 <cgp_core+23623>: pop %esi
- 0x80bb478 <cgp_core+23624>: pop %edi
- 0x80bb479 <cgp_core+23625>: mov %ebp,%esp
- 0x80bb47b <cgp_core+23627>: pop %ebp
- 0x80bb47c <cgp_core+23628>: ret
-
-This returns after the position where B<cgp_core> was called during the init
-sequence, but now the return value B<%eax> is zero and the..
-
- 0x812c52b <jit_func+27>: test %eax,%eax
- 0x812c52d <jit_func+29>: jne 0x812c536 <jit_func+38>
- 0x812c52f <jit_func+31>: pop %ebx
- 0x812c531 <jit_func+33>: mov %ebp,%esp
- 0x812c533 <jit_func+35>: pop %ebp
- 0x812c535 <jit_func+37>: ret
-
-... whole story ends here, we are back again in B<runops_jit>.
-
-So this is rather simple once it gets going.
-
-=head1 BUGS
-
-The floating point registers do not get saved to Parrot before vtable calls.
-This assumes that external routines preserve the FP stack pointer and don't use
-more the 4 floating point registers at once.
-
-=head1 AUTHOR
-
-Leopold Toetsch C<lt at toetsch.at>
-
-=head1 VERSION
-
-=head2 CURRENT
-
-14.02.2003 by Leopold Toetsch
-
Deleted: trunk/docs/jit.pod
==============================================================================
--- trunk/docs/jit.pod Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,587 +0,0 @@
-# Copyright (C) 2001-2006, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-docs/jit.pod - Parrot JIT Subsystem
-
-=head1 ABSTRACT
-
-This PDD describes the Parrot Just In Time compilation subsystem.
-
-=head1 DESCRIPTION
-
-The Just In Time, or JIT, subsystem converts a bytecode file to native machine
-code instructions and executes the generated instruction sequence directly.
-
-=head1 IMPLEMENTATION
-
-Currently works on B<ALPHA>, B<Arm>, B<Intel x86>, B<PPC>, and B<SPARC version
-8> processor systems, on most operating systems. Currently only 32-bit INTVALs
-are supported.
-
-The initial step in generating native code is to invoke B<Parrot_jit_begin>,
-which generally provides architecture specific preamble code. For each parrot
-opcode in the bytecode, either a generic or opcode specific sequence of native
-code is generated. The F<.jit> files provide functions that generate native
-code for specific opcode functions, for a given instruction set architecture.
-If a function is not provided for a specific opcode, a generic sequence of
-native code is output which calls the interpreter C function that implements
-the opcode. Such opcode are handled by B<Parrot_jit_normal_op>.
-
-If the opcode can cause a control flow change, as in the case of a branch or
-call opcode, an extended or modified version of this generic code is used that
-tracks changes in the bytecode program counter with changes in the hardware
-program counter. This type of opcode is handled by B<Parrot_jit_cpcf_op>.
-
-While generating native code, certain offsets and absolute addresses may not be
-available. This occurs with forward opcode branches, as the native code
-corresponding to the branch target has not yet been generated. On some
-platforms, function calls are performed using program-counter relative
-addresses. Since the location of the buffer holding the native code may move
-as code is generated (due to growing of the buffer), these relative addresses
-may only be calculated once the buffer is guaranteed to no longer move. To
-handle these instances, the JIT subsystem uses "fixups", which record locations
-in native code where adjustments to the native code are required.
-
-=head1 FILES
-
-=over 4
-
-=item jit/${jitcpuarch}/jit_emit.h
-
-This file defines B<Parrot_jit_begin>, B<Parrot_jit_dofixup>,
-B<Parrot_jit_normal_op>, B<Parrot_jit_cpcf_op>, B<Parrot_jit_restart_op> and
-optionally B<Parrot_jit_vtable*_op>. In addition, this file defines the macros
-and static functions used in F<.jit> files to produce binary representations of
-native instructions.
-
-For moving registers from processor to parrot and vice versa, the
-B<Parrot_jit_emit_mov*> functions have to be implemented.
-
-=item jit/${jitcpuarch}/core.jit
-
-The functions to generate native code for core parrot opcodes are specified
-here. To simplify the maintenance of these functions, they are specified in a
-format that is pre-processed by F<jit2c.pl> to produce a valid C source file,
-F<jit_cpu.c>. See L<Format of .jit Files> below.
-
-=item src/jit.h
-
-This file contains definitions of generic structures used by the JIT subsystem.
-
-The B<op_jit> array of B<jit_fn_info_t> structures, provides for each opcode, a
-pointer to the function that generates native code for the opcode, whether the
-generic B<Parrot_jit_normal_op> or B<Parrot_jit_cpcf_op> functions or an opcode
-specific function. B<Parrot_jit_restart_op> is like B<Parrot_jit_cpcf_op> with
-the addition to check for a zero program counter. The B<Parrot_jit_vtable*_op>
-functions are defined as B<Parrot_jit_normal_op> or B<Parrot_jit_cpcf_op> and
-may be implemented to do native vtable calls (s. F<jit/i386/jit_emit.h> for an
-example).
-
-The B<Parrot_jit_fixup> structure records the offset in native code where a
-fixup must be applied, the type of fixup required and the specific information
-needed to perform the parameters of the fixup. Currently, a fixup parameter is
-either an B<opcode_t> value or a function pointer.
-
-The B<Parrot_jit_info> structure holds data used while producing and executing
-native code. An important piece of data in this structure is the B<op_map>
-array, which maps from opcode addresses to native code addresses.
-
-=item src/jit.c
-
-B<parrot_build_asm>() is the main routine of the code generator, which loops
-over the parrot bytecode, calling the code generating routines for each opcode
-while filling in the B<op_map> array. This array is used by the JIT subsystem
-to perform certain types of fixups on native code, as well as by the native
-code itself to convert bytecode program counters values (opcode_t *'s) to
-hardware program counter values.
-
-The bytecode is considered an array of B<opcode_t> sized elements, with
-parallel entries in B<op_map>. B<op_map> is initially populated with the
-offsets into the native code corresponding to the opcodes in the bytecode. Once
-code generation is complete and fixups have been applied, the native code
-offsets are converted to absolute addresses. This trades the low up-front cost
-of converting all offsets once, for the unknown cost of repeatedly converting
-these offsets while executing native code.
-
-See F<src/jit/skeleton/jit_emit.h> for details.
-
-=item tools/build/jit2c.pl
-
-Preprocesses the .jit files to produce F<jit_cpu.c>.
-
-=back
-
-=head1 Defines in jit_emit.h
-
-The architecture specific F<jit_emit.h> file communicates some defines and
-tables with F<jit.c> and F<languages/imcc/imc.c>. The structure of the file and
-the defines must therefore follow a specific syntax.
-
-=head2 Overall structure
-
- #if JIT_EMIT
-
- ... emit code
-
- #else
-
- ... defines
- static const jit_arch_info arch_info = {
- ... initialization of maps
- ... and possibly private static functions
- }
-
- #endif
-
-See F<src/jit/skeleton/jit_emit.h> for a more detailed explanation.
-
-=head2 Defines
-
-XXX most are moved into C<jit_arch_info> now.
-
-=over 4
-
-=item INT_REGISTERS_TO_MAP
-
-This is the amount of integer registers to be mapped to processor registers.
-The corresponding B<intval_map[]> has to have exactly this amount of register
-numbers. A register with the value of zero can not be in the list.
-
-=item FLOAT_REGISTERS_TO_MAP
-
-When this is defined, it works like above for floating point registers.
-
-=item PRESERVED_INT_REGS
-
-When this is defined, it's the amount of integer registers, that are preserved
-over function calls. These preserved registers have to be first in
-B<intval_map>. When this is not defined, it is assumed that B<all> registers
-are preserved over function calls.
-
-=item PRESERVED_FLOAT_REGS
-
-Same for floating point registers.
-
-=item jit_emit_noop(pc)
-
-=item JUMP_ALIGN
-
-If these are defined, B<JUMP_ALIGN> should be a small number stating the
-desired alignment of jump targets is B<1 << JUMP_ALIGN>. The B<jit_emit_noop>
-gets called with the unaligned B<pc> repeatedly, until the B<pc> has the
-desired alignment. So the function can either emit a one byte B<noop>
-instruction, or a B<noop> like instruction (sequence) with the desired size, to
-achieve the necessary padding. The emitted code must not have any side
-effects.
-
-=item ALLOCATE_REGISTERS_PER_SECTION
-
-Normally F<jit.c> does register allocation per section, but there is a somewhat
-experimental feature, to allocate registers per basic block.
-
-=item MAP
-
-Jit code generated by the F<imcc> JIT optimizer used negative numbers for
-mapped registers and positive numbers for non mapped parrot registers. To use
-this feature, the definition of mapped registers can be redefined like so:
-
- #define MAP(i) OMAP(i)
- #undef MAP
- #define MAP(i) (i) >= 0 ? 0 : OMAP(i)
-
-=item Parrot_jit_emit_get_base_reg_no(pc)
-
-This macro should return the register number of the register
-base pointer.
-
-=back
-
-See F<src/jit/i386/jit_emit.h> for actual usage of these defines.
-
-=head1 Format of .jit Files
-
-Jit files are interpreted as follows:
-
-=over 4
-
-=item I<op-name> { \n I<body> \n }
-
-Where I<op-name> is the name of the Parrot opcode, and I<body> consists of C
-syntax code which may contain any of the identifiers listed in the following
-section.
-
-The closing curly brace has to be in the first column.
-
-=item Comment lines
-
-Comments are marked with a I<;> in the first column. These and empty lines are
-ignored.
-
-=item Identifiers
-
-In general, prefixing an identifier with I<&> yields an address. The I<*>
-prefix specifies a value. Since Parrot register values vary during code
-execution, their values can not be obtained through identifier substitution
-alone, therefore offsets are used for accessing registers.
-
-To obtain register offsets, a set of macros exists, that have C<OFFS> in
-their names:
-
-B<REG_OFFS_INT(reg_no)> ...
-
-B<ROFFS_INT(n)> ...
-
-B<INT_CONST[n]>
-
-Gets replaced by the C<INTVAL> constant specified in the I<n>th argument.
-
-B<NUM_CONST[n]>
-
-Gets replaced by the C<FLOATVAL> constant specified in the I<n>th argument.
-
-B<MAP[n]>
-
-The I<n>th integer or floating processor register, mapped in this section.
-
-Note: The register with the physical number zero can not be mapped.
-
-=begin unimp
-
-B<STRING_CONST_strstart[n]>
-
-Gets replaced by C<strstart> of the C<STRING> constant specified in the I<n>th
-argument.
-
-B<STRING_CONST_buflen[n]>
-
-Gets replaced by C<buflen> of the C<STRING> constant specified in the I<n>th
-argument.
-
-B<STRING_CONST_flags[n]>
-
-Gets replaced by C<flags> of the C<STRING> constant specified in the I<n>th
-argument.
-
-B<STRING_CONST_strlen[n]>
-
-Gets replaced by C<strlen> of the C<STRING> constant specified in the I<n>th
-argument.
-
-B<STRING_CONST_encoding[n]>
-
-Gets replaced by C<encoding> of the C<STRING> constant specified in the I<n>th
-argument.
-
-B<STRING_CONST_type[n]>
-
-Gets replaced by C<type> of the C<STRING> constant specified in the I<n>th
-argument.
-
-B<STRING_CONST_language[n]>
-
-Gets replaced by C<language> of the C<STRING> constant specified in the I<n>th
-argument.
-
-=end unimp
-
-B<NATIVECODE>
-
-Gets replaced by the current native program counter.
-
-B<*CUR_OPCODE[n]>
-
-Gets replaced by the address of the current opcode in the Parrot bytecode.
-
-B<ISRn> B<FSRn>
-
-The I<n>th integer or floating point scratch register.
-
-
-=item B<TEMPLATE> I<template-name> { \n I<body> \n }
-
-Defines a template for similar functions, e.g. all the binary ops taking three
-variable parameters.
-
-=item I<template-name> I<perl-subst> ...
-
-Take a template and do all substitutions to generate the implementation for
-this jit function.
-
-Example:
-
- TEMPLATE Parrot_set_x_ic {
- if (MAP[1]) {
- jit_emit_mov_ri<_N>(NATIVECODE, MAP[1], <typ>_CONST[2]);
- }
- else {
- jit_emit_mov_mi<_N>(NATIVECODE, &INT_REG[1], <typ>_CONST[2]);
- }
- }
-
- Parrot_set_i_ic {
- Parrot_set_x_ic s/<_N>/_i/ s/<typ>/*INT/
- }
-
- Parrot_set_n_ic {
- Parrot_set_x_ic s/<_N>/_ni/ s/<typ>/&INT/ s/INT_R/NUM_R/
- }
-
-The jit function B<Parrot_set_i_ic> is based on the template
-B<Parrot_set_x_ic>, the I<s/x/y/> are substitutions on the template body, to
-generate the actual function body. These substitutions are done before the
-other substitutions.
-
-s. F<jit/i386/core.jit> for more.
-
-=back
-
-=head2 Naming convention for jit_emit functions
-
-To make it easier to share F<core.jit> files between machines of similar
-architecture, the jit_emit functions B<should> follow this syntax:
-
-jit_emit_I<<op>>_I<<args>>_I<<type>>
-
-=over 4
-
-=item I<<op>>
-
-This is the operation like B<mov>, B<add> or B<bxor>. In normal cases this is
-the PASM name of the op.
-
-=item I<<args>>
-
-B<args> specify the arguments of the function in the PASM sequence B<dest>,
-B<source> ... The B<args> consist of one letter per argument:
-
-=over 4
-
-=item B<r>
-
-A mapped processor register.
-
-=item B<m>
-
-A memory operand, the address of the parrot register.
-
-=item B<i>
-
-An immediate operand, i.e. an integer constant.
-
-=back
-
-=item I<<type>>
-
-Specifies if this operation works on integer or floating point arguments. If
-all arguments are of the same type, only one type specifier is needed.
-
-=over 4
-
-=item B<i>
-
-An integer argument
-
-=item B<n>
-
-A float argument.
-
-=back
-
-Examples:
-
-=over 4
-
-=item B<jit_emit_sub_rm_i>
-
-Subtract integer at memory from integer processor register.
-
-=item B<jit_emit_mov_ri_ni>
-
-Move integer constant (immediate) to floating point register.
-
-=back
-
-=back
-
-=head1 ALPHA Notes
-
-The access to Parrot registers is done relative to C<$6>, all other memory
-access is done relative to C<$27>, to access float constants relative to C<$7>
-so you must preside the instruction with I<ldah $7,0($27)>.
-
-=head1 i386 Notes
-
-Only 32 bit INTVALs are supported. Long double FLOATVALs are ok.
-
-There are four mapped integer registers B<%edi>, B<%esi>, B<%ecx>, and B<%edx>.
-The first 2 of these are callee saved, they preserve their value around extern
-function calls.
-
-Four floating point operations the registers B<ST1> ... B<ST4> are mapped and
-considered as preserved over function calls.
-
-The register C<%ebx> holds the register frame pointer.
-
-=head1 EXAMPLE
-
-Let's see how this works:
-
-B<Parrot Assembly:>
-
- set I0,8
- set I2,I0
- print I2
- end
-
-B<Parrot Bytecode:> (only the bytecode segment is shown)
-
- +--------------------------------------+
- | 73 | 0 | 8 | 72 | 2 | 0 | 21 | 2 | 0 |
- +-|------------|------------|--------|-+
- | | | |
- | | | +----------- end (no arguments)
- | | +-------------------- print_i (1 argument)
- | +--------------------------------- set_i_i (2 arguments)
- +---------------------------------------------- set_i_ic (2 arguments)
-
-Please note that the opcode numbers used might have already changed. Also
-generated assembly code might be different.
-
-B<Intel x86 assembly version of the Parrot ops:>
-
-B<Parrot_jit_begin>
-
- 0x817ddd0 <jit_func>: push %ebp
- 0x817ddd1 <jit_func+1>: mov %esp,%ebp
- 0x817ddd3 <jit_func+3>: push %ebx
- 0x817ddd4 <jit_func+4>: push %esi
- 0x817ddd5 <jit_func+5>: push %edi
-
- normal function header till here, now push interpreter
-
- 0x817ddd6 <jit_func+6>: push $0x8164420
-
- get jit function table to %ebp and
- jump to first instruction
-
- 0x817dddb <jit_func+11>: mov 0xc(%ebp),%eax
- 0x817ddde <jit_func+14>: mov $0x81773f0,%ebp
- 0x817dde3 <jit_func+19>: sub $0x81774a8,%eax
- 0x817dde9 <jit_func+25>: jmp *%ds:0x0(%ebp,%eax,1)
-
-B<set_i_ic>
-
- 0x817ddee <jit_func+30>: mov $0x8,%edi
-
-B<set_i_i>
-
- 0x817ddf3 <jit_func+35>: mov %edi,%ebx
-
-B<Parrot_jit_save_registers>
-
- 0x817ddf5 <jit_func+37>: mov %edi,0x8164420
- 0x817ddfb <jit_func+43>: mov %ebx,0x8164428
-
-B<Parrot_jit_normal_op>
-
- 0x817de01 <jit_func+49>: push $0x81774c0
- 0x817de06 <jit_func+54>: call 0x804be00 <Parrot_print_i>
- 0x817de0b <jit_func+59>: add $0x4,%esp
-
-B<Parrot_jit_end>
-
- 0x817de0e <jit_func+62>: add $0x4,%esp
- 0x817de14 <jit_func+68>: pop %edi
- 0x817de16 <jit_func+70>: pop %ebx
- 0x817de18 <jit_func+72>: pop %esi
- 0x817de1a <jit_func+74>: pop %ebp
- 0x817de1c <jit_func+76>: ret
-
-Please note the reverse argument direction. PASM and JIT notations use
-I<dest,src,src>, while F<gdb> and the internal macros in F<jit_emit.h> have
-I<src,dest>.
-
-=head1 Debugging
-
-Above listing was generated by F<gdb>, the GNU debugger, with a little help
-from Parrot_jit_debug, which generates a symbol file in I<stabs> format, s.
-B<info stabs> for more (or less :-()
-
-The following script calls F<ddd> (the graphic debugger fronted) and attaches
-the symbol file, after it got built in F<parrot_build_asm>.
-
- # dddp
- # run ddd parrot with given file
- # gdb confirmations should be off
- parrot -o $1.pbc -d1 $1.pasm
- echo "b runops_jit
- r -D4 -R jit $1.pbc
- n
- add-symbol-file $1.o 0
- s
- " > .ddd
-
- ddd --command .ddd parrot &
-
-Run this with e.g. I<dddp t/op/jit_2>, then turn on the register status,
-I<step> or I<nexti> through the source, or set break points as with any other
-language.
-
-You can examine parrot registers via the debugger or even set them and you can
-always step into external opcode and look at I<*interpreter>.
-
-The tests F<t/op/jit*.t> have some test cases for testing register allocation.
-These tests are written for a mapping of 4 processor registers. If your
-processor architecture has more mapped registers, reduce them to 4 and run
-these tests.
-
-=head2 Example for a debug session
-
- $ cat j.pasm
- set I0, 10
- set N1, 1.1
- set S2, "abc"
- print "\n"
- end
- $ dddp j
-
-(ddd shows above source code and assembly (startup code snipped):
-
- 0x815de46 <jit_func+30>: mov $0xa,%ebx
- 0x815de4b <jit_func+35>: fldl 0x81584c0
- 0x815de51 <jit_func+41>: fstp %st(2)
- 0x815de53 <jit_func+43>: mov %ebx,0x8158098
- 0x815de59 <jit_func+49>: fld %st(1)
- 0x815de5b <jit_func+51>: fstpl 0x8158120
- 0x815de61 <jit_func+57>: push $0x815cd90
- 0x815de66 <jit_func+62>: call 0x804db90 <Parrot_set_s_sc>
- 0x815de6b <jit_func+67>: add $0x4,%esp
- 0x815de6e <jit_func+70>: push $0x815cd9c
- 0x815de73 <jit_func+75>: call 0x804bcd0 <Parrot_print_sc>
- 0x815de78 <jit_func+80>: add $0x4,%esp
- 0x815de7b <jit_func+83>: add $0x4,%esp
- 0x815de81 <jit_func+89>: pop %edi
- 0x815de83 <jit_func+91>: pop %ebx
- 0x815de85 <jit_func+93>: pop %esi
- 0x815de87 <jit_func+95>: pop %ebp
- 0x815de89 <jit_func+97>: ret
- (gdb) n
- (gdb) n
- (gdb) n
- (gdb) p I0
- $1 = 10
- (gdb) p N1
- $2 = 1.1000000000000001
- (gdb) p *S2
- $3 = {bufstart = 0x815ad30, buflen = 15, flags = 336128, bufused =
- 3, strstart = 0x815ad30 "abc"}
- (gdb) p &I0
- $4 = (INTVAL *) 0x8158098
-
-XXX (p)rinting register contents like shown above is currently not supported.
-
-=head1 SEE ALSO
-
-F<docs/dev/jit_i386.pod>, F<jit/skeleton/jit_emit.h>
Deleted: trunk/docs/native_exec.pod
==============================================================================
--- trunk/docs/native_exec.pod Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,77 +0,0 @@
-# Copyright (C) 2001-2004, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-docs/native_exec.pod - Parrot Native Object Execution Subsystem
-
-=head1 Overview
-
-On supported platforms, Parrot can use the JIT subsystem to assemble a native
-executable binary from a Parrot program. This method wraps the VM runtime
-engine and a precompiled Parrot program into a single binary.
-
-=head1 Generating a native executable
-
-Generating a native executable is done in three steps: building a packfile,
-assembling a native object, and then linking the native executable.
-
-The packfile is generated in the standard way from .pir or .pasm source by IMCC.
-For a program in myprog.pasm:
-
- ./parrot -o myprog.pbc myprog.pasm
-
-This generates the myprog.pbc packfile. The native object is generated
-similarly:
-
- ./parrot -o myprog.o myprog.pbc
-
-This creates a native object called myprog.o. Assembly of the executable is
-done by the "exec" target in the root Makefile like so:
-
- make EXEC=myprog exec
-
-This generates the "myprog" executable, which runs equivalently to
-
- ./parrot -R jit myprog.pbc
-
-minus the time required to JIT-compile the bytecode.
-
-The "hello" target of the root Makefile demonstrates this method
-for a "Hello world" program.
-
-=head1 Details
-
-=head2 Platform support
-
-The exec subsystem is enabled if support is determined automatically by
-config/auto/jit.pl, or if the option --execcapable is explicitly specified to
-Configure.pl. The platform must support the JIT core, and some additional
-scaffold in the exec* sources must be provided. Implementation of such is
-beyond the scope of this document.
-
-=head2 Native object generation
-
-Native objects are generated by the "exec" run core. This core uses the JIT
-subsystem to compile a packfile to native instructions, then serializes it to
-the platform's native object format. This object is then loaded at runtime and
-executed using the normal JIT core.
-
-Unlike the standard cores (switch, computed goto, etc.) which are activated by
-command-line switch, the exec core is invoked by IMCC when the output file
-specified by the -o option has a .o extension. When creating a native object
-this way, IMCC requires that the input be a packfile. This process therefore
-must be performed in two steps, building the packfile and assembling the native
-object, as demonstrated above.
-
-=head2 Executable generation
-
-A native executable is generated by linking a native object against the parrot
-library and the loader in exec_start.c. The "exec" target in the root Makefile
-does this with the compile flags used to build parrot itself. Alternatively it
-may be done by hand, e.g.
-
- gcc -o myprog myprog.o src/exec_start.o blib/lib/libparrot.a
-
-Additional libraries may need to be included as appropriate for the platform.
-
Modified: trunk/docs/parrot.pod
==============================================================================
--- trunk/docs/parrot.pod Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/docs/parrot.pod Sat Sep 19 08:10:11 2009 (r41356)
@@ -81,10 +81,6 @@
Describes the embedding subsystem in excruciating detail.
-=item F<jit.pod>
-
-A brief description of Parrot's Just-In-Time compiler.
-
=item F<memory_internals.pod>
An introduction to the Parrot GC subsystem
Modified: trunk/docs/porting_intro.pod
==============================================================================
--- trunk/docs/porting_intro.pod Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/docs/porting_intro.pod Sat Sep 19 08:10:11 2009 (r41356)
@@ -46,71 +46,6 @@
=back
-=head1 JIT
-
-=head2 What it is
-
-Parrot contains a just-in-time compilation subsystem that compiles Parrot
-bytecode into native processor instructions just prior to execution,
-eliminating much of the overhead of bytecode interpretation.
-
-=head2 How to help
-
-Each unique processor target requires its own JIT engine. So far, engines have
-been implemented for DEC Alpha, ARM, Intel i386, SGI MIPS, PPC, and Sun4. If
-you know that your architecture is substantially similar to one of these,
-adding support may be possible with relatively little effort. Implementing a
-novel JIT core from scratch is a substantial undertaking.
-
-Also note that some changes may be required based on OS as well. (e.g.:
-OS X/i386 vs. Linux/i386; OS X/i386 doesn't currently work.)
-
-=head2 References
-
-=over 4
-
-=item * F<docs/jit.pod>
-
-=item * F<src/jit/$arch/*>
-
-=item * I<make testj>
-
-=item * F<t/op/jit.t>
-
-=back
-
-=head1 Native Exec
-
-=head2 What it is
-
-Parrot's "native exec" feature allows the integration of the parrot runtime and
-a Parrot program into a single precompiled binary, reducing program start-up
-cost and negating the need to package Parrot distinctly from an application.
-It's perl2exe/PerlApp/PAR for the Parrot generation.
-
-=head2 How to help
-
-The exec feature makes use of the JIT subsystem, and requires supporting code
-with knowledge of the operating system's native object format. This feature is
-only supported on JITable architectures (for now, just x86) running Linux,
-*BSD, or Darwin. An interested Parrot hacker with an eligible platform can
-contribute by submitting patches which emit exec objects in the OS's native
-object format (e.g., ELF, a.out, XCOFF).
-
-=head2 References
-
-=over 4
-
-=item * F<docs/native_exec.pod>
-
-=item * F<src/exec*.c>
-
-=item * F<include/parrot/exec*.h>
-
-=item * F<config/auto/jit.pl>
-
-=back
-
=head1 Threads
=head2 What it is
Modified: trunk/docs/running.pod
==============================================================================
--- trunk/docs/running.pod Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/docs/running.pod Sat Sep 19 08:10:11 2009 (r41356)
@@ -137,7 +137,6 @@
slow, bounds bounds checking core (default)
cgoto computed goto core
cgp computed goto-predereferenced core
- exec exec core (uses JIT at compile time to generate native code)
fast fast core (no bounds checking, profiling, or tracing)
gcdebug performs a full GC run before every op dispatch (good for
debugging GC problems)
@@ -217,17 +216,6 @@
=head1 Generated files
-If JIT debugging is enabled (e.g. via C<--parrot-debug 04>), the
-following additional output files are generated:
-
- F<file.stabs.s> stabsfile for the program
- F<file.o> object file with debug information
- F<EVAL_n> source of C<compile> op number I<n>
- F<EVAL_n.stabs.s> stabsfile for this block
- F<EVAL_n.o> object file with debug information
-
-See F<docs/jit.pod> for further information.
-
=head1 About runcores
The runcore (or runloop) tells Parrot how to find the C code that implements
@@ -282,11 +270,6 @@
addresses. See "Predereferencing" in F<docs/glossary.pod> for a
fuller explanation.
-Finally, the JIT runcore uses the "slow" core, but also creates and
-jumps to JIT-compiled native code for supported opcodes. "cgp-jit"
-and "switched-jit" are variations that use the CGP or switched core
-but run JIT code when possible.
-
=head1 Operation table
Command Line Action Output
Modified: trunk/docs/tests.pod
==============================================================================
--- trunk/docs/tests.pod Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/docs/tests.pod Sat Sep 19 08:10:11 2009 (r41356)
@@ -18,9 +18,6 @@
updated your code recently and tests began failing, go for a C<make
realclean> and recompile parrot before complaining.
-If your architecture supports JIT, you can test parrot JIT engine using C<make
-testj>. It works just like C<make test>, but uses the JIT engine when possible.
-
C<make languages-test> runs the test suite for most language implementations
in the languages directory.
Deleted: trunk/include/parrot/exec.h
==============================================================================
--- trunk/include/parrot/exec.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2003-2007, Parrot Foundation.
- */
-
-/*
- * exec.h
- *
- * SVN Info
- * $Id$
- * Overview:
- * Exec header file.
- * History:
- * Initial version by Daniel Grunblatt on 2003.6.9
- * Notes:
- * References:
- */
-
-#ifndef PARROT_EXEC_H_GUARD
-#define PARROT_EXEC_H_GUARD
-
-#if EXEC_CAPABLE
-
-# ifdef PARROT_EXEC_OS_OPENBSD
-# ifdef PARROT_OPENBSD_ELF
-# define EXEC_ELF
-# else
-# define EXEC_A_OUT
-# endif
-# endif
-# ifdef PARROT_EXEC_OS_DARWIN
-# define EXEC_MACH_O
-# endif
-# if defined(PARROT_EXEC_OS_FREEBSD) || defined(PARROT_EXEC_OS_NETBSD) || defined(PARROT_EXEC_OS_LINUX)
-# define EXEC_ELF
-# endif
-# if defined(PARROT_EXEC_OS_MSWIN32) || defined(PARROT_EXEC_OS_CYGWIN)
-# define EXEC_COFF
-# endif
-
-# ifdef EXEC_A_OUT
-# define EXEC_CALLDISP jit_info->arena.start - jit_info->native_ptr - 4
-# elif defined(EXEC_COFF)
-# define EXEC_CALLDISP 0
-# else
-# define EXEC_CALLDISP 0xfffffffc
-# endif
-
-/* Symbol types */
-# define STYPE_UND 1 /* Undefined */
-# define STYPE_GCC 2 /* GCC */
-# ifdef I386
-# define STYPE_GDATA 3 /* Global data */
-# define STYPE_FUNC 4 /* Function */
-# else
-# define STYPE_GDATA 0x0F020000 /* Global data */
-# define STYPE_FUNC 0x0F010000 /* Function */
-# endif
-# define STYPE_COM 5 /* Variable */
-
-/* Rellocation types */
-# define RTYPE_DATA 1 /* Data */
-# define RTYPE_COM 2 /* Variable */
-# define RTYPE_FUNC 3 /* Function */
-# define RTYPE_DATA1 4 /* 2nd. rellocation for RISC machines */
-
-typedef struct Parrot_exec_symbol_t {
- int offset_list;
- int type;
- int value;
- const char *symbol;
-} Parrot_exec_symbol_t;
-
-typedef struct Parrot_exec_rellocation_t {
- int offset;
- short symbol_number;
- int type;
-} Parrot_exec_rellocation_t;
-
-typedef struct Parrot_exec_section_t {
- char *code;
- size_t size;
-} Parrot_exec_section_t;
-
-typedef struct Parrot_exec_objfile_t {
- Parrot_exec_section_t text;
- Parrot_exec_section_t data;
- Parrot_exec_section_t bss;
- int *data_size;
- int data_count;
- Parrot_exec_rellocation_t *text_rellocation_table;
- int text_rellocation_count;
- Parrot_exec_rellocation_t *data_rellocation_table;
- int data_rellocation_count;
- Parrot_exec_symbol_t *symbol_table;
- int symbol_count;
- int symbol_list_size;
- int bytecode_header_size;
-} Parrot_exec_objfile_t;
-
-/* HEADERIZER BEGIN: src/exec.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-
-PARROT_EXPORT
-void Parrot_exec_add_text_rellocation(
- ARGIN(Parrot_exec_objfile_t *obj),
- ARGIN(char *nptr),
- int type,
- ARGIN(const char *symbol),
- int disp)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(4);
-
-PARROT_EXPORT
-void Parrot_exec_add_text_rellocation_func(
- ARGIN(Parrot_exec_objfile_t *obj),
- ARGIN(char *nptr),
- ARGIN(const char *func_name))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(3);
-
-PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
-int * Parrot_exec_add_text_rellocation_reg(
- ARGIN(Parrot_exec_objfile_t *obj),
- ARGIN(char *nptr),
- ARGIN(const char *var),
- int offset,
- int disp)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(3);
-
-void Parrot_exec(PARROT_INTERP,
- ARGIN(opcode_t *pc),
- ARGIN(opcode_t *code_start),
- ARGIN(opcode_t *code_end))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(3)
- __attribute__nonnull__(4);
-
-int Parrot_exec_add_symbol(
- ARGMOD(Parrot_exec_objfile_t *obj),
- ARGIN(const char *symbol),
- int stype)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- FUNC_MODIFIES(*obj);
-
-#define ASSERT_ARGS_Parrot_exec_add_text_rellocation \
- __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(obj) \
- || PARROT_ASSERT_ARG(nptr) \
- || PARROT_ASSERT_ARG(symbol)
-#define ASSERT_ARGS_Parrot_exec_add_text_rellocation_func \
- __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(obj) \
- || PARROT_ASSERT_ARG(nptr) \
- || PARROT_ASSERT_ARG(func_name)
-#define ASSERT_ARGS_Parrot_exec_add_text_rellocation_reg \
- __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(obj) \
- || PARROT_ASSERT_ARG(nptr) \
- || PARROT_ASSERT_ARG(var)
-#define ASSERT_ARGS_Parrot_exec __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp) \
- || PARROT_ASSERT_ARG(pc) \
- || PARROT_ASSERT_ARG(code_start) \
- || PARROT_ASSERT_ARG(code_end)
-#define ASSERT_ARGS_Parrot_exec_add_symbol __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(obj) \
- || PARROT_ASSERT_ARG(symbol)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-/* HEADERIZER END: src/exec.c */
-
-#endif /* EXEC_CAPABLE */
-
-#endif /* PARROT_EXEC_H_GUARD */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Modified: trunk/include/parrot/interpreter.h
==============================================================================
--- trunk/include/parrot/interpreter.h Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/include/parrot/interpreter.h Sat Sep 19 08:10:11 2009 (r41356)
@@ -580,7 +580,6 @@
void exec_init_prederef(PARROT_INTERP,
void *prederef_arena);
void prepare_for_run(PARROT_INTERP);
-void *init_jit(PARROT_INTERP, opcode_t *pc);
PARROT_EXPORT void dynop_register(PARROT_INTERP, PMC *op_lib);
/* interpreter.pmc */
Modified: trunk/include/parrot/packfile.h
==============================================================================
--- trunk/include/parrot/packfile.h Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/include/parrot/packfile.h Sat Sep 19 08:10:11 2009 (r41356)
@@ -265,7 +265,6 @@
struct PackFile_ByteCode {
PackFile_Segment base;
Prederef prederef; /* The predereferenced code and info */
- struct Parrot_jit_info_t *jit_info; /* JITs data */
struct PackFile_Debug *debugs;
PackFile_ConstTable *const_table;
PackFile_FixupTable *fixups;
Modified: trunk/include/parrot/runcore_api.h
==============================================================================
--- trunk/include/parrot/runcore_api.h Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/include/parrot/runcore_api.h Sat Sep 19 08:10:11 2009 (r41356)
@@ -109,15 +109,6 @@
__attribute__nonnull__(1)
__attribute__nonnull__(2);
-void exec_init_prederef(PARROT_INTERP, ARGIN(void *prederef_arena))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-void * init_jit(PARROT_INTERP, SHIM(opcode_t *pc))
- __attribute__nonnull__(1);
-
void Parrot_runcore_destroy(PARROT_INTERP)
__attribute__nonnull__(1);
@@ -150,11 +141,6 @@
#define ASSERT_ARGS_dynop_register __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(lib_pmc)
-#define ASSERT_ARGS_exec_init_prederef __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp) \
- || PARROT_ASSERT_ARG(prederef_arena)
-#define ASSERT_ARGS_init_jit __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp)
#define ASSERT_ARGS_Parrot_runcore_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp)
#define ASSERT_ARGS_Parrot_runcore_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
Modified: trunk/lib/Parrot/Configure/Options/Conf.pm
==============================================================================
--- trunk/lib/Parrot/Configure/Options/Conf.pm Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/lib/Parrot/Configure/Options/Conf.pm Sat Sep 19 08:10:11 2009 (r41356)
@@ -95,6 +95,7 @@
--jitcapable Use JIT
--execcapable Use JIT to emit a native executable
--without-threads Build parrot without thread support
+ --buildframes Dynamically build NCI call frames
External Library Options:
Modified: trunk/lib/Parrot/Configure/Options/Conf/Shared.pm
==============================================================================
--- trunk/lib/Parrot/Configure/Options/Conf/Shared.pm Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/lib/Parrot/Configure/Options/Conf/Shared.pm Sat Sep 19 08:10:11 2009 (r41356)
@@ -38,6 +38,7 @@
inline
intval
jitcapable
+ buildframes
languages
ld
ldflags
Modified: trunk/lib/Parrot/Configure/Step/List.pm
==============================================================================
--- trunk/lib/Parrot/Configure/Step/List.pm Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/lib/Parrot/Configure/Step/List.pm Sat Sep 19 08:10:11 2009 (r41356)
@@ -40,6 +40,7 @@
auto::isreg
auto::arch
auto::jit
+ auto::frames
auto::cpu
auto::funcptr
auto::cgoto
Modified: trunk/src/embed.c
==============================================================================
--- trunk/src/embed.c Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/src/embed.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -80,13 +80,6 @@
*/
-#ifdef JIT_CAPABLE
-# if EXEC_CAPABLE
-# include "parrot/exec.h"
-# endif /* EXEC_CAPABLE */
-# include "jit.h"
-#endif
-
PARROT_EXPORT
PARROT_CANNOT_RETURN_NULL
Parrot_Interp
@@ -571,8 +564,8 @@
if (!(pf->options & PFOPT_HEADERONLY))
do_sub_pragmas(interp, pf->cur_cs, PBC_PBC, NULL);
- /* JITting and/or prederefing the sub/the bytecode is done
- * in switch_to_cs before actual usage of the segment */
+ /* Prederefing the sub/the bytecode is done in switch_to_cs before
+ * actual usage of the segment */
#ifdef PARROT_HAS_HEADER_SYSMMAN
/* the man page states that it's ok to close a mmaped file */
@@ -814,15 +807,6 @@
/* Set up @ARGS (or whatever this language calls it) in userargv. */
userargv = setup_argv(interp, argc, argv);
-#if EXEC_CAPABLE
-
- /* s. runops_exec interpreter.c */
- if (Parrot_str_equal(interp, interp->run_core->name,
- Parrot_str_new_constant(interp, "exec")))
- Parrot_exec_run = 1;
-
-#endif
-
/*
* If any profile information was gathered, print it out
* before exiting, then print debug infos if turned on.
Deleted: trunk/src/exec.c
==============================================================================
--- trunk/src/exec.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,417 +0,0 @@
-/*
-Copyright (C) 2001-2009, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/exec.c - Generate an object file
-
-=head1 DESCRIPTION
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-#include <parrot/parrot.h>
-#ifdef HAVE_COMPUTED_GOTO
-# include <parrot/oplib/core_ops_cgp.h>
-#endif /* HAVE_COMPUTED_GOTO */
-#include "parrot/exec.h"
-#include "jit.h"
-#define JIT_EMIT 1
-#include "jit_emit.h"
-#include "exec_dep.h"
-#include "exec_save.h"
-#include "parrot/compiler.h"
-
-/* HEADERIZER HFILE: include/parrot/exec.h */
-
-/* HEADERIZER BEGIN: static */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-
-static void add_data_member(
- ARGMOD(Parrot_exec_objfile_t *obj),
- ARGIN_NULLOK(const void *src),
- size_t len)
- __attribute__nonnull__(1)
- FUNC_MODIFIES(*obj);
-
-static void exec_init(ARGIN(Parrot_exec_objfile_t *obj))
- __attribute__nonnull__(1);
-
-static int symbol_list_find(
- ARGIN(const Parrot_exec_objfile_t *obj),
- ARGIN(const char *symbol))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-#define ASSERT_ARGS_add_data_member __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(obj)
-#define ASSERT_ARGS_exec_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(obj)
-#define ASSERT_ARGS_symbol_list_find __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(obj) \
- || PARROT_ASSERT_ARG(symbol)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-/* HEADERIZER END: static */
-
-/*
- * Parrot_exec_run must be 0 while the program runs.
- * It will be set to 2 inside eval (s. eval.pmc)
- * to switch to runops_jit (s. interpreter.c:runops_exec()).
- * Must be 1 while starting the compiled code to have Parrot_new()
- * return the address of the global interpreter (s. interpreter.c)
- * and PackFile_ConstTable_unpack use the global const_table (s. packfile.c).
- * Must also be 1 while generating the executable.
- */
-
-int Parrot_exec_run = 0;
-
-/*
-
-=item C<void Parrot_exec(PARROT_INTERP, opcode_t *pc, opcode_t *code_start,
-opcode_t *code_end)>
-
-Call the jit to get the program code. Adds the members of the data
-section. And emits the executable.
-
-=cut
-
-*/
-
-void
-Parrot_exec(PARROT_INTERP, ARGIN(opcode_t *pc),
- ARGIN(opcode_t *code_start), ARGIN(opcode_t *code_end))
-{
- ASSERT_ARGS(Parrot_exec)
-#ifdef JIT_CGP
- int i, j *k;
-#endif
- const char *output;
- long bhs;
- Parrot_jit_info_t *jit_info;
-
- Parrot_exec_objfile_t * const obj =
- mem_allocate_zeroed_typed(Parrot_exec_objfile_t);
- exec_init(obj);
- obj->bytecode_header_size =
- (interp->code->base.file_offset + 4) * sizeof (opcode_t);
- jit_info = parrot_build_asm(interp, code_start, code_end,
- obj, JIT_CODE_FILE);
-
- /* TODO Go zero the calls to jited opcodes. */
- /* Place the program code in the data section. */
- /* program_code */
- add_data_member(obj, interp->code->base.pf->src,
- interp->code->base.pf->size);
- /* opcode_map */
- add_data_member(obj, jit_info->arena.op_map, (jit_info->arena.map_size+1) *
- sizeof (opcode_t *));
- /* const_table */
- add_data_member(obj, NULL, interp->code->const_table->const_count *
- sizeof (PackFile_Constant));
-#ifdef JIT_CGP
- /* prederef_code */
- j = (int)cgp_core;
- j = (int)((op_func_t*)interp->op_lib->op_func_table)[2] - j;
- k = (int *)interp->code->prederef.code;
- for (i = 0; i < (int)interp->code->base.size; i++) {
- if (k[i] != j)
- k[i] = 0;
- }
- add_data_member(obj, interp->code->prederef.code,
- interp->code->base.size * sizeof (void *));
-#endif /* JIT_CGP */
- /* bytecode_offset */
- bhs = obj->bytecode_header_size / sizeof (opcode_t);
- add_data_member(obj, &bhs, 4);
-
- obj->text.code = jit_info->arena.start;
- obj->text.size = jit_info->arena.size;
-
- /* PAD */
- obj->text.size += (4 - obj->text.size % 4);
- obj->data.size += (4 - obj->data.size % 4);
- offset_fixup(obj);
- output = interp->output_file ?
- interp->output_file : "exec_output.o";
- Parrot_exec_save(interp, obj, output);
-}
-
-/*
-
-=item C<static void add_data_member(Parrot_exec_objfile_t *obj, const void *src,
-size_t len)>
-
-Adds a member to the data section, storing the size of it at
-C<< obj->data_size[N] >>.
-
-=cut
-
-*/
-
-static void
-add_data_member(ARGMOD(Parrot_exec_objfile_t *obj),
- ARGIN_NULLOK(const void *src), size_t len)
-{
- ASSERT_ARGS(add_data_member)
- char *cp;
-
- if (obj->data.size == 0) {
- obj->data.code = (char *)mem_sys_allocate(len);
- obj->data_size = (int *)mem_sys_allocate(sizeof (int));
- }
- else {
- int *nds;
- obj->data.code = (char *)mem_sys_realloc(obj->data.code,
- obj->data.size + len);
- nds = (int *)mem_sys_realloc(obj->data_size, (obj->data_count + 2) *
- sizeof (int));
- obj->data_size = nds;
- }
-
- cp = obj->data.code + obj->data.size;
- if (src)
- memcpy(cp, src, len);
- else
- memset(cp, 0, len);
- obj->data_size[obj->data_count++] = len;
- obj->data.size += len;
-}
-
-/*
-
-=item C<static void exec_init(Parrot_exec_objfile_t *obj)>
-
-Initialize the obj structure.
-
-=cut
-
-*/
-
-static void
-exec_init(ARGIN(Parrot_exec_objfile_t *obj))
-{
- ASSERT_ARGS(exec_init)
- obj->text_rellocation_table = (Parrot_exec_rellocation_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_exec_rellocation_t));
- obj->data_rellocation_table = (Parrot_exec_rellocation_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_exec_rellocation_t));
- obj->symbol_table = (Parrot_exec_symbol_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_exec_symbol_t));
- /* size of table */
-#ifdef PARROT_I386
- obj->symbol_list_size = 4;
-#else
- obj->symbol_list_size = 0;
-#endif
-#ifdef EXEC_ELF
- obj->symbol_list_size = 0;
-#endif
- Parrot_exec_add_symbol(obj, "program_code", STYPE_GDATA);
- Parrot_exec_add_symbol(obj, "opcode_map", STYPE_GDATA);
- Parrot_exec_add_symbol(obj, "const_table", STYPE_GDATA);
-#ifdef JIT_CGP
- Parrot_exec_add_symbol(obj, "exec_prederef_code", STYPE_GDATA);
-#endif /* JIT_CGP */
- Parrot_exec_add_symbol(obj, "bytecode_offset", STYPE_GDATA);
- Parrot_exec_add_symbol(obj, "run_compiled", STYPE_FUNC);
-}
-
-/*
-
-=item C<int Parrot_exec_add_symbol(Parrot_exec_objfile_t *obj, const char
-*symbol, int stype)>
-
-Adds a symbol to the object file.
-
-=cut
-
-*/
-
-int
-Parrot_exec_add_symbol(ARGMOD(Parrot_exec_objfile_t *obj),
- ARGIN(const char *symbol), int stype)
-{
- ASSERT_ARGS(Parrot_exec_add_symbol)
-
- int symbol_number = symbol_list_find(obj, symbol);
- if (symbol_number == -1) {
- Parrot_exec_symbol_t *new_symbol;
-
- symbol_number = obj->symbol_count;
- new_symbol = (Parrot_exec_symbol_t *)mem_sys_realloc(obj->symbol_table,
- (size_t)(obj->symbol_count + 1) * sizeof (Parrot_exec_symbol_t));
- obj->symbol_table = new_symbol;
-
- new_symbol = &obj->symbol_table[obj->symbol_count++];
- new_symbol->offset_list = obj->symbol_list_size;
- new_symbol->symbol = symbol;
- obj->symbol_list_size += strlen(symbol);
-#if defined(EXEC_A_OUT) || defined(EXEC_COFF)
- /* for the trailing "_" */
- obj->symbol_list_size++;
-#endif
- if (stype != STYPE_GCC)
- obj->symbol_list_size++;
- if (stype == STYPE_COM) {
- new_symbol->type = STYPE_COM;
- new_symbol->value = sizeof (Interp);
- }
- else {
- new_symbol->type = stype;
- new_symbol->value = 0;
- }
- }
- return symbol_number;
-}
-
-/*
-
-=item C<int * Parrot_exec_add_text_rellocation_reg(Parrot_exec_objfile_t *obj,
-char *nptr, const char *var, int offset, int disp)>
-
-Adds a register's text rellocation to the object file. Wrapper
-around C<Parrot_exec_add_text_rellocation>.
-
-Returns pointer to offset.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
-int *
-Parrot_exec_add_text_rellocation_reg(ARGIN(Parrot_exec_objfile_t *obj),
- ARGIN(char *nptr), ARGIN(const char *var), int offset, int disp)
-{
- ASSERT_ARGS(Parrot_exec_add_text_rellocation_reg)
- Parrot_exec_add_text_rellocation(obj, nptr, RTYPE_COM, var, disp);
- return (int *)offset;
-}
-
-/*
-
-=item C<void Parrot_exec_add_text_rellocation_func(Parrot_exec_objfile_t *obj,
-char *nptr, const char *func_name)>
-
-Adds a function's text rellocation to the object file. Wrapper
-around C<Parrot_exec_add_text_rellocation>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_exec_add_text_rellocation_func(ARGIN(Parrot_exec_objfile_t *obj),
- ARGIN(char *nptr), ARGIN(const char *func_name))
-{
- ASSERT_ARGS(Parrot_exec_add_text_rellocation_func)
- Parrot_exec_add_text_rellocation(obj, nptr, RTYPE_FUNC, func_name, 1);
-}
-
-/*
-
-=item C<void Parrot_exec_add_text_rellocation(Parrot_exec_objfile_t *obj, char
-*nptr, int type, const char *symbol, int disp)>
-
-Adds a text rellocation to the object file.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_exec_add_text_rellocation(ARGIN(Parrot_exec_objfile_t *obj), ARGIN(char *nptr),
- int type, ARGIN(const char *symbol), int disp)
-{
- ASSERT_ARGS(Parrot_exec_add_text_rellocation)
- int symbol_number;
- char *addr;
- Parrot_exec_rellocation_t * new_relloc = (Parrot_exec_rellocation_t *)
- mem_sys_realloc(obj->text_rellocation_table,
- (size_t)(obj->text_rellocation_count + 1) *
- sizeof (Parrot_exec_rellocation_t));
-
- obj->text_rellocation_table = new_relloc;
- new_relloc = &obj->text_rellocation_table[obj->text_rellocation_count++];
-
- switch (type) {
- case RTYPE_FUNC:
- symbol_number = Parrot_exec_add_symbol(obj, symbol, STYPE_UND);
- break;
- case RTYPE_COM:
- symbol_number = Parrot_exec_add_symbol(obj, symbol, STYPE_COM);
- break;
- case RTYPE_DATA:
- case RTYPE_DATA1:
- symbol_number = Parrot_exec_add_symbol(obj, symbol, STYPE_GDATA);
- break;
- default:
- symbol_number = 0;
- break;
- }
-
- addr = nptr + disp;
- new_relloc->offset = (int)(addr - obj->text.code);
- new_relloc->symbol_number = symbol_number;
- new_relloc->type = type;
-}
-
-/*
-
-=item C<static int symbol_list_find(const Parrot_exec_objfile_t *obj, const char
-*symbol)>
-
-Returns the index of C<symbol> in the symbol list. Returns -1 if it is
-not in the list.
-
-Used by C<Parrot_exec_add_symbol()>.
-
-=cut
-
-*/
-
-static int
-symbol_list_find(ARGIN(const Parrot_exec_objfile_t *obj), ARGIN(const char *symbol))
-{
- ASSERT_ARGS(symbol_list_find)
- int i;
-
- for (i = 0; i < obj->symbol_count; i++)
- if (STREQ(symbol, obj->symbol_table[i].symbol))
- return i;
- return -1;
-}
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<include/parrot/exec.h>, F<src/exec_cpu.c>, F<src/exec_save.h>
-and F<src/exec_start.c>.
-
-=head1 HISTORY
-
-Initial version by Daniel Grunblatt on 2003.6.9.
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/exec_save.c
==============================================================================
--- trunk/src/exec_save.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,844 +0,0 @@
-/*
-Copyright (C) 2001-2008, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/exec_save.c - Save object file in native format
-
-=head1 DESCRIPTION
-
-Save the C<Parrot_exec_objfile_t> to the native format.
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include <parrot/parrot.h>
-#include "parrot/exec.h"
-#include "exec_save.h"
-
-static void save_zero(FILE *fp);
-static void save_int(FILE *fp, int i);
-static void save_short(FILE *fp, short s);
-static void save_struct(FILE *fp, void *sp, size_t size);
-
-#ifdef EXEC_A_OUT
-
-# include <a.out.h>
-# include <link.h>
-
-/*
-
-=item C<void
-Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)>
-
-Save the C<Parrot_exec_objfile_t> to C<file>.
-
-=cut
-
-*/
-
-void
-Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)
-{
- FILE * const fp = fopen(file, "w");
- int i;
- struct exec header;
- struct relocation_info rellocation;
- struct nlist symlst;
-
-
- header.a_midmag = 0x07018600;
- header.a_text = obj->text.size;
- header.a_data = obj->data.size;
- header.a_bss = obj->bss.size;
- header.a_syms = obj->symbol_count * sizeof (struct nlist);
- header.a_entry = 0;
- header.a_trsize = obj->text_rellocation_count
- * sizeof (struct relocation_info);
- header.a_drsize = obj->data_rellocation_count
- * sizeof (struct relocation_info);
- save_struct(fp, &header, sizeof (struct exec));
- /* Text */
- for (i = 0; i < obj->text.size; i++)
- fprintf(fp, "%c", obj->text.code[i]);
- /* Data */
- for (i = 0; i < obj->data.size; i++)
- fprintf(fp, "%c", obj->data.code[i]);
- /* Text rellocations */
- for (i = obj->text_rellocation_count - 1; i >= 0; i--) {
- memset(&rellocation, 0, sizeof (struct relocation_info));
- rellocation.r_address = obj->text_rellocation_table[i].offset;
- rellocation.r_symbolnum = obj->text_rellocation_table[i].symbol_number;
- switch (obj->text_rellocation_table[i].type) {
- case RTYPE_FUNC:
- rellocation.r_pcrel = 1;
- rellocation.r_length = 2;
- rellocation.r_extern = 1;
- break;
- case RTYPE_COM:
- case RTYPE_DATA:
- rellocation.r_length = 2;
- rellocation.r_extern = 1;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_ERROR,
- "Unknown text rellocation type: %d\n",
- obj->text_rellocation_table[i].type);
- break;
- }
- save_struct(fp, &rellocation, sizeof (struct relocation_info));
- }
- /* Symbol table */
- for (i = 0; i < obj->symbol_count; i++) {
- memset(&symlst, 0, sizeof (struct nlist));
- symlst.n_un.n_strx = obj->symbol_table[i].offset_list;
- switch (obj->symbol_table[i].type) {
- case STYPE_FUNC:
- symlst.n_type = N_EXT | N_TEXT;
- symlst.n_other = AUX_FUNC;
- break;
- case STYPE_GDATA:
- symlst.n_type = N_EXT | N_DATA;
- symlst.n_other = AUX_OBJECT;
- symlst.n_value = obj->symbol_table[i].value;
- break;
- case STYPE_COM:
- symlst.n_type = N_EXT;
- symlst.n_value = obj->symbol_table[i].value;
- break;
- case STYPE_UND:
- symlst.n_type = N_EXT;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_ERROR,
- "Unknown symbol type: %d\n", obj->symbol_table[i].type);
- break;
- }
- save_struct(fp, &symlst, sizeof (struct nlist));
- }
- /* String table size */
- save_int(fp, obj->symbol_list_size);
- /* String table */
- for (i = 0; i < obj->symbol_count; i++) {
- if (obj->symbol_table[i].type != STYPE_GCC)
- fprintf(fp, "_%s", obj->symbol_table[i].symbol);
- else
- fprintf(fp, "%s", obj->symbol_table[i].symbol);
- save_zero(fp);
- }
- fclose(fp);
-}
-
-#endif /* EXEC_A_OUT */
-
-#ifdef EXEC_ELF
-
-# ifdef PARROT_EXEC_OS_OPENBSD
-# define R_386_32 1
-# define R_386_PC32 2
-# include <elf_abi.h>
-# else
-# include <elf.h>
-# endif
-
-# if defined(PARROT_PPC)
-# if !defined(R_PPC_ADDR16_HI) && !defined(R_PPC_ADDR16_LO) && \
- defined(R_PPC_16_HI) && defined(R_PPC_16_LO)
-# define R_PPC_ADDR16_HI R_PPC_16_HI
-# define R_PPC_ADDR16_LO R_PPC_16_LO
-# endif
- /*
- * NetBSD/powerpc 3.x and OpenBSD/powerpc doesn't define these constants,
- * but instead has them as enums, so add some workarounds for those.
- */
-# if !defined(R_PPC_ADDR16_HI) && !defined(R_PPC_ADDR16_LO) && \
- (defined(__NetBSD__) || defined(__OpenBSD__))
-# define R_PPC_ADDR16_HI RELOC_16_HI
-# define R_PPC_ADDR16_LO RELOC_16_LO
-# endif
-# if !defined(R_PPC_REL24) && (defined(__NetBSD__) || defined(__OpenBSD__))
-# define R_PPC_REL24 RELOC_REL24
-# endif
-# endif /* PARROT_PPC */
-
-/* Add a section to the file
- *
- * n = Name
- * t = Type
- * f = Flags
- * s = Size
- * l = Link
- * i = Info
- * a = Align
- * e = Entry size
- */
-# define sh_add(n, t, f, s, l, i, a, e) { \
- memset(&sechdr, 0, sizeof (Elf32_Shdr)); \
- sechdr.sh_name = shste - shst; \
- shste += sprintf(shste, "%s", (n)); \
- shste++; \
- sechdr.sh_type = (t); \
- sechdr.sh_flags = (f); \
- sechdr.sh_addr = 0; \
- sechdr.sh_offset = current_offset; \
- sechdr.sh_size = (s); \
- sechdr.sh_link = (l); \
- sechdr.sh_info = (i); \
- sechdr.sh_addralign = (a); \
- sechdr.sh_entsize = (e); \
- save_struct(fp, &sechdr, sizeof (Elf32_Shdr)); \
- current_offset += (s); \
- if ((s) % 4) \
- current_offset += (4 - (s) % 4); \
- }
-
-/* Sizeof the section header string table */
-# define SHSTRTABSIZE 0x48
-/* Previously defined symbols (zero, text, data, bss) */
-# define PDFS 4
-/* Number of sections */
-# define NSECTIONS 8
-
-void
-Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)
-{
- FILE *fp = fopen(file, "w");
- char *shste;
- char shst[SHSTRTABSIZE];
-
- Elf32_Ehdr header;
- Elf32_Shdr sechdr;
- Elf32_Rel rellocation;
- Elf32_Rela rel_addend;
- Elf32_Sym symlst;
- Elf32_Off current_offset;
- int i;
-
- memset(&header, 0, sizeof (Elf32_Ehdr));
- header.e_ident[0] = ELFMAG0;
- header.e_ident[1] = ELFMAG1;
- header.e_ident[2] = ELFMAG2;
- header.e_ident[3] = ELFMAG3;
- header.e_ident[4] = ELFCLASS32;
-# if PARROT_BIGENDIAN
- header.e_ident[5] = ELFDATA2MSB;
-# else /* PARROT_BIGENDIAN */
- header.e_ident[5] = ELFDATA2LSB;
-# endif /* PARROT_BIGENDIAN */
- header.e_ident[6] = EV_CURRENT;
-# ifdef PARROT_EXEC_OS_FREEBSD
- header.e_ident[7] = ELFOSABI_FREEBSD;
-# endif
-# ifdef PARROT_EXEC_OS_NETBSD
- header.e_ident[7] = ELFOSABI_NETBSD;
-# endif
-# if defined(PARROT_EXEC_OS_LINUX) && defined(ELFOSABI_LINUX) && \
- !defined(PARROT_PPC) && !defined(PARROT_ARM)
- header.e_ident[7] = ELFOSABI_LINUX;
-# endif
-
- header.e_type = ET_REL;
-# ifdef PARROT_I386
- header.e_machine = EM_386;
-# endif
-# ifdef PARROT_PPC
- header.e_machine = EM_PPC;
-# endif
-# ifdef PARROT_ARM
- header.e_ident[7] = ELFOSABI_ARM;
- header.e_machine = EM_ARM;
-# endif
- header.e_version = EV_CURRENT;
- header.e_entry = 0;
- header.e_phoff = 0;
- header.e_shoff = sizeof (Elf32_Ehdr);
- header.e_flags = 0;
- header.e_ehsize = sizeof (Elf32_Ehdr);
- header.e_phentsize = 0;
- header.e_phnum = 0;
- header.e_shentsize = sizeof (Elf32_Shdr);
- header.e_shnum = NSECTIONS;
- header.e_shstrndx = 1;
-
- save_struct(fp, &header, sizeof (Elf32_Ehdr));
-
- current_offset = sizeof (Elf32_Ehdr) + NSECTIONS * sizeof (Elf32_Shdr);
-
- /* Sections */
- memset(&shst, 0, SHSTRTABSIZE);
- shste = shst + 1;
-
- /* NULL */
- memset(&sechdr, 0, sizeof (Elf32_Shdr));
- save_struct(fp, &sechdr, sizeof (Elf32_Shdr));
-
- /* Section Header String Table */
- sh_add(".shstrtab", SHT_STRTAB, 0, SHSTRTABSIZE, 0, 0, 1, 0);
-
- /* Text */
- sh_add(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, obj->text.size,
- 0, 0, 4, 0);
-
- /* Data */
- sh_add(".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, obj->data.size,
- 0, 0, 4, 0);
-
- /* Bss */
- sh_add(".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, obj->bss.size,
- 0, 0, 4, 0);
- /*
- * Text rellocation records.
- * Link must be the symtab section header index.
- * Info is the text section header index.
- */
-# if defined(PARROT_I386) || defined(PARROT_ARM)
- sh_add(".rel.text", SHT_REL, 0, obj->text_rellocation_count *
- sizeof (Elf32_Rel), 6, 2, 4, sizeof (Elf32_Rel));
-# endif
- /*
- * PPC requires rellocation structures with addends.
- */
-# ifdef PARROT_PPC
- sh_add(".rela.text", SHT_RELA, 0, obj->text_rellocation_count *
- sizeof (Elf32_Rela), 6, 2, 4, sizeof (Elf32_Rela));
-# endif
- /*
- * Symbol table.
- * Link is the strtab section header index.
- * Info is the index of the first symbol in the symbol table.
- */
- sh_add(".symtab", SHT_SYMTAB, 0, (obj->symbol_count + PDFS) *
- sizeof (Elf32_Sym), 7, PDFS - 1, 4, sizeof (Elf32_Sym));
- /* String Table */
- obj->symbol_list_size += 1; /* Trailing \0 */
- sh_add(".strtab", SHT_STRTAB, 0, obj->symbol_list_size, 0, 0, 1, 0);
-
- /* Section header string table */
- save_struct(fp, &shst, SHSTRTABSIZE);
- save_struct(fp, obj->text.code, obj->text.size); /* Text */
- save_struct(fp, obj->data.code, obj->data.size); /* Data */
- /* Text rellocations */
- for (i = 0; i < obj->text_rellocation_count; i++) {
-# ifdef PARROT_I386
- memset(&rellocation, 0, sizeof (Elf32_Rel));
-
- rellocation.r_offset = obj->text_rellocation_table[i].offset;
- switch (obj->text_rellocation_table[i].type) {
- case RTYPE_FUNC:
- rellocation.r_info =
- ELF32_R_INFO(
- obj->text_rellocation_table[i].symbol_number + PDFS,
- R_386_PC32);
- break;
- case RTYPE_DATA:
- case RTYPE_COM:
- rellocation.r_info =
- ELF32_R_INFO(
- obj->text_rellocation_table[i].symbol_number + PDFS,
- R_386_32);
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_ERROR,
- "Unknown text rellocation type: %d\n",
- obj->text_rellocation_table[i].type);
- break;
- }
- save_struct(fp, &rellocation, sizeof (Elf32_Rel));
-# endif
-# ifdef PARROT_PPC
- memset(&rel_addend, 0, sizeof (Elf32_Rela));
- rel_addend.r_offset = obj->text_rellocation_table[i].offset;
- switch (obj->text_rellocation_table[i].type) {
- case RTYPE_FUNC:
- rel_addend.r_info =
- ELF32_R_INFO(
- obj->text_rellocation_table[i].symbol_number + PDFS,
- R_PPC_REL24);
- break;
- case RTYPE_DATA:
- case RTYPE_COM:
- rel_addend.r_info =
- ELF32_R_INFO(
- obj->text_rellocation_table[i].symbol_number + PDFS,
- R_PPC_ADDR16_HI);
- rel_addend.r_addend = *((short *)
- (&obj->text.code[obj->text_rellocation_table[i].offset]))
- << 16;
- rel_addend.r_addend += *((short *)
- (&obj->text.code[
- obj->text_rellocation_table[i].offset + 4]));
- break;
- case RTYPE_DATA1:
- rel_addend.r_info =
- ELF32_R_INFO(
- obj->text_rellocation_table[i].symbol_number + PDFS,
- R_PPC_ADDR16_LO);
- rel_addend.r_addend = *((short *)
- (&obj->text.code[obj->text_rellocation_table[i].offset]));
- rel_addend.r_addend += *((short *)
- (&obj->text.code[
- obj->text_rellocation_table[i].offset - 4])) << 16;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_ERROR,
- "Unknown text rellocation type: %d\n",
- obj->text_rellocation_table[i].type);
- break;
- }
- save_struct(fp, &rel_addend, sizeof (Elf32_Rela));
-# endif
-# ifdef PARROT_ARM
- memset(&rellocation, 0, sizeof (Elf32_Rel));
- rellocation.r_offset = obj->text_rellocation_table[i].offset;
- switch (obj->text_rellocation_table[i].type) {
- case RTYPE_FUNC:
- rellocation.r_info =
- ELF32_R_INFO(
- obj->text_rellocation_table[i].symbol_number + PDFS,
- R_ARM_ABS32);
- break;
- case RTYPE_DATA:
- rellocation.r_info =
- ELF32_R_INFO(
- obj->text_rellocation_table[i].symbol_number + PDFS,
- R_ARM_ABS32);
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_ERROR,
- "Unknown text rellocation type: %d\n",
- obj->text_rellocation_table[i].type);
- break;
- }
- save_struct(fp, &rellocation, sizeof (Elf32_Rel));
-# endif
- }
- /* Symbol table */
- /* zero */
- memset(&symlst, 0, sizeof (Elf32_Sym));
- save_struct(fp, &symlst, sizeof (Elf32_Sym));
-
- /* Text */
- memset(&symlst, 0, sizeof (Elf32_Sym));
- symlst.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
- symlst.st_shndx = 2;
- save_struct(fp, &symlst, sizeof (Elf32_Sym));
-
- /* Data */
- memset(&symlst, 0, sizeof (Elf32_Sym));
- symlst.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
- symlst.st_shndx = 3;
- save_struct(fp, &symlst, sizeof (Elf32_Sym));
-
- /* Bss */
- memset(&symlst, 0, sizeof (Elf32_Sym));
- symlst.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
- symlst.st_shndx = 4;
- save_struct(fp, &symlst, sizeof (Elf32_Sym));
-
- for (i = 0; i < obj->symbol_count; i++) {
- memset(&symlst, 0, sizeof (Elf32_Sym));
- symlst.st_name = obj->symbol_table[i].offset_list + 1;
- switch (obj->symbol_table[i].type) {
- case STYPE_FUNC:
- symlst.st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC);
- symlst.st_size = obj->text.size;
- symlst.st_shndx = 2; /* text */
- break;
- case STYPE_GDATA:
- symlst.st_value = obj->symbol_table[i].value;
- symlst.st_size = obj->data_size[i];
- symlst.st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
- symlst.st_shndx = 3; /* data */
- break;
- case STYPE_COM:
- symlst.st_value = obj->symbol_table[i].value;
- /* symlst.st_size = obj->data_size[i]; XXX daniel why? */
- symlst.st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
- symlst.st_shndx = SHN_COMMON;
- break;
- case STYPE_UND:
- symlst.st_info = ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE);
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_ERROR,
- "Unknown symbol type: %d\n", obj->symbol_table[i].type);
- break;
- }
- save_struct(fp, &symlst, sizeof (Elf32_Sym));
- }
- /* String table */
- save_zero(fp);
- for (i = 0; i < obj->symbol_count; i++) {
- fprintf(fp, "%s", obj->symbol_table[i].symbol);
- save_zero(fp);
- }
- /* PAD */
- for (i = 0; i < (4 - obj->symbol_list_size % 4); i++)
- save_zero(fp);
- fclose(fp);
-}
-
-#endif /* EXEC_ELF */
-
-#ifdef EXEC_MACH_O
-
-void
-Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)
-{
- FILE *fp = fopen(file, "w");
- size_t i;
-
- fprintf(fp, "\xFE\xED\xFA\xCE"); /* Header for Darwin */
- save_int(fp, 0x12);
- save_int(fp, 0);
- save_int(fp, 0x1);
- save_int(fp, 0x3);
- save_int(fp, 0x128);
- save_int(fp, 0);
- save_int(fp, 0x1);
- save_int(fp, 0xC0);
- for (i = 0; i < 5; i++)
- save_int(fp, 0);
- /* Sizeof text + data */
- save_int(fp, obj->text.size + obj->data.size);
- /* Offset of text */
- save_int(fp, 0x144);
- save_int(fp, obj->text.size + obj->data.size);
- save_int(fp, 0x7);
- save_int(fp, 0x7);
- save_int(fp, 0x2);
- save_int(fp, 0);
- fprintf(fp, "__text");
- for (i = 0; i < 10; i++)
- save_zero(fp);
- fprintf(fp, "__TEXT");
- for (i = 0; i < 10; i++)
- save_zero(fp);
- save_int(fp, 0);
- /* Sizeof text */
- save_int(fp, obj->text.size);
- save_int(fp, 0x144);
- save_int(fp, 0x2);
- /* Offset of rellocation table. */
- save_int(fp, 0x144 + obj->text.size + obj->data.size);
- save_int(fp, obj->text_rellocation_count);
- save_int(fp, 0x80000400);
- save_int(fp, 0);
- save_int(fp, 0);
- fprintf(fp, "__data");
- for (i = 0; i < 10; i++)
- save_zero(fp);
- fprintf(fp, "__DATA");
- for (i = 0; i < 10; i++)
- save_zero(fp);
- /* Data VMA */
- save_int(fp, obj->text.size);
- /* Data size */
- save_int(fp, obj->data.size);
- /* Data file offset */
- save_int(fp, 0x144 + obj->text.size);
- save_int(fp, 0x2);
- for (i = 0; i < 5; i++)
- save_int(fp, 0);
- save_int(fp, 0x2);
- /* save_int(fp, obj->symbol_count * 0xc); */
- save_int(fp, 0x18);
- /* Offset of stabs */
- save_int(fp, 0x144 +
- obj->text.size + obj->data.size + obj->text_rellocation_count * 0x8);
- /* Number of stabs (symbol table) */
- save_int(fp, obj->symbol_count);
- /* Offset of symbol list */
- save_int(fp, 0x144 + obj->text.size + obj->data.size +
- obj->text_rellocation_count * 0x8 + obj->symbol_count * 0xc);
- /* Sizeof symbol list */
- save_int(fp, obj->symbol_list_size);
- save_int(fp, 0xB);
- save_int(fp, 0x50);
- for (i = 0; i < 3; i++)
- save_int(fp, 0);
- save_int(fp, obj->symbol_count);
- save_int(fp, obj->symbol_count);
- for (i = 0; i < 13; i++)
- save_int(fp, 0);
-
- /* Text */
- for (i = 0; i < obj->text.size; i++)
- fprintf(fp, "%c", obj->text.code[i]);
- /* Data */
- for (i = 0; i < obj->data.size; i++)
- fprintf(fp, "%c", obj->data.code[i]);
- /* Text rellocations */
- /* XXX This is an infinite loop. When i = 0, i-- goes to very large. */
- for (i = obj->text_rellocation_count - 1; i >= 0; i--) {
- save_int(fp, obj->text_rellocation_table[i].offset);
- save_short(fp, obj->text_rellocation_table[i].symbol_number);
- save_short(fp, obj->text_rellocation_table[i].type);
- }
- /* Symbol table */
- for (i = 0; i < obj->symbol_count; i++) {
- save_int(fp, obj->symbol_table[i].offset_list);
- save_int(fp, obj->symbol_table[i].type);
- save_int(fp, obj->symbol_table[i].value);
- }
- /* Symbol list */
- for (i = 0; i < obj->symbol_count; i++) {
- if (obj->symbol_table[i].type != STYPE_GCC)
- fprintf(fp, "_%s", obj->symbol_table[i].symbol);
- else
- fprintf(fp, "%s", obj->symbol_table[i].symbol);
- save_zero(fp);
- }
- fclose(fp);
-}
-
-#endif /* EXEC_MACH_O */
-
-#ifdef EXEC_COFF
-
-/* File offsets */
-# define TEXT_CODE 0x14 + (3 * 0x28)
-# define DATA_CODE TEXT_CODE + obj->text.size
-# define TEXT_RELOC DATA_CODE + obj->data.size
-# define DATA_RELOC TEXT_RELOC + (obj->text_rellocation_count * 0xA)
-# define SYMTAB DATA_RELOC + (obj->data_rellocation_count * 0xA)
-
-void
-Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)
-{
- FILE *fp;
- int i;
- size_t j;
-
- fp = fopen(file, "wb");
-
- save_short(fp, 0x14C); /* i386 */
- save_short(fp, 3); /* Number of sections */
- save_int(fp, Parrot_intval_time());
- save_int(fp, SYMTAB);
- save_int(fp, obj->symbol_count);
- save_short(fp, 0);
- save_short(fp, 0x104); /* 32 bit LE, no line numbers */
-
- fwrite(".text\0\0\0", 8, 1, fp);
- save_int(fp, 0);
- save_int(fp, 0);
- save_int(fp, obj->text.size);
- save_int(fp, TEXT_CODE);
- save_int(fp, TEXT_RELOC);
- save_int(fp, 0);
- save_short(fp, (short)obj->text_rellocation_count);
- save_short(fp, 0);
- save_int(fp, 0x20);
-
- fwrite(".data\0\0\0", 8, 1, fp);
- save_int(fp, 0);
- save_int(fp, 0);
- save_int(fp, obj->data.size);
- save_int(fp, DATA_CODE);
- save_int(fp, DATA_RELOC);
- save_int(fp, 0);
- save_short(fp, (short)obj->data_rellocation_count);
- save_short(fp, 0);
- save_int(fp, 0x40);
-
- fwrite(".bss\0\0\0\0", 8, 1, fp);
- save_int(fp, 0);
- save_int(fp, 0);
- save_int(fp, obj->bss.size);
- save_int(fp, 0);
- save_int(fp, 0);
- save_int(fp, 0);
- save_short(fp, 0);
- save_short(fp, 0);
- save_int(fp, 0x80);
-
- /* Text */
- for (j = 0; j < obj->text.size; j++)
- fprintf(fp, "%c", obj->text.code[j]);
- /* Data */
- for (j = 0; j < obj->data.size; j++)
- fprintf(fp, "%c", obj->data.code[j]);
- /* Text rellocations */
- for (i = 0; i < obj->text_rellocation_count; i++) {
- save_int(fp, obj->text_rellocation_table[i].offset);
- save_int(fp, obj->text_rellocation_table[i].symbol_number);
- switch (obj->text_rellocation_table[i].type) {
- case RTYPE_FUNC:
- save_short(fp, 0x14);
- break;
- case RTYPE_COM:
- case RTYPE_DATA:
- save_short(fp, 0x06);
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_ERROR,
- "Unknown text rellocation type: %d\n",
- obj->text_rellocation_table[i].type);
- break;
- }
- }
- /* Symbol table */
- for (i = 0; i < obj->symbol_count; i++) {
- save_int(fp, 0);
- save_int(fp, obj->symbol_table[i].offset_list);
- save_int(fp, obj->symbol_table[i].value);
- switch (obj->symbol_table[i].type) {
- case STYPE_FUNC:
- save_short(fp, 1); /* .text */
- save_short(fp, 0x20);
- break;
- case STYPE_GDATA:
- save_short(fp, 2); /* .data */
- save_short(fp, 0);
- break;
- case STYPE_COM:
- save_short(fp, 0);
- save_short(fp, 0);
- break;
- case STYPE_UND:
- save_short(fp, 0);
- save_short(fp, 0x20);
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_ERROR,
- "Unknown symbol type: %d\n", obj->symbol_table[i].type);
- break;
- }
- putc(2, fp); /* "extern" class */
- putc(0, fp);
- }
- /* Symbol list */
- save_int(fp, obj->symbol_list_size);
- for (i = 0; i < obj->symbol_count; i++) {
- if (obj->symbol_table[i].type != STYPE_GCC)
- fprintf(fp, "_%s", obj->symbol_table[i].symbol);
- else
- fprintf(fp, "%s", obj->symbol_table[i].symbol);
- save_zero(fp);
- }
- fclose(fp);
-}
-
-#endif /* EXEC_COFF */
-
-/*
-
-=item C<static void save_struct(FILE *fp, void *sp, size_t size)>
-
-Writes the C<struct> C<sp> to the file.
-
-=cut
-
-*/
-
-static void
-save_struct(FILE *fp, void *sp, size_t size)
-{
- unsigned int i;
-
- for (i = 0; i < size; i++)
- fprintf(fp, "%c", ((char *)sp)[i]);
-}
-
-/*
-
-=item C<static void save_zero(FILE *fp)>
-
-Writes 0 to the file.
-
-=cut
-
-*/
-
-static void
-save_zero(FILE *fp)
-{
- fprintf(fp, "%c", 0);
-}
-
-#if PARROT_BIGENDIAN
-
-/*
-
-=item C<static void save_int(FILE *fp, int i)>
-
-Writes C<i> to the file.
-
-=cut
-
-*/
-
-static void
-save_int(FILE *fp, int i)
-{
- fprintf(fp, "%c%c%c%c", (char)(i >> 24), (char)(i >> 16),
- (char)(i >> 8), (char)i);
-}
-
-/*
-
-=item C<static void save_short(FILE *fp, short s)>
-
-Writes C<s> to the file.
-
-=cut
-
-*/
-
-static void
-save_short(FILE *fp, short s)
-{
- fprintf(fp, "%c%c", (char)(s >> 8), (char)s);
-}
-
-#else /* PARROT_BIGENDIAN */
-
-static void
-save_short(FILE *fp, short s)
-{
- fprintf(fp, "%c%c", (char)s, (char)(s >> 8));
-}
-
-static void
-save_int(FILE *fp, int i)
-{
- fprintf(fp, "%c%c%c%c", (char)i, (char)(i >> 8),
- (char)(i >> 16), (char)(i >> 24));
-}
-
-#endif /* PARROT_BIGENDIAN */
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<include/parrot/exec.h>, F<src/exec_save.h>, F<src/exec.c>
-and F<src/exec_start.c>.
-
-=head1 HISTORY
-
-Initial version by Daniel Grunblatt on 2003.6.9.
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/exec_save.h
==============================================================================
--- trunk/src/exec_save.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2003-2007, Parrot Foundation.
- */
-
-/*
- * exec.h
- *
- * SVN Info
- * $Id$
- * Overview:
- * Exec header file.
- * History:
- * Initial version by Daniel Grunblatt on 2003.6.9
- * Notes:
- * References:
- */
-
-#ifndef PARROT_EXEC_SAVE_H_GUARD
-#define PARROT_EXEC_SAVE_H_GUARD
-
-void Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file);
-
-#endif /* PARROT_EXEC_SAVE_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/exec_start.c
==============================================================================
--- trunk/src/exec_start.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,135 +0,0 @@
-/*
-Copyright (C) 2001-2009, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/exec_start.c - Call compiled code
-
-=head1 SYNOPSIS
-
-I<What goes here?>
-
-=head1 DESCRIPTION
-
-Exec is a tool for using the JIT at compile time to generate native
-executables.
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-#include "parrot/parrot.h"
-#include "parrot/string.h"
-#include "parrot/exec.h"
-#include "jit.h"
-#define JIT_EMIT 1
-#include "jit_emit.h"
-#include "parrot/embed.h"
-
-opcode_t* run_compiled(PARROT_INTERP,
- opcode_t *cur_opcode, opcode_t *code_start);
-
-/*
-
-=item C<int main(int argc, char * argv[])>
-
-The run-loop.
-
-=cut
-
-*/
-
-int
-main(int argc, char * argv[])
-{
- /* long * opp; */
- Interp * interp;
- PackFile * pf;
- opcode_t * code_start;
- extern char * program_code;
- /* extern long opcode_map; */
- /* extern int bytecode_offset; */
-#if defined(JIT_CGP)
- extern void * exec_prederef_code;
-#endif
- /* extern int Parrot_exec_run; */
- /* extern PackFile_Constant *exec_const_table; */
- /* extern PackFile_Constant const_table; */
- extern Interp interpre;
-
- /* s. exec.c */
- /* Parrot_exec_run = 1; */
- /* s. packfile.c (PackFile_ConstTable_unpack()) */
- /* exec_const_table = &const_table; */
- interp = Parrot_new(NULL);
- if (!interp) {
- return 1;
- }
-
- /* run_native = run_compiled; */
- /* TODO make also a shared variant of PackFile_new */
- pf = PackFile_new(interp, 0);
-
- if (!PackFile_unpack(interp, pf, (opcode_t *)(&program_code),
- sizeof (&program_code)))
- {
- printf("Can't unpack.\n");
- return 1;
- }
- Parrot_pbc_load(interp, pf);
- PackFile_fixup_subs(interp, PBC_PBC, NULL);
-
- /* opcode_map has the offset of each opcode in the compiled code
- * this modifies it to be address of the opcode.
- */
- /*
- opp = &opcode_map;
- for (i = 0; i < (int)interpre.code->base.size; i++) {
- opp[i] += (long)run_compiled;
- }
- */
-
-#if defined(JIT_CGP)
- exec_init_prederef(interp, &exec_prederef_code);
-#endif
- /* Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "exec"));
- interp->code->base.data =
- (opcode_t *)&((&program_code)[bytecode_offset]);
- Parrot_exec_run = 0; */
- Parrot_runcode(interp, argc, argv);
- /*
- run_compiled(interp,
- (opcode_t *)&((&program_code)[bytecode_offset]));
- */
- Parrot_exit(interp, 0);
-}
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<include/parrot/exec.h>, F<src/exec_save.h>, F<src/exec.c>
-and F<compilers/imcc/main.c>.
-
-=head1 HISTORY
-
-Initial version by Daniel Grunblatt on 2003.6.9
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Added: trunk/src/frame_builder.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/src/frame_builder.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -0,0 +1,848 @@
+/*
+Copyright (C) 2008-2009, Parrot Foundation.
+$Id$
+*/
+
+/* HEADERIZER HFILE: none */
+/* HEADERIZER STOP */
+
+#include "parrot/parrot.h"
+#include "pmc/pmc_fixedintegerarray.h"
+#include "pmc/pmc_unmanagedstruct.h"
+#include "pmc/pmc_managedstruct.h"
+#include "frame_builder.h"
+
+/*
+
+=over 4
+
+=item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)>
+
+This is a callback to implement the proper freeing semantics. It is called by
+the ManagedStruct PMC as it is garbage collected.
+
+=cut
+
+*/
+
+void
+Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)
+{
+ const struct jit_buffer_private_data * const jit = (struct jit_buffer_private_data*)priv;
+ mem_free_executable(ptr, jit->size);
+ free(priv);
+}
+
+/*
+
+=item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)>
+
+This is a callback to implement the proper cloning semantics for jit buffers.
+It is called by the ManagedStruct PMC's clone() function.
+
+=back
+
+=cut
+
+*/
+
+PMC *
+Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)
+{
+ PMC * const rv = pmc_new(interp, pmc->vtable->base_type);
+
+ VTABLE_init(interp, rv);
+ /* copy the attributes */
+ {
+ void (*tmpfreefunc)(PARROT_INTERP, void*, void*);
+ GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc);
+ SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc);
+ }
+ {
+ PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*);
+ GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc);
+ SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc);
+ }
+
+ {
+ void *freepriv, *clonepriv;
+ GETATTR_ManagedStruct_custom_free_priv(interp , pmc, freepriv);
+ GETATTR_ManagedStruct_custom_clone_priv(interp, pmc, clonepriv);
+ if (freepriv) {
+ void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
+ memcpy(tmp, freepriv, sizeof (struct jit_buffer_private_data));
+ SETATTR_ManagedStruct_custom_free_priv(interp, rv , tmp);
+ if (clonepriv == freepriv) {
+ /* clonepriv is a copy of freepriv, make it a copy in the clone too. */
+ SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
+ clonepriv = NULL; /* disable the clonepriv copying below */
+ }
+ }
+ if (clonepriv) {
+ void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
+ memcpy(tmp, clonepriv, sizeof (struct jit_buffer_private_data));
+ SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
+ }
+ }
+
+ /* copy the execmem buffer */
+ if (PARROT_MANAGEDSTRUCT(pmc)->ptr) {
+ struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
+ void *ptr = PARROT_MANAGEDSTRUCT(pmc)->ptr;
+ void *newptr = mem_alloc_executable(jit->size);
+ if (!newptr)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+ "Cannot allocate executable memory");
+ memcpy(newptr, ptr, jit->size);
+ PARROT_MANAGEDSTRUCT(rv)->ptr = newptr;
+ }
+
+ return rv;
+}
+
+INTVAL
+get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n)
+{
+ if (n >= st->src.n)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "too few arguments passed to NCI function");
+
+ Parrot_fetch_arg_nci(interp, st);
+
+ return UVal_int(st->val);
+}
+
+FLOATVAL
+get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n)
+{
+ if (n >= st->src.n)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "too few arguments passed to NCI function");
+
+ Parrot_fetch_arg_nci(interp, st);
+
+ return UVal_num(st->val);
+}
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+STRING*
+get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n)
+{
+ /* TODO or act like below? */
+ if (n >= st->src.n)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "too few arguments passed to NCI function");
+
+ Parrot_fetch_arg_nci(interp, st);
+
+ return UVal_str(st->val);
+}
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+PMC*
+get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n)
+{
+ /*
+ * excessive args are passed as NULL
+ * used by e.g. MMD infix like __add
+ */
+ if (n < st->src.n)
+ Parrot_fetch_arg_nci(interp, st);
+ else
+ UVal_pmc(st->val) = PMCNULL;
+
+ return UVal_pmc(st->val);
+}
+
+/*
+ * set return value
+ */
+void
+set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val)
+{
+ Parrot_init_ret_nci(interp, st, "I");
+ if (st->dest.i < st->dest.n) {
+ UVal_int(st->val) = val;
+ Parrot_convert_arg(interp, st);
+ Parrot_store_arg(interp, st);
+ }
+}
+
+void
+set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val)
+{
+ Parrot_init_ret_nci(interp, st, "N");
+ if (st->dest.i < st->dest.n) {
+ UVal_num(st->val) = val;
+ Parrot_convert_arg(interp, st);
+ Parrot_store_arg(interp, st);
+ }
+}
+
+void
+set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val)
+{
+ Parrot_init_ret_nci(interp, st, "S");
+ if (st->dest.i < st->dest.n) {
+ UVal_str(st->val) = val;
+ Parrot_convert_arg(interp, st);
+ Parrot_store_arg(interp, st);
+ }
+}
+
+void
+set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val)
+{
+ Parrot_init_ret_nci(interp, st, "P");
+ if (st->dest.i < st->dest.n) {
+ UVal_pmc(st->val) = val;
+ Parrot_convert_arg(interp, st);
+ Parrot_store_arg(interp, st);
+ }
+}
+
+int
+emit_is8bit(long disp)
+{
+ return disp >= -128 && disp <= 127;
+}
+
+char *
+emit_disp8_32(char *pc, int disp)
+{
+ if (emit_is8bit(disp)) {
+ *(pc++) = (char)disp;
+ return pc;
+ }
+ else {
+ *(long *)pc = disp;
+ return pc + 4;
+ }
+}
+
+void
+emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base)
+{
+ int scale_byte;
+
+ switch (scale) {
+ case 1:
+ scale_byte = emit_Scale_1;
+ break;
+ case 2:
+ scale_byte = emit_Scale_2;
+ break;
+ case 4:
+ scale_byte = emit_Scale_4;
+ break;
+ case 8:
+ scale_byte = emit_Scale_8;
+ break;
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+ "Invalid scale factor %d\n", scale);
+ return;
+ }
+
+ *pc = (char)(scale_byte | (i == emit_None ? emit_Index_None : emit_reg_Index(i)) |
+ emit_reg_Base(base));
+}
+
+char *
+emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i, int scale, long disp)
+{
+ if (i && !scale)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+ "emit_r_X passed invalid scale+index combo\n");
+
+ if (base == emit_EBP) {
+ /* modrm disp */
+ if (i == emit_None) {
+ *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
+ | reg_opcode | emit_reg_rm(emit_EBP));
+ return emit_disp8_32(pc, disp);
+ }
+ /* modrm sib disp */
+ else {
+ *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
+ | reg_opcode | emit_b100);
+ emit_sib(interp, pc++, scale, i, base);
+ return emit_disp8_32(pc, disp);
+ }
+ }
+
+ /* modrm sib disp */
+ if (base == emit_ESP) {
+ *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
+ | reg_opcode | emit_rm_b100);
+ emit_sib(interp, pc++, scale, i, emit_ESP);
+ return emit_disp8_32(pc, disp);
+ }
+
+ /* modrm disp32 */
+ if (!base && !(i && scale)) {
+ *(pc++) = (char)(emit_Mod_b00 | reg_opcode | emit_rm_b101);
+ *(long *)pc = disp;
+ return pc + 4;
+ }
+
+ /* Ok, everything should be more regular here */
+ *(pc++) = (char)((disp == 0 ? emit_Mod_b00 :
+ (emit_is8bit(disp) ?
+ emit_Mod_b01 : emit_Mod_b10)) |
+ reg_opcode |
+ (!base || (scale && i) ? emit_rm_b100 : emit_reg_rm(base)));
+
+ if (!base || (scale && i)) {
+ emit_sib(interp, pc++, scale, i, base);
+ }
+ if (disp)
+ pc = emit_disp8_32(pc, disp);
+
+ return pc;
+}
+
+char *
+emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg)
+{
+ if (opcode == emit_b000 && imm < 0) {
+ opcode = emit_b001; /* -rol => 32 + ror */
+ imm = -imm;
+ }
+
+ if (imm == 0) {
+ /* noop */
+ }
+ else if (imm == 1) {
+ *(pc++) = (char) 0xd1;
+ *(pc++) = (char) emit_alu_X_r(opcode, reg);
+ }
+ else if (imm > 1 && imm < 33) {
+ *(pc++) = (char) 0xc1;
+ *(pc++) = (char) emit_alu_X_r(opcode, reg);
+ *(pc++) = (char)imm;
+ }
+ else {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+ "emit_shift_i_r passed invalid shift\n");
+ }
+
+ return pc;
+}
+
+char *
+emit_popl_r(char *pc, int reg)
+{
+ *(pc++) = (char)(0x58 | (reg - 1));
+ return pc;
+}
+
+unsigned char *lastpc;
+
+# define NATIVECODE jit_info->native_ptr
+
+/*
+ * preserve registers around a functioncall
+ *
+ * all used register around a call (skip >= 0 := return result
+ *
+ * TODO factor out common code
+ * use jit_emit_mov_RM_{in} functions (load/store base indexed)
+ * and a macro to retrieve sp
+ */
+int
+jit_save_regs_call(Parrot_jit_info_t *jit_info, PARROT_INTERP, int skip)
+{
+ int i, used_i, used_n;
+ const jit_arch_regs *reg_info;
+
+ used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
+ used_n = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM);
+ jit_emit_sub_ri_i(interp, jit_info->native_ptr, emit_ESP,
+ (used_i * sizeof (INTVAL) + used_n * sizeof (FLOATVAL)));
+ reg_info = &jit_info->arch_info->regs[jit_info->code_type];
+ for (i = 0; i < used_i; ++i) {
+ /* XXX need 2 skip vars */
+ if (reg_info->map_I[i] == skip)
+ continue;
+ emitm_movl_r_m(interp, NATIVECODE, reg_info->map_I[i], emit_ESP,
+ emit_None, 1,
+ (used_n * sizeof (FLOATVAL) +
+ i * sizeof (INTVAL)));
+ }
+ for (i = 0; i < used_n; ++i) {
+ if (reg_info->map_F[i] == skip)
+ continue;
+ emitm_fld(NATIVECODE, reg_info->map_F[i]);
+ jit_emit_fstore_mb_n(interp, NATIVECODE, emit_ESP, (i * sizeof (FLOATVAL)));
+ }
+ return used_n;
+}
+
+void
+jit_restore_regs_call(Parrot_jit_info_t *jit_info, PARROT_INTERP,
+ int skip)
+{
+
+ int i, used_i, used_n;
+ const jit_arch_regs *reg_info;
+
+ used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
+ used_n = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM);
+ reg_info = &jit_info->arch_info->regs[jit_info->code_type];
+
+ for (i = 0; i < used_i; ++i) {
+ if (reg_info->map_I[i] == skip)
+ continue;
+ emitm_movl_m_r(interp, NATIVECODE, reg_info->map_I[i], emit_ESP,
+ emit_None, 1,
+ (used_n * sizeof (FLOATVAL) +
+ i * sizeof (INTVAL)));
+ }
+ for (i = 0; i < used_n; ++i) {
+ if (reg_info->map_F[i] == skip)
+ continue;
+ jit_emit_fload_mb_n(interp, NATIVECODE, emit_ESP, (i * sizeof (FLOATVAL)));
+ emitm_fstp(NATIVECODE, (1+reg_info->map_F[i]));
+ }
+
+ jit_emit_add_ri_i(interp, jit_info->native_ptr, emit_ESP,
+ (used_i * sizeof (INTVAL) + used_n * sizeof (FLOATVAL)));
+}
+
+/*
+ * params are put rigth to left on the stack
+ * parrot registers are counted left to right
+ * so this function returns for a given register type
+ * the needed register number
+ * TODO handel overflow params
+ */
+
+int
+count_regs(PARROT_INTERP, char *sig, char *sig_start)
+{
+ const char *typs[] = {
+ "Ilisc", /* I */
+ "StbB", /* S */
+ "pP234", /* P */
+ "Nfd" /* N */
+ };
+ int first_reg = 0;
+ int i, found;
+
+ /* char at sig is the type to look at */
+ for (found = -1, i = 0; i < 4; i++) {
+ if (strchr(typs[i], *sig)) {
+ found = i;
+ break;
+ }
+ }
+
+ if (found == -1)
+ Parrot_ex_throw_from_c_args(interp, NULL, 1,
+ "Parrot_jit_build_call_func: sig char not found\n");
+
+ for (--sig; sig > sig_start; --sig) {
+ if (strchr(typs[found], *sig)) {
+ ++first_reg;
+ }
+ }
+ return first_reg;
+}
+
+size_t
+calc_signature_needs(const char *sig, int *strings)
+{
+ size_t stack_size = 0;
+ while (*sig) {
+ switch (*sig) {
+ case 't':
+ (*strings)++;
+ stack_size +=4;
+ break;
+ case 'd':
+ stack_size +=8;
+ break;
+ default:
+ stack_size +=4;
+ break;
+ }
+ sig++;
+ }
+ return stack_size;
+
+}
+
+/*
+ * The function generated here is called as func(interp, nci_info)
+ * interp ... 8(%ebp)
+ * nci_info ... 12(%ebp)
+ *
+ * The generate function for a specific signature looks quite similar to
+ * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles
+ * just compare the disassembly.
+ *
+ * If a non-NULL sizeptr is passed, the integer it points to will be written
+ * with the size of the allocated execmem buffer.
+ */
+
+void *
+Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, int *sizeptr)
+{
+ Parrot_jit_info_t jit_info;
+ char *pc;
+ int i = 0;
+ int arg_count = 0;
+ int string_buffer_count = 0;
+ const int ST_SIZE_OF = 124;
+ const int JIT_ALLOC_SIZE = 1024;
+
+ char *signature_str = Parrot_str_to_cstring(interp, signature);
+ /* skip over the result */
+ char *sig = signature_str + 1;
+ size_t stack_space_needed = calc_signature_needs(sig,
+ &string_buffer_count);
+
+ int base_offset = 0;
+ int strings_offset = base_offset - (sizeof (char *) * string_buffer_count);
+ int st_offset = strings_offset - ST_SIZE_OF;
+ int args_offset = st_offset - stack_space_needed;
+ int temp_calls_offset = args_offset - 16;
+ int total_stack_needed = -temp_calls_offset;
+
+ /*
+ * ESP
+ * 0-15, 16 bytes for utility calls
+ * stack_space_needed for actual NCI call
+ * st
+ * STRINGS -> char * holding space
+ * EBP
+ */
+
+ /* this ought to be enough - the caller of this function
+ * should free the function pointer returned here
+ */
+ pc = jit_info.native_ptr = jit_info.arena.start = (char *)mem_alloc_executable(JIT_ALLOC_SIZE);
+ if (! pc)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+ "Cannot allocate executable memory");
+
+
+ /* this generated jit function will be called as (INTERP (EBP 8), func_ptr
+ * (ESP 12), args signature (ESP 16)) */
+
+ /* make stack frame, preserve %ebx */
+ jit_emit_stack_frame_enter(pc);
+
+ emitm_subl_i_r(pc, total_stack_needed, emit_ESP);
+
+ /* Parrot_init_arg_nci(interp, &st, "S"); */
+ /* args signature "S" */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 16);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+
+ /*&st*/
+ emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+
+ /*interpreter*/
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
+
+ if (sig && *sig)
+ emitm_call_cfunc(pc, Parrot_init_arg_nci);
+
+ while (*sig) {
+ emitm_movl_i_m(pc, arg_count, emit_EBP, 0, 1, temp_calls_offset + 8);
+
+ switch (*sig) {
+ case '0': /* null ptr or such - doesn't consume a reg */
+ jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ break;
+ case 'f':
+ emitm_call_cfunc(pc, get_nci_N);
+ emitm_fstps(interp, pc, emit_EBP, 0, 1, args_offset);
+ break;
+ case 'N':
+ case 'd':
+ emitm_call_cfunc(pc, get_nci_N);
+ emitm_fstpl(interp, pc, emit_EBP, 0, 1, args_offset);
+ args_offset += 4;
+ break;
+ case 'I': /* INTVAL */
+ case 'l': /* long */
+ case 'i': /* int */
+ emitm_call_cfunc(pc, get_nci_I);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ break;
+ case 't': /* string, pass a cstring */
+ emitm_call_cfunc(pc, get_nci_S);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+ emitm_call_cfunc(pc, string_to_cstring_nullable);
+
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ /* save off temporary allocation address */
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset);
+ strings_offset += 4;
+
+ /* reset ESP(4) */
+ emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+ break;
+ case 's': /* short: movswl intreg_o(base), %eax */
+ emitm_call_cfunc(pc, get_nci_I);
+ emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ break;
+ case 'c': /* char: movsbl intreg_o(base), %eax */
+ emitm_call_cfunc(pc, get_nci_I);
+ emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ break;
+ case 'J': /* interpreter */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ arg_count--;
+ break;
+ case 'p': /* push pmc->data */
+ emitm_call_cfunc(pc, get_nci_P);
+ /* save off PMC* */
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+ /* lookup get_pointer in VTABLE */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable));
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer));
+ emitm_callr(pc, emit_EAX);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ /* reset ESP(4) */
+ emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+
+ break;
+ case 'O': /* push PMC * object in P2 */
+ case 'P': /* push PMC * */
+ case '@':
+ emitm_call_cfunc(pc, get_nci_P);
+#if PARROT_CATCH_NULL
+ /* PMCNULL is a global */
+ jit_emit_cmp_rm_i(pc, emit_EAX, &PMCNULL);
+ emitm_jxs(pc, emitm_jne, 2); /* skip the xor */
+ jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
+#endif
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ break;
+ case 'v':
+ break;
+ case 'b': /* buffer (void*) pass Buffer_bufstart(SReg) */
+ emitm_call_cfunc(pc, get_nci_S);
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
+ (size_t) &Buffer_bufstart((STRING *) NULL));
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ break;
+ case 'B': /* buffer (void**) pass &Buffer_bufstart(SReg) */
+ emitm_call_cfunc(pc, get_nci_S);
+ emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
+ (size_t) &Buffer_bufstart((STRING *) NULL));
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ break;
+ case 'S':
+ emitm_call_cfunc(pc, get_nci_S);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
+ break;
+
+
+ /* I have no idea how to handle these */
+ case '2':
+ case '3':
+ case '4':
+ case 'V':
+ mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
+ Parrot_str_free_cstring(signature_str);
+ return NULL;
+ break;
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+ "Unknown arg Signature %c\n", *sig);
+ /*
+ * oops unknown signature:
+ * cleanup and try nci.c
+ */
+ mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
+ Parrot_str_free_cstring(signature_str);
+ return NULL;
+ }
+ args_offset +=4;
+ arg_count++;
+ sig++;
+ }
+
+ /* prepare to call VTABLE_get_pointer, set up args */
+ /* interpreter - movl 8(%ebp), %eax */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
+
+ /* pmc - movl 12(%ebp), %eax */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 12);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+
+ /* get the get_pointer() pointer from the pmc's vtable */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable));
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer));
+
+ /* call get_pointer(), result goes into eax */
+ emitm_callr(pc, emit_EAX);
+ emitm_addl_i_r(pc, 16, emit_ESP);
+
+ /* call the resulting function pointer */
+ emitm_callr(pc, emit_EAX);
+ emitm_subl_i_r(pc, 16, emit_ESP);
+
+ /* SAVE OFF EAX */
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+
+ /*&st*/
+ emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+
+ /*interpreter*/
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
+
+ /* RESTORE BACK EAX */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+
+ /* now place return value in registers */
+ /* first in signature is the return value */
+ sig = signature_str; /* the result */
+ switch (*sig) {
+ /* I have no idea how to handle these */
+ case '2':
+ case '3':
+ case '4':
+ /* get integer from pointer - untested */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0);
+ if (*sig == 2) /* short */
+ emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
+ emitm_call_cfunc(pc, set_nci_I);
+ break;
+ case 'f':
+ case 'd':
+ jit_emit_fstore_mb_n(interp, pc, emit_EBP, temp_calls_offset + 8);
+ emitm_call_cfunc(pc, set_nci_N);
+ /* pop num from st(0) and mov to reg */
+ break;
+ case 's':
+ /* movswl %ax, %eax */
+ emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+ emitm_call_cfunc(pc, set_nci_I);
+ break;
+ case 'c':
+ /* movsbl %al, %eax */
+ emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+ emitm_call_cfunc(pc, set_nci_I);
+ break;
+ case 'I': /* INTVAL */
+ case 'l':
+ case 'i':
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+ emitm_call_cfunc(pc, set_nci_I);
+ break;
+ case 'v': /* void - do nothing */
+ break;
+ case 'P':
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+ emitm_call_cfunc(pc, set_nci_P);
+ break;
+ case 'p': /* make a new unmanaged struct */
+ /* save return value on stack */
+
+ /* save pointer p */
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 12);
+
+ /* make new pmc */
+ emitm_movl_i_m(pc, enum_class_UnManagedStruct, emit_EBP, 0, 1, temp_calls_offset + 4);
+ emitm_call_cfunc(pc, pmc_new);
+
+ /* restore pointer p to EDX */
+ emitm_movl_m_r(interp, pc, emit_EDX, emit_EBP, 0, 1, temp_calls_offset + 12);
+
+ /* copy UnManagedStruct to stack for set_nci_P call */
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+
+ /* eax = PMC, get return value into edx */
+ /* mov data(%eax), %eax
+ mov %edx, ptr(%eax) */
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));
+ emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1,
+ offsetof(struct Parrot_UnManagedStruct_attributes, ptr));
+
+ /* reset EBP(4) */
+ emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+
+ emitm_call_cfunc(pc, set_nci_P);
+ break;
+ case 'S':
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+ emitm_call_cfunc(pc, set_nci_S);
+ break;
+ case 't': /* string */
+ /* EAX is char* */
+ emitm_movl_i_m(pc, 0, emit_EBP, 0, 1, temp_calls_offset + 8); /* len */
+
+ /* overwrites address of st in EBP(4) */
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+
+ emitm_call_cfunc(pc, Parrot_str_new);
+
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
+
+ /* reset EBP(4) */
+ emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+
+ emitm_call_cfunc(pc, set_nci_S);
+ break;
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+ "Unknown return Signature %c\n", *sig);
+ /*
+ * oops unknown signature:
+ * cleanup and try nci.c
+ */
+ Parrot_str_free_cstring(signature_str);
+ mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
+ return NULL;
+ }
+
+ /* free temporary strings */
+ strings_offset = st_offset + ST_SIZE_OF;
+ for (i=0; i<string_buffer_count; i++) {
+ emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset);
+ emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
+ emitm_call_cfunc(pc, Parrot_str_free_cstring);
+ strings_offset += 4;
+ }
+
+ jit_emit_stack_frame_leave(pc);
+ emitm_ret(pc);
+ PARROT_ASSERT(pc - jit_info.arena.start <= JIT_ALLOC_SIZE);
+
+ /* could shrink arena.start here to used size */
+
+ if (sizeptr)
+ *sizeptr = JIT_ALLOC_SIZE;
+ Parrot_str_free_cstring(signature_str);
+ return (void *)D2FPTR(jit_info.arena.start);
+}
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Copied and modified: trunk/src/frame_builder.h (from r41354, trunk/src/jit/i386/jit_emit.h)
==============================================================================
--- trunk/src/jit/i386/jit_emit.h Sat Sep 19 07:22:47 2009 (r41354, copy source)
+++ trunk/src/frame_builder.h Sat Sep 19 08:10:11 2009 (r41356)
@@ -3,7 +3,7 @@
*/
/*
- * jit_emit.h
+ * frame_builder.h
*
* i386
*
@@ -24,6 +24,88 @@
#include "parrot/hash.h"
#include "parrot/oplib/ops.h"
+/* Parrot_jit_arena_t
+ * Holds pointers to the native code of one or more sections.
+ *
+ * start: Start of current native code segment.
+ * size: The size of the arena in bytes
+ * map_size: The size of the map in bytes.
+ */
+
+typedef struct Parrot_jit_arena_t {
+ char *start;
+ ptrdiff_t size;
+ unsigned long map_size;
+} Parrot_jit_arena_t;
+
+typedef enum {
+ JIT_CODE_FILE,
+ JIT_CODE_SUB,
+ JIT_CODE_SUB_REGS_ONLY,
+
+ /* size */
+ JIT_CODE_TYPES,
+ /* special cases */
+ JIT_CODE_RECURSIVE = 0x10,
+ JIT_CODE_SUB_REGS_ONLY_REC = JIT_CODE_SUB_REGS_ONLY|JIT_CODE_RECURSIVE
+} enum_jit_code_type;
+
+/* Parrot_jit_info_t
+ * All the information needed to jit the bytecode will be here.
+ *
+ * native_ptr: Current pointer to native code.
+ * arena: The arena inlined, this will be the only one used in cases
+ * where there is a way to load an immediate.
+ */
+
+typedef struct Parrot_jit_info_t {
+ char *native_ptr;
+ Parrot_jit_arena_t arena;
+ INTVAL code_type;
+ const struct jit_arch_info_t *arch_info;
+} Parrot_jit_info_t;
+
+typedef struct jit_arch_regs {
+ /*
+ * begin function - emit ABI call prologue
+ */
+
+ int n_mapped_I;
+ int n_preserved_I;
+ const char *map_I;
+ int n_mapped_F;
+ int n_preserved_F;
+ const char *map_F;
+} jit_arch_regs;
+
+typedef void (*mov_RM_f)(PARROT_INTERP, Parrot_jit_info_t *,
+ int cpu_reg, int base_reg, INTVAL offs);
+typedef void (*mov_MR_f)(PARROT_INTERP, Parrot_jit_info_t *,
+ int base_reg, INTVAL offs, int cpu_reg);
+
+typedef struct jit_arch_info_t {
+ /* CPU <- Parrot reg move functions */
+ mov_RM_f mov_RM_i;
+ mov_RM_f mov_RM_n;
+ /* Parrot <- CPU reg move functions */
+ mov_MR_f mov_MR_i;
+ mov_MR_f mov_MR_n;
+
+ /* register mapping info */
+ const jit_arch_regs regs[JIT_CODE_TYPES];
+} jit_arch_info;
+
+/*
+ * NCI interface
+ */
+void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *);
+/* custom pmc callback functions */
+void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv);
+PMC* Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
+struct jit_buffer_private_data {
+ int size;
+};
+
/* Scale factor values */
#define emit_Scale(scale) ((scale) << 6)
#define emit_Scale_1 emit_Scale(0)
@@ -49,7 +131,6 @@
INTVAL get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n);
FLOATVAL get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n);
-;
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
@@ -61,6 +142,11 @@
PMC*
get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n);
+#define GET_NCI_I(n) get_nci_I(interp, &st, (n))
+#define GET_NCI_S(n) get_nci_S(interp, &st, (n))
+#define GET_NCI_N(n) get_nci_N(interp, &st, (n))
+#define GET_NCI_P(n) get_nci_P(interp, &st, (n))
+
/*
* set return value
*/
@@ -72,35 +158,6 @@
void set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val);
-
-#if defined HAVE_COMPUTED_GOTO && defined __GNUC__ && PARROT_I386_JIT_CGP
-# define JIT_CGP
-#endif
-
-void call_func(Parrot_jit_info_t *jit_info, void (*addr) (void));
-
-void jit_emit_real_exception(Parrot_jit_info_t *jit_info);
-
-/*
- * get the register frame pointer
- */
-#define Parrot_jit_emit_get_base_reg_no(pc) \
- emit_EBX
-
-/*
- * get the *runtime* interpreter
- */
-
-#define Parrot_jit_emit_get_INTERP(interp, pc, dest) \
- emitm_movl_m_r((interp), (pc), (dest), emit_EBP, emit_None, 1, INTERP_BP_OFFS)
-
-/* see jit_begin */
-#ifdef JIT_CGP
-# define INTERP_BP_OFFS todo
-#else
-# define INTERP_BP_OFFS -16
-#endif
-
/*
* if we have a delegated method like typeof_i_p, that returns an INTVAL
* and that is all in a sequence of JITted opcodes, and when these INTVAL
@@ -138,8 +195,6 @@
#define emit_ESI 7
#define emit_EDI 8
-#define INT_REGISTERS_TO_MAP 4
-
/* Scratch register. */
#define ISR1 emit_EAX
@@ -218,19 +273,11 @@
*(long *)(pc) = (long)(imm); \
(pc) += 4; }
-#if EXEC_CAPABLE
-# define emitm_pushl_m(pc, mem) { \
- *((pc)++) = (char) 0xff; \
- *((pc)++) = (char) 0x35; \
- *(long *)(pc) = (long)(mem); \
- (pc) += 4; }
-#else /* EXEC_CAPABLE */
-# define emitm_pushl_m(pc, mem) { \
+#define emitm_pushl_m(pc, mem) { \
*((pc)++) = (char) 0xff; \
*((pc)++) = (char) 0x35; \
*(long *)(pc) = (long)(mem); \
(pc) += 4; }
-#endif /* EXEC_CAPABLE */
char * emit_pushl_m(PARROT_INTERP, char *pc, int base, int i, int scale,
long disp);
@@ -1040,16 +1087,9 @@
*((pc)++) = (char) 0xff; \
*((pc)++) = (char) 0xd0 | ((reg) - 1); }
-#if EXEC_CAPABLE
-# define emitm_callm(pc, b, i, s, d) { \
- *((pc)++) = (char) 0xff; \
- (pc) = emit_r_X((interp), (pc), emit_reg(emit_b010), (b), (i), (s), (d));\
- }
-#else /* EXEC_CAPABLE */
# define emitm_callm(pc, b, i, s, d) { \
*((pc)++) = (char) 0xff; \
(pc) = emit_r_X((interp), (pc), emit_reg(emit_b010), (b), (i), (s), (d)); }
-#endif /* EXEC_CAPABLE */
# define emitm_jumps(pc, disp) { \
*((pc)++) = (char) 0xeb; \
@@ -1063,16 +1103,9 @@
*((pc)++) = (char) 0xff; \
*((pc)++) = (char)(0xe0 | ((reg) - 1)); }
-#if EXEC_CAPABLE
-# define emitm_jumpm(pc, b, i, s, d) { \
- *((pc)++) = (char) 0xff; \
- (pc) = emit_r_X((interp), (pc), emit_reg(emit_b100), (b), (i), (s), (d)); \
- }
-#else /* EXEC_CAPABLE */
# define emitm_jumpm(pc, b, i, s, d) { \
*((pc)++) = (char) 0xff; \
(pc) = emit_r_X((interp), (pc), emit_reg(emit_b100), (b), (i), (s), (d)); }
-#endif /* EXEC_CAPABLE */
/* Conditional jumps */
@@ -1558,151 +1591,6 @@
emitm_popl_r((pc), emit_EBP); \
} while (0)
-#if JIT_VTABLE_OPS
-
-# undef Parrot_jit_vtable1_op
-# undef Parrot_jit_vtable1r_op
-
-# undef Parrot_jit_vtable_111_op
-# undef Parrot_jit_vtable_112_op
-# undef Parrot_jit_vtable_221_op
-# undef Parrot_jit_vtable_1121_op
-# undef Parrot_jit_vtable_1123_op
-# undef Parrot_jit_vtable_2231_op
-
-# undef Parrot_jit_vtable_1r223_op
-# undef Parrot_jit_vtable_1r332_op
-
-# undef Parrot_jit_vtable_ifp_op
-# undef Parrot_jit_vtable_unlessp_op
-# undef Parrot_jit_vtable_newp_ic_op
-
-/* emit a call to a vtable func
- * $X->vtable(interp, $X [, $Y...])
- */
-# define MAP(i) jit_info->optimizer->map_branch[jit_info->op_i + (i)]
-
-# include "parrot/oplib/ops.h"
-
-INTVAL Parrot_FixedIntegerArray_get_integer_keyed_int(Interp*, PMC*, INTVAL);
-void Parrot_FixedIntegerArray_set_integer_keyed_int(Interp*, PMC*, INTVAL, INTVAL);
-
-char * jit_set_i_p_ki(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- size_t offset);
-
-char * jit_set_p_ki_i(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- size_t offset);
-
-/*
- * for vtable calls registers are already saved back
- */
-void Parrot_jit_vtable_n_op(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int n, int *args);
-
-void Parrot_jit_store_retval(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1)
- */
-void Parrot_jit_vtable1_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1 = $2->vtable(interp, $2)
- */
-void Parrot_jit_vtable1r_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1 = $2->vtable(interp, $2, $3)
- */
-void Parrot_jit_vtable_1r223_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1 = $3->vtable(interp, $3, $2)
- */
-void Parrot_jit_vtable_1r332_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2)
- */
-void Parrot_jit_vtable_112_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $1)
- */
-void Parrot_jit_vtable_111_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $2->vtable(interp, $2, $1)
- */
-void Parrot_jit_vtable_221_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $2->vtable(interp, $2, $3, $1)
- */
-void Parrot_jit_vtable_2231_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2, $3)
- */
-void Parrot_jit_vtable_1123_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2, $1)
- */
-void Parrot_jit_vtable_1121_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* if_p_ic, unless_p_ic */
-void Parrot_jit_vtable_if_unless_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int unless);
-
-/* unless_p_ic */
-void Parrot_jit_vtable_unlessp_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* if_p_ic */
-void Parrot_jit_vtable_ifp_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-#endif /* JIT_VTABLE_OPS */
-
-#if EXEC_CAPABLE
-# ifdef JIT_CGP
-# ifdef EXEC_SHARED
-# define exec_emit_end(interp, pc) { \
- jit_emit_mov_rm_i((pc), c, 2); \
- Parrot_exec_add_text_rellocation(jit_info->objfile, \
- jit_info->native_ptr, RTYPE_COM, "cgp_core", 0); \
- emitm_movl_m_r((interp), jit_info->native_ptr, emit_ESI, emit_ESI, \
- emit_None, 1, 0); \
- emitm_addb_i_r(jit_info->native_ptr, \
- (int)((ptrcast_t)((op_func_t*) \
- (interp)->op_lib->op_func_table)[0]) - (int)cgp_core, \
- emit_ESI); \
- emitm_jumpr((pc), emit_ESI); \
- }
-# else /* EXEC_SHARED */
-# define exec_emit_end(interp, pc) { \
- jit_emit_mov_ri_i((interp), (pc), emit_ESI, \
- (int)((ptrcast_t)((op_func_t*) \
- (interp)->op_lib->op_func_table)[0]) - (int)cgp_core); \
- Parrot_exec_add_text_rellocation(jit_info->objfile, \
- jit_info->native_ptr, RTYPE_COM, "cgp_core", -4); \
- emitm_jumpr((pc), emit_ESI); \
- }
-# endif /* EXEC_SHARED */
-
-# else /* JIT_CGP */
-
-# define exec_emit_end(pc) jit_emit_end(pc)
-
-# endif /* JIT_CGP */
-#endif /* EXEC_CAPABLE */
-
-#ifdef JIT_CGP
-# define jit_emit_end(interp, pc) { \
- jit_emit_mov_ri_i((interp), (pc), emit_ESI, \
- (ptrcast_t)((op_func_t*)(interp)->op_lib->op_func_table) [0]); \
- emitm_jumpr((pc), emit_ESI); \
- }
-#else /* JIT_CGP */
# define jit_emit_end(pc) { \
jit_emit_add_ri_i((interp), (pc), emit_ESP, 4); \
emitm_popl_r((pc), emit_EDI); \
@@ -1712,8 +1600,6 @@
emitm_ret(pc); \
}
-#endif /* JIT_CGP */
-
void jit_get_params_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP);
/*
@@ -1780,97 +1666,6 @@
# define JUMP_ALIGN 0
# define SUB_ALIGN 0
-#ifdef JIT_EMIT
-# if JIT_EMIT == 0
-
-extern int control_word;
-
-# ifdef JIT_CGP
-# include <parrot/oplib/core_ops_cgp.h>
-# endif
-
-# define REQUIRES_CONSTANT_POOL 0
-/*
- * examples/pir/mandel.pir and t/op/jitn_14 show rounding problems
- * due to keeping intermediate results in FP registers
- * When intermediates are written back to parrot regs, rounding to
- * 64 bit is performed, which changes results slightly
- *
- * One method is to just turn off mapped floats. The other one is
- * setting a different control word (with precision control = double)
- * see emitm_fldcw above
- */
-# define FLOAT_REGISTERS_TO_MAP 4
-
-/* registers are either allocate per section or per basic block
- * set this to 1 or 0 to change allocation scheme
- */
-# define ALLOCATE_REGISTERS_PER_SECTION 1
-
-/*
- * new style move function using offsets relative to the base_reg
- */
-# ifdef JIT_CGP
-# define INTERP_BP_OFFS todo
-# else
-# define INTERP_BP_OFFS -16
-# endif
-
-# endif /* JIT_EMIT = 0 */
-#endif /* JIT_EMIT */
-
-void Parrot_jit_dofixup(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void Parrot_jit_begin(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/*
- * create a JITted version of a PIR sub, where everything
- * resided in registers
- *
- * The sub is called as
- *
- * opcode_t * func(Interp *i, INTVAL *sig_bits, void **args);
- *
- * args[0] ... NULL / return value address
- * args[1..n] ... addresses of n arguments
- * args[n + 1] .. opcode_t* next - usually just returned
- */
-
-void Parrot_jit_begin_sub_regs(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void Parrot_jit_begin_sub(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void jit_mov_mr_n_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg);
-
-void jit_mov_mr_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg);
-
-void jit_mov_rm_n_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs);
-
-void jit_mov_rm_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs);
-
-void Parrot_jit_emit_finit(Parrot_jit_info_t *jit_info);
-
-void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-#ifdef JIT_EMIT
-# if JIT_EMIT == 2
-/* generate code just once */
-
-/* autogened inside core.ops */
-static void Parrot_end_jit(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-# undef Parrot_jit_restart_op
-# endif /* JIT_EMIT == 2 */
-#endif /* JIT_EMIT */
-
-void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
int count_regs(PARROT_INTERP, char *sig, char *sig_start);
size_t calc_signature_needs(const char *sig, int *strings);
@@ -1886,19 +1681,6 @@
* %eax ... scratch, return value register
*/
-extern const char i_map[];
-
-extern const char floatval_map[];
-
-extern const char i_map_sub[];
-
-extern const jit_arch_info arch_info;
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info * Parrot_jit_init(PARROT_INTERP);
-
-#undef INT_REGISTERS_TO_MAP
#endif /* PARROT_I386_JIT_EMIT_H_GUARD */
/*
Modified: trunk/src/interp/inter_create.c
==============================================================================
--- trunk/src/interp/inter_create.c Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/src/interp/inter_create.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -44,14 +44,6 @@
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
-#if EXEC_CAPABLE
- extern int Parrot_exec_run;
-#endif
-
-#if EXEC_CAPABLE
-Interp interpre;
-#endif
-
#define ATEXIT_DESTROY
/*
@@ -122,12 +114,7 @@
Interp *interp;
/* Get an empty interpreter from system memory */
-#if EXEC_CAPABLE
- if (Parrot_exec_run)
- interp = &interpre;
- else
-#endif
- interp = mem_allocate_zeroed_typed(Interp);
+ interp = mem_allocate_zeroed_typed(Interp);
interp->lo_var_ptr = NULL;
Deleted: trunk/src/jit.c
==============================================================================
--- trunk/src/jit.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,1869 +0,0 @@
-/*
-Copyright (C) 2001-2009, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/jit.c - JIT
-
-=head1 DESCRIPTION
-
-JIT (Just In Time) compilation converts bytecode to native machine code
-instructions and executes the generated instruction sequence directly.
-
-Actually it's not really just in time, it's just before this piece of code is
-used and not per subroutine or even opcode, it works per bytecode segment.
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include <parrot/parrot.h>
-#if PARROT_EXEC_CAPABLE
-# include "parrot/exec.h"
-#endif
-#include "jit.h"
-#define JIT_EMIT 0
-#include "jit_emit.h"
-#include "parrot/packfile.h"
-#include "parrot/oplib/ops.h"
-#include "pmc/pmc_sub.h"
-#include "pmc/pmc_managedstruct.h"
-
-#define JIT_SEGS 0
-
-extern int jit_op_count(void);
-/*
- * s. jit/$jitcpuarch/jit_emit.h for the meaning of these defs
- */
-
-#ifndef ALLOCATE_REGISTERS_PER_SECTION
-# define ALLOCATE_REGISTERS_PER_SECTION 1
-#endif
-
-#if defined __GNUC__ || defined __IBMC__
-void Parrot_jit_debug(PARROT_INTERP);
-#endif
-
-/*
-
-=item C<static void
-insert_fixup_targets(PARROT_INTERP, char *branch,
- size_t limit)>
-
-Look at fixups, mark all fixup entries as branch target.
-
-TODO: actually this is wrong: fixups belong only to one code segment.
-The code below doesn't check, for which segments the fixups are
-inserted.
-
-=cut
-
-*/
-
-static void
-insert_fixup_targets(PARROT_INTERP, char *branch,
- size_t limit)
-{
- PackFile_FixupTable *ft = interp->code->fixups;
- int i;
-
- if (!ft)
- return;
-
- for (i = 0; i < ft->fixup_count; i++) {
- if (ft->fixups[i]->type == enum_fixup_label) {
- if ((size_t)ft->fixups[i]->offset < limit)
- branch[ft->fixups[i]->offset] |= JIT_BRANCH_TARGET;
- }
- }
-}
-
-/*
-
-=item C<static void
-make_branch_list(PARROT_INTERP,
- Parrot_jit_optimizer_t * optimizer,
- opcode_t *code_start, opcode_t *code_end)>
-
-C<< optimizer->map_branch >> parallels the opcodes with a list of
-branch information and register mapping information
-
-=over 4
-
-=item branch instructions have C<JIT_BRANCH_SOURCE>
-
-=item opcodes jumped to have C<JIT_BRANCH_TARGET>
-
-=item mapped arguments have register type + 1 and finally
-
-=item after register allocation these have the processor register that
-got mapped
-
-=back
-
-=cut
-
-*/
-
-static void
-make_branch_list(PARROT_INTERP,
- Parrot_jit_optimizer_t * optimizer,
- opcode_t *code_start, opcode_t *code_end)
-{
- op_info_t *op_info;
- char *branch;
- opcode_t *cur_op;
-
- cur_op = code_start;
-
- /* Allocate space for the branch information and register map */
- optimizer->map_branch = branch =
- (char *)mem_sys_allocate_zeroed((size_t)(code_end - code_start + 1));
-
- /* Allocate space for the branch list */
- optimizer->branch_list = (opcode_t **)
- mem_sys_allocate_zeroed(
- (size_t)(code_end - code_start) * sizeof (opcode_t *));
-
- /* If the opcode jumps we may:
- *
- * PARROT_JUMP_RELATIVE:
- * The op jumps to an address relative to the current position,
- * thus we mark the branch target and the branch source.
- *
- * PARROT_JUMP_ADDRESS:
- * The op jumps to an absolute address, thus we mark the branch
- * target.
- *
- * PARROT_JUMP_POP:
- * The op pops the address to jump to, thus we don't mark the
- * branch target, anyway it may probably use expr(NEXT)
- *
- * PARROT_JUMP_ENEXT:
- * The op does something with expr(NEXT),
- * XXX I'll assume that it's stored in the control stack for
- * later returning since that's the only way it's used now
- * but this should go away by the time we add some metadata
- * to the ops.
- * So we will mark the branch target.
- *
- * PARROT_JUMP_GNEXT:
- * Means the opcode does some other kind of jump, and also
- * might goto(NEXT)
- *
- * PARROT_JUMP_UNPREDICTABLE:
- * The branch target is unpredictable.
- * Things get a little tricky since it's not 100% true that the
- * target is unpredictable because of the set_addr opcode, we
- * need to find a solution for this, in the mean time, we will
- * make each section have its own arena and try to avoid
- * going in and out from them as much as possible.
- *
- * PARROT_JUMP_RESTART
- * If the parrot program counter is zero, fall out of the
- * run loop.
- *
- */
-
- while (cur_op < code_end) {
- opcode_t op = *cur_op;
- int i, n;
- size_t rel_offset;
-
-
- /* Predereference the opcode information table for this opcode
- * early since it's going to be used many times */
- op_info = &interp->op_info_table[op];
-
- /* if op_info->jump is not 0 this opcode may jump,
- * so mark this opcode as a branch source */
- rel_offset = cur_op - code_start;
-
- n = op_info->op_count;
-
- if (op == PARROT_OP_set_args_pc ||
- op == PARROT_OP_set_returns_pc ||
- op == PARROT_OP_get_results_pc)
- goto no_branch;
- if (op_info->jump)
- branch[rel_offset] |= JIT_BRANCH_SOURCE;
- for (i = 1; i < n; ++i) {
- /* If it's not a constant, no joy */
- if (op_info->types[i-1] == PARROT_ARG_IC && op_info->labels[i-1]) {
- /* The branch target is relative,
- * the offset is in the i argument
- */
- if (op_info->jump & PARROT_JUMP_RELATIVE) {
- /* Set the branch target */
- optimizer->branch_list[rel_offset] = cur_op + cur_op[i];
- branch[rel_offset + cur_op[i]] |= JIT_BRANCH_TARGET;
- }
- /* The branch target is absolute,
- * the address is in the i argument
- */
- else if (op_info->jump & PARROT_JUMP_ADDRESS) {
- /* Set the branch target */
- optimizer->branch_list[rel_offset] = cur_op + cur_op[i];
- branch[cur_op[i]] |= JIT_BRANCH_TARGET;
- }
- /* the labels of set_addr and newsub are branch targets too
- * this is needed e.g. for JIT_CGP
- */
- else {
- branch[rel_offset + cur_op[i]] |= JIT_BRANCH_TARGET;
- }
- }
- }
- /* The address of the next opcode */
- if ((op_info->jump & PARROT_JUMP_ENEXT) ||
- (op_info->jump & PARROT_JUMP_GNEXT))
- branch[rel_offset + n] |= JIT_BRANCH_TARGET;
- if (op_info->jump & PARROT_JUMP_UNPREDICTABLE) {
- /*
- * TODO
- * this flag is currently not used or set
- * and: if we have a branch that isn't going to a constant
- * target like a calculated branch used by rx_ opcodes
- * we are totally lost WRT register preservation.
- * If we don't know, that the code is a branch target, inside
- * a JITted code section, mapped registers might be
- * not up to date WRT Parrot registers.
- */
- optimizer->has_unpredictable_jump = 1;
- }
-no_branch:
- /* Move to the next opcode */
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
- cur_op += n;
- }
- insert_fixup_targets(interp, branch, code_end - code_start);
-}
-
-/*
-
-=item C<static void
-set_register_usage(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- Parrot_jit_optimizer_section_ptr cur_section,
- op_info_t *op_info, opcode_t *cur_op, opcode_t *code_start)>
-
-Sets the register usage counts.
-
-=cut
-
-*/
-
-static void
-set_register_usage(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- Parrot_jit_optimizer_section_ptr cur_section,
- op_info_t *op_info, opcode_t *cur_op, opcode_t *code_start)
-{
- int argn, args, argt;
- int typ;
- Parrot_jit_register_usage_t *ru = cur_section->ru;
- Parrot_jit_optimizer_t * optimizer = jit_info->optimizer;
- char * const map = optimizer->map_branch;
-
- /* For each argument that has the opcode increment the usage count,
- * We move from the end since we need to check if the first opcode
- * using the register will read or write it.
- *
- * registers are set per their type [IPSN]
- * */
- args = argt = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, argt);
- for (argn = argt - 1; argn > 0; argn--) {
- /* TODO check the argn-1 entries */
- int idx = *(cur_op + argn);
- int arg_type;
- PMC *sig;
- if (argn >= args) {
- sig = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), cur_op[1]);
- arg_type = VTABLE_get_integer_keyed_int(interp,
- sig, argn - args);
- arg_type &= (PARROT_ARG_TYPE_MASK | PARROT_ARG_CONSTANT);
- }
- else
- arg_type = op_info->types[argn - 1];
-
- switch (arg_type) {
- case PARROT_ARG_I:
- case PARROT_ARG_KI:
- typ = 0;
- /*
- * if the register number is negative, the register mapping
- * was done by imcc/jit.c, which used negative numbers
- * for allocated CPU registers. That's currently not
- * functional because of changed register allocation
- * strategy inside imcc.
- * The code is still here and should probably be reactivated
- * later, when things are stable: imcc has all the
- * necessary information like basic blocks and loop depth
- * calculated already. A lot is duplicated here to regain this
- * information.
- */
- if (idx < 0)
- idx = -1 - idx;
- break;
- case PARROT_ARG_P:
- case PARROT_ARG_K:
- /*
- * P and S regs aren't currently used at all. That's not
- * really optimal. If we have plenty of mappable registers
- * and if we can call vtables or MMD functions directly
- * we should finally allocate P and S regs too.
- */
- typ = 1;
- break;
- case PARROT_ARG_S:
- typ = 2;
- break;
- case PARROT_ARG_N:
- if (idx < 0)
- idx = -1 - idx;
- typ = 3;
- break;
- default:
- typ = -1;
- break;
- }
- /*
- * JIT structures are NUM_REGISTERS big
- * we can currently allocate only that much
- */
- if (typ >= 0 && idx < NUM_REGISTERS) {
- /* remember the register typ (+1) for this op argument
- * for register allocation */
- map[cur_op + argn - code_start] = typ + 1;
- if ((!ru[typ].reg_count[idx]++) &&
- (op_info->dirs[argn-1] & PARROT_ARGDIR_IN))
- ru[typ].reg_dir[idx] |= PARROT_ARGDIR_IN;
- if (op_info->dirs[argn-1] & PARROT_ARGDIR_OUT) {
- ru[typ].reg_dir[idx] |= PARROT_ARGDIR_OUT;
- }
- }
- /* key constants may have register keys */
- else if (arg_type == PARROT_ARG_KC) {
- PMC *key = interp->code->const_table->constants[idx]->u.key;
- while (key) {
- const UINTVAL flags = PObj_get_FLAGS(key);
- if (flags & KEY_register_FLAG) {
- INTVAL n = 0;
- if (flags & KEY_integer_FLAG) {
- n = VTABLE_get_integer(interp, key);
- typ = 0;
- if (n < 0)
- n = -1 - n;
- }
- else if (flags & KEY_pmc_FLAG)
- typ = 1;
- else if (flags & KEY_string_FLAG)
- typ = 2;
-
- if (n < NUM_REGISTERS && !ru[typ].reg_count[n]++)
- ru[typ].reg_dir[n] |= PARROT_ARGDIR_IN;
- }
- key = VTABLE_shift_pmc(interp, key);
- }
- }
- }
-}
-
-/*
-
-=item C<static void
-init_regusage(PARROT_INTERP,
- Parrot_jit_optimizer_section_ptr cur_section)>
-
-Init all register usage to Parrot register usage. Used when JITting
-subroutines to registers only
-
-=cut
-
-*/
-
-static void
-init_regusage(PARROT_INTERP, Parrot_jit_optimizer_section_ptr cur_section)
-{
- int typ;
-
- cur_section->ru[0].registers_used = Parrot_pcc_get_regs_used(interp,
- CURRENT_CONTEXT(interp), REGNO_INT);
- cur_section->ru[3].registers_used = Parrot_pcc_get_regs_used(interp,
- CURRENT_CONTEXT(interp), REGNO_NUM);
- cur_section->ru[1].registers_used = cur_section->ru[2].registers_used = 0;
-
- for (typ = 0; typ < 4; typ++) {
- int j;
- for (j = 0; j < cur_section->ru[typ].registers_used; j++)
- cur_section->ru[typ].reg_usage[j] = j;
- }
-}
-
-/*
-
-=item C<static void make_sections(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end)>
-
-I386 has JITed vtables, which have the vtable# in extcall.
-
-This C<Parrot_jit_vtable_n_op()> does use register mappings.
-
-=cut
-
-*/
-
-#ifndef EXTCALL
-# define EXTCALL(op) (op_jit[(op)].extcall >= 1 || (op) >= jit_op_count())
-# define CALLS_C_CODE(op) (op_func[(op)].extcall == -1)
-#endif
-
-static void
-make_sections(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end)
-{
- Parrot_jit_optimizer_section_ptr cur_section, t_section, prev_section;
- opcode_t *next_op;
- op_info_t *op_info;
- char *branch;
- int branched, start_new;
- opcode_t *cur_op;
- Parrot_jit_optimizer_t * optimizer;
-
- optimizer = jit_info->optimizer;
- branch = optimizer->map_branch;
-
- /* Allocate the first section */
- cur_section = optimizer->sections = (Parrot_jit_optimizer_section_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_jit_optimizer_section_t));
- cur_section->begin = code_start;
- prev_section = cur_section;
-
- cur_op = code_start;
- /* set all regs to Parrot's */
- if (jit_info->code_type == JIT_CODE_SUB_REGS_ONLY)
- init_regusage(interp, cur_section);
- while (cur_section) {
- opcode_t op = *cur_op;
- branched = start_new = 0;
- /* Predereference the opcode information for this opcode
- * early since it's going to be used many times */
- op_info = &interp->op_info_table[op];
-
- /* Calculate the next pc */
- next_op = cur_op + op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, next_op);
-
- /* Update op_count */
- cur_section->op_count++;
-
- /* set register usage for this section */
- set_register_usage(interp, jit_info, cur_section,
- op_info, cur_op, code_start);
-
- /*
- * End a section:
- * If this opcode is jitted and next is a C function */
- if (!EXTCALL(op)) {
- cur_section->jit_op_count++;
-
- if (next_op < code_end && EXTCALL(*next_op))
- start_new = 1;
- }
- else
- /* or if current section is not jitted, and the next opcode
- * is. */
- if (next_op < code_end && !EXTCALL(*next_op))
- start_new = 1;
-
- /* or when the current opcode is a branch source,
- * in other words if the opcode jumps, or if the next opcode is
- * a branch target, allocate a new section only if it's not the
- * last opcode */
- if ((branch[cur_op - code_start] & JIT_BRANCH_SOURCE)
- || (next_op < code_end &&
- (branch[next_op - code_start] & JIT_BRANCH_TARGET))
- || (next_op >= code_end)) {
- /* remember to start a new block */
- branched = 1;
- start_new = 1;
- }
-
- if (start_new) {
- /* Set the type, depending on whether the current
- * instruction is external or jitted. */
- cur_section->isjit = !EXTCALL(op);
-
- /* Save the address where the section ends */
- cur_section->end = cur_op;
-
- if (next_op < code_end) {
- /* Allocate a new section */
- t_section = (Parrot_jit_optimizer_section_t *)
- mem_sys_allocate_zeroed(
- sizeof (Parrot_jit_optimizer_section_t));
- /* Add it to the double linked list */
- cur_section->next = t_section;
- t_section->prev = cur_section;
- /* Make the new section be the current one */
- cur_section = t_section;
- /* set all regs to Parrot's */
- if (jit_info->code_type == JIT_CODE_SUB_REGS_ONLY)
- init_regusage(interp, cur_section);
-
- /* registers get either allocated per section or
- * per basic block (i.e. one or more sections divided
- * by branches. When allocation per block is done
- * all sections in one block have the same block number
- */
- if (ALLOCATE_REGISTERS_PER_SECTION || branched) {
- cur_section->block = prev_section->block + 1;
- prev_section = cur_section;
- }
- else
- cur_section->block = prev_section->block;
- /* Save the address where the section begins */
- cur_section->begin = next_op;
- }
- else {
- cur_section = NULL;
- }
- }
-
- /* Move to the next opcode */
- cur_op = next_op;
- }
-}
-
-/*
-
-=item C<static void
-make_branch_targets(
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)>
-
-Makes the branch targets.
-
-=cut
-
-*/
-
-static void
-make_branch_targets(Parrot_jit_optimizer_t *optimizer, const opcode_t * code_start)
-{
- Parrot_jit_optimizer_section_ptr cur_section, t_section;
- /* Set the branch target of this section, that is the section where
- * the program execution continues, if it ends in a branch source we
- * use the branch target and not the next section. */
- cur_section = optimizer->sections;
- while (cur_section) {
- if (optimizer->branch_list[cur_section->end - code_start]) {
- /* If the branch target is to a section before the current one
- * move from the start, otherwise from the current section */
- if (optimizer->branch_list[cur_section->end - code_start] <
- cur_section->begin)
- t_section = optimizer->sections;
- else
- t_section = cur_section;
-
- while (t_section) {
- /* If we find the section attach it to the current one. */
- if (t_section->begin ==
- optimizer->branch_list[cur_section->end - code_start]) {
- cur_section->branch_target = t_section;
- break;
- }
- /* If not move to the next. */
- t_section = t_section->next;
- }
-
- }
- /* Move to the next section */
- cur_section = cur_section->next;
- }
-}
-
-/*
-
-=item C<static void
-sort_registers(Parrot_jit_info_t *jit_info)>
-
-Sorts the Parrot registers prior to mapping them to actual hardware registers.
-
-=cut
-
-*/
-
-static void
-sort_registers(Parrot_jit_info_t *jit_info)
-{
- Parrot_jit_optimizer_t *optimizer;
- Parrot_jit_optimizer_section_ptr cur_section, next;
- int any, k, typ, code_type;
- int max_count, max_i = 0;
- 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;
-
- while (cur_section) {
- Parrot_jit_register_usage_t *ru = cur_section->ru;
- /* sum up register usage for one block, don't change
- * reg_dir. If allocation is done per section, block numbers
- * are different, so this is a nop
- */
- next = cur_section->next;
- while (next && next->block == cur_section->block) {
- const Parrot_jit_register_usage_t * const nru = next->ru;
- for (typ = 0; typ < 4; typ++) {
- int i;
- for (i = 0; i < NUM_REGISTERS; i++)
- ru[typ].reg_count[i] += nru[typ].reg_count[i];
- }
- next = next->next;
- }
-
- /* now sort registers by their usage count */
- for (typ = 0; typ < 4; typ++) {
- /* find most used register */
- int i;
- for (i = max_count = 0; i < NUM_REGISTERS; i++) {
- if (cur_section->ru[typ].reg_count[i] > max_count) {
- max_count = cur_section->ru[typ].reg_count[i];
- max_i = i;
- }
- }
- /* start from this register and set usage */
- k = ru[typ].registers_used = 0;
- /* no usage, go on with next type */
- if (max_count == 0 || !to_map[typ])
- continue;
- /* as long as we map registers for this typ */
- while (1) {
- if (max_i >= 0)
- ru[typ].reg_usage[k++] = max_i;
- /* all mapped? */
- if (k == to_map[typ])
- break;
- /* now check for equal usage starting after maxi */
- for (any = 0, i = max_i + 1; i < NUM_REGISTERS; i++) {
- if (ru[typ].reg_count[i] == max_count) {
- max_i = i;
- any = 1;
- break;
- }
- }
- /* if same usage not found, look for lower usage */
- if (any == 0) {
- if (max_count > 1) {
- max_count--;
- max_i = -1;
- continue;
- }
- break;
- }
- }
- ru[typ].registers_used = k;
- }
- next = cur_section->next;
- /* duplicate usage to all sections of block */
- while (next && next->block == cur_section->block) {
- Parrot_jit_register_usage_t * const nru = next->ru;
- for (typ = 0; typ < 4; typ++) {
- int i;
- for (i = 0; i < ru[typ].registers_used; i++) {
- nru[typ].reg_count[i] = ru[typ].reg_count[i];
- nru[typ].reg_usage[i] = ru[typ].reg_usage[i];
- }
- nru[typ].registers_used = ru[typ].registers_used;
- }
- next = next->next;
- }
- /* Move to the next section */
- cur_section = next;
- }
-}
-
-/*
-
-=item C<static void
-assign_registers(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- Parrot_jit_optimizer_section_ptr cur_section,
- opcode_t * code_start, int from_imcc)>
-
-Called by C<map_registers()> to actually assign the Parrot registers to
-hardware registers.
-
-TODO
-
-Before actually assigning registers, we should optimize a bit:
-
-1) calculate max use count of register types for all sections
-
-2) calculate costs for register preserving and restoring
- for two different allocation strategies:
-
- a) allocate non-volatiles first
- overhead for jit_begin, jit_end:
- - 2 * max_used_non_volatile registers
- overhead for register preserving around non-jitted sections:
- - only used IN arguments are saved
- - only OUT non-volatile arguments are restored
- b) allocate volatiles first
- no overhead for jit_begin, jit_end
- overhead per JITed op that calls a C function:
- - 2 * n_used_volatiles_to_preserve for each call
- overhead for register preserving around non-jitted sections:
- - all volatiles are saved and restored around non-jitted sections
-
-NB for all cost estimations size does matter: a 64bit double counts as
- two 32bit ints. Opcode count is assumed to be just one.
-
-3) depending on costs from 2) use one of the strategies
- That does still not account for any usage patterns. Imcc has loop
- nesting depth, but that's not available here. OTOH smaller code tends
- to perform better because of better cache usage.
-
-Usage analysis could show that a mixture of both strategies is best, e.g:
-allocate 2-4 non-volatiles and the rest from volatiles. But that would
-complicate the allocation code a bit.
-
-=cut
-
-*/
-
-static void
-assign_registers(PARROT_INTERP,
- 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;
- int i;
- opcode_t * cur_op;
- const char * maps[] = {0, 0, 0, 0};
- const int 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;
- while (cur_op <= cur_section->end) {
- const opcode_t op = *cur_op;
- const op_info_t * const op_info = &interp->op_info_table[op];
- int op_arg;
- int n;
-
- /* For each argument of the current opcode */
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
- for (op_arg = 1; op_arg < n; op_arg++) {
- /* get the register typ */
- int typ = map[cur_op + op_arg - code_start];
- /* clear the register typ/map */
- map[cur_op + op_arg - code_start] = 0;
- /* if not JITted, don't map */
- if (!cur_section->isjit)
- continue;
- if (typ > 0) {
- typ--; /* types are + 1 */
- if (!maps[typ])
- continue;
- /* If the argument is in most used list for this typ */
- for (i = 0; i < cur_section->ru[typ].registers_used; i++) {
- opcode_t idx = cur_op[op_arg];
- if (from_imcc)
- idx = -1 - idx;
- if (idx == (opcode_t)cur_section->ru[typ].reg_usage[i]) {
- map[cur_op + op_arg - code_start] = maps[typ][i];
- cur_section->maps++;
- break;
- }
- }
- }
- }
-
- /* Move to the next opcode */
- cur_op += n;
- }
-}
-
-/*
-
-=item C<static void
-map_registers(PARROT_INTERP,
- Parrot_jit_info_t *jit_info, opcode_t * code_start)>
-
-Maps the most used Parrot registers to hardware registers.
-
-=cut
-
-*/
-
-static void
-map_registers(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t * code_start)
-{
- /* Start from the first section */
- Parrot_jit_optimizer_section_ptr cur_section = jit_info->optimizer->sections;
-
- /* While there is section */
- while (cur_section) {
-
- assign_registers(interp, jit_info, cur_section, code_start, 0);
-
- /* Move to the next section */
- cur_section = cur_section->next;
- }
-}
-
-
-#define JIT_DEBUG 0
-
-#if JIT_DEBUG
-/*
-
-=item C<static void
-debug_sections(PARROT_INTERP,
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)>
-
-Prints out debugging info.
-
-=cut
-
-*/
-
-static void
-debug_sections(PARROT_INTERP,
- Parrot_jit_optimizer_t *optimizer, opcode_t * code_start)
-{
- Parrot_jit_optimizer_section_ptr cur_section;
-# if JIT_DEBUG > 1
- char * map = optimizer->map_branch;
-# endif
- int n;
- const char types[] = "IPSN";
- int types_to_list[] = {0, 3};
-
- cur_section = optimizer->sections;
- while (cur_section) {
- opcode_t * cur_op;
- unsigned int j;
- Parrot_jit_register_usage_t *ru = cur_section->ru;
-
- Parrot_io_eprintf(interp, "\nSection:\n");
- Parrot_io_eprintf(interp, "%s block %d\n",
- (cur_section->isjit) ? "JITTED" : "NOT JITTED",
- cur_section->block);
- for (cur_op = cur_section->begin; cur_op <= cur_section->end;) {
- char instr[256];
- const opcode_t op = *cur_op;
- const op_info_t * const op_info = &interp->op_info_table[op];
-
- PDB_disassemble_op(interp, instr, sizeof (instr),
- op_info, cur_op, NULL, code_start, 0);
- Parrot_io_eprintf(interp, "\t\tOP%vu: ext %3d\t%s\n",
- cur_op - code_start, op_jit[*cur_op].extcall, instr);
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
-# if JIT_DEBUG > 1
- Parrot_io_eprintf(interp, "\t\t\tmap_branch: ");
- for (i = 0; i < n; i++)
- Parrot_io_eprintf(interp, "%02x ", map[cur_op-code_start+i]);
- Parrot_io_eprintf(interp, "\n");
-# endif
- cur_op += n;
- }
- Parrot_io_eprintf(interp, "\tbegin:\t%#p\t(%Ou)\n",
- cur_section->begin, *cur_section->begin);
- Parrot_io_eprintf(interp, "\tend:\t%#p\t(%Ou)\n",
- cur_section->end, *cur_section->end);
-
- for (j = 0; j < sizeof (types_to_list)/sizeof (int); j++) {
- const int typ = types_to_list[j];
- const char t = types[typ];
- Parrot_io_eprintf(interp, "\t%c registers used:\t%i\n",
- t, ru[typ].registers_used);
- if (ru[typ].registers_used) {
- int i;
- Parrot_io_eprintf(interp, "\t%c register count:\t", t);
- for (i = 0; i < NUM_REGISTERS; i++)
- Parrot_io_eprintf(interp, "%i ", ru[typ].reg_count[i]);
- Parrot_io_eprintf(interp, "\n\t%c register usage:\t", t);
- for (i = 0; i < NUM_REGISTERS; i++)
- Parrot_io_eprintf(interp, "%i ", ru[typ].reg_usage[i]);
- Parrot_io_eprintf(interp, "\n\t%c register direction:\t", t);
- for (i = 0; i < NUM_REGISTERS; i++)
- Parrot_io_eprintf(interp, "%i ", (int)ru[typ].reg_dir[i]);
- Parrot_io_eprintf(interp, "\n");
- }
- }
- Parrot_io_eprintf(interp, "\tJit opcodes:\t%u\n",
- cur_section->jit_op_count);
- Parrot_io_eprintf(interp, "\tTotal opcodes:\t%u\n",
- cur_section->op_count);
- if (cur_section->branch_target)
- Parrot_io_eprintf(interp, "\tBranch target:\tOP%u\n",
- cur_section->branch_target->begin - code_start);
-
- cur_section = cur_section->next;
- }
-}
-#endif
-
-/*
-
-=item C<static Parrot_jit_optimizer_t *
-optimize_jit(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end)>
-
-Called by C<parrot_build_asm()> to run the optimizer.
-
-=cut
-
-*/
-
-static void
-optimize_jit(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end)
-{
- Parrot_jit_optimizer_t *optimizer;
-
- /* Allocate space for the optimizer */
- 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(interp, optimizer, code_start, code_end);
-
- /* ok, let's loop again and generate the sections */
- make_sections(interp, jit_info, code_start, code_end);
-
- /* look where a section jumps to */
- make_branch_targets(optimizer, code_start);
-
- /* This is where we start deciding which Parrot registers get
- * mapped to a hardware one in each different section. */
-
-#if JIT_DEBUG > 2
- debug_sections(interp, optimizer, code_start);
-#endif
- if (jit_info->code_type != JIT_CODE_SUB_REGS_ONLY)
- sort_registers(jit_info);
- map_registers(interp, jit_info, code_start);
-
-#if JIT_DEBUG
- debug_sections(interp, optimizer, code_start);
-#endif
-}
-
-/*
-
-=item C<static Parrot_jit_optimizer_t *
-optimize_imcc_jit(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end,
- PackFile_Segment *jit_seg)>
-
-Generate optimizer stuff from the C<_JIT> section in the packfile.
-
-=cut
-
-*/
-
-static void
-optimize_imcc_jit(PARROT_INTERP,
- Parrot_jit_info_t *jit_info,
- opcode_t *code_start, opcode_t *code_end,
- PackFile_Segment *jit_seg)
-{
- Parrot_jit_optimizer_t *optimizer;
- size_t size, i, typ, n;
- int j;
- opcode_t *ptr, offs;
- Parrot_jit_optimizer_section_ptr section, prev;
- char *branch;
- opcode_t *cur_op;
-
- /* Allocate space for the optimizer */
- 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
- */
- optimizer->map_branch = branch =
- (char *)mem_sys_allocate_zeroed((size_t)(code_end - code_start));
- ptr = jit_seg->data;
- size = jit_seg->size;
- PARROT_ASSERT(jit_seg->itype == 0);
- PARROT_ASSERT((size % 6) == 0);
- cur_op = code_start;
- for (prev = NULL, i = 0; i < size/6; i++, prev = section) {
- section = (Parrot_jit_optimizer_section_t *)
- mem_sys_allocate_zeroed(sizeof (Parrot_jit_optimizer_section_t));
- if (prev)
- prev->next = section;
- else
- optimizer->sections = section;
- section->prev = prev;
- section->block = i;
- offs = *ptr++;
- if (offs & 0x80000000) {
- offs &= ~0x80000000;
- branch[offs] = JIT_BRANCH_TARGET;
- }
- section->begin = code_start + offs;
- section->end = code_start + *ptr++;
- section->isjit = 1;
- for (typ = 0; typ < 4; typ++) {
- section->ru[typ].registers_used = *ptr++;
- for (j = 0; j < section->ru[typ].registers_used; j++)
- section->ru[typ].reg_usage[j] = j;
-
- }
- while (cur_op <= section->end) {
- const opcode_t op = *cur_op;
- op_info_t * const op_info = &interp->op_info_table[op];
- set_register_usage(interp, jit_info, section,
- op_info, cur_op, code_start);
- section->op_count++;
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
- cur_op += n;
- }
- assign_registers(interp, jit_info, section, code_start, 1);
- }
- insert_fixup_targets(interp, branch, code_end - code_start);
-#if JIT_DEBUG
- debug_sections(interp, optimizer, code_start);
-#endif
-}
-
-/*
-
-=item C<size_t reg_offs(int typ, int i)>
-
-Returns the offset of register C<typ[i]>.
-
-F<src/jit/arch/jit_emit.h> has to define C<Parrot_jit_emit_get_base_reg_no(pc)>
-
-=cut
-
-*/
-
-/* we always are using offsets */
-
-
-static size_t
-reg_offs(int typ, int i)
-{
- switch (typ) {
- case 0:
- return REG_OFFS_INT(i);
- case 3:
- return REG_OFFS_NUM(i);
- default:
- return 0;
- }
-}
-
-/*
-
-=item C<static void
-Parrot_jit_load_registers(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int volatiles)>
-
-Load registers for the current section from parrot to processor registers.
-If C<volatiles> is true, this code is used to restore these registers in
-JITted code that calls out to Parrot.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_load_registers(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int volatiles)
-{
- Parrot_jit_optimizer_section_t *sect = jit_info->optimizer->cur_section;
- Parrot_jit_register_usage_t *ru = sect->ru;
- int typ;
- size_t offs;
- int base_reg = 0; /* -O3 warning */
- int lasts[] = { 0, 0, 0, 0 };
- const char * maps[] = {0, 0, 0, 0};
- int first = 1;
- const int code_type = jit_info->code_type;
- const jit_arch_info * const arch_info = jit_info->arch_info;
- const jit_arch_regs * const 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]) {
- int i;
- for (i = ru[typ].registers_used-1; i >= 0; --i) {
- const int us = ru[typ].reg_usage[i];
- const 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;
- }
- offs = reg_offs(typ, us);
- if (typ == 3)
- (arch_info->mov_RM_n)(interp, jit_info,
- maps[typ][i], base_reg, offs);
- else
- (arch_info->mov_RM_i)(interp, jit_info,
- maps[typ][i], base_reg, offs);
-
- }
- }
- }
- }
-
- /* 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,
- PARROT_INTERP, int volatiles)>
-
-Save registers for the current section.
-If C<volatiles> is true, this code is used to preserve these registers in
-JITted code that calls out to Parrot.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_save_registers(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int volatiles)
-{
- Parrot_jit_optimizer_section_t *sect = jit_info->optimizer->cur_section;
- Parrot_jit_register_usage_t *ru = sect->ru;
- int i, typ;
- size_t offs;
- int base_reg = 0; /* -O3 warning */
- 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;
-
- for (typ = 0; typ < 4; typ++) {
- if (maps[typ])
- for (i = 0; i < ru[typ].registers_used; ++i) {
- const int us = ru[typ].reg_usage[i];
- const 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;
- }
-
- offs = reg_offs(typ, us);
- if (typ == 3)
- (arch_info->mov_MR_n)(interp, jit_info,
- base_reg, offs, maps[typ][i]);
- else
- (arch_info->mov_MR_i)(interp, jit_info,
- base_reg, offs, maps[typ][i]);
-
- }
- }
- }
-}
-
-/*
-
-=item C<void
-Parrot_destroy_jit(void *ptr)>
-
-Frees the memory used by the JIT subsystem.
-
-=cut
-
-*/
-
-void
-Parrot_destroy_jit(void *ptr)
-{
- Parrot_jit_optimizer_t *optimizer;
- Parrot_jit_optimizer_section_ptr cur_section, next;
- Parrot_jit_fixup_t *fixup, *next_f;
- Parrot_jit_info_t *jit_info = (Parrot_jit_info_t *)ptr;
-
- if (!jit_info)
- return;
- /* delete sections */
- optimizer = jit_info->optimizer;
- cur_section = optimizer->sections;
- while (cur_section) {
- next = cur_section->next;
- mem_sys_free(cur_section);
- cur_section = next;
- }
- /* arena stuff */
- mem_sys_free(jit_info->arena.op_map);
- mem_free_executable(jit_info->arena.start, jit_info->arena.size);
- fixup = jit_info->arena.fixups;
- while (fixup) {
- next_f = fixup->next;
- mem_sys_free(fixup);
- fixup = next_f;
- }
- /* optimizer stuff */
- mem_sys_free(optimizer->map_branch);
- mem_sys_free(optimizer->branch_list);
- mem_sys_free(optimizer);
-
- free(jit_info);
-}
-
-/*
- * see TODO below
- * - locate Sub according to pc
- * - set register usage in context
- */
-static void
-set_reg_usage(PARROT_INTERP, const opcode_t *pc)
-{
- PackFile_ByteCode * const seg = interp->code;
- PackFile_FixupTable * const ft = seg->fixups;
- PackFile_ConstTable * const ct = seg->const_table;
-
- int i;
-
- if (!ft)
- return;
-
- if (!ct)
- return;
-
- for (i = 0; i < ft->fixup_count; i++) {
- if (ft->fixups[i]->type == enum_fixup_sub) {
- const int ci = ft->fixups[i]->offset;
- PMC * const sub_pmc = ct->constants[ci]->u.key;
- Parrot_Sub_attributes *sub;
- size_t offs;
- int i;
-
- PMC_get_sub(interp, sub_pmc, sub);
- offs = pc - sub->seg->base.data;
-
- if (offs >= sub->start_offs && offs < sub->end_offs) {
- for (i = 0; i < 4; i++)
- Parrot_pcc_set_regs_used(interp, CURRENT_CONTEXT(interp),
- i, sub->n_regs_used[i]);
-
- return;
- }
- }
- }
-}
-
-/*
-
-=item C<Parrot_jit_info_t *
-parrot_build_asm(PARROT_INTERP,
- opcode_t *code_start, opcode_t *code_end,
- void *objfile, enum_jit_code_type)>
-
-This is the main function of the JIT code generator.
-
-It loops over the bytecode, calling the code generating routines for
-each opcode.
-
-The information obtained is used to perform certain types of fixups on
-native code, as well as by the native code itself to convert bytecode
-program counters values to hardware program counter values.
-
-Finally this code here is used to generate native executables (or better
-object files that are linked to executables), if EXEC_CAPABLE is defined.
-This functionality is triggered by
-
- parrot -o foo.o foo.pir
-
-which uses the JIT engine to translate to native code inside the object
-file.
-
-=cut
-
-*/
-
-Parrot_jit_info_t *
-parrot_build_asm(PARROT_INTERP, ARGIN(opcode_t *code_start), ARGIN(opcode_t *code_end),
- ARGIN(void *objfile), INTVAL jit_type)
-{
- int n;
- UINTVAL i;
- char *new_arena;
- Parrot_jit_info_t *jit_info = NULL;
- opcode_t cur_opcode_byte;
- opcode_t *cur_op;
- PackFile_Segment *jit_seg;
- char *map;
- Parrot_jit_fn_info_t *op_func;
- INTVAL n_regs_used[4]; /* INSP in PBC */
- op_info_t *op_info;
- const jit_arch_info *arch_info;
- int needs_fs; /* fetch/store */
-
- /* XXX
- * no longer referenced due to disabled code below
- char *name;
- */
-
- Parrot_jit_optimizer_section_ptr cur_section;
-
-#if EXEC_CAPABLE
- Parrot_exec_objfile_t *obj = (Parrot_exec_objfile_t *)objfile;
-#endif
-
- jit_info = interp->code->jit_info = mem_allocate_typed(Parrot_jit_info_t);
-
- jit_info->flags = jit_type & JIT_CODE_RECURSIVE;
- jit_type &= ~ JIT_CODE_RECURSIVE;
- jit_info->code_type = jit_type;
- needs_fs = jit_type
- != JIT_CODE_SUB_REGS_ONLY;
-
-#if EXEC_CAPABLE
- if (objfile) {
- op_func = op_exec;
- jit_info->objfile = obj;
- }
- else
-#endif
- {
- op_func = op_jit;
- jit_info->objfile = NULL;
- }
-
- /* reset some extcall bits - all is JITed
- */
- if (jit_type == JIT_CODE_SUB_REGS_ONLY) {
- op_func[PARROT_OP_set_returns_pc].extcall = 0;
- op_func[PARROT_OP_get_params_pc].extcall = 0;
- op_func[PARROT_OP_get_params_pc].extcall = 0;
- op_func[PARROT_OP_invokecc_p].extcall = 0;
- }
-
- /* get register mappings and such */
- arch_info = jit_info->arch_info = Parrot_jit_init(interp);
-
- /*
- * check if IMCC did all the work. If yes, we have a PF segment with
- * register allocation information inside.
- * See imcc/jit.c for more
- */
-#if JIT_SEGS
- /* RT #45055
- * JIT segs are currently not built
- * the find_segments also segfaults on PPC eval_2
- * maybe something not initialized correctly
- * - disabled --leo
- */
- name = mem_sys_allocate(strlen(interp->code->base.name) + 5);
- sprintf(name, "%s_JIT", interp->code->base.name);
- jit_seg = PackFile_find_segment(interp,
- interp->code->base.dir, name, 0);
- mem_sys_free(name);
-#else
- jit_seg = NULL;
-#endif
-
- /* remember register usage */
- for (i = 0; i < 4; i++)
- n_regs_used[i] = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), i);
-
- set_reg_usage(interp, code_start);
-
-#if JIT_SEGS
- optimize_imcc_jit(interp, jit_info, code_start, code_end, jit_seg);
-#else
- optimize_jit(interp, jit_info, code_start, code_end);
-#endif
-
- /* Byte code size in opcode_t's */
- jit_info->arena.map_size = (code_end - code_start) + 1;
- jit_info->arena.op_map =
- (Parrot_jit_opmap_t *)mem_sys_allocate_zeroed(
- jit_info->arena.map_size * sizeof (* (jit_info->arena.op_map)));
-
-#if REQUIRES_CONSTANT_POOL
- Parrot_jit_init_arenas(jit_info);
-#else
- jit_info->arena.size = 1024;
-
- /* estimate size needed
- * 10 times pbc code size seems to be enough for i386
- */
- if ((size_t)jit_info->arena.map_size * 20 > (size_t)jit_info->arena.size)
- jit_info->arena.size = jit_info->arena.map_size * 20;
- jit_info->native_ptr = jit_info->arena.start =
- (char *)mem_alloc_executable((size_t)jit_info->arena.size);
- if (! jit_info->native_ptr)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Cannot allocate executable memory");
-
-# if EXEC_CAPABLE
- if (obj)
- jit_info->objfile->text.code = jit_info->arena.start;
-# endif
-#endif
-
- jit_info->op_i = 0;
- jit_info->arena.fixups = NULL;
-
- /* The first section */
- cur_section = jit_info->optimizer->cur_section
- = jit_info->optimizer->sections;
- map = jit_info->optimizer->map_branch;
-
- /*
- * from C's ABI all the emitted code here is one (probably big)
- * function. So we have to generate an appropriate function
- * prologue, that makes all this look like a normal function ;)
- */
- jit_info->cur_op = cur_section->begin;
- (arch_info->regs[jit_type].jit_begin)(jit_info, interp);
-
- /*
- * op_map holds the offset from arena.start
- * of the parrot op at the given opcode index
- *
- * Set the offset of the first opcode
- */
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
-
- /*
- * the function epilog can basically be anywhere, that's done
- * by the Parrot_end opcode somewhere in core.jit
- */
-
- while (jit_info->optimizer->cur_section) {
- /* the code emitting functions need cur_op and cur_section
- * so these vars are in jit_info too
- */
-
- /*
- * TODO
- *
- * Register offsets depend on n_regs_used, which is per
- * subroutine. JIT code is currently generated for a whole
- * PBC. We can either:
- * 1) create JIT per subroutine or
- * 2) track the sub we are currently in, set register usage
- * in the interpreter context and restore it at end
- *
- * for now we use 2) - longterm plan is 1)
- */
-
- /* The first opcode for this section */
- cur_op = jit_info->cur_op = cur_section->begin;
-
- set_reg_usage(interp, cur_op);
-
- /* Load mapped registers for this section, if JIT */
- if (!jit_seg && cur_section->isjit && needs_fs)
- Parrot_jit_load_registers(jit_info, interp, 0);
-
- /* The first opcode of each section doesn't have a previous one since
- * it's impossible to be sure which was it */
- jit_info->prev_op = NULL;
-
- while (cur_op <= cur_section->end) {
- /* Grow the arena early */
- if (jit_info->arena.size <
- (jit_info->arena.op_map[jit_info->op_i].offset + 200)) {
-#if REQUIRES_CONSTANT_POOL
- Parrot_jit_extend_arena(jit_info);
-#else
- new_arena = (char *)mem_realloc_executable(jit_info->arena.start,
- jit_info->arena.size, (size_t)jit_info->arena.size * 2);
- jit_info->arena.size *= 2;
- jit_info->native_ptr = new_arena +
- (jit_info->native_ptr - jit_info->arena.start);
- jit_info->arena.start = new_arena;
-# if EXEC_CAPABLE
- if (obj)
- obj->text.code = new_arena;
-# endif
-#endif
- }
-
- cur_opcode_byte = *cur_op;
-
- /* Need to save the registers if there is a branch and is not to
- * the same section, I admit I don't like this, and it should be
- * really checking if the target section has the same registers
- * mapped too.
- *
- * Yep so: TODO
- * during register allocation try to use the same registers, if
- * its a loop or a plain branch and if register usage doesn't
- * differ too much. This could save a lot of register reloads.
- *
- * --
- *
- * save also, if we have a jitted sections and encounter
- * an "end" opcode, e.g. in evaled code
- */
- if (needs_fs) {
- if ((((map[cur_op - code_start] == JIT_BRANCH_SOURCE) &&
- (cur_section->branch_target != cur_section)) ||
- !cur_opcode_byte) &&
- cur_section->isjit &&
- !jit_seg) {
- Parrot_jit_save_registers(jit_info, interp, 0);
- }
- else if (CALLS_C_CODE(cur_opcode_byte)) {
- /*
- * a JITted function with a function call, we have to
- * save volatile registers but
- * TODO not if the previous opcode was also one
- * that called C code
- */
- Parrot_jit_save_registers(jit_info, interp, 1);
- }
- }
-
- /*
- * for all opcodes that are dynamically loaded, we can't have
- * a JITted version, so we execute the function incarnation
- * via the wrapper opcode, which just runs one opcode
- * see ops/core.ops for more
- */
- if (cur_opcode_byte >= jit_op_count())
- cur_opcode_byte = CORE_OPS_wrapper__;
-
- (op_func[cur_opcode_byte].fn) (jit_info, interp);
-
- if (CALLS_C_CODE(cur_opcode_byte) && needs_fs) {
- /*
- * restore volatiles only - and TODO only if next
- * wouldn't load registers anyway
- */
- Parrot_jit_load_registers(jit_info, interp, 1);
- }
- /* Update the previous opcode */
- jit_info->prev_op = cur_op;
-
- op_info = &interp->op_info_table[*cur_op];
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
- cur_op += n;
-
- /* update op_i and cur_op accordingly */
- jit_info->op_i += n;
- jit_info->cur_op += n;
-
- if (*jit_info->prev_op == PARROT_OP_set_args_pc &&
- jit_type == JIT_CODE_SUB_REGS_ONLY) {
- PARROT_ASSERT(*cur_op == PARROT_OP_set_p_pc);
-
- /* skip it */
- cur_op += 3;
- jit_info->op_i += 3;
- jit_info->cur_op += 3;
-
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
-
- PARROT_ASSERT(*cur_op == PARROT_OP_get_results_pc);
-
- /* now emit the call - use special op for this */
- /* Don't want to fix it. JIT on chopping block.
- * (op_func[PARROT_OP_pic_callr___pc].fn)(jit_info, interp);
- */
-
- /* and the get_results */
- (op_func[*cur_op].fn)(jit_info, interp);
-
- op_info = &interp->op_info_table[*cur_op];
- n = op_info->op_count;
- ADD_OP_VAR_PART(interp, interp->code, cur_op, n);
-
- cur_op += n;
-
- /* update op_i and cur_op accordingly */
- jit_info->op_i += n;
- jit_info->cur_op += n;
-
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
-
- /* now at invoke */
- PARROT_ASSERT(*cur_op == PARROT_OP_invokecc_p);
-
- cur_op += 2; /* skip it */
- jit_info->op_i += 2;
- jit_info->cur_op += 2;
- }
-
- /* if this is a branch target, align it */
-#ifdef jit_emit_noop
-# if JUMP_ALIGN
- if (((!cur_section->next && cur_op <= cur_section->end) ||
- cur_section->next) &&
- map[cur_op - code_start] == JIT_BRANCH_TARGET) {
- while ((long)jit_info->native_ptr & ((1<<JUMP_ALIGN) - 1))
- jit_emit_noop(jit_info->native_ptr);
- }
-# endif
-#endif
- /* set the offset */
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
- }
-
- /* Save mapped registers back to the Parrot registers */
- if (!jit_seg && cur_section->isjit && needs_fs)
- Parrot_jit_save_registers(jit_info, interp, 0);
-
- /* update the offset for saved registers */
- jit_info->arena.op_map[jit_info->op_i].offset =
- jit_info->native_ptr - jit_info->arena.start;
-
- /* Move to the next section */
- cur_section = jit_info->optimizer->cur_section =
- cur_section->next;
- }
-
- /* restore register usage */
- for (i = 0; i < 4; i++)
- Parrot_pcc_set_regs_used(interp, CURRENT_CONTEXT(interp), i, n_regs_used[i]);
-
- /* Do fixups before converting offsets */
- (arch_info->jit_dofixup)(jit_info, interp);
-
- /* Convert offsets to pointers */
- if (!objfile)
- for (i = 0; i < jit_info->arena.map_size; i++) {
-
- /* Assuming native code chunks contain some initialization code,
- * the first op (and every other op) is at an offset > 0
- */
- if (jit_info->arena.op_map[i].offset) {
- jit_info->arena.op_map[i].ptr = (char *)jit_info->arena.start +
- jit_info->arena.op_map[i].offset;
- }
- }
-
- jit_info->arena.size =
- (ptrdiff_t)(jit_info->native_ptr - jit_info->arena.start);
-#if JIT_DEBUG
- Parrot_io_eprintf(interp, "\nTotal size %u bytes\n",
- (unsigned int)(jit_info->native_ptr - jit_info->arena.start));
-#endif
-
- /*
- * sync data cache if needed - we are executing it as code in some usecs
- */
- if (arch_info->jit_flush_cache)
- (arch_info->jit_flush_cache)(jit_info, interp);
-
- /* assume gdb is available: generate symbol information */
-#if defined __GNUC__ || defined __IBMC__
- if (Interp_debug_TEST(interp, PARROT_JIT_DEBUG_FLAG)) {
- /*
- * TODO same like above here e.g. create ASM listing of code
- * if real debug support isn't available
- */
- if (jit_type == JIT_CODE_FILE) {
- interp->code->jit_info = jit_info;
- Parrot_jit_debug(interp);
- }
- }
-#endif
-
- return jit_info;
-}
-
-/*
-
-=item C<void
-Parrot_jit_newfixup(Parrot_jit_info_t *jit_info)>
-
-Remember the current position in the native code for later update.
-
-=cut
-
-*/
-
-void
-Parrot_jit_newfixup(Parrot_jit_info_t *jit_info)
-{
- Parrot_jit_fixup_t *fixup;
-
- fixup = mem_allocate_zeroed_typed(Parrot_jit_fixup_t);
-
- /* Insert fixup at the head of the list */
- fixup->next = jit_info->arena.fixups;
- jit_info->arena.fixups = fixup;
-
- /* Fill in the native code offset */
- fixup->native_offset =
- (ptrdiff_t)(jit_info->native_ptr - jit_info->arena.start);
-}
-
-/*
-
-=item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)>
-
-This is a callback to implement the proper freeing semantics. It is called by
-the ManagedStruct PMC as it is garbage collected.
-
-=cut
-
-*/
-
-void
-Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)
-{
- const struct jit_buffer_private_data * const jit = (struct jit_buffer_private_data*)priv;
- mem_free_executable(ptr, jit->size);
- free(priv);
-}
-
-/*
-
-=item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)>
-
-This is a callback to implement the proper cloning semantics for jit buffers.
-It is called by the ManagedStruct PMC's clone() function.
-
-=cut
-
-*/
-
-PMC *
-Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)
-{
- PMC * const rv = pmc_new(interp, pmc->vtable->base_type);
-
- VTABLE_init(interp, rv);
- /* copy the attributes */
- {
- void (*tmpfreefunc)(PARROT_INTERP, void*, void*);
- GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc);
- SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc);
- }
- {
- PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*);
- GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc);
- SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc);
- }
-
- {
- void *freepriv, *clonepriv;
- GETATTR_ManagedStruct_custom_free_priv(interp , pmc, freepriv);
- GETATTR_ManagedStruct_custom_clone_priv(interp, pmc, clonepriv);
- if (freepriv) {
- void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
- memcpy(tmp, freepriv, sizeof (struct jit_buffer_private_data));
- SETATTR_ManagedStruct_custom_free_priv(interp, rv , tmp);
- if (clonepriv == freepriv) {
- /* clonepriv is a copy of freepriv, make it a copy in the clone too. */
- SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
- clonepriv = NULL; /* disable the clonepriv copying below */
- }
- }
- if (clonepriv) {
- void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
- memcpy(tmp, clonepriv, sizeof (struct jit_buffer_private_data));
- SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
- }
- }
-
- /* copy the execmem buffer */
- if (PARROT_MANAGEDSTRUCT(pmc)->ptr) {
- struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
- void *ptr = PARROT_MANAGEDSTRUCT(pmc)->ptr;
- void *newptr = mem_alloc_executable(jit->size);
- if (!newptr)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Cannot allocate executable memory");
- memcpy(newptr, ptr, jit->size);
- PARROT_MANAGEDSTRUCT(rv)->ptr = newptr;
- }
-
- return rv;
-}
-
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<src/jit.h>, F<docs/jit.pod>, F<src/jit_debug.c>,
-F<src/jit/$jitcpuarch/jit_emit.h>, F<jit/$jitcpuarch/core.jit>.
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit.h
==============================================================================
--- trunk/src/jit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2001-2007, Parrot Foundation.
- */
-
-/*
- * jit.h
- *
- * $Id$
- */
-
-#ifndef PARROT_JIT_H_GUARD
-#define PARROT_JIT_H_GUARD
-
-#if EXEC_CAPABLE
-# include "parrot/exec.h"
-#endif
-
-typedef void (*jit_f)(PARROT_INTERP, opcode_t *pc);
-
-
-void Parrot_destroy_jit(void *);
-
-/* Parrot_jit_fixup_t
- * Platform generic fixup information
- *
- * type: The type of fixup.
- * native_offset: Where to apply the fixup.
- * skip: Skip instructions after the target.
- * param: Fixup specific data.
- */
-
-typedef struct Parrot_jit_fixup *Parrot_jit_fixup_ptr;
-
-typedef struct Parrot_jit_fixup {
- int type;
- ptrdiff_t native_offset;
- char skip;
- char dummy[3]; /* For alignment ??? XXX */
- union { /* What has to align with what? */
- opcode_t opcode;
- void (*fptr)(void);
- } param;
-
- Parrot_jit_fixup_ptr next;
-} Parrot_jit_fixup_t;
-
-/* Parrot_jit_opmap_t
- * Hold native code offsets/addresses
- *
- * ptr: Pointer to native code
- * offset: Offset of native code from arena.start
- */
-
-typedef union {
- void *ptr;
- ptrdiff_t offset;
-} Parrot_jit_opmap_t;
-
-enum {
- JIT_BRANCH_NO, /* The opcode doesn't branch */
- JIT_BRANCH_TARGET, /* The opcode is a branch target */
- JIT_BRANCH_SOURCE /* The opcode is a branch source */
-};
-
-
-/* Parrot_jit_arena_t
- * Holds pointers to the native code of one or more sections.
- *
- * start: Start of current native code segment.
- * size: The size of the arena in bytes
- * op_map: Maps opcode offsets to native code.
- * map_size: The size of the map in bytes.
- * fixups: List of fixups.
- */
-
-typedef struct Parrot_jit_arena_t {
- char *start;
- ptrdiff_t size;
- Parrot_jit_opmap_t *op_map;
- unsigned long map_size;
- Parrot_jit_fixup_t *fixups;
-} Parrot_jit_arena_t;
-
-/* Parrot_jit_optimizer_section_t
- * The bytecode will be divided in sections depending on the
- * program structure.
- *
- * begin: Points where sections begins in the bytecode.
- * end: Points where sections ends in the bytecode.
- * arena: The first arena for this section, or NULL if the
- * section is in the arena inlined in jit_info.
- * ru[4]: register_usage_t per [IPSN]
- * maps: Total maps done.
- * jit_op_count: How many opcodes are jitted.
- * op_count: Opcodes in this section.
- * load_size: The size of the register load instructions to be
- * skipped in an in-section branch.
- * isjit: If this section is a jitted one or not.
- * block: block number of section
- * branch_target: The section where execution continues if this section
- * ends at a branch source the targeted section is used.
- */
-
-typedef struct Parrot_jit_optimizer_section *Parrot_jit_optimizer_section_ptr;
-
-/* reg_count: An array with one position for each register
- * holding the number of times each register is used in the
- * section.
- * reg_usage: An array with the registers sorted by the usage.
- * reg_dir: If the register needs to be loaded or saved.
- * registers_used: count of used registers
- */
-typedef struct Parrot_jit_register_usage_t {
- int reg_count[NUM_REGISTERS];
- unsigned int reg_usage[NUM_REGISTERS];
- char reg_dir[NUM_REGISTERS];
- int registers_used;
-} Parrot_jit_register_usage_t;
-
-typedef struct Parrot_jit_optimizer_section {
- opcode_t *begin;
- opcode_t *end;
- Parrot_jit_register_usage_t ru[4];
- Parrot_jit_arena_t *arena;
- unsigned int maps;
- unsigned int jit_op_count;
- unsigned int op_count;
- ptrdiff_t load_size;
- char isjit;
- char done;
- char ins_count;
- char dummy; /* For alignment ??? XXX */
- int block; /* What has to align with what? */
- Parrot_jit_optimizer_section_ptr branch_target;
- Parrot_jit_optimizer_section_ptr prev;
- Parrot_jit_optimizer_section_ptr next;
-} Parrot_jit_optimizer_section_t;
-
-/* Parrot_jit_optimizer_section_t
- * All the information related to optimizing the bytecode.
- *
- * sections: A pointer to the first section.
- * cur_section: Pointer to the current section.
- * map_branch: A pointer to an array with the size of the bytecode
- * where the positions of the opcodes will have a value
- * indicating if the opcode is a branch target, source
- * or isn't related with a control flow opcode at all,
- * and which register was allocated for each opcode
- * argument if any.
- * has_unpredictable_jump: XXX need to define how to handle this.
- */
-
-typedef struct Parrot_jit_optimizer_t {
- Parrot_jit_optimizer_section_t *sections;
- Parrot_jit_optimizer_section_t *cur_section;
- char *map_branch;
- opcode_t **branch_list;
- unsigned char has_unpredictable_jump;
- unsigned char dummy[3]; /* For alignment ??? XXX */
-} Parrot_jit_optimizer_t; /* What has to align with what? */
-
-/* Parrot_jit_constant_pool_t
- * Constants pool information.
- *
- */
-typedef struct Parrot_jit_constant_pool_t {
- long frames_used;
- long cur_used;
- char *cur_const;
- 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,
- /* special cases */
- JIT_CODE_RECURSIVE = 0x10,
- JIT_CODE_SUB_REGS_ONLY_REC = JIT_CODE_SUB_REGS_ONLY|JIT_CODE_RECURSIVE
-} enum_jit_code_type;
-
-/* Parrot_jit_info_t
- * All the information needed to jit the bytecode will be here.
- *
- * prev_op: The previous opcode in this section.
- * cur_op: The current opcode during the build process.
- * op_i: Opcode index.
- * native_ptr: Current pointer to native code.
- * arena: The arena inlined, this will be the only one used in cases
- * where there is a way to load an immediate.
- * optimizer: Optimizer information.
- * constant_pool: The constant pool information.
- */
-
-typedef struct Parrot_jit_info_t {
- opcode_t *prev_op;
- opcode_t *cur_op;
- opcode_t op_i;
- char *native_ptr;
- Parrot_jit_arena_t arena;
- Parrot_jit_optimizer_t *optimizer;
- Parrot_jit_constant_pool_t *constant_pool;
- INTVAL code_type;
- int flags;
- const struct jit_arch_info_t *arch_info;
- int n_args;
-#if EXEC_CAPABLE
- Parrot_exec_objfile_t *objfile;
-#else
- void *objfile;
-#endif /* EXEC_CAPABLE */
-} Parrot_jit_info_t;
-
-#define Parrot_jit_fixup_target(jit_info, fixup) \
- ((jit_info)->arena.start + (fixup)->native_offset)
-
-typedef void (*jit_fn_t)(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-/* Parrot_jit_fn_info_t
- * The table of opcodes.
- *
- * 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 Parrot_jit_fn_info_t {
- jit_fn_t fn;
- int extcall;
-} Parrot_jit_fn_info_t;
-
-PARROT_DATA Parrot_jit_fn_info_t *op_jit;
-extern Parrot_jit_fn_info_t op_exec[];
-
-PARROT_EXPORT void Parrot_jit_newfixup(Parrot_jit_info_t *jit_info);
-
-void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_exec_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_exec_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-void Parrot_exec_restart_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP);
-
-/*
- * interface functions for the register save/restore code
- * with offsets relative to the base register (obtained by
- * Parrot_jit_emit_get_base_reg_no)
- */
-void Parrot_jit_emit_mov_mr_n_offs(
- Interp *, int base_reg, size_t offs, int src_reg);
-void Parrot_jit_emit_mov_mr_offs(
- Interp *, int base_reg, size_t offs, int src_reg);
-void Parrot_jit_emit_mov_rm_n_offs(
- Interp *, int dst_reg, int base_reg, size_t offs);
-void Parrot_jit_emit_mov_rm_offs(
- Interp *, int dst_reg, int base_reg, size_t offs);
-
-/*
- * interface to architecture specific details
- */
-typedef void (*jit_arch_f)(Parrot_jit_info_t *, Interp *);
-
-typedef struct jit_arch_regs {
- /*
- * begin function - emit ABI call prologue
- */
- jit_arch_f jit_begin;
-
- int n_mapped_I;
- int n_preserved_I;
- const char *map_I;
- int n_mapped_F;
- int n_preserved_F;
- const char *map_F;
-} jit_arch_regs;
-
-typedef void (*mov_RM_f)(PARROT_INTERP, Parrot_jit_info_t *,
- int cpu_reg, int base_reg, INTVAL offs);
-typedef void (*mov_MR_f)(PARROT_INTERP, Parrot_jit_info_t *,
- int base_reg, INTVAL offs, int cpu_reg);
-
-typedef struct jit_arch_info_t {
- /* CPU <- Parrot reg move functions */
- mov_RM_f mov_RM_i;
- mov_RM_f mov_RM_n;
- /* Parrot <- CPU reg move functions */
- mov_MR_f mov_MR_i;
- mov_MR_f mov_MR_n;
-
- /* fixup branches and calls after codegen */
- jit_arch_f jit_dofixup;
- /* flush caches */
- jit_arch_f jit_flush_cache;
- /* register mapping info */
- const jit_arch_regs regs[JIT_CODE_TYPES];
-} jit_arch_info;
-
-/*
- * interface to create JIT code
- */
-Parrot_jit_info_t *
-parrot_build_asm(PARROT_INTERP,
- opcode_t *code_start, opcode_t *code_end,
- void *objfile, INTVAL);
-/*
- * NCI interface
- */
-void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *);
-/* custom pmc callback functions */
-void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv);
-PMC* Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
-struct jit_buffer_private_data {
- int size;
-};
-
-#endif /* PARROT_JIT_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/alpha/core.jit
==============================================================================
--- trunk/src/jit/alpha/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,142 +0,0 @@
-;
-; alpha/core.jit
-;
-;
-; $Id$
-;
-
-Parrot_noop {
- emit_nop(NATIVECODE);
-}
-
-Parrot_set_i_i {
- if (MAP[1] && MAP[2]) {
- jit_emit_mov_rr(NATIVECODE, MAP[2], MAP[1]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, MAP[1], &INT_REG[2]);
- }
- else if (MAP[2]) {
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], MAP[2]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
-}
-
-Parrot_set_i_ic {
- if (MAP[1]) {
- jit_emit_mov_ri_i(NATIVECODE, MAP[1], *INT_CONST[2]);
- }
- else {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
-}
-
-Parrot_sub_i_i_i {
- if (MAP[1] && MAP[2] && MAP[3]) {
- jit_emit_sub_rrr(NATIVECODE, MAP[2], MAP[3], MAP[1]);
- }
- else if (MAP[1] && MAP[2]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_sub_rrr(NATIVECODE, MAP[2], ISR1, MAP[1]);
- }
- else if (MAP[1] && MAP[3]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
- jit_emit_sub_rrr(NATIVECODE, ISR1, MAP[3], MAP[1]);
- }
- else if (MAP[2] && MAP[3]) {
- jit_emit_sub_rrr(NATIVECODE, MAP[2], MAP[3], ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
- jit_emit_sub_rrr(NATIVECODE, ISR2, ISR1, MAP[1]);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_sub_rrr(NATIVECODE, MAP[2], ISR1, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else if (MAP[3]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
- jit_emit_sub_rrr(NATIVECODE, ISR1, MAP[3], ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
- jit_emit_sub_rrr(NATIVECODE, ISR1, ISR2, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
-}
-
-Parrot_add_i_i_i {
- if (MAP[1] && MAP[2] && MAP[3]) {
- jit_emit_add_rrr(NATIVECODE, MAP[2], MAP[3], MAP[1]);
- }
- else if (MAP[1] && MAP[2]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_add_rrr(NATIVECODE, MAP[2], ISR1, MAP[1]);
- }
- else if (MAP[1] && MAP[3]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
- jit_emit_add_rrr(NATIVECODE, ISR1, MAP[3], MAP[1]);
- }
- else if (MAP[2] && MAP[3]) {
- jit_emit_add_rrr(NATIVECODE, MAP[2], MAP[3], ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
- jit_emit_add_rrr(NATIVECODE, ISR2, ISR1, MAP[1]);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_add_rrr(NATIVECODE, MAP[2], ISR1, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else if (MAP[3]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
- jit_emit_add_rrr(NATIVECODE, ISR1, MAP[3], ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
- jit_emit_add_rrr(NATIVECODE, ISR1, ISR2, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
-}
-
-Parrot_if_i_ic {
- if (MAP[1]) {
- emit_bne(NATIVECODE, MAP[1], *INT_CONST[2]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
- emit_bne(NATIVECODE, ISR1, *INT_CONST[2]);
- }
-}
-
-Parrot_end {
-; jit_emit_mov_rr(NATIVECODE, REG15_s6, REG30_sp);
- emit_ldq_b(NATIVECODE, REG26_ra, 0, REG30_sp);
- emit_ldq_b(NATIVECODE, REG15_s6, 8, REG30_sp);
- emit_lda_b(NATIVECODE, REG30_sp, 16, REG30_sp);
- emit_ret(NATIVECODE);
-}
-
-/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/alpha/jit_defs.c
==============================================================================
--- trunk/src/jit/alpha/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,13 +0,0 @@
-/* Stub file for RT#38929 fixes */
-/*
-Copyright (C) 2008, Parrot Foundation.
-$Id$
-*/
-/* HEADERIZER HFILE: none */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/alpha/jit_emit.h
==============================================================================
--- trunk/src/jit/alpha/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,561 +0,0 @@
-/*
- * Copyright (C) 2002-2007, Parrot Foundation.
- */
-
-/*
- * jit_emit.h
- *
- * ALPHA
- *
- * $Id$
- */
-
-/* Register usage:
- *
- * REG0 v0 Used for expression evaluations and to hold the integer
- * function results. Not preserved across procedure calls.
- * REG1-8 t0-t7 Temporary registers used for expression evaluations. Not
- * preserved across procedure calls.
- * REG9-14 s0-s5 Saved registers. Preserved across procedure calls.
- * REG15 s6 or fp Contains the frame pointer (if needed); otherwise, a saved
- * register.
- * REG16-21 a0-a5 Used to pass the first six integer type actual arguments.
- * Not preserved across procedure calls.
- * REG22-25 t8-t11 Temporary registers used for expression evaluations. Not
- * preserved across procedure calls.
- * REG26 ra Contains the return address. Preserved across procedure
- * calls.
- * REG27 pv or t12 Contains the procedure value and used for expression
- * evaluation. Not preserved across procedure calls.
- * REG28 or at AT Reserved for the assembler. Not preserved across
- * procedure calls.
- * REG29 or gp gp Contains the global pointer. Not preserved across
- * procedure calls.
- * REG30 or sp sp Contains the stack pointer. Preserved across procedure
- * calls.
- * REG31 zero Always has the value 0.
- *
- */
-
-#ifndef PARROT_ALPHA_JIT_EMIT_H_GUARD
-#define PARROT_ALPHA_JIT_EMIT_H_GUARD
-
-typedef enum {
- REG0_v0,
- REG1_t0,
- REG2_t1,
- REG3_t2,
- REG4_t3,
- REG5_t4,
- REG6_t5,
- REG7_t6,
- REG8_t7,
- REG9_s0,
- REG10_s1,
- REG11_s2,
- REG12_s3,
- REG13_s4,
- REG14_s5,
- REG15_s6,
- REG16_a0,
- REG17_a1,
- REG18_a2,
- REG19_a3,
- REG20_a4,
- REG21_a5,
- REG22_t8,
- REG23_t9,
- REG24_t10,
- REG25_t11,
- REG26_ra,
- REG27_t12,
- REG28_at,
- REG29_gp,
- REG30_sp,
- REG31_zero
-} alpha_register_t;
-
-typedef enum {
- LDA = 8,
- LDH = 9,
- LDQ = 41,
- STQ = 45
-} ld_st_t;
-
-typedef enum {
- BSR = 0xd0,
- BEQ = 0xe4,
- BNE = 61
-} branch_t;
-
-# define CONSTANT_POOL_SIZE 0xfff0
-
-#if JIT_EMIT
-
-/* All instruction formats are 32 bits long with a 6-bit major opcode field in
- bits <31:26> of the instruction. */
-
-enum { JIT_ALPHABRANCH, JIT_ALPHABSR };
-
-# define emit_nop(pc) { \
- *((pc)++) = 0x1f; \
- *((pc)++) = 0x04; \
- *((pc)++) = 0xff; \
- *((pc)++) = 0x47; }
-
-# define jit_emit_mov_rr(pc, src, Ra) { \
- *((pc)++) = (Ra); \
- *((pc)++) = 0x04; \
- *((pc)++) = 0xe0 + (src); \
- *((pc)++) = 0x47; }
-
-/* Memory instruction format
- *
- * +---------------------------------------------------------------+
- * | Opcode | Ra | Rb | memory_disp |
- * +---------------------------------------------------------------+
- * 31 26 25 21 20 16 15 0
- *
- * Depending on the opcode Ra could be the source of a store or the
- * destination of a load.
- *
- * The displacement field is a byte offset. It is sign-extended and added to
- * the contents of Rb to form a virtual address. Overflow is ignored in this
- * calculation.
- *
- */
-
-# define emit_mem(pc, opcode, Ra, Rb, disp) \
- *((pc)++) = (char)(disp); \
- *((pc)++) = (char)((disp) >> 8); \
- *((pc)++) = (char)((Rb) | (char)((Ra) << 5)); \
- *((pc)++) = (opcode) << 2 | (Ra) >> 3
-
-# define base_reg REG9_s0
-
-/* Scratch registers. */
-
-# define ISR1 REG0_v0
-# define ISR2 REG8_t7
-
-/* Load / Store a Parrot register.
- *
- * Perform a memory operation using a Parrot register as the source or
- * the destination.
- *
- */
-
-# define emit_l_s_r(pc, opcode, Ra, Rb, Parrot_reg) \
- emit_mem((pc), (opcode), (Ra), (Rb), \
- (((char *)(Parrot_reg)) - (char *)®_INT(interp, 0)))
-
-# define emit_ldq_b(pc, Ra, addr, Rb) \
- emit_mem((pc), LDQ, (Ra), (Rb), (addr))
-
-# define emit_lda_b(pc, Ra, addr, Rb) \
- emit_mem((pc), LDA, (Ra), (Rb), (addr))
-
-# define jit_emit_mov_rm_i(pc, Ra, addr) \
- emit_l_s_r((pc), LDQ, (Ra), (base_reg), (addr))
-
-# define emit_lda(pc, Ra, addr) \
- emit_l_s_r((pc), LDA, (Ra), (base_reg), (addr))
-
-# define emit_ldah(pc, Ra, addr, Rb) \
- emit_mem((pc), LDH, (Ra), (Rb), (addr))
-
-# define emit_stq_b(pc, Ra, addr, Rb) \
- emit_mem((pc), STQ, (Ra), (Rb), (addr))
-
-# define jit_emit_mov_mr_i(pc, addr, Ra) \
- emit_l_s_r((pc), STQ, (Ra), (base_reg), (addr))
-
-/* Branch instruction format
- *
- * +---------------------------------------------------------------+
- * | Opcode | Ra | Branch_disp |
- * +---------------------------------------------------------------+
- * 31 26 25 21 20 0
- *
- * The displacement is treated as a longword offset. This means it is shifted
- * left two bits (to address a longword boundary), sign-extended to 64 bits,
- * and added to the updated PC to form the target virtual address. Overflow is
- * ignored.
- *
- */
-
-# define emit_branch(pc, opcode, Ra) \
- *((pc)++) = 0; \
- *((pc)++) = 0; \
- *((pc)++) = (Ra) << 5; \
- *((pc)++) = (opcode) << 2 | (Ra) >> 3
-
-/* Operate instruction format
- *
- * +---------------------------------------------------------------+
- * | Opcode | Ra | Rb | SBZ | 0 | Function | Rc |
- * +---------------------------------------------------------------+
- * 31 26 25 21 20 16 15 13 12 11 5 4 0
- *
- * +---------------------------------------------------------------+
- * | Opcode | Ra | LIT | 1 | Function | Rc |
- * +---------------------------------------------------------------+
- * 31 26 25 21 20 13 12 11 5 4 0
- *
- * The operate format is used for instructions that perform integer register to
- * register operations. The operate format allows the specification of one
- * destination register and two source operands. One of the source operands can
- * be a literal constant.
- *
- */
-
-# define emit_operate1(pc, opcode, Ra, Rb, function, Rc) \
- *((pc)++) = (Rc) | (char)((function) << 5); \
- *((pc)++) = (char)((function) >> 5); \
- *((pc)++) = (Rb) | (char)(Ra) << 5; \
- *((pc)++) = (opcode) << 2 | (Ra) >> 3
-
-/* Addq (Operate instruction)
- *
- * opcode = 16;
- * function = 128;
- *
- */
-
-# define jit_emit_add_rrr(pc, Ra, Rb, Rc) \
- emit_operate1((pc), 16, (Ra), (Rb), 128, (Rc))
-
-/* Subq (Operate instruction)
- *
- * opcode = 16;
- * function = 161;
- *
- */
-
-# define jit_emit_sub_rrr(pc, Ra, Rb, Rc) \
- emit_operate1((pc), 16, (Ra), (Rb), 161, (Rc))
-
-/* Mulq (Operate instruction)
- *
- * opcode = 19;
- * function = 128;
- *
- */
-
-# define emit_mulq(pc, Ra, Rb, Rc) \
- emit_operate1((pc), 19, (Ra), (Rb), 128, (Rc))
-
-/* Load a constant */
-
-# define jit_emit_mov_ri_i(pc, target, constant) \
- (pc) = emit_l_c(jit_info, interp, (target), (long)(constant))
-
-static void
-emit_load_intval_cpool(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, alpha_register_t dest, INTVAL constant)
-{
- char *new_arena;
-
- /* If there is not space in the current pool */
- if ((char *)(jit_info->constant_pool->slot_ptr + sizeof (INTVAL)) >=
- jit_info->arena.start)
- {
- /* Check if the arena is big enough for a move or needs a realloc */
- if (jit_info->arena.size >
- (jit_info->arena.op_map[jit_info->op_i].offset + CONSTANT_POOL_SIZE))
- {
- new_arena = mem_sys_realloc(jit_info->arena.start,
- (size_t)jit_info->arena.size * 2);
- jit_info->arena.size *= 2;
- jit_info->native_ptr = new_arena +
- (jit_info->native_ptr - jit_info->arena.start);
- jit_info->constant_pool->slot_ptr = (INTVAL *)new_arena +
- ((char *)jit_info->constant_pool->slot_ptr -
- jit_info->arena.start);
- jit_info->arena.start = new_arena;
- jit_info->constant_pool->cur_used = 0;
- }
- memcpy(jit_info->arena.start + CONSTANT_POOL_SIZE,
- jit_info->arena.start, jit_info->arena.size);
- jit_info->constant_pool->frames_used++;
- }
-
- if (jit_info->constant_pool->frames_used) {
- emit_ldah(jit_info->native_ptr, dest,
- jit_info->constant_pool->frames_used, REG15_s6);
- emit_ldq_b(jit_info->native_ptr, dest,
- jit_info->constant_pool->cur_used, dest);
- }
- else {
- emit_ldq_b(jit_info->native_ptr, dest,
- jit_info->constant_pool->cur_used, REG15_s6);
- }
- jit_info->constant_pool->cur_used += sizeof (INTVAL);
- *(jit_info->constant_pool->slot_ptr++) = constant;
-}
-
-/* calculates the proper values for the displacement
- * from s to d.
- * returned values should be interpreted as:
- * d = s + *high * 65536 + *low
- */
-
-static void
-calculate_displacement(long *s, long *d, long *high, long *low)
-{
- long displacement = *d - *s;
-
- *high = displacement / 65536;
- *low = displacement % 65536;
- if (*low > 32767) {
- *high += 1;
- *low -= 65536;
- }
- else if (*low < -32767) {
- *high -= 1;
- *low += 65536;
- }
-}
-
-static char *
-emit_l_c(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- alpha_register_t target, long constant)
-{
- char *pc = jit_info->native_ptr;
- long high, low;
-
- if ((constant < -0x7fffffff) || (constant > 0x7fffffff)) {
- emit_load_intval_cpool(jit_info, interp, target, (INTVAL)constant);
- return jit_info->native_ptr;
- }
- else if ((constant < -0x7fff) || (constant > 0x7fff)) {
- high = 0;
- calculate_displacement(&high, &constant, &high, &low);
- emit_ldah(pc, target, high, REG31_zero);
- emit_lda_b(pc, target, low, target);
- }
- else {
- emit_lda_b(pc, target, constant, REG31_zero);
- }
- return pc;
-}
-
-static char *
-emit_b(Parrot_jit_info_t *jit_info, branch_t opcode, alpha_register_t reg,
- opcode_t disp)
-{
- char *pc = jit_info->native_ptr;
-
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_ALPHABRANCH;
- jit_info->arena.fixups->param.opcode = jit_info->op_i + disp;
-
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- emit_branch(pc, opcode, reg);
-
- return pc;
-}
-
-# define emit_bne(pc, reg, disp) \
- (pc) = emit_b(jit_info, BNE, (reg), (disp))
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- emit_lda_b(jit_info->native_ptr, REG30_sp, -16, REG30_sp);
- emit_stq_b(jit_info->native_ptr, REG26_ra, 0, REG30_sp);
- emit_stq_b(jit_info->native_ptr, REG15_s6, 8, REG30_sp);
- jit_emit_mov_rr(jit_info->native_ptr, REG16_a0, REG9_s0);
- jit_emit_mov_rr(jit_info->native_ptr, REG27_t12, REG15_s6);
- /* TODO
- emit_ldah(jit_info->native_ptr, REG15_s6, -1, REG15_s6);
- */
- emit_lda_b(jit_info->native_ptr, REG15_s6, -0x7ff8, REG15_s6);
- jit_emit_mov_ri_i(jit_info->native_ptr, REG10_s1,
- interp->code->base.data);
- jit_emit_mov_ri_i(jit_info->native_ptr, REG11_s2, jit_info->arena.op_map);
-}
-
-void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_fixup_t *fixup;
- char *fixup_ptr;
- char *disp;
- long d, high, low;
-
- fixup = jit_info->arena.fixups;
-
- while (fixup){
- switch (fixup->type){
- case JIT_ALPHABRANCH:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = (jit_info->arena.op_map[fixup->param.opcode].offset -
- fixup->native_offset + fixup->skip - 4) / 4;
- disp = (char *)&d;
- *(fixup_ptr++) = *disp;
- *(fixup_ptr++) = *(disp + 1);
- *(fixup_ptr++) |= *(disp + 2) & 0x1f;
- break;
- case JIT_ALPHABSR:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = ((long)fixup->param.fptr - (long)fixup_ptr - 4) / 4;
- disp = (char *)&d;
- *(fixup_ptr++) = *disp;
- *(fixup_ptr++) = *(disp + 1);
- *(fixup_ptr++) |= *(disp + 2) & 0x1f;
- break;
- default:
- exit_fatal(EXCEPTION_JIT_ERROR, "Unknown fixup type:%d\n",
- fixup->type);
- break;
- }
- fixup = fixup->next;
- }
-}
-
-static char *
-emit_bsr(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- char *pc = jit_info->native_ptr;
-
- jit_emit_mov_ri_i(pc, REG27_t12,
- interp->op_func_table[*(jit_info->cur_op)]);
-
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_ALPHABSR;
- jit_info->arena.fixups->param.fptr =
- (void (*)(void))interp->op_func_table[*(jit_info->cur_op)];
-
- *(pc++) = 0;
- *(pc++) = 0;
- *(pc++) = 0x40;
- *(pc++) = 0xd3;
-
- return pc;
-}
-
-/* TODO: re-write this properly */
-# define emit_jsr(pc) { \
- *((pc)++) = 0; \
- *((pc)++) = 0x40; \
- *((pc)++) = 0xe0; \
- *((pc)++) = 0x6b; \
-}
-
-# define emit_ret(pc) { \
- *((pc)++) = 1; \
- *((pc)++) = 0x80; \
- *((pc)++) = 0xfa; \
- *((pc)++) = 0x6b; \
-}
-
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- jit_emit_mov_ri_i(jit_info->native_ptr, REG16_a0, jit_info->cur_op);
- jit_emit_mov_rr(jit_info->native_ptr, REG9_s0, REG17_a1);
- jit_info->native_ptr = emit_bsr(jit_info, interp);
-}
-
-void
-Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
-
- jit_emit_sub_rrr(jit_info->native_ptr, ISR1, REG10_s1, ISR1);
- jit_emit_add_rrr(jit_info->native_ptr, ISR1, REG11_s2, ISR1);
- emit_ldq_b(jit_info->native_ptr, ISR1, 0, ISR1);
- /* XXX this is incorrect, might blow the stack, use jmp instead */
- emit_jsr(jit_info->native_ptr);
-}
-
-
-/* move reg to mem (i.e. intreg) */
-void
-Parrot_jit_emit_mov_mr(PARROT_INTERP, char *mem, int reg)
-{
- jit_emit_mov_mr_i(
- ((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr, mem, reg);
-}
-
-/* move mem (i.e. intreg) to reg */
-void
-Parrot_jit_emit_mov_rm(PARROT_INTERP, int reg, char *mem)
-{
- jit_emit_mov_rm_i(
- ((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr, reg, mem);
-}
-
-/* move reg to mem (i.e. numreg) */
-void
-Parrot_jit_emit_mov_mr_n(PARROT_INTERP, char *mem, int reg)
-{
-}
-
-/* move mem (i.e. numreg) to reg */
-void
-Parrot_jit_emit_mov_rm_n(PARROT_INTERP, int reg, char *mem)
-{
-}
-
-#else
-
-# define REQUIRES_CONSTANT_POOL 1
-# define INT_REGISTERS_TO_MAP 21
-
-# ifndef JIT_IMCC
-
-char intval_map[INT_REGISTERS_TO_MAP] =
- { REG1_t0, REG2_t1, REG3_t2, REG4_t3, REG5_t4, REG6_t5, REG7_t6, REG12_s3,
- REG13_s4, REG14_s5, REG16_a0, REG17_a1, REG18_a2, REG19_a3, REG20_a4,
- REG21_a5, REG22_t8, REG23_t9, REG24_t10, REG25_t11, REG28_at };
-
-static void
-Parrot_jit_init_arenas(Parrot_jit_info_t *jit_info)
-{
- jit_info->arena.size = CONSTANT_POOL_SIZE;
- jit_info->native_ptr = jit_info->arena.start =
- mem_sys_allocate((size_t)jit_info->arena.size * 2);
- jit_info->constant_pool = (Parrot_jit_constant_pool_t *)
- mem_sys_allocate((size_t)sizeof (Parrot_jit_constant_pool_t));
- jit_info->constant_pool->slot_ptr = (INTVAL *)jit_info->arena.start;
- jit_info->arena.start = jit_info->native_ptr += CONSTANT_POOL_SIZE;
- jit_info->constant_pool->cur_used = -0x7ff8;
-}
-
-static void
-Parrot_jit_extend_arena(Parrot_jit_info_t *jit_info)
-{
- char *new_arena;
-
- new_arena = mem_sys_realloc(jit_info->arena.start,
- (size_t)jit_info->arena.size * 2);
- jit_info->arena.size *= 2;
- jit_info->native_ptr = new_arena +
- (jit_info->native_ptr - jit_info->arena.start);
- jit_info->constant_pool->slot_ptr = (INTVAL *)new_arena +
- ((char *)jit_info->constant_pool->slot_ptr - jit_info->arena.start);
- jit_info->arena.start = new_arena;
-}
-
-# endif /* JITIMCC */
-#endif /* JIT_EMIT */
-#endif /* PARROT_ALPHA_JIT_EMIT_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/amd64/core.jit
==============================================================================
--- trunk/src/jit/amd64/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,471 +0,0 @@
-;
-; amd64/core.jit
-;
-; $Id$
-;
-
-Parrot_end {
- jit_emit_end(NATIVECODE);
-}
-
-Parrot_noop {
- emit_nop(NATIVECODE);
-}
-
-TEMPLATE Parrot_set_x_x {
- if (MAP[1] && MAP[2]) {
- emit_mov_<R>_<R>(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- emit_mov_<R>_m<R>(NATIVECODE, MAP[1], RBX, ROFFS_INT(2));
- }
- else if (MAP[2]) {
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), MAP[2]);
- }
- else {
- emit_mov_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(2));
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
-}
-
-
-Parrot_set_i_i {
- Parrot_set_x_x s/<R>/r/
-}
-
-Parrot_set_i_ic {
- if (MAP[1]) {
- emit_mov_r_i(NATIVECODE, MAP[1], *INT_CONST[2]);
- }
- else {
- emit_mov_mr_i(NATIVECODE, RBX, (long)ROFFS_INT(1), *INT_CONST[2]);
- }
-}
-
-Parrot_set_n_n {
- Parrot_set_x_x s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_set_i_n {
- if (MAP[1] && MAP[2]) {
- emit_cvttsd2si_r_x(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- emit_cvttsd2si_r_mx(NATIVECODE, MAP[1], RBX, ROFFS_NUM(2));
- }
- else if (MAP[2]) {
- emit_cvttsd2si_r_x(NATIVECODE, ISR1, MAP[2]);
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
- else {
- emit_cvttsd2si_r_mx(NATIVECODE, ISR1, RBX, ROFFS_NUM(2));
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_set_i_nc {
- if (MAP[1]) {
- emit_xor_r_r(NATIVECODE, ISR1, ISR1);
- emit_cvttsd2si_r_mx(NATIVECODE, MAP[1], ISR1, &NUM_CONST[2]);
- }
- else {
- emit_xor_r_r(NATIVECODE, ISR1, ISR1);
- emit_cvttsd2si_r_mx(NATIVECODE, FSR1, ISR1, &NUM_CONST[2]);
- emit_mov_mx_x(NATIVECODE, RBX, ROFFS_NUM(1), FSR1);
- }
-}
-
-Parrot_set_n_i {
- if (MAP[1] && MAP[2]) {
- emit_cvtsi2sd_x_r(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- emit_cvtsi2sd_x_mr(NATIVECODE, MAP[1], RBX, ROFFS_INT(2));
- }
- else if (MAP[2]) {
- emit_cvtsi2sd_x_r(NATIVECODE, FSR1, MAP[2]);
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_NUM(1), FSR1);
- }
- else {
- emit_cvtsi2sd_x_mr(NATIVECODE, FSR1, RBX, ROFFS_INT(2));
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_NUM(1), FSR1);
- }
-}
-
-Parrot_set_n_ic {
- if (MAP[1]) {
- emit_mov_r_i(NATIVECODE, ISR1, *INT_CONST[2]);
- emit_cvtsi2sd_x_r(NATIVECODE, MAP[1], ISR1);
- }
- else {
- emit_mov_r_i(NATIVECODE, ISR1, *INT_CONST[2]);
- emit_cvtsi2sd_x_r(NATIVECODE, FSR1, ISR1);
- emit_mov_mx_x(NATIVECODE, RBX, ROFFS_NUM(1), FSR1);
- }
-}
-
-Parrot_set_n_nc {
- if (MAP[1]) {
- /* I want something like this
- * emit_mov_x_mx(NATIVECODE, MAP[1], RBX, ROFFS_NUM(2));
- * but this works, even if ugly
- * It's either this or dereferencing
- * ((interp->ctx).state)->constants[cur_opcode[2]]->u.number
- * Instead we do a jit-run time
- * &interp->code->const_table->constants[jit_info->cur_op[2]]->u.number
- */
- emit_xor_r_r(NATIVECODE, ISR1, ISR1);
- emit_mov_x_mx(NATIVECODE, MAP[1], ISR1, &NUM_CONST[2]);
- }
- else {
- /* unmapped floats is screwy at the moment, but we get 15 plus a
- * scratch */
- emit_xor_r_r(NATIVECODE, ISR1, ISR1);
- emit_mov_x_mx(NATIVECODE, FSR1, ISR1, &NUM_CONST[2]);
- emit_mov_mx_x(NATIVECODE, RBX, ROFFS_NUM(1), FSR1);
- }
-}
-
-
-TEMPLATE Parrot_binop_x_x {
- if (MAP[1] && MAP[2]) {
- emit_<op>_<R>_<R>(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- emit_<op>_<R>_m<R>(NATIVECODE, MAP[1], RBX, ROFFS_INT(2));
- }
- else if (MAP[2]) {
-# ifdef emit_<op>_m<R>_<R>
- emit_<op>_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), MAP[2]);
-# else
- emit_mov_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(1));
- emit_<op>_<R>_<R>(NATIVECODE, ISR1, MAP[2]);
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
-# endif
- }
- else {
- emit_mov_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(1));
- emit_<op>_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(2));
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
-}
-
-TEMPLATE Parrot_binop_x_xc {
- if (MAP[1]) {
- emit_<op>_<R>_i(NATIVECODE, MAP[1], *INT_CONST[2]);
- }
- else {
-# ifdef emit_<op>_m<R>_i
- emit_<op>_m<R>_i(NATIVECODE, RBX, ROFFS_INT(1), *INT_CONST[2]);
-# else
- emit_mov_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(1));
- emit_<op>_<R>_i(NATIVECODE, ISR1, *INT_CONST[2]);
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
-# endif
- }
-}
-
-TEMPLATE Parrot_binop_x_x_x {
- if (MAP[1] && MAP[2] && MAP[3]){
- if (MAP[1] == MAP[3]) {
- emit_mov_<R>_<R>(NATIVECODE, ISR1, MAP[2]);
- emit_<op>_<R>_<R>(NATIVECODE, ISR1, MAP[3]);
- emit_mov_<R>_<R>(NATIVECODE, MAP[1], ISR1);
- }
- else {
- emit_mov_<R>_<R>(NATIVECODE, MAP[1], MAP[2]);
- emit_<op>_<R>_<R>(NATIVECODE, MAP[1], MAP[3]);
- }
- }
- else if (MAP[1] && MAP[2]) {
- emit_mov_<R>_<R>(NATIVECODE, MAP[1], MAP[2]);
- emit_<op>_<R>_m<R>(NATIVECODE, MAP[1], RBX, ROFFS_INT(3));
- }
- else if (MAP[1] && MAP[3]) {
- if (MAP[1] == MAP[3]) {
- emit_mov_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(2));
- emit_<op>_<R>_<R>(NATIVECODE, ISR1, MAP[3]);
- emit_mov_<R>_<R>(NATIVECODE, MAP[1], ISR1);
- }
- else {
- emit_mov_<R>_m<R>(NATIVECODE, MAP[1], RBX, ROFFS_INT(2));
- emit_<op>_<R>_<R>(NATIVECODE, MAP[1], MAP[3]);
- }
- }
- else if (MAP[2] && MAP[3]) {
- emit_mov_<R>_<R>(NATIVECODE, ISR1, MAP[2]);
- emit_<op>_<R>_<R>(NATIVECODE, ISR1, MAP[3]);
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
- else if (MAP[1]) {
- emit_mov_<R>_m<R>(NATIVECODE, MAP[1], RBX, ROFFS_INT(2));
- emit_<op>_<R>_m<R>(NATIVECODE, MAP[1], RBX, ROFFS_INT(3));
- }
- else if (MAP[2]) {
- emit_mov_<R>_<R>(NATIVECODE, ISR1, MAP[2]);
- emit_<op>_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(3));
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
- else if (MAP[3]) {
- emit_mov_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(2));
- emit_<op>_<R>_<R>(NATIVECODE, ISR1, MAP[3]);
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
- else {
- emit_mov_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(2));
- emit_<op>_<R>_m<R>(NATIVECODE, ISR1, RBX, ROFFS_INT(3));
- emit_mov_m<R>_<R>(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_add_i_i {
- Parrot_binop_x_x s/<op>/add/ s/<R>/r/
-}
-
-Parrot_add_i_ic {
- Parrot_binop_x_xc s/<op>/add/ s/<R>/r/
-}
-
-Parrot_add_i_i_i {
- Parrot_binop_x_x_x s/<op>/add/ s/<R>/r/
-}
-
-Parrot_sub_i_i {
- Parrot_binop_x_x s/<op>/sub/ s/<R>/r/
-}
-
-Parrot_sub_i_ic {
- Parrot_binop_x_xc s/<op>/sub/ s/<R>/r/
-}
-
-Parrot_sub_i_i_i {
- Parrot_binop_x_x_x s/<op>/sub/ s/<R>/r/
-}
-
-Parrot_band_i_i {
- Parrot_binop_x_x s/<op>/and/ s/<R>/r/
-}
-
-Parrot_band_i_i_i {
- Parrot_binop_x_x_x s/<op>/and/ s/<R>/r/
-}
-
-Parrot_band_i_ic {
- Parrot_binop_x_xc s/<op>/and/ s/<R>/r/
-}
-
-Parrot_bxor_i_i {
- Parrot_binop_x_x s/<op>/xor/ s/<R>/r/
-}
-
-Parrot_bxor_i_ic {
- Parrot_binop_x_xc s/<op>/xor/ s/<R>/r/
-}
-
-Parrot_bxor_i_i_i {
- Parrot_binop_x_x_x s/<op>/xor/ s/<R>/r/
-}
-
-Parrot_bor_i_i {
- Parrot_binop_x_x s/<op>/or/ s/<R>/r/
-}
-
-Parrot_bor_i_ic {
- Parrot_binop_x_xc s/<op>/or/ s/<R>/r/
-}
-
-Parrot_bor_i_i_i {
- Parrot_binop_x_x_x s/<op>/or/ s/<R>/r/
-}
-
-Parrot_neg_i {
- if (MAP[1]) {
- emit_not_r(NATIVECODE, MAP[1]);
- }
- else {
- emit_mov_r_mr(NATIVECODE, ISR1, RBX, ROFFS_INT(1));
- emit_neg_r(NATIVECODE, ISR1);
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_mul_i_i {
- Parrot_binop_x_x s/<op>/imul/ s/<R>/r/ s/ISR1/ISR2/
-}
-
-Parrot_div_i_i {
- if (MAP[1]) {
- emit_mov_r_r(NATIVECODE, ISR2, MAP[1]);
- }
- else {
- emit_mov_r_mr(NATIVECODE, ISR2, RBX, ROFFS_INT(1));
- }
-
- if (MAP[2]) {
- emit_idiv_r_r(NATIVECODE, ISR2, MAP[2]);
- }
- else {
- emit_idiv_r_mr(NATIVECODE, ISR2, RBX, ROFFS_INT(2));
- }
-
- if (MAP[2]) {
- emit_mov_r_r(NATIVECODE, MAP[1], ISR2);
- }
- else {
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_INT(1), ISR2);
- }
-}
-
-
-
-Parrot_not_i {
- if (MAP[1]) {
- emit_not_r(NATIVECODE, MAP[1]);
- }
- else {
- emit_mov_r_mr(NATIVECODE, ISR1, RBX, ROFFS_INT(1));
- emit_not_r(NATIVECODE, ISR1);
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_exchange_i_i {
- Parrot_binop_x_x s/<op>/xchg/ s/<R>/r/
-}
-
-Parrot_exchange_s_s {
- Parrot_binop_x_x s/<op>/xchg/ s/<R>/r/ s/INT/STR/
-}
-
-Parrot_exchange_p_p {
- Parrot_binop_x_x s/<op>/xchg/ s/<R>/r/ s/INT/PMC/
-}
-
-
-TEMPLATE Parrot_unary_x {
- if (MAP[1]) {
- emit_<op>_r(NATIVECODE, MAP[1]);
- }
- else {
- emit_mov_r_mr(NATIVECODE, ISR1, RBX, ROFFS_INT(1));
- emit_<op>_r(NATIVECODE, ISR1);
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_INT(1), ISR1)
- }
-}
-
-Parrot_inc_i {
- Parrot_unary_x s/<op>/inc/
-}
-
-Parrot_dec_i {
- Parrot_unary_x s/<op>/dec/
-}
-
-Parrot_add_n_n {
- Parrot_binop_x_x s/<op>/add/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_add_n_n_n {
- Parrot_binop_x_x_x s/<op>/add/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_sub_n_n {
- Parrot_binop_x_x s/<op>/sub/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_sub_n_n_n {
- Parrot_binop_x_x_x s/<op>/sub/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_mul_n_n {
- Parrot_binop_x_x s/<op>/mul/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_mul_n_n_n {
- Parrot_binop_x_x_x s/<op>/mul/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_div_n_n {
- Parrot_binop_x_x s/<op>/div/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_div_n_n_n {
- Parrot_binop_x_x_x s/<op>/div/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_sqrt_n_n {
- Parrot_binop_x_x s/<op>/sqrt/ s/<R>/x/ s/ISR/FSR/ s/INT/NUM/
-}
-
-
-Parrot_neg_n {
- if (MAP[1]) {
- emit_mov_r_i(NATIVECODE, ISR1, 1L << 63);
- emit_movd_x_r(NATIVECODE, FSR1, ISR1);
- emit_xor_x_x(NATIVECODE, MAP[1], FSR1);
- }
- else {
- emit_mov_r_mr(NATIVECODE, ISR1, RBX, ROFFS_NUM(1));
- emit_mov_r_i(NATIVECODE, RAX, 1L << 63);
- emit_xor_r_r(NATIVECODE, ISR1, RAX);
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_NUM(1), ISR1);
- }
-}
-
-Parrot_abs_n {
- if (MAP[1]) {
- emit_mov_r_i(NATIVECODE, ISR1, ~(1L << 63));
- emit_movd_x_r(NATIVECODE, FSR1, ISR1);
- emit_and_x_x(NATIVECODE, MAP[1], FSR1);
- }
- else {
- emit_mov_r_mr(NATIVECODE, ISR1, RBX, ROFFS_NUM(1));
- emit_mov_r_i(NATIVECODE, RAX, ~(1L << 63));
- emit_and_r_r(NATIVECODE, ISR1, RAX);
- emit_mov_mr_r(NATIVECODE, RBX, ROFFS_NUM(1), ISR1);
- }
-}
-
-Parrot_branch_ic {
- emit_jmp_i_fixup(jit_info, *INT_CONST[1]);
-}
-
-TEMPLATE Parrot_ifunless_x_ic {
- if (MAP[1]) {
- emit_test_<R>(NATIVECODE, MAP[1]);
- emit_jcc_fixup(jit_info, <jcc>, *INT_CONST[2]);
- }
- else {
- emit_mov_r_mr(NATIVECODE, ISR1, RBX, ROFFS_INT(1));
- emit_test_<R>(NATIVECODE, ISR1);
- emit_jcc_fixup(jit_info, <jcc>, *INT_CONST[2]);
- }
-}
-
-Parrot_if_i_ic {
- Parrot_ifunless_x_ic s/<jcc>/jcc_jnz/ s/<R>/r/
-}
-
-Parrot_unless_i_ic {
- Parrot_ifunless_x_ic s/<jcc>/jcc_jz/ s/<R>/r/
-}
-
-Parrot_if_n_ic {
- Parrot_ifunless_x_ic s/<jcc>/jcc_jnz/ s/<R>/x/ s/ISR/FSR/
-}
-
-Parrot_unless_n_ic {
- Parrot_ifunless_x_ic s/<jcc>/jcc_jz/ s/<R>/x/ s/ISR/FSR/
-}
-
-
-
-/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/amd64/jit_defs.c
==============================================================================
--- trunk/src/jit/amd64/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,370 +0,0 @@
-/*
-Copyright (C) 2008-2009, Parrot Foundation.
-$Id$
-*/
-
-#include "parrot/parrot.h"
-#include "jit_emit.h"
-
-/* HEADERIZER HFILE: none */
-
-/*
- * enumerate these mapped registers
- * please note that you have to preserve registers in
- * Parrot_jit_begin according to the ABI of the architecture
- */
-
-const char intval_map[INT_REGISTERS_TO_MAP] =
- {
-
- /* Preserved, we'd have more, but keeping code_start, op_map, interp,
- * and the base pointer in registers takes away four, not to mention
- * RBP which is used for easier debugging. That's five registers used
- * for one reason or another at the moment. I'm not sure if it's worth
- * it yet. */
- /*
- * RAX ISR2
- * RDX for idiv, TODO: handle corner cases, i.e. steal i386 code
- * RBX for Interp->ctx.bp
- * RBP for debugging, can add it to the preserved list
- * R12
- * R13 for CODE_START
- * R14 for OP_MAP
- * R15 for INTERP
- */
- R12,
-#ifndef USE_OP_MAP_AND_CODE_START
- R13, R14,
-#endif
- /* Unpreserved */
- RCX, RSI, RDI, R8, R9, R10, RDX
- };
-
-const char floatval_map[FLOAT_REGISTERS_TO_MAP] =
- {
- XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
- XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15
- };
-
-
-/*
- * define arch specific details in jit_arch_info
- */
-
-const jit_arch_info arch_info = {
- /* CPU <- Parrot reg move functions */
- jit_mov_r_mr,
- jit_mov_x_mx,
- /* Parrot <- CPU reg move functions */
- jit_mov_mr_r,
- jit_mov_mx_x,
- Parrot_jit_dofixup,
- (jit_arch_f)NULL,
- {
- /* JIT_CODE_FILE */
- {
- Parrot_jit_begin, /* emit code prologue */
-#ifdef USE_OP_MAP_AND_CODE_START
- 7,
- 1,
-#else
- 9, /* mapped int */
- 3, /* preserved int */
-#endif
- intval_map, /* which ints mapped */
- 14, /* mapped float */
- 0, /* preserved float */
- floatval_map /* which floats mapped */
- },
- /* JIT_CODE_SUB */
- {
- Parrot_jit_begin_sub,
- 9,
- 8,
- intval_map,
- 0,
- 0,
- floatval_map
- },
- /* JIT_CODE_SUB_REGS_ONLY */
- {
- /*Parrot_jit_begin_sub_regs*/0, /* emit code prologue */
- 16,
- 6,
- intval_map,
- 0,
- 0,
- floatval_map
- }
- }
-};
-
-const char div_by_zero[] = "Divide by zero";
-const int mxcsr = 0x7fa0; /* Add 6000 to mxcsr */
-
-/*
- * emit code that calls a Parrot opcode function
- */
-void call_func(Parrot_jit_info_t *jit_info, void *addr) {
- if ((long)addr > (long)INT_MAX) {
- /* Move the address into our scratch register R11
- * We cannot use just the immediate form of call because the address
- * will be too large if we're using a shared parrot, but will be ok on
- * a static parrot.
- *
- * This will most likely only be used on shared libraries.
- */
- /* Absolute near call to R11 */
- emit_mov_r_i(jit_info->native_ptr, R11, addr);
- emit_call_r(jit_info->native_ptr, R11);
- }
- else {
- /* Call with an immediate value. Mainly for a static parrot, and
- * debugging */
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_AMD64CALL;
- jit_info->arena.fixups->param.fptr = D2FPTR(addr);
- emit_call_i(jit_info->native_ptr, 0xdead);
- }
-}
-
-/* Jump to RAX, which needs to be set before calling this */
-void
-Parrot_emit_jump_to_rax(Parrot_jit_info_t *jit_info, Interp *interp)
-{
- if (!jit_info->objfile) {
-#ifdef USE_OP_MAP_AND_CODE_START
- /* Get interp->code->base.data */
- jit_emit_load_code_start(jit_info->native_ptr);
- emit_sub_r_r(jit_info->native_ptr, RAX, CODE_START);
-
- /* Get interp->code->jit_info->arena->op_map */
- jit_emit_load_op_map(jit_info->native_ptr);
-#else
- /* emit code that gets interp->code->base.data */
- emit_mov_r_mr(jit_info->native_ptr, RCX, INTERP, (long)offsetof(Interp, code));
- emit_mov_r_mr(jit_info->native_ptr, RDX, RCX, (long)offsetof(PackFile_Segment, data));
- emit_sub_r_r(jit_info->native_ptr, RAX, RDX);
-
- /* Reuse interp->code in RCX, get interp->code->jit_info->arena->op_map */
- emit_mov_r_mr(jit_info->native_ptr, RDX, RCX, (long)offsetof(PackFile_ByteCode, jit_info));
- emit_lea_r_mr(jit_info->native_ptr, RDX, RDX, (long)offsetof(Parrot_jit_info_t, arena));
- emit_mov_r_mr(jit_info->native_ptr, RDX, RDX, (long)offsetof(Parrot_jit_arena_t, op_map));
-#endif
- }
- /* Base pointer */
- emit_mov_r_mr(jit_info->native_ptr, RBX, INTERP, (long)offsetof(Interp, ctx));
- emit_mov_r_mr(jit_info->native_ptr, RBX, RBX, (long)offsetof(PMC, data));
- emit_mov_r_mr(jit_info->native_ptr, RBX, RBX, (long)offsetof(Parrot_Context, bp));
-
-#ifdef USE_OP_MAP_AND_CODE_START
- emit_jmp_r_r(jit_info->native_ptr, RAX, OP_MAP);
-#else
- emit_jmp_r_r(jit_info->native_ptr, RAX, RDX);
-#endif
-}
-
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- Interp *interp)
-{
- int cur_op = *jit_info->cur_op;
- static int check;
-
- if (cur_op >= jit_op_count()) {
- cur_op = CORE_OPS_wrapper__;
- }
-
- /* check every eight ops, could be changed to 16, or 32, or ... */
- if ((++check & 0x7) == 0) {
- emit_mov_r_i(jit_info->native_ptr, RDI, jit_info->cur_op);
- emit_mov_r_r(jit_info->native_ptr, RSI, INTERP);
- call_func(jit_info, (void (*)(void))interp->op_func_table[CORE_OPS_check_events]);
- }
-
- emit_mov_r_i(jit_info->native_ptr, RDI, jit_info->cur_op);
- emit_mov_r_r(jit_info->native_ptr, RSI, INTERP);
-
- call_func(jit_info, (void (*)(void))interp->op_func_table[cur_op]);
-
-}
-
-/*
- * emit code for a branching parrot opcode. All cached registers
- * need recalculation, as a branch can go into different code segments
- * with different code start and different jit_info
- */
-void
-Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
- Interp *interp)
-{
- Parrot_jit_normal_op(jit_info, interp);
- Parrot_emit_jump_to_rax(jit_info, interp);
-}
-
-/*
- * emit code that might leave the JIT runcore
- * see ppc or i386
- */
-void
-Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
- Interp *interp)
-{
- char *sav_ptr;
-
- Parrot_jit_normal_op(jit_info, interp);
- emit_test_r(jit_info->native_ptr, RAX);
-
- /* Quick fixup, but we know it's 12, anyway it needs to be a byte */
- emit_jcc(jit_info->native_ptr, jcc_jnz, 0x00);
- sav_ptr = (char *)(jit_info->native_ptr - 1);
- /* Parrot_end_jit(jit_info, interp); */
- jit_emit_end(jit_info->native_ptr);
- *sav_ptr = (char)(jit_info->native_ptr - sav_ptr - 1);
-
- Parrot_emit_jump_to_rax(jit_info, interp);
-}
-
-/*
- * emit stack frame according to ABI
- * preserve mapped registers according to ABI
- * load INTERP, OP_MAP, CODE_START, BP registers
- * then run the code at pc
- *
- * the function is called as
- * runops(interp, pc)
- *
- * at runtime
- */
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- Interp *interp)
-{
- jit_emit_stack_frame_enter(jit_info->native_ptr);
-
- /* Saved registers */
- /* push rbp
- * push rbx
- * push r12
- * push r13
- * push r14
- * push r15 */
- emit_push_r(jit_info->native_ptr, RBP);
- emit_push_r(jit_info->native_ptr, RBX);
- emit_push_r(jit_info->native_ptr, R12);
- emit_push_r(jit_info->native_ptr, R13);
- emit_push_r(jit_info->native_ptr, R14);
- emit_push_r(jit_info->native_ptr, R15);
- /* When our "function" gets called, RDI will be the interp,
- * and RSI will be jit_info->native_ptr */
- /* Set R15 to interp */
- /* mov r15, rdi */
- /* emit_ldmxcsr(jit_info->native_ptr); */
- emit_mov_r_r(jit_info->native_ptr, R15, RDI);
- emit_mov_r_r(jit_info->native_ptr, RAX, RSI);
-
- Parrot_emit_jump_to_rax(jit_info, interp);
-
-}
-
-
-/*
- * fix up all emitted branches
- * see ppc or i386
- */
-
-void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
- Interp *interp)
-{
- Parrot_jit_fixup_t *fixup, *next;
- char *fixup_ptr;
-
- fixup = jit_info->arena.fixups;
-
- while (fixup) {
- switch (fixup->type) {
- case JIT_AMD64BRANCH:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup) + 2;
- *(int *)(fixup_ptr) =
- jit_info->arena.op_map[fixup->param.opcode].offset
- - (fixup->native_offset + 6) + fixup->skip;
- break;
- case JIT_AMD64JUMP:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup) + 1;
- *(int *)(fixup_ptr) =
- jit_info->arena.op_map[fixup->param.opcode].offset
- - (fixup->native_offset + 5) + fixup->skip;
- break;
- case JIT_AMD64CALL:
- fixup_ptr = jit_info->arena.start + fixup->native_offset + 1;
- *(int *)(fixup_ptr) = (int)(long)fixup->param.fptr -
- (int)(long)fixup_ptr - 4;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Unknown fixup type: %d\n", fixup->type);
- }
- next = fixup->next;
- free(fixup);
- fixup = next;
- }
- jit_info->arena.fixups = NULL;
-}
-
-void
-Parrot_jit_begin_sub(Parrot_jit_info_t *jit_info,
- Interp *interp)
-{
- /* NOT CALLED CURRENTLY */
-}
-
-/*
- * define interface functions for register -> parrot register moves
- * and v.v.
- */
-
-/* set mem to reg */
-void
-jit_mov_mx_x(Interp *interp, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg)
-{
- emit_mov_mx_x(jit_info->native_ptr, base_reg, offs, src_reg);
-}
-
-void
-jit_mov_mr_r(Interp *interp, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg)
-{
- emit_mov_mr_r(jit_info->native_ptr, base_reg, offs, src_reg);
-}
-
-/* set reg to mem */
-void
-jit_mov_x_mx(Interp *interp, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs)
-{
- emit_mov_x_mx(jit_info->native_ptr, dst_reg, base_reg, offs);
-}
-
-void
-jit_mov_r_mr(Interp *interp, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs)
-{
- emit_mov_r_mr(jit_info->native_ptr, dst_reg, base_reg, offs);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info *
-Parrot_jit_init(SHIM_INTERP)
-{
- return &arch_info;
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/amd64/jit_emit.h
==============================================================================
--- trunk/src/jit/amd64/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,946 +0,0 @@
-/*
- * Copyright (C) 2007-2009, Parrot Foundation.
- */
-
-/*
- * jit_emit.h
- *
- * amd64
- *
- * $Id$
-
-=head1 NAME
-
-src/jit/amd64/jit_emit.h - AMD64 JIT Generation
-
-=head1 DESCRIPTION
-
-Provide the support for a JIT on the AMD64 architecture.
-
-=cut
-
-*/
-
-#ifndef PARROT_JIT_AMD64_JIT_EMIT_H_GUARD
-#define PARROT_JIT_AMD64_JIT_EMIT_H_GUARD
-
-/*
-
-hex to binary converter
-perl -ne '@a=split;push at b,unpack"B*",chr hex foreach at a;print"@b\n";@b=()'
-
-src/jit/amd64/jit_emit.h copied to src/jit_emit.h
-src/jit/amd64/exec_dep.h copied to src/exec_dep.h
-src/jit/amd64/core.jit used to build src/jit_cpu.h
-src/jit/amd64/core.jit used to build src/exec_cpu.h
-
-src/exec_start.c #define JIT_EMIT 1
-src/exec.c #define JIT_EMIT 1
-src/jit.c #define JIT_EMIT 0
-src/jit_cpu.c #define JIT_EMIT 2
-
-REX Byte
- 0100 wrxb
- w => make 64 bits
- r => use upper 8 registers for REG
- x => high bit of index in SIB
- b => use upper 8 registers for r/m, and for the base in SIB
-
-ModRM
- mm REG R/m
- mm => mode
- 00 no displacement
- 01 disp8
- 10 disp16/32
- 11 only regs
- xxx/yyy
- 0 EAX AX AL SS0 MM0
- 1 ECX CX CL SS1 MM1
- 2 EDX DX DL SS2 MM2
- 3 EBX BX BL SS3 MM3
- 4 ESP SP AH SS4 MM4
- 5 EBP BP CH SS5 MM5
- 6 ESI SI DH SS6 MM6
- 7 EDI DI BH SS7 MM7
-
-SIB
- ssiiibbb
- scale
- index
- base
- [index * 2**scale + base]
-
-
-For calling functions use: RDI, RSI, RDX, RCX, R8, and R9
- XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, and XMM7
- For varargs, RAX is used for the number of SSE regs
- Extras are pushed onto the stack
- The return is in RAX
-
- R11 is a scratch register, not preserved, not used in calling
- R10 is used for a static chain pointer
-
-RBP, RBX, and R12->R15 are preserved
-
-*/
-
-#include "parrot/parrot.h"
-#include "jit.h"
-#include <unistd.h>
-#include <limits.h>
-
-void Parrot_jit_begin(Parrot_jit_info_t *, PARROT_INTERP);
-
-
-/* This is used for testing whether or not keeping these two in registers is an
- * improvement or not. This file may need to be expanded further to know for
- * sure. But so far, there appears a 20 second improvement on my 2GHz. */
-#undef USE_OP_MAP_AND_CODE_START
-
-/*
- * define all the available cpu registers
- * reserve some for special purposes
- */
-typedef enum {
- RAX,
- ISR2 = RAX, /* Not like it's good for anything else */
- RCX,
- RDX,
- RBX,
- RSP,
- RBP,
- RSI,
- RDI,
-
- R8,
- R9,
- R10,
- R11,
- ISR1 = R11,
- R12,
- R13,
-#ifdef USE_OP_MAP_AND_CODE_START
- CODE_START = R13,
-#endif
- R14,
-#ifdef USE_OP_MAP_AND_CODE_START
- OP_MAP = R14,
-#endif
- R15,
- INTERP = R15
-} amd64_iregister_t;
-
-
-/*
-
-=head2 Register usage
-
-=over 4
-
-=item RAX
-
-Return values, second scratch
-
-=item RCX
-
-Allocated, unpreserved
-
-=item RDX
-
-Allocated, unpreserved
-
-=item RBX
-
-Parrot register frame pointer
-
-=item RSP
-
-Stack pointer
-
-=item RBP
-
-Base pointer
-
-=item RSI
-
-Allocated, unpreserved
-
-=item RDI
-
-Allocated, unpreserved
-
-=item R8
-
-Allocated, unpreserved
-
-=item R9
-
-Allocated, unpreserved
-
-=item R10
-
-Allocated, unpreserved
-
-=item R11
-
-Scratch
-
-=item R12
-
-Allocated, preserved
-
-=item R13
-
-Allocated, preserved, or code_start
-
-=item R14
-
-Allocated, preserved, or op_map
-
-=item R15
-
-Interp
-
-=item XMM0
-
-Scratch
-
-=item XMM1-XMM15
-
-Allocated, all unpreserved
-
-=back
-
-=cut
-
-*/
-
-
-#define Parrot_jit_emit_get_base_reg_no(pc) RBX
-
-typedef enum {
- XMM0,
- FSR1 = XMM0,
- XMM1,
- FSR2 = XMM1,
- XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
- XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15
-} amd64_fregister_t;
-
-
-/* Call can be handled without a fixup */
-enum { JIT_AMD64BRANCH, JIT_AMD64JUMP, JIT_AMD64CALL };
-
-
-/*
- * now define macros for all possible (and implemented) operations
- *
- * Parrot defines JIT_EMIT to 1 or 2, when this file is included in
- * exec_cpu.c or jit_cpu.c
- */
-
-/*
-
-=head2 Macros
-
-Most of the functionality is provided by macros instead of functions.
-
-=over 4
-
-=cut
-
-*/
-
-#define b00 0
-#define b01 1
-#define b10 2
-#define b11 3
-
-#define b000 0
-#define b001 1
-#define b010 2
-#define b011 3
-#define b100 4
-#define b101 5
-#define b110 6
-#define b111 7
-
-/* rex.[wrxb], incomplete but oh well */
-/*
-
-=item C<emit_rex64(pc, reg, rm)>
-
-The REX prefix, setting REX.W making the instruction 64 bit.
-
-=item C<emit_rex(pc, reg, rm)>
-
-The REX prefix, only emitted if using an extended register.
-
-=cut
-
-*/
-# define emit_rex64(pc, reg, rm) \
- *((pc)++) = (char)(0x48 | (((reg) & 8) >> 1) | (((rm) & 8) >> 3))
-
-# define emit_rex(pc, dst, src) { \
- if ((dst) & 8 || (src) & 8) \
- *((pc)++) = (char)(0x40 | (((dst) & 8) >> 1) | (((src) & 8) >> 3)); }
-
-/* Use a 0x66 prefix for increased padding */
-# define emit_nop(pc) { \
- *((pc)++) = (char)(0x90); }
-
-# define emit_modrm(pc, mod, dst, src) { \
- *((pc)++) = (char)(((mod) << 6) | (((dst) & 7) << 3) | ((src) & 7)); }
-
-# define emit_sib(pc, scale, index, base) { \
- *((pc)++) = (char)(((scale) << 6) | (((index) & 7) << 3) | ((base) & 7)); }
-
-/* 0xXX +rq */
-# define emit_op_r(op, pc, reg) { \
- emit_rex64((pc), 0x0, (reg)); \
- *((pc)++) = (char)((op) | ((reg) & 7)); \
- }
-
-# define emit_64op_r(op, pc, reg) { \
- emit_rex((pc), 0x0, (reg)); \
- *((pc)++) = (char)((op) | ((reg) & 7)); \
- }
-
-/* 0xXX /r */
-# define emit_op_r_r(op, pc, dst, src) { \
- emit_rex64((pc), (dst), (src)); \
- *((pc)++) = (char) (op); \
- emit_modrm((pc), b11, (dst), (src)); \
- }
-
-# define emit_op_r_mr(op, pc, dst, src, disp) { \
- emit_rex64((pc), (dst), (src)); \
- *((pc)++) = (char) (op); \
- if ((disp) == 0) { \
- emit_modrm((pc), b00, (dst), (src)); \
- } \
- else if (is8bit(disp)) { \
- emit_modrm((pc), b01, (dst), (src)); \
- *((pc)++) = (char)(disp); \
- } \
- else { \
- emit_modrm((pc), b10, (dst), (src)); \
- *(int *)(pc) = (int)(disp); \
- (pc) += 4; \
- } \
- }
-
-# define emit_op_i(op, pc, imm) { \
- *((pc)++) = (char)(op); \
- *(int *)(pc) = (int)(imm); \
- (pc) += 4; \
- }
-
-# define emit_op_r_i(pc, op, op2, code, dst, imm) { \
- emit_rex64((pc), 0x0, (dst)); \
- if (is8bit(imm)) { \
- *((pc)++) = (char) (op); \
- emit_modrm((pc), b11, (code), (dst)); \
- *((pc)++) = (char)(imm); \
- } \
- else { \
- *((pc)++) = (char) (op2); \
- emit_modrm((pc), b11, (code), (dst)); \
- *(int *)(pc) = (int)(imm); \
- (pc) += 4; \
- } \
- }
-
-# define emit_op_mr_i(pc, op, op2, code, dst, disp, imm) { \
- emit_rex64((pc), 0x0, (dst)); \
- if (is8bit(imm)) { \
- *((pc)++) = (char) (op); \
- if ((disp) == 0) { \
- emit_modrm((pc), b00, (code), (dst)); \
- } \
- else if (is8bit(disp)) { \
- emit_modrm((pc), b01, (code), (dst)); \
- *((pc)++) = (char)(disp); \
- } \
- else { \
- emit_modrm((pc), b10, (code), (dst)); \
- *(int *)(pc) = (int)(disp); \
- (pc) += 4; \
- } \
- *((pc)++) = (char)(imm); \
- } \
- else { \
- *((pc)++) = (char) (op2); \
- if ((disp) == 0) { \
- emit_modrm((pc), b00, (code), (dst)); \
- } \
- else if (is8bit(disp)) { \
- emit_modrm((pc), b01, (code), (dst)); \
- *((pc)++) = (char)(disp); \
- } \
- else { \
- emit_modrm((pc), b10, (code), (dst)); \
- *(int *)(pc) = (int)(disp); \
- (pc) += 4; \
- } \
- *(int *)(pc) = (int)(imm); \
- (pc) += 4; \
- } \
- }
-
-/* Test for zero, then call this; it'll call Parrot_ex_throw_from_c_args if you try
- * to divide by zero */
-# define emit_div_check_zero(pc) { \
- char *sav_ptr; \
- emit_jcc((pc), jcc_jnz, 0x00); \
- sav_ptr = (char *)((pc) - 1); \
- emit_mov_r_r((pc), RDI, INTERP); \
- emit_mov_r_i((pc), RSI, 0); \
- emit_mov_r_i((pc), RDX, EXCEPTION_DIV_BY_ZERO); \
- emit_mov_r_i((pc), RCX, div_by_zero); \
- /* We must explicitly zero out RAX, since RAX is used in calling
- * conventions for va_arg functions, and Parrot_ex_throw_from_c_args is a va_arg
- * function */ \
- emit_xor_r_r((pc), RAX, RAX); \
- /* This assumes that jit_info is defined, if it's not, the code's not "consistent" */ \
- call_func(jit_info, (void (*)(void)) Parrot_ex_throw_from_c_args); \
- *sav_ptr = (char)((pc) - sav_ptr - 1); \
-}
-
-# define emit_cmp_r_i(pc, dst, imm) emit_op_r_i((pc), 0x83, 0x81, 0x7, (dst), (imm))
-# define emit_cmp_mr_i(pc, dst, disp, imm) emit_op_mr_i((pc), 0x83, 0x81, 0x7, (dst), (disp), (imm))
-# define emit_cmp_r_r(pc, dst, src) emit_op_r_r(0x3b, (pc), (dst), (src))
-# define emit_cmp_r_mr(pc, dst, src, disp) emit_op_r_mr(0x3b, (pc), (dst), (src), (disp))
-# define emit_cmp_mr_r(pc, dst, disp, src) emit_op_r_mr(0x39, (pc), (src), (dst), (disp))
-
-
-# define emit_add_r_i(pc, dst, imm) emit_op_r_i((pc), 0x83, 0x81, 0x0, (dst), (imm))
-# define emit_add_mr_i(pc, dst, disp, imm) emit_op_mr_i((pc), 0x83, 0x81, 0x0, (dst), (disp), (imm))
-# define emit_add_r_r(pc, dst, src) emit_op_r_r(0x03, (pc), (dst), (src))
-# define emit_add_r_mr(pc, dst, src, disp) emit_op_r_mr(0x03, (pc), (dst), (src), (disp))
-# define emit_add_mr_r(pc, dst, disp, src) emit_op_r_mr(0x01, (pc), (src), (dst), (disp))
-
-# define emit_sub_r_i(pc, dst, imm) emit_op_r_i((pc), 0x83, 0x81, 0x5, (dst), (imm))
-# define emit_sub_mr_i(pc, dst, disp, imm) emit_op_mr_i((pc), 0x83, 0x81, 0x5, (dst), (disp), (imm))
-# define emit_sub_r_r(pc, dst, src) emit_op_r_r(0x2b, (pc), (dst), (src))
-# define emit_sub_r_mr(pc, dst, src, disp) emit_op_r_mr(0x29, (pc), (dst), (src), (disp))
-# define emit_sub_mr_r(pc, dst, disp, src) emit_op_r_mr(0x2b, (pc), (src), (dst), (disp))
-
-# define emit_xchg_r_r(pc, dst, src) emit_op_r_r(0x87, (pc), (dst), (src))
-# define emit_xchg_r_mr(pc, dst, src, disp) emit_op_r_mr(0x87, (pc), (dst), (src), (disp))
-# define emit_xchg_mr_r(pc, dst, disp, src) emit_op_r_mr(0x87, (pc), (src), (dst), (disp))
-
-# define emit_xor_r_i(pc, dst, imm) emit_op_r_i((pc), 0x83, 0x81, 0x6, (dst), (imm))
-# define emit_xor_mr_i(pc, dst, disp, imm) emit_op_mr_i((pc), 0x83, 0x81, 0x6, (dst), (disp), (imm))
-# define emit_xor_r_r(pc, dst, src) emit_op_r_r(0x33, (pc), (dst), (src))
-# define emit_xor_r_mr(pc, dst, src, disp) emit_op_r_mr(0x33, (pc), (dst), (src), (disp))
-# define emit_xor_mr_r(pc, dst, disp, src) emit_op_r_mr(0x31, (pc), (src), (dst), (disp))
-
-# define emit_and_r_i(pc, dst, imm) emit_op_r_i((pc), 0x83, 0x81, 0x4, (dst), (imm))
-# define emit_and_mr_i(pc, dst, disp, imm) emit_op_mr_i((pc), 0x83, 0x81, 0x4, (dst), (disp), (imm))
-# define emit_and_r_r(pc, dst, src) emit_op_r_r(0x23, (pc), (dst), (src))
-# define emit_and_r_mr(pc, dst, src, disp) emit_op_r_mr(0x23, (pc), (dst), (src), (disp))
-# define emit_and_mr_r(pc, dst, disp, src) emit_op_r_mr(0x21, (pc), (src), (dst), (disp))
-
-# define emit_or_r_i(pc, dst, imm) emit_op_r_i((pc), 0x83, 0x81, 0x1, (dst), (imm))
-# define emit_or_mr_i(pc, dst, disp, imm) emit_op_mr_i((pc), 0x83, 0x81, 0x1, (dst), (disp), (imm))
-# define emit_or_r_r(pc, dst, src) emit_op_r_r(0x0b, (pc), (dst), (src))
-# define emit_or_r_mr(pc, dst, src, disp) emit_op_r_mr(0x0b, (pc), (dst), (src), (disp))
-# define emit_or_mr_r(pc, dst, disp, src) emit_op_r_mr(0x09, (pc), (src), (dst), (disp))
-
-# define emit_imul_r_r(pc, dst, src) { \
- emit_rex64((pc), (dst), (src)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0xaf; \
- emit_modrm((pc), b11, (dst), (src)); \
-}
-# define emit_imul_r_mr(pc, dst, src, disp) { \
- emit_rex64((pc), (dst), (src)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0xaf; \
- if ((disp) == 0) { \
- emit_modrm((pc), b00, (dst), (src)); \
- } \
- else if (is8bit(disp)) { \
- emit_modrm((pc), b01, (dst), (src)); \
- *((pc)++) = (char)(disp); \
- } \
- else { \
- emit_modrm((pc), b10, (dst), (src)); \
- *(int *)(pc) = (int)(disp); \
- (pc) += 4; \
- } \
-}
-
-# define emit_idiv_r_r(pc, dst, src) { \
- emit_xor_r_r((pc), RDX, RDX); \
- emit_test_r((pc), (src)); \
- emit_div_check_zero(pc); \
- emit_op_r_r(0xf7, (pc), 0x7, (src)); \
-}
-# define emit_idiv_r_mr(pc, dst, src, disp) { \
- emit_xor_r_r((pc), RDX, RDX); \
- emit_mov_r_mr((pc), ISR1, (src), (disp)); \
- emit_test_r((pc), ISR1); \
- emit_div_check_zero(pc); \
- emit_op_r_mr(0xf7, (pc), 0x7, (src), (disp)); \
-}
-
-# define emit_abs_r(pc, reg) emit_and_r_i((pc), (reg), ~(1L << 63))
-
-# define emit_neg_r(pc, reg) emit_op_r_r(0xf7, (pc), 0x2, (reg))
-# define emit_not_r(pc, reg) emit_op_r_r(0xf7, (pc), 0x3, (reg))
-# define emit_inc_r(pc, reg) emit_op_r_r(0xff, (pc), 0x0, (reg))
-# define emit_dec_r(pc, reg) emit_op_r_r(0xff, (pc), 0x1, (reg))
-
-/* This needs a fixup it seems... call_r doesn't */
-# define emit_call_i(pc, imm) emit_op_i(0xe8, (pc), (imm))
-# define emit_call_r(pc, reg) { \
- emit_rex64((pc), 0x0, (reg)); \
- *(pc)++ = (char)0xff; \
- emit_modrm((pc), b11, 0x2, (reg)); }
-
-# define emit_jmp_r_r(pc, reg1, reg2) { \
- emit_rex((pc), (reg1), (reg2)); \
- *((pc)++) = (char)0xff; \
- emit_modrm((pc), b00, 0x4, b100); \
- emit_sib((pc), b00, (reg1), (reg2)); \
-}
-
-# define emit_jmp_i(pc, imm) emit_op_i(0xe9, (pc), (imm))
-# define emit_jmp_i_fixup(ji, imm) { \
- opcode_t opcode; \
- opcode = jit_info->op_i + (imm); \
- Parrot_jit_newfixup(jit_info); \
- jit_info->arena.fixups->type = JIT_AMD64JUMP; \
- jit_info->arena.fixups->param.opcode = opcode; \
- if (jit_info->optimizer->cur_section->branch_target == \
- jit_info->optimizer->cur_section) \
- jit_info->arena.fixups->skip = \
- jit_info->optimizer->cur_section->branch_target->load_size; \
- emit_jmp_i(jit_info->native_ptr, 0xdead); \
-}
-
-# define emit_leave(pc) *((pc)++) = (char)0xc9;
-# define emit_ret(pc) *((pc)++) = (char)0xc3;
-
-# define emit_mov_r_r(pc, dst, src) \
- emit_op_r_r(0x8B, (pc), (dst), (src))
-
-/* mov [reg + offs], imm */
-# define emit_mov_mr_i(pc, reg, offs, imm) {\
- if (is32bit(imm)) { \
- emit_rex64((pc), 0x0, (reg)); \
- *((pc)++) = (char) 0xc7; \
- if ((offs) == 0) { \
- emit_modrm((pc), b00, 0x0, (reg)); \
- } \
- else if (is8bit(offs)) { \
- emit_modrm((pc), b01, 0x0, (reg)); \
- *((pc)++) = (char)(offs); \
- } \
- else { \
- emit_modrm((pc), b10, 0x0, (reg)); \
- *(int *)(pc) = (int)(offs); \
- (pc) += 4; \
- } \
- *(int *)(pc) = (int)(imm); \
- (pc) += 4; \
- } \
- else { \
- emit_mov_r_i((pc), ISR1, (imm)); \
- emit_mov_mr_r((pc), (reg), (offs), ISR1); \
- } \
- }
-
-/* mov reg, imm */
-# define emit_mov_r_i(pc, reg, imm) {\
- emit_op_r(0xb8, (pc), (reg)); \
- *(long *)(pc) = (long)(imm); \
- (pc) += 8; \
- }
-
-/* push reg */
-# define emit_push_r(pc, reg) emit_64op_r(0x50, (pc), (reg))
-/* pop reg */
-# define emit_pop_r(pc, reg) emit_64op_r(0x58, (pc), (reg))
-
-/* push imm */
-# define emit_push_i(pc, imm) emit_op_i(0x68, (pc), (imm))
-
-/* did you know, that (unsigned)0 is not an 8 bit value? */
-# define is8bit(c) (((long)(c)) >= -128 && ((long)(c)) <= 127)
-# define is32bit(c) (((long)(c)) >= -2147483648 && ((long)(c)) <= 2147483647)
-
-# define emit_get_int_from_stack(pc, dst, disp) \
- emit_mov_r_mr((pc), (dst), RBP, (disp))
-
-# define emit_send_int_to_stack(pc, src, disp) \
- emit_mov_mr_r((pc), RBP, (disp), (src))
-
-/* mov dst, [src + disp] */
-# define emit_mov_r_mr(pc, dst, src, disp) \
- emit_op_r_mr(0x8b, (pc), (dst), (src), (disp))
-/* mov [dst + disp], src */
-# define emit_mov_mr_r(pc, dst, disp, src) \
- emit_op_r_mr(0x89, (pc), (src), (dst), (disp))
-
-/* lea dst, [src + disp] */
-# define emit_lea_r_mr(pc, dst, src, disp) \
- emit_op_r_mr(0x8d, (pc), (src), (dst), (disp))
-
-/* push rbp
- * mov rbp, rsp */
-/* move rsp to rbp; set rbp to rsp */
-# define jit_emit_stack_frame_enter(pc) { \
- emit_push_r((pc), RBP); \
- emit_mov_r_r((pc), RBP, RSP); \
- }
-
-/* pop rbp */
-# define jit_emit_stack_frame_leave(pc) { \
- emit_pop_r((pc), RBP); \
- }
-
-# define emit_jcc(pc, code, disp) { \
- if (is8bit(disp)) { \
- *((pc)++) = (char) 0x70 | (code); \
- *((pc)++) = (char) (disp); \
- } \
- else { \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0x80 | (code); \
- *(int *)(pc) = (int)(disp); \
- (pc) += 4; \
- } \
-}
-
-# define emit_jcc_fixup(ji, code, imm) { \
- opcode_t opcode; \
- opcode = (ji)->op_i + (imm); \
- Parrot_jit_newfixup(ji); \
- (ji)->arena.fixups->type = JIT_AMD64BRANCH; \
- (ji)->arena.fixups->param.opcode = opcode; \
- if ((ji)->optimizer->cur_section->branch_target == \
- (ji)->optimizer->cur_section) \
- (ji)->arena.fixups->skip = \
- (ji)->optimizer->cur_section->branch_target->load_size; \
- emit_jcc((ji)->native_ptr, (code), 0xdead); \
-}
-
-typedef enum {
- jcc_jo, /* Jump if overflow */
- jcc_jno, /* Jump if not overflow */
- jcc_jb, /* Jump if below */
- jcc_jc = jcc_jb, /* Jump if carry */
- jcc_jnae = jcc_jb, /* Jump if not above or equal */
- jcc_jnb, /* Jump if not below */
- jcc_jnc = jcc_jnb, /* Jump if not carry */
- jcc_jae = jcc_jnb, /* Jump if above or equal */
- jcc_jz, /* Jump if zero */
- jcc_je = jcc_jz, /* Jump if equal */
- jcc_jnz, /* Jump if not zero */
- jcc_jne = jcc_jnz, /* Jump if not equal */
- jcc_jbe, /* Jump if below or equal */
- jcc_jna = jcc_jbe, /* Jump if not above */
- jcc_jnbe, /* Jump if not below or equal */
- jcc_ja = jcc_jnbe, /* Jump if above */
- jcc_js, /* Jump if sign */
- jcc_jns, /* Jump if not sign */
- jcc_jp, /* Jump if parity */
- jcc_jpe = jcc_jp, /* Jump if parity even */
- jcc_jnp, /* Jump if not parity */
- jcc_jpo = jcc_jnp, /* Jump if parity odd */
- jcc_jl, /* Jump if less */
- jcc_jnge = jcc_jl, /* Jump if not greater or equal */
- jcc_jnl, /* Jump if not less */
- jcc_jge = jcc_jnl, /* Jump if greater or equal */
- jcc_jle, /* Jump if less or equal */
- jcc_jng = jcc_jle, /* Jump if not greater */
- jcc_jnle, /* Jump if not less or equal */
- jcc_jg = jcc_jnle /* Jump if greater */
-} amd64_jcc_t;
-
-# define emit_test_r(pc, reg) \
- emit_op_r_r(0x85, (pc), (reg), (reg))
-
-# define emit_test_r_r(pc, dst, src) \
- emit_op_r_r(0x85, (pc), (src), (dst))
-
- /* pop r15
- * pop r14
- * pop r13
- * pop r12
- * pop rbx
- * pop rbp
- * ret */
-# define jit_emit_end(pc) { \
- emit_pop_r((pc), R15); \
- emit_pop_r((pc), R14); \
- emit_pop_r((pc), R13); \
- emit_pop_r((pc), R12); \
- emit_pop_r((pc), RBX); \
- emit_pop_r((pc), RBP); \
- emit_leave(pc); \
- emit_ret(pc); \
-}
-
-
-/**************************************
- * Floating Point *
- **************************************/
-
-# define emit_op_x_x(prefix, op, pc, dst, src) { \
- *((pc)++) = (char) (prefix); \
- emit_rex((pc), (dst), (src)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) (op); \
- emit_modrm((pc), b11, (dst), (src)); \
-}
-
-# define emit_op64_x_x(prefix, op, pc, dst, src) { \
- *((pc)++) = (char) (prefix); \
- emit_rex64((pc), (dst), (src)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) (op); \
- emit_modrm((pc), b11, (dst), (src)); \
-}
-
-# define emit_op_x_mx(prefix, op, pc, dst, src, offs) { \
- *((pc)++) = (char) (prefix); \
- emit_rex((pc), (dst), (src)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) (op); \
- if ((offs) == 0) { \
- emit_modrm((pc), b00, (dst), (src)); \
- } \
- else if (is8bit(offs)) { \
- emit_modrm((pc), b01, (dst), (src)); \
- *((pc)++) = (char)(long)(offs); \
- } \
- else { \
- emit_modrm((pc), b10, (dst), (src)); \
- *(int *)(pc) = (int)(long)(offs); \
- (pc) += 4; \
- } \
-}
-
-# define emit_op64_x_mx(prefix, op, pc, dst, src, offs) { \
- *((pc)++) = (char) (prefix); \
- emit_rex64((pc), (dst), (src)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) (op); \
- if ((offs) == 0 || (src) == RBP) { \
- emit_modrm((pc), b00, (dst), (src)); \
- } \
- else if (is8bit(offs)) { \
- emit_modrm((pc), b01, (dst), (src)); \
- *((pc)++) = (char)(long)(offs); \
- } \
- else { \
- emit_modrm((pc), b10, (dst), (src)); \
- *(int *)(pc) = (int)(long)(offs); \
- (pc) += 4; \
- } \
-}
-
-# define emit_mov_x_x(pc, dst, src) emit_op_x_x(0x66, 0x28, (pc), (dst), (src))
-
-# define emit_mov_x_mx(pc, dst, src, offs) emit_op_x_mx(0xf2, 0x10, (pc), (dst), (src), (offs))
-# define emit_mov_mx_x(pc, dst, offs, src) emit_op_x_mx(0xf2, 0x11, (pc), (src), (dst), (offs))
-
-/* Intended to zero a register */
-# define emit_movhlps_x_x(pc, dst, src) { \
- emit_rex((pc), (src), (dst)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0x12; \
- emit_modrm((pc), b11, (src), (dst)); \
-}
-
-# define emit_movlhps_x_x(pc, dst, src) { \
- emit_rex((pc), (src), (dst)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0x16; \
- emit_modrm((pc), b11, (src), (dst)); \
-}
-
-# define emit_movd_r_x(pc, dst, src) { \
- *((pc)++) = (char) 0x66; \
- emit_rex64((pc), (dst), (src)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0x7e; \
- emit_modrm((pc), b11, (dst), (src)); \
-}
-
-# define emit_movd_x_r(pc, dst, src) { \
- *((pc)++) = (char) 0x66; \
- emit_rex64((pc), (dst), (src)); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0x6e; \
- emit_modrm((pc), b11, (dst), (src)); \
-}
-
-# define emit_test_x(pc, reg) { \
- emit_xor_x_x((pc), FSR2, FSR2); \
- emit_comisd_x_x((pc), (reg), FSR2); \
-}
-
-# define emit_comisd_x_x(pc, dst, src) emit_op_x_x(0x66, 0x2f, (pc), (dst), (src))
-# define emit_comisd_x_mx(pc, dst, src, offs) emit_op_x_mx(0x66, 0x2f, (pc), (dst), (src), (offs))
-
-# define emit_add_x_x(pc, dst, src) emit_op_x_x(0xf2, 0x58, (pc), (dst), (src))
-# define emit_add_x_mx(pc, dst, src, offs) emit_op_x_mx(0xf2, 0x58, (pc), (dst), (src), (offs))
-
-# define emit_sub_x_x(pc, dst, src) emit_op_x_x(0xf2, 0x5c, (pc), (dst), (src))
-# define emit_sub_x_mx(pc, dst, src, offs) emit_op_x_mx(0xf2, 0x5c, (pc), (dst), (src), (offs))
-
-# define emit_and_x_x(pc, dst, src) emit_op_x_x(0x66, 0x54, (pc), (dst), (src))
-# define emit_and_x_mx(pc, dst, src, offs) emit_op_x_mx(0x66, 0x54, (pc), (dst), (src), (offs))
-
-# define emit_xor_x_x(pc, dst, src) emit_op_x_x(0x66, 0x57, (pc), (dst), (src))
-# define emit_xor_x_mx(pc, dst, src, offs) emit_op_x_mx(0x66, 0x57, (pc), (dst), (src), (offs))
-
-# define emit_mul_x_x(pc, dst, src) emit_op_x_x(0xf2, 0x59, (pc), (dst), (src))
-# define emit_mul_x_mx(pc, dst, src, offs) emit_op_x_mx(0xf2, 0x59, (pc), (dst), (src), (offs))
-
-/* I tried to do a check for FSR1 == dst, such as from core.jit, but the bugs
- * to track down, the hackish things to do(movhlpd and movlhpd were used, but I
- * gave up and settled on the cleaner and likely faster overall method of
- * getting an FSR2 and going down to 14 mapped registers.
- */
-# define emit_div_x_x(pc, dst, src) { \
- emit_movhlps_x_x((pc), FSR2, FSR2); \
- emit_comisd_x_x((pc), FSR2, (src)); \
- emit_div_check_zero((pc)); \
- emit_op_x_x(0xf2, 0x5e, (pc), (dst), (src)); \
-}
-# define emit_div_x_mx(pc, dst, src, offs) { \
- emit_movhlps_x_x((pc), FSR2, FSR2); \
- emit_comisd_x_mx((pc), FSR2, (src), (offs)); \
- emit_div_check_zero((pc)); \
- emit_op_x_mx(0xf2, 0x5e, (pc), (dst), (src), (offs)); \
-}
-
-# define emit_sqrt_x_x(pc, dst, src) emit_op_x_x(0xf2, 0x51, (pc), (dst), (src))
-# define emit_sqrt_x_mx(pc, dst, src, offs) emit_op_x_mx(0xf2, 0x51, (pc), (dst), (src), (offs))
-
-# define emit_cvtsi2sd_x_mr(pc, dst, src, offs) emit_op64_x_mx(0xf2, 0x2a, (pc), (dst), (src), (offs))
-# define emit_cvtsi2sd_x_r(pc, dst, src) emit_op64_x_x(0xf2, 0x2a, (pc), (dst), (src))
-
-/* Truncate */
-# define emit_cvttsd2si_r_mx(pc, dst, src, offs) emit_op64_x_mx(0xf2, 0x2c, (pc), (dst), (src), (offs))
-# define emit_cvttsd2si_r_x(pc, dst, src) emit_op64_x_x(0xf2, 0x2c, (pc), (dst), (src))
-
-/* Round */
-# define emit_cvtsd2si_r_mx(pc, dst, src, offs) emit_op64_x_mx(0xf2, 0x2d, (pc), (dst), (src), (offs))
-# define emit_cvtsd2si_r_x(pc, dst, src) emit_op64_x_x(0xf2, 0x2d, (pc), (dst), (src))
-
-# define emit_ldmxcsr(pc) { \
- emit_xor_r_r((pc), ISR2, ISR2); \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0xAE; \
- emit_modrm((pc), b10, 0x2, ISR2); \
- *(int *)(pc) = (int)&mxcsr; \
- (pc) += 4; \
-}
-/*********************************************************/
-
-#ifdef USE_OP_MAP_AND_CODE_START
-/* These two can be mixed together just like in the i386 jit. All the places I
- * can see this being called require it to be included, but for the moment I'm
- * keeping it as these macros. */
-/*
- * emit code that gets interp->code->jit_info->arena->op_map
- * and sets the OP_MAP register
- */
-# define jit_emit_load_op_map(pc) { \
- emit_mov_r_mr((pc), OP_MAP, INTERP, (long)offsetof(Interp, code)); \
- emit_mov_r_mr((pc), OP_MAP, OP_MAP, (long)offsetof(PackFile_ByteCode, jit_info)); \
- emit_lea_r_mr((pc), OP_MAP, OP_MAP, (long)offsetof(Parrot_jit_info_t, arena)); \
- emit_mov_r_mr((pc), OP_MAP, OP_MAP, (long)offsetof(Parrot_jit_arena_t, op_map)); \
-}
-
-/*
- * emit code that gets interp->code->base.data
- * and sets the CODE_START register
- */
-# define jit_emit_load_code_start(pc) { \
- emit_mov_r_mr((pc), CODE_START, INTERP, (long)offsetof(Interp, code)); \
- emit_mov_r_mr((pc), CODE_START, CODE_START, (long)offsetof(PackFile_Segment, data)); \
-}
-
-#endif /* USE_OP_MAP_AND_CODE_START */
-
-void call_func(Parrot_jit_info_t *jit_info, void *addr);
-void Parrot_emit_jump_to_rax(Parrot_jit_info_t *jit_info, Interp *interp);
-
-/*
- * emit code that calls a core.ops function from src/core_ops.c,
- * the generated code is the translation of this:
- *
- * PC = ((INTERP->op_func_table)[*PC])(PC,INTERP)
- */
-
-extern int jit_op_count(void);
-
-/*
- * release stack frame end exit see core.jit
- */
-/* extern static void Parrot_end_jit(Parrot_jit_info_t *, Interp *); */
-
-# undef Parrot_jit_restart_op
-
-void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info, Interp *interp);
-void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info, Interp *interp);
-void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info, Interp *interp);
-void jit_mov_mx_x(Interp *interp, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg);
-void jit_mov_mr_r(Interp *interp, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg);
-void jit_mov_x_mx(Interp *interp, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs);
-void jit_mov_r_mr(Interp *interp, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info * Parrot_jit_init(Interp *interp);
-
-
-/*
- * define how many int and float registers can be used by the
- * jit core
- */
-
-# define INT_REGISTERS_TO_MAP 10
-# define FLOAT_REGISTERS_TO_MAP 15
-
-# define REQUIRES_CONSTANT_POOL 0
-
-void Parrot_jit_begin(Parrot_jit_info_t *jit_info, Interp *interp);
-void Parrot_jit_dofixup(Parrot_jit_info_t *jit_info, Interp *interp);
-void Parrot_jit_begin_sub(Parrot_jit_info_t *jit_info, Interp *interp);
-
-extern const char intval_map[INT_REGISTERS_TO_MAP];
-extern const char floatval_map[FLOAT_REGISTERS_TO_MAP];
-extern const jit_arch_info arch_info;
-extern const char div_by_zero[];
-extern const int mxcsr;
-
-#endif /* PARROT_JIT_AMD64_JIT_EMIT_H_GUARD */
-
-/*
-
-=back
-
-=cut
-
-*/
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/arm/core.jit
==============================================================================
--- trunk/src/jit/arm/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,673 +0,0 @@
-;
-; arm/core.jit
-;
-; $Id$
-;
-
-Parrot_noop {
- jit_info->native_ptr = emit_nop(jit_info->native_ptr);
-}
-
-; ldmea fp, {r4, r5, r6, r7, fp, sp, pc
-; but K bug Grr if I load pc direct.
-
-Parrot_end {
- #ifndef ARM_K_BUG
- jit_info->native_ptr = emit_ldmstm (jit_info->native_ptr,
- cond_AL, is_load, dir_EA, no_writeback,
- REG11_fp,
- reg2mask(4) | reg2mask(REG11_fp)
- | reg2mask(REG13_sp)
- | reg2mask(REG15_pc));
- #else
- jit_info->native_ptr = emit_ldmstm (jit_info->native_ptr,
- cond_AL, is_load, dir_EA, no_writeback,
- REG11_fp,
- reg2mask(4) | reg2mask(REG11_fp)
- | reg2mask(REG13_sp)
- | reg2mask(REG14_lr));
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, REG15_pc, REG14_lr);
- #endif
-}
-
-; This shows why it would be nice in the future to have a way to have ops
-; broken into 1 to 3 of:
-;
-; -1) get values from parrot registers into CPU registers
-; 0) do stuff
-; +1) write values back to parrot registers
-;
-; that way, a JIT optimiser could punt -1 and +1 outside loops leaving
-; intermediate values in CPU registers. It could collate -1 and +1 [leaving
-; nothing :-)] and choose how to maximise use of as many real CPU registers as
-; possible.
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; set ops
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-Parrot_set_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-Parrot_set_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; comparison ops
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-Parrot_eq_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, r1);
- emit_jump_to_op (jit_info, cond_EQ, *INT_CONST[3]);
-}
-Parrot_eq_i_ic_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 1, *INT_CONST[2],
- *INT_CONST[3], cond_EQ);
-}
-Parrot_eq_ic_i_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 2, *INT_CONST[1],
- *INT_CONST[3], cond_EQ);
-}
-Parrot_eq_ic_ic_ic {
- if (*INT_CONST[1] == *INT_CONST[2])
- emit_jump_to_op (jit_info, cond_AL, *INT_CONST[3]);
-}
-
-Parrot_ne_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, r1);
- emit_jump_to_op (jit_info, cond_NE, *INT_CONST[3]);
-}
-Parrot_ne_i_ic_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 1, *INT_CONST[2],
- *INT_CONST[3], cond_NE);
-}
-Parrot_ne_ic_i_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 2, *INT_CONST[1],
- *INT_CONST[3], cond_NE);
-}
-Parrot_ne_ic_ic_ic {
- if (*INT_CONST[1] != *INT_CONST[2])
- emit_jump_to_op (jit_info, cond_AL, *INT_CONST[3]);
-}
-
-Parrot_lt_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, r1);
- emit_jump_to_op (jit_info, cond_LT, *INT_CONST[3]);
-}
-Parrot_lt_i_ic_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 1, *INT_CONST[2],
- *INT_CONST[3], cond_LT);
-}
-Parrot_lt_ic_i_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 2, *INT_CONST[1],
- *INT_CONST[3], cond_GE);
-}
-Parrot_lt_ic_ic_ic {
- if (*INT_CONST[1] < *INT_CONST[2])
- emit_jump_to_op (jit_info, cond_AL, *INT_CONST[3]);
-}
-
-Parrot_le_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, r1);
- emit_jump_to_op (jit_info, cond_LE, *INT_CONST[3]);
-}
-Parrot_le_i_ic_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 1, *INT_CONST[2],
- *INT_CONST[3], cond_LE);
-}
-Parrot_le_ic_i_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 2, *INT_CONST[1],
- *INT_CONST[3], cond_GT);
-}
-Parrot_le_ic_ic_ic {
- if (*INT_CONST[1] <= *INT_CONST[2])
- emit_jump_to_op (jit_info, cond_AL, *INT_CONST[3]);
-}
-
-Parrot_gt_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, r1);
- emit_jump_to_op (jit_info, cond_GT, *INT_CONST[3]);
-}
-Parrot_gt_i_ic_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 1, *INT_CONST[2],
- *INT_CONST[3], cond_GT);
-}
-Parrot_gt_ic_i_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 2, *INT_CONST[1],
- *INT_CONST[3], cond_LE);
-}
-Parrot_gt_ic_ic_ic {
- if (*INT_CONST[1] > *INT_CONST[2])
- emit_jump_to_op (jit_info, cond_AL, *INT_CONST[3]);
-}
-
-Parrot_ge_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, r1);
- emit_jump_to_op (jit_info, cond_GE, *INT_CONST[3]);
-}
-Parrot_ge_i_ic_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 1, *INT_CONST[2],
- *INT_CONST[3], cond_GE);
-}
-Parrot_ge_ic_i_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 2, *INT_CONST[1],
- *INT_CONST[3], cond_LT);
-}
-Parrot_ge_ic_ic_ic {
- if (*INT_CONST[1] >= *INT_CONST[2])
- emit_jump_to_op (jit_info, cond_AL, *INT_CONST[3]);
-}
-
-Parrot_if_i_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 1, 0, *INT_CONST[2],
- cond_NE);
-}
-Parrot_unless_i_ic {
- Parrot_jit_jumpif_const (jit_info, interp, 1, 0, *INT_CONST[2],
- cond_EQ);
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; arithmetic ops
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-Parrot_abs_i_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp, cond_AL,
- (*INT_CONST[2] < 0)
- ? -*INT_CONST[2] : *INT_CONST[2],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-;
-; maybe not the best way:
-; cmp r0, #0
-; rsblt r0, r0, #0
-;
-Parrot_abs_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, 0, 0);
- jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_LT,
- RSB, 0, r0, r0, 0, 0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-;
-; rsbs r0, r0, #0
-; strgt r0, [...]
-;
-;Parrot_abs_i {
-; Parrot_jit_int_laod(jit_info, interp, cond_AL, 1, r0);
-; jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_AL,
-; RSB, arith_sets_S,
-; r0, r0, 0, 0);
-; Parrot_jit_int_store(jit_info, interp, cond_GT, 1, r0);
-;}
-
-Parrot_add_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- ADD, 0, r2, r0, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_add_i_i_ic {
- Parrot_jit_arith_const_neg (jit_info, interp, cond_AL, ADD, SUB,
- 1, 2, *INT_CONST[3]);
-}
-Parrot_add_i_ic_i {
- Parrot_jit_arith_const_neg (jit_info, interp, cond_AL, ADD, SUB,
- 1, 3, *INT_CONST[2]);
-}
-Parrot_add_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- *INT_CONST[2] + *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_add_i_ic {
- Parrot_jit_arith_const_neg (jit_info, interp, cond_AL, ADD, SUB,
- 1, 1, *INT_CONST[2]);
-}
-
-Parrot_dec_i {
- Parrot_jit_arith_const_neg (jit_info, interp, cond_AL, SUB, ADD,
- 1, 1, 1);
-}
-Parrot_inc_i {
- Parrot_jit_arith_const_neg (jit_info, interp, cond_AL, ADD, SUB,
- 1, 1, 1);
-}
-
-; mul can't do immediate constants, and there are restrictions on which
-; registers you can use. (IIRC rd and rn can't be the same register)
-Parrot_mul_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r1);
- jit_info->native_ptr = emit_mul (jit_info->native_ptr, cond_AL, 0,
- r2, r0, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_mul_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr = emit_mul (jit_info->native_ptr, cond_AL, 0,
- r2, r0, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_mul_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- *INT_CONST[2] * *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-Parrot_neg_i {
- Parrot_jit_arith_const (jit_info, interp, cond_AL, RSB, 1, 1, 0);
-}
-Parrot_neg_i_i {
- Parrot_jit_arith_const (jit_info, interp, cond_AL, RSB, 1, 2, 0);
-}
-Parrot_neg_i_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- -*INT_CONST[2],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-
-Parrot_sub_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- SUB, 0, r2, r0, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_sub_i_i_ic {
- Parrot_jit_arith_const_neg (jit_info, interp, cond_AL, SUB, ADD,
- 1, 2, *INT_CONST[3]);
-}
-Parrot_sub_i_ic_i {
- Parrot_jit_arith_const_neg (jit_info, interp, cond_AL, RSB, ADD,
- 1, 3, *INT_CONST[2]);
-}
-Parrot_sub_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- *INT_CONST[2] - *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_sub_i_ic {
- Parrot_jit_arith_const_neg (jit_info, interp, cond_AL, SUB, ADD,
- 1, 1, *INT_CONST[2]);
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; bit ops
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-Parrot_band_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- AND, 0, r2, r0, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_band_i_i_ic {
- Parrot_jit_arith_const_not (jit_info, interp, cond_AL, AND, BIC,
- 1, 2, *INT_CONST[3]);
-}
-Parrot_band_i_ic_i {
- Parrot_jit_arith_const_not (jit_info, interp, cond_AL, AND, BIC,
- 1, 3, *INT_CONST[2]);
-}
-Parrot_band_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- *INT_CONST[2] & *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_band_i_ic {
- Parrot_jit_arith_const_not (jit_info, interp, cond_AL, AND, BIC,
- 1, 1, *INT_CONST[2]);
-}
-
-;Parrot_bnot_i {
-; Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
-; jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
-; MVN, 0, r0, 0, r0);
-; Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-;}
-Parrot_bnot_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- MVN, 0, r0, 0, r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_bnot_i_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- ~*INT_CONST[2],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-Parrot_bor_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- ORR, 0, r2, r0, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_bor_i_i_ic {
- Parrot_jit_arith_const (jit_info, interp, cond_AL, ORR,
- 1, 2, *INT_CONST[3]);
-}
-Parrot_bor_i_ic_i {
- Parrot_jit_arith_const (jit_info, interp, cond_AL, ORR,
- 1, 3, *INT_CONST[2]);
-}
-Parrot_bor_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- *INT_CONST[2] | *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_bor_i_ic {
- Parrot_jit_arith_const(jit_info, interp, cond_AL, ORR,
- 1, 1, *INT_CONST[2]);
-}
-
-Parrot_bxor_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr = emit_arith_reg (jit_info->native_ptr, cond_AL,
- EOR, 0, r2, r0, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_bxor_i_i_ic {
- Parrot_jit_arith_const (jit_info, interp, cond_AL, EOR,
- 1, 2, *INT_CONST[3]);
-}
-Parrot_bxor_i_ic_i {
- Parrot_jit_arith_const (jit_info, interp, cond_AL, EOR,
- 1, 3, *INT_CONST[2]);
-}
-Parrot_bxor_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- *INT_CONST[2] | *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_bxor_i_ic {
- Parrot_jit_arith_const(jit_info, interp, cond_AL, EOR,
- 1, 1, *INT_CONST[2]);
-}
-
-Parrot_shl_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr
- = emit_arith_reg_shift_reg (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_LSL, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_shl_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr
- = emit_arith_reg_shift_const (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_LSL,
- *INT_CONST[3]);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_shl_i_ic_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr
- = emit_arith_reg_shift_reg (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_LSL, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_shl_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- *INT_CONST[2] << *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_shr_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr
- = emit_arith_reg_shift_reg (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_ASR, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_shr_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr
- = emit_arith_reg_shift_const (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_ASR,
- *INT_CONST[3]);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_shr_i_ic_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr
- = emit_arith_reg_shift_reg (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_ASR, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_shr_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- *INT_CONST[2] >> *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-Parrot_lsr_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr
- = emit_arith_reg_shift_reg (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_LSR, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_lsr_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr
- = emit_arith_reg_shift_const (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_LSR,
- *INT_CONST[3]);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_lsr_i_ic_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r1);
- jit_info->native_ptr
- = emit_arith_reg_shift_reg (jit_info->native_ptr, cond_AL,
- MOV, 0, r2, 0, r0, shift_LSR, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r2);
-}
-Parrot_lsr_i_ic_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- ((UINTVAL)*INT_CONST[2]) >> *INT_CONST[3],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; logical ops
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-Parrot_and_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, 0, 0);
- Parrot_jit_int_load(jit_info, interp, cond_NE, 3, r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_and_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, 0, 0);
- Parrot_jit_int_load(jit_info, interp, cond_NE, 3, r1);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_and_i_ic_i {
- if (*INT_CONST[2]) {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r0);
- } else {
- /* *INT_CONST[2] is going to be 0 anyway, but this does generate the
- shortest code to load 0. */
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- }
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_and_i_ic_ic {
- if (*INT_CONST[2]) {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r0);
- } else {
- /* *INT_CONST[2] is going to be 0 anyway, but this does generate the
- shortest code to load 0. */
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- }
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-Parrot_or_i_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, 0, 0);
- Parrot_jit_int_load(jit_info, interp, cond_EQ, 3, r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_or_i_i_ic {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_AL,
- CMP, 0, 0, r0, 0, 0);
- Parrot_jit_int_load(jit_info, interp, cond_EQ, 3, r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_or_i_ic_i {
- if (*INT_CONST[2]) {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- } else {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r0);
- }
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-Parrot_or_i_ic_ic {
- if (*INT_CONST[2]) {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- } else {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 3, r0);
- }
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-;
-; no or_i_i :-(
-;
-;
-; RSBS r1, r0, #1
-; ie flags set for CMP #1, r0
-; think unsigned - if r0 is 0, #1 is HIgher
-; for all other cases it's Lower or Same.
-; if r0 is 0, then #1 - #0 is 1, and r1 is set correctly.
-; else
-; MOVLS r1, #0
-; (actaully it's also set correctly for r0 is #1)
-Parrot_not_i_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 2, r0);
- jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_AL,
- RSB, arith_sets_S,
- r1, r0, 1, 0);
- jit_info->native_ptr = emit_arith_immediate (jit_info->native_ptr, cond_LS,
- MOV, 0,
- r1, 0, 0, 0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r1);
-}
-Parrot_not_i_ic {
- jit_info->native_ptr = emit_load_constant (jit_info->native_ptr,
- interp,
- cond_AL,
- !*INT_CONST[2],
- r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-; XXX TODO - the non constant versions of this
-Parrot_xor_i_ic_ic {
- jit_info->native_ptr
- = emit_load_constant (jit_info->native_ptr, interp, cond_AL,
- (*INT_CONST[2] && ! *INT_CONST[3])
- ? *INT_CONST[2]
- : (*INT_CONST[3] && ! *INT_CONST[2])
- ? *INT_CONST[3] : 0, r0);
- Parrot_jit_int_store(jit_info, interp, cond_AL, 1, r0);
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; branches
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-Parrot_branch_i {
- Parrot_jit_int_load(jit_info, interp, cond_AL, 1, r0);
- Parrot_jump_to_op_in_reg(jit_info, interp, r0);
-}
-Parrot_branch_ic {
- emit_jump_to_op (jit_info, cond_AL, *INT_CONST[1]);
-}
-
-/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/arm/exec_dep.c
==============================================================================
--- trunk/src/jit/arm/exec_dep.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,100 +0,0 @@
-/*
- Copyright (C) 2003-2008, Parrot Foundation.
- $Id$
-*/
-
-/*
- * exec_dep.c
- *
- * Overview:
- * ARM dependent functions to emit an executable.
- * History:
- * Initial version by Daniel Grunblatt on 2003.8.12
- * Notes:
- * References:
- */
-
-#include "parrot/parrot.h"
-#include "jit.h"
-#define JIT_EMIT 1
-#include "jit_emit.h"
-#include "exec_dep.h"
-
-/* HEADERIZER HFILE: src/jit/arm/exec_dep.h */
-
-#ifdef JIT_CGP
-
-void
-Parrot_exec_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
-}
-
-#else /* JIT_CGP */
-
-void
-Parrot_exec_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, r1, r4);
-# ifndef ARM_K_BUG
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, REG14_lr, REG15_pc);
- jit_info->native_ptr = emit_ldmstm(jit_info->native_ptr,
- cond_AL, is_load, dir_IA,
- is_writeback,
- REG14_lr,
- reg2mask(0) | reg2mask(REG15_pc));
-# else
- jit_info->native_ptr = emit_arith_immediate(jit_info->native_ptr, cond_AL,
- ADD, 0, REG14_lr, REG15_pc,
- 4, 0);
- jit_info->native_ptr = emit_ldmstm(jit_info->native_ptr,
- cond_AL, is_load, dir_IA,
- is_writeback,
- REG14_lr,
- reg2mask(0) | reg2mask(REG12_ip));
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, REG15_pc, REG12_ip);
-# endif /* ARM_K_BUG */
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_DATA, "program_code", 0);
- jit_info->native_ptr
- = emit_word(jit_info->native_ptr, ((int)jit_info->cur_op) -
- ((int)interp->code->base.data) +
- (jit_info->objfile->bytecode_header_size));
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_FUNC,
- interp->op_info_table[*jit_info->cur_op].func_name, 0);
- jit_info->native_ptr
- = emit_word(jit_info->native_ptr, 0);
-}
-
-#endif /* JIT_CGP */
-
-void
-Parrot_exec_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_exec_normal_op(jit_info, interp);
- Parrot_jump_to_op_in_reg(jit_info, interp, r0);
-}
-
-void
-Parrot_exec_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
-}
-
-/* Assign the offset of the progra_code */
-void
-offset_fixup(Parrot_exec_objfile_t *obj)
-{
- int i, j;
-
- for (i = 0; i < obj->data_count; i++) {
- for (j = 0; j < i; j++)
- obj->symbol_table[i].value += obj->data_size[j];
- }
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/arm/exec_dep.h
==============================================================================
--- trunk/src/jit/arm/exec_dep.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,47 +0,0 @@
-/*
- Copyright (C) 2003-2008, Parrot Foundation.
- $Id$
-*/
-
-/*
- * exec_dep.h
- *
- * Overview:
- * ARM dependent functions to emit an executable.
- * History:
- * Initial version by Daniel Grunblatt on 2003.8.12
- * Notes:
- * References:
- */
-
-#include "jit.h"
-#include "jit_emit.h"
-
-#ifndef PARROT_ARM_EXEC_DEP_H_GUARD
-#define PARROT_ARM_EXEC_DEP_H_GUARD
-
-/* HEADERIZER BEGIN: src/exec_dep.c */
-
-void
-Parrot_exec_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void
-Parrot_exec_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void
-Parrot_exec_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* Assign the offset of the program_code */
-void
-offset_fixup(Parrot_exec_objfile_t *obj);
-
-/* HEADERIZER END: src/exec_dep.c */
-
-#endif /* PARROT_ARM_EXEC_DEP_H_GUARD */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/arm/jit_defs.c
==============================================================================
--- trunk/src/jit/arm/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,13 +0,0 @@
-/* Stub file for RT#38929 fixes */
-/*
-Copyright (C) 2008, Parrot Foundation.
-$Id$
-*/
-/* HEADERIZER HFILE: none */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/arm/jit_emit.h
==============================================================================
--- trunk/src/jit/arm/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,1101 +0,0 @@
-/*
- * Copyright (C) 2003-2008, Parrot Foundation.
- */
-
-/*
- * jit_emit.h
- *
- * ARM (I think this is all ARM2 or later, although it is APCS-32)
- *
- * $Id$
- */
-
-#ifndef PARROT_ARM_JIT_EMIT_H_GUARD
-#define PARROT_ARM_JIT_EMIT_H_GUARD
-
-#ifdef ARM
-# ifdef __linux
-# include <asm/unistd.h>
-# endif
-#endif /* ARM */
-
-/* Registers
- *
- * r0 Argument/result/scratch register 0.
- * r1 Argument/result/scratch register 1.
- * r2 Argument/result/scratch register 2.
- * r3 Argument/result/scratch register 3.
- * r4 Variable register 1.
- * r5 Variable register 2.
- * r6 Variable register 3.
- * r7 Variable register 4.
- * r8 Variable register 5.
- * r9 ARM State variable register 6. Static Base in PID, re-entrant
- * shared-library variants.
- * r10 ARM State variable register 7. Stack limit pointer in stack-checked
- * variants.
- * r11 ARM State variable register 8. ARM state frame pointer.
- * r12 The Intra-Procedure call scratch register.
- * r13 The Stack Pointer.
- * r14 The Link Register.
- * r15 The Program Counter.
- *
- * r0-r3 are used to pass in first 4 arguments, and are not preserved by a
- * function. Results (that would fit) are returned in r0
- * Other registers are preserved across calls, although (by implication) r14
- * and r15 are used by the call process. I don't think that it is mandated
- * that r14 on return must hold the link address.
- * r12 (ip) is only used on subroutine entry for stack frame calculations -
- * after then it is a useful scratch register. If you push r14 you get
- * another scratch register quickly.
- *
- * Most things nowadays are StrongARM or later. StrongARM is v4 of the
- * architecture. ARM6 and ARM7 cores are v3, which introduced the 32 bit
- * address bus. Earlier cores (which you won't encounter) used a 26 bit address
- * bus, with program counter and status register combined in r15
- */
-
-typedef enum {
- r0,
- r1,
- r2,
- r3,
- r4,
- r5,
- r6,
- r7,
- r8,
- r9,
- r10,
- r11,
- r12,
- r13,
- r14,
- r15,
- REG10_sl = 10,
- REG11_fp = 11,
- REG12_ip = 12,
- REG13_sp = 13,
- REG14_lr = 14,
- REG15_pc = 15
-} arm_register_t;
-
-#if JIT_EMIT
-
-typedef enum {
- cond_EQ = 0x00,
- cond_NE = 0x10,
- cond_CS = 0x20,
- cond_CC = 0x30,
- cond_MI = 0x40,
- cond_PL = 0x50,
- cond_VS = 0x60,
- cond_VC = 0x70,
- cond_HI = 0x80,
- cond_LS = 0x90,
- cond_GE = 0xA0,
- cond_LT = 0xB0,
- cond_GT = 0xC0,
- cond_LE = 0xD0,
- cond_AL = 0xE0,
-/* cond_NV = 0xF0, */
-/* synonyms for CS and CC: */
- cond_HS = 0x20,
- cond_LO = 0x30
-} arm_cond_t;
-
-/* I've deliberately shifted these right by 1 bit so that I can forcibly
- set the status flag on ops such as CMP. It's easy to forget (the assembler
- doesn't mandate you explicitly write CMPS, it just sets the bit for you).
- I got an illegal instruction trap on a StrongARM for a CMP without S, but
- I think some of the other comparison operators have legal weird effects
- with no S flag. */
-typedef enum {
- AND = 0x00,
- EOR = 0x02,
- SUB = 0x04, /* Subtract rd = rn - op2 */
- RSB = 0x06, /* Reverse SUbtract rd = op2 - rn ; op2 is more flexible. */
- ADD = 0x08,
- ADC = 0x0A, /* ADd with Carry. */
- SBC = 0x0C, /* SuBtract with Carry. */
- RSC = 0x0E, /* Reverse Subtract with Carry. */
- TST = 0x11, /* TeST rn AND op2 (sets flags). */
- TEQ = 0x13, /* Test EQuivalence rn XOR op2 (won't set V flag). */
- CMP = 0x15, /* CoMPare rn - op2 */
- CMN = 0x17, /* CoMpare Negated rn + op2 */
- ORR = 0x18,
- MOV = 0x1A, /* MOVe rd = op2 */
- BIC = 0x1C, /* BIt Clear rd = rn AND NOT op2 */
- MVN = 0x1E /* MoV Not rd = NOT op2 */
-} alu_op_t;
-
-/* note MVN is move NOT (ie logical NOT, 1s complement), whereas
- CMN is compare NEGATIVE (ie arithmetic NEGATION, 2s complement) */
-
-# define arith_sets_S 0x10
-
-# define INTERP_STRUCT_ADDR_REG r4
-
-/* B / BL
- *
- * +--------------------------------------------------------------------+
- * | cond | 1 0 1 | L | signed_immed_24 |
- * +--------------------------------------------------------------------+
- * 31 28 27 25 24 23 0
- *
- *
- * The L bit
- *
- * If L == 1 the instruction will store a return address in the link
- * register (R14). Otherwise L == 0, the instruction will simply branch without
- * storing a return address.
- *
- * The target address
- *
- * Specifies the address to branch to. The branch target address is calculated
- * by:
- *
- * - Sign-extending the 24-bit signed (two's complement) immediate to 32 bits.
- *
- * - Shifting the result left two bits.
- *
- * - Adding this to the contents of the PC, which contains the address of the
- * branch instruction plus 8.
- *
- * The instruction can therefore specify a branch of approximately ±32MB.
- *
- * [Not the full 32 bit address range of the v3 and later cores.]
- */
-
-/* IIRC bx is branch into thumb mode, so don't name this back to bx */
-
-static char *
-emit_branch(char *pc,
- arm_cond_t cond,
- int L,
- int imm)
-{
- *(pc++) = imm;
- *(pc++) = ((imm) >> 8);
- *(pc++) = ((imm) >> 16);
- *(pc++) = cond | 0xA | L;
- return pc;
-}
-
-# define emit_b(pc, cond, imm) \
- emit_branch((pc), (cond), 0, (imm))
-
-# define emit_bl(pc, cond, imm) \
- emit_branch((pc), (cond), 1, (imm))
-
-
-# define reg2mask(reg) (1<<(reg))
-
-typedef enum {
- is_store = 0x00,
- is_load = 0x10,
- is_writeback = 0x20,
- no_writeback = 0,
- is_caret = 0x40, /* assembler syntax is ^ - load sets status flags in
- USR mode, or load/store use user bank registers
- in other mode. IIRC. */
- no_caret = 0,
- is_byte = 0x40,
- no_byte = 0, /* It's a B suffix for a byte load, no suffix for
- word load, so this is more natural than is_word */
- is_pre = 0x01, /* pre index addressing. */
- is_post = 0x00 /* post indexed addressing. ie arithmetic for free */
-} transfer_flags;
-
-/* multiple register transfer direction.
- D = decrease, I = increase
- A = after, B = before
- or the stack notation
- FD = full descending (the usual)
- ED = empty descending
- FA = full ascending
- FD = full descending
- values for stack notation are 0x10 | (ldm type) << 2 | (stm type)
-*/
-typedef enum {
- dir_DA = 0,
- dir_IA = 1,
- dir_DB = 2,
- dir_IB = 3,
- dir_FD = 0x10 | (1 << 2) | 2,
- dir_FA = 0x10 | (0 << 2) | 3,
- dir_ED = 0x10 | (3 << 2) | 0,
- dir_EA = 0x10 | (2 << 2) | 1
-} ldm_stm_dir_t;
-
-typedef enum {
- dir_Up = 0x80,
- dir_Down = 0x00
-} ldr_str_dir_t;
-
-enum { JIT_ARMBRANCH };
-
-static char *
-emit_ldmstm_x(char *pc,
- arm_cond_t cond,
- int l_s,
- ldm_stm_dir_t direction,
- int caret,
- int writeback,
- arm_register_t base,
- int regmask)
-{
- if ((l_s == is_load) && (direction & 0x10))
- direction >>= 2;
-
- *(pc++) = regmask;
- *(pc++) = regmask >> 8;
- /* bottom bit of direction is the up/down flag. */
- *(pc++) = ((direction & 1) << 7) | caret | writeback | l_s | base;
- /* binary 100x is code for stm/ldm. */
- /* Top bit of direction is pre/post increment flag. */
- *(pc++) = cond | 0x8 | ((direction >> 1) & 1);
- return pc;
-}
-
-/* Is is going to be rare to non existent that anyone needs to use the ^
- syntax on LDM or STM, so make it easy to generate the normal form: */
-# define emit_ldmstm(pc, cond, l_s, direction, writeback, base, regmask) \
- emit_ldmstm_x((pc), (cond), (l_s), (direction), 0, (writeback), (base), (regmask))
-
-/* Load / Store
- *
- * +--------------------------------------------------------------------+
- * | cond | 0 1 | I | P | U | B | W | L | Rn | Rd | offset |
- * +--------------------------------------------------------------------+
- * 31 28 27 26 25 24 23 22 21 20 19 16 15 12 11 0
- *
- *
- * The P bit
- *
- * P == 0 indicates the use of post-indexed addressing. The base register value
- * is used for the memory address, and the offset is then applied to the
- * base register and written back to the base register.
- *
- * P == 1 indicates the use of offset addressing or pre-indexed addressing (the
- * W bit determines which). The memory address is generated by applying
- * the offset to the base register value.
- *
- * The U bit
- *
- * Indicates whether the offset is added to the base (U == 1) or is subtracted
- * from the base (U == 0).
- *
- * The B bit
- *
- * Distinguishes between an unsigned byte (B == 1) and a word (B == 0) access.
- *
- * The W bit
- *
- * P == 0 If W == 0, the instruction is LDR, LDRB, STR or STRB and a normal
- * memory access is performed. If W == 1, the instruction is LDRBT,
- * LDRT, STRBT or STRT and an unprivileged (User mode) memory access is
- * performed.
- *
- * P == 1 If W == 0, the base register is not updated (offset addressing). If
- * W == 1, the calculated memory address is written back to the base
- * register (pre-indexed addressing).
- *
- * The L bit
- *
- * Distinguishes between a Load (L == 1) and a Store (L == 0).
- *
- * <Rd> is the destination register.
- * <Rn> is the base register.
- *
- * XXX need to detail addr mode, for I = 0 and I = 1
- *
- * Note that you can take advantage of post indexed addressing to get a free
- * add onto the base register if you need it for some other purpose.
- *
- * Note that on StrongARM [and later? but not XScale :-(] if you don't use Rd
- * next instruction then a load doesn't stall if it is from the cache (ie
- * 1 cycle loads). You will want to re-order things where possible to take
- * advantage of this.
- *
- * ARM1 had register shift register as possibilities for the offset (as the
- * ALU ops still do. These took 1 more cycle, and were taken out as virtually
- * no use was found for them. However, the bit patterns they represent
- * certainly didn't used to fault as an illegal instruction on ARM2s, and
- * probably later. So beware of generating illegal bit pattern offsets, as
- * you'll get silent undefined behaviour.
- */
-
-static char *
-emit_ldrstr(char *pc,
- arm_cond_t cond,
- int l_s,
- ldr_str_dir_t direction,
- int pre,
- int writeback,
- int byte,
- arm_register_t dest,
- arm_register_t base,
- int offset_type,
- unsigned int offset)
-{
- *(pc++) = offset;
- *(pc++) = ((offset >> 8) & 0xF) | (dest << 4);
- *(pc++) = direction | byte | writeback | l_s | base;
- *(pc++) = cond | 0x4 | offset_type | pre;
- return pc;
-}
-
-static char *
-emit_ldrstr_offset(char *pc,
- arm_cond_t cond,
- int l_s,
- int pre,
- int writeback,
- int byte,
- arm_register_t dest,
- arm_register_t base,
- int offset)
-{
- ldr_str_dir_t direction = dir_Up;
- if (offset > 4095 || offset < -4095) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Unable to generate offset %d, larger than 4095\n", offset);
- }
-
- if (offset < 0) {
- direction = dir_Down;
- offset = -offset;
- }
- return emit_ldrstr(pc, cond, l_s, direction, pre, writeback, byte, dest,
- base, 0, offset);
-}
-
-/* Arithmetic
- *
- * +--------------------------------------------------------------------+
- * | cond | 0 0 | I | ALU Opcode | S | Rn | Rd | shifted operand |
- * +--------------------------------------------------------------------+
- * 31 28 27 26 25 24 23 22 21 20 19 16 15 12 11 0
- *
- *
- * The S bit
- *
- * Indicates if the CPSR will be updated (S == 1) or not (S == 0).
- *
- * Two types of CPSR updates can occur:
- *
- * - If <Rd> is not R15, the N and Z flags are set according to the result of
- * of the addition, and C and V flags are set according to whether the
- * addition generated a carry (unsigned overflow) and a signed overflow,
- * respectively. The rest of the CPSR is unchanged.
- *
- * XXX shifted immediate values for the second operand can also set the C
- * flag (and therefore presumably also clear it) when the S flag is set for
- * certain ALU ops. (I think just the logical ops) This is obscure, but
- * sometimes useful. No idea where this is documented.
- *
- * - If <Rd> is R15, the SPSR of the current mode is copied to the CPSR. This
- * form of the instruction is UNPREDICTABLE if executed in User mode or
- * System mode, because these do not have an SPSR.
- *
- *
- */
-
-typedef enum {
- shift_LSL = 0x00,
- shift_LSR = 0x20,
- shift_ASR = 0x40,
- shift_ROR = 0x60,
- shift_ASL = 0x00 /* Synonym - no sign extension (or not) on << */
-} barrel_shift_t;
-/* RRX (rotate right with extend - a 1 position 33 bit rotate including the
- carry flag) is encoded as ROR by 0. */
-
-static char *
-emit_arith(char *pc,
- arm_cond_t cond,
- alu_op_t op,
- int status,
- arm_register_t rd,
- arm_register_t rn,
- int operand2_type,
- int operand2)
-{
- *(pc++) = operand2;
- *(pc++) = rd << 4 | ((operand2 >> 8) & 0xF);
- *(pc++) = op << 4 | status | rn;
- *(pc++) = cond | 0 | operand2_type | op >> 4;
- return pc;
-}
-
-static char *
-emit_mul(char *pc,
- arm_cond_t cond,
- int status,
- arm_register_t rd,
- arm_register_t rm,
- arm_register_t rs)
-{
- *(pc++) = 0x90 | rm;
- *(pc++) = rs;
- *(pc++) = status | rd;
- *(pc++) = cond | 0;
- return pc;
-}
-
-static char *
-emit_mla(char *pc,
- arm_cond_t cond,
- int status,
- arm_register_t rd,
- arm_register_t rm,
- arm_register_t rs,
- arm_register_t rn)
-{
- *(pc++) = 0x90 | rm;
- *(pc++) = rn << 4 | rs;
- *(pc++) = 0x20 | status | rd;
- *(pc++) = cond | 0;
- return pc;
-}
-
-/* operand2 immediate constants are expressed as val rotate right (2 * n),
- where val is 8 bits, n is 4 bits. This uses the 12 bits available to
- generate many useful common constants, far more than would be given by a
- 12 bit number 0 - 0xFFF.
- Often, you're trying to use the immediate constant in an operand that could
- be replaced its complement. So if MOV rd, #const doesn't work,
- MVN rn, #~const might. And ADD rd, rn, #const may be impossible, but
- SUB rd, rn, #-const will. So allow the return struct to flag this.
-
- I believe that the only case where a 32 bit value and its converse is
- representable in 8 shift 4 is for 0 and -(0)
- So it's perfectly valid to try the inverse every time. */
-
-
-enum constant_state {doesnt_fit, fits_as_not, fits_as_neg, fits_as_is};
-
-/* Deliberate 4th char to pad the struct and hence silence a warning. */
-struct constant {
- unsigned char value;
- unsigned char rotation;
- unsigned char state;
- unsigned char pad;
-};
-/* XXX Future work would be to try to find a fast compramise way of looking
- for the double instruction constants. eg 0xFFF is 0xF00 + 0xFF, or
- 0xF00 | 0xFF
- The problem comes that for building an immediate constant all combinations
- are on (ie MOV followed by anything, including hacks with setting the carry
- flag using non-standard rotations) but for add_i_i_ic you probably only
- want to break down into two halves that are in turn each added/subtracted.
-*/
-
-static void
-constant_neg(int value, struct constant *result)
-{
- result->rotation = 0;
- while (1) {
- if ((value & ~0xFF) == 0) {
- /* No bits spill out. */
- result->state = fits_as_is;
- result->value = value;
- return;
- }
- if (((-value) & ~0xFF) == 0) {
- result->value = -value;
- result->state = fits_as_neg;
- return;
- }
- if (++result->rotation == 16)
- break;
-
- /* There is no rotate op in C, and to do it with 2 shifts and an or
- would mean casting to unsigned to prevent sign extensions, and it's
- exactly 1 arm instruction I need, so it's clearer like this: */
- __asm__(
- "mov %0, %1, ror #30\n"
- : "=r" (value)
- : "r" (value));
-
- }
- result->state = doesnt_fit;
- return;
-}
-
-
-static void
-constant_not(int value, struct constant *result)
-{
- result->rotation = 0;
- while (1) {
- if ((value & ~0xFF) == 0) {
- /* No bits spill out. */
- result->state = fits_as_is;
- result->value = value;
- return;
- }
- if (((~value) & ~0xFF) == 0) {
- result->value = ~value;
- result->state = fits_as_not;
- return;
- }
- if (++result->rotation == 16)
- break;
-
- /* There is no rotate op in C, and to do it with 2 shifts and an or
- would mean casting to unsigned to prevent sign extensions, and it's
- exactly 1 arm instruction I need, so it's clearer like this: */
- __asm__(
- "mov %0, %1, ror #30\n"
- : "=r" (value)
- : "r" (value));
-
- }
- result->state = doesnt_fit;
- return;
-}
-
-/* eg add r0, r3, r7 */
-# define emit_arith_reg(pc, cond, op, status, rd, rn, rm) \
- emit_arith((pc), (cond), (op), (status), (rd), (rn), 0, (rm))
-
-/* eg sub r0, r3, r7 lsr #3 */
-# define emit_arith_reg_shift_const(pc, cond, op, status, rd, rn, rm, shift, by) \
- emit_arith((pc), (cond), (op), (status), (rd), (rn), 0, ((by) << 7) | (shift) | 0 | (rm))
-
-/* eg orrs r1, r2, r1 rrx */
-# define emit_arith_reg_rrx(pc, cond, op, status, rd, rn, rm) \
- emit_arith((pc), (cond), (op), (status), (rd), (rn), 0, shift_ROR | 0 | (rm))
-
-/* I believe these take 2 cycles (due to having to access a 4th register. */
-# define emit_arith_reg_shift_reg(pc, cond, op, status, rd, rn, rm, shift, rs) \
- emit_arith((pc), (cond), (op), (status), (rd), (rn), 0, ((rs) << 8) | (shift) | 0x10 | (rm))
-
-# define emit_arith_immediate(pc, cond, op, status, rd, rn, val, rotate) \
- emit_arith((pc), (cond), (op), (status), (rd), (rn), 2, ((rotate) << 8) | (val))
-
-/* I'll use mov r0, r0 as my NOP for now. */
-# define emit_nop(pc) emit_mov((pc), r0, r0)
-
-/* MOV ignores rn */
-# define emit_mov(pc, dest, src) emit_arith_reg((pc), cond_AL, MOV, 0, (dest), 0, (src))
-
-static char *
-emit_word(char *pc, unsigned int word)
-{
- *(pc++) = word;
- *(pc++) = word >> 8;
- *(pc++) = word >> 16;
- *(pc++) = word >> 24;
- return pc;
-}
-
-static void emit_jump_to_op(Parrot_jit_info_t *jit_info, arm_cond_t cond,
- opcode_t disp)
-{
- opcode_t opcode = jit_info->op_i + disp;
- int offset = 0;
- if (opcode <= jit_info->op_i) {
- offset = jit_info->arena.op_map[opcode].offset -
- (jit_info->native_ptr - jit_info->arena.start);
- }
- else {
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_ARMBRANCH;
- jit_info->arena.fixups->param.opcode = opcode;
- }
-
- jit_info->native_ptr
- = emit_branch(jit_info->native_ptr, cond, 0, (offset >> 2) - 2);
-}
-
-static char *
-emit_load_constant_from_pool(char *pc,
- PARROT_INTERP,
- arm_cond_t cond,
- int value,
- arm_register_t hwreg)
-{
- /* can't do it in one. XXX this should use a constant pool.
- ldr rd, [pc] ; pipelining makes this .L1
- b L2
- .L1 value
- .L2 next
- */
-
- pc = emit_ldrstr_offset(pc, cond,
- is_load, is_pre,
- 0, 0,
- hwreg,
- REG15_pc, 0);
- /* Must always jump round our inlined constant, if if we don't load it
- (due to condition codes) */
- pc = emit_b(pc, cond_AL, 0);
- pc = emit_word(pc, value);
- return pc;
-}
-
-static char *
-emit_load_constant(char *pc,
- PARROT_INTERP,
- arm_cond_t cond,
- int value,
- arm_register_t hwreg)
-{
- struct constant immediate;
-
- constant_not(value, &immediate);
-
- if (immediate.state == fits_as_is) {
- pc = emit_arith_immediate(pc, cond, MOV, 0, hwreg, 0,
- immediate.value, immediate.rotation);
- }
- else if (immediate.state == fits_as_not) {
- pc = emit_arith_immediate(pc, cond, MVN, 0, hwreg, 0,
- immediate.value, immediate.rotation);
- }
- else {
- pc = emit_load_constant_from_pool(pc, interp, cond, value, hwreg);
- }
- return pc;
-}
-
-static void
-Parrot_jit_int_load(Parrot_jit_info_t *jit_info,
- PARROT_INTERP,
- arm_cond_t cond,
- int param,
- arm_register_t hwreg)
-{
- opcode_t op_type
- = interp->op_info_table[*jit_info->cur_op].types[param];
- int val = jit_info->cur_op[param];
- int offset;
-
- switch (op_type){
- case PARROT_ARG_I:
- offset = ((char *)&interp->int_reg.registers[val])
- - (char *)interp;
- if (offset > 4095)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "integer load register %d generates offset %d, "
- "larger than 4095\n", val, offset);
- }
- jit_info->native_ptr = emit_ldrstr_offset(jit_info->native_ptr,
- cond,
- is_load,
- is_pre,
- 0, 0,
- hwreg,
- INTERP_STRUCT_ADDR_REG,
- offset);
- break;
- case PARROT_ARG_IC:
- jit_info->native_ptr = emit_load_constant(jit_info->native_ptr,
- interp,
- cond,
- val,
- hwreg);
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Unsupported op parameter type %d in jit_int_load\n", op_type);
- }
-}
-
-static void
-Parrot_jit_int_store(Parrot_jit_info_t *jit_info,
- PARROT_INTERP,
- arm_cond_t cond,
- int param,
- arm_register_t hwreg)
-{
- opcode_t op_type
- = interp->op_info_table[*jit_info->cur_op].types[param];
- int val = jit_info->cur_op[param];
- int offset;
-
- switch (op_type){
- case PARROT_ARG_I:
- offset = ((char *)&interp->int_reg.registers[val])
- - (char *)interp;
-
- if (offset > 4095)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "integer store register %d generates offset %d, "
- "larger than 4095\n", val, offset);
- }
- jit_info->native_ptr = emit_ldrstr_offset(jit_info->native_ptr,
- cond,
- is_store,
- is_pre,
- 0, 0,
- hwreg,
- INTERP_STRUCT_ADDR_REG,
- offset);
- break;
-
- case PARROT_ARG_N:
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Unsupported op parameter type %d in jit_int_store\n", op_type);
- }
-}
-
-static void
-Parrot_jit_arith_const_alternate(Parrot_jit_info_t *jit_info,
- PARROT_INTERP,
- arm_cond_t cond,
- enum constant_state alternate_on,
- alu_op_t normal, alu_op_t alternative,
- int dest, int src, int const_val)
-{
- struct constant val;
-
- Parrot_jit_int_load(jit_info, interp, cond, src, r0);
-
- constant_neg(const_val, &val);
-
- if (val.state == fits_as_is || val.state == alternate_on) {
- /* We can use an immediate constant. */
- /* say plus is ADD, minus is SUB
- Then if value fits into an immediate constant, we add r0, r0, #value
- If -value fits, then we sub, r0, r0, #-value
- */
- jit_info->native_ptr
- = emit_arith_immediate(jit_info->native_ptr, cond,
- val.state == fits_as_is
- ? normal : alternative,
- 0, r0, r0, val.value, val.rotation);
- }
- else {
- /* Else we load it into a reg the slow way. */
- jit_info->native_ptr
- = emit_load_constant_from_pool(jit_info->native_ptr, interp,
- cond, const_val, r1);
- jit_info->native_ptr
- = emit_arith_reg(jit_info->native_ptr, cond, normal, 0,
- r0, r0, r1);
- }
- Parrot_jit_int_store(jit_info, interp, cond, dest, r0);
-}
-
-# define Parrot_jit_arith_const_neg(ji, i, cond, plus, minus, dest, src, const_val) \
- Parrot_jit_arith_const_alternate((ji), (i), (cond), fits_as_neg, \
- (plus), (minus), (dest), (src), (const_val))
-
-# define Parrot_jit_arith_const_not(ji, i, cond, plus, minus, dest, src, const_val) \
- Parrot_jit_arith_const_alternate((ji), (i), (cond), fits_as_not, \
- (plus), (minus), (dest), (src), (const_val))
-# define Parrot_jit_arith_const(ji, i, cond, plus, dest, src, const_val) \
- Parrot_jit_arith_const_alternate((ji), (i), (cond), fits_as_is, \
- (plus), (plus), (dest), (src), (const_val))
-
-
-/* branching on if cannot (in future) be conditional (easily), because we
- want to set the flags.
- Yes, for seriously advanced stuff you can
- 1: chain compatible comparisons (eg something setting LE and something else
- setting LE can be done with the second conditional)
- 2: use TEQ which doesn't change the V flag (or C, IIRC), and chain that with
- something else that did set the V flag
-
- but that's JIT v5 or later (where v3 can hold intermediate values in CPU
- registers, and v4 can do some things conditionally)
-*/
-static void
-Parrot_jit_jumpif_const(Parrot_jit_info_t *jit_info,
- PARROT_INTERP,
- int src, int const_val, int where_to,
- arm_cond_t when)
-{
- struct constant val;
-
- Parrot_jit_int_load(jit_info, interp, cond_AL, src, r0);
-
- constant_neg(const_val, &val);
-
- if (val.state == fits_as_is || val.state == fits_as_neg) {
- /* We can use an immediate constant. */
- jit_info->native_ptr
- = emit_arith_immediate(jit_info->native_ptr, cond_AL,
- val.state == fits_as_is ? CMP : CMN, 0,
- 0, r0, val.value, val.rotation);
- }
- else {
- /* Else we load it into a reg the slow way. */
- jit_info->native_ptr
- = emit_load_constant_from_pool(jit_info->native_ptr, interp,
- cond_AL, const_val, r1);
- jit_info->native_ptr
- = emit_arith_reg(jit_info->native_ptr, cond_AL, CMP, 0, 0, r0, r1);
- }
- emit_jump_to_op(jit_info, when, where_to);
-}
-
-static void
-Parrot_jump_to_op_in_reg(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, arm_register_t reg)
-{
- /* This is effectively the pseudo-opcode ldr - ie load relative to PC.
- So offset includes pipeline. */
- jit_info->native_ptr = emit_ldrstr_offset(jit_info->native_ptr, cond_AL,
- is_load, is_pre, 0, 0,
- REG14_lr, REG15_pc, 0);
- /* ldr pc, [r14, r0] */
- /* lazy. this is offset type 0, 0x000 which is r0 with zero shift */
- jit_info->native_ptr = emit_ldrstr(jit_info->native_ptr, cond_AL,
- is_load, dir_Up, is_pre, 0, reg,
- REG15_pc, REG14_lr, 2, 0);
- /* and this "instruction" is never reached, so we can use it to store
- the constant that we load into r14 */
- jit_info->native_ptr
- = emit_word(jit_info->native_ptr,
- ((int) jit_info->arena.op_map) -
- ((int) interp->code->base.code));
-}
-
-#endif /* JIT_EMIT */
-#if JIT_EMIT == 2
-
-void Parrot_jit_dofixup(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_jit_fixup_t *fixup = jit_info->arena.fixups;
-
- while (fixup){
- switch (fixup->type){
- case JIT_ARMBRANCH:
- {
- char *fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- int offset = jit_info->arena.op_map[fixup->param.opcode].offset
- - fixup->native_offset;
- int disp = (offset >> 2) - 2;
- *(fixup_ptr++) = disp;
- *(fixup_ptr++) = disp >> 8;
- *(fixup_ptr) = disp >> 16;
- break;
- }
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Unknown fixup type:%d\n", fixup->type);
- break;
- }
- fixup = fixup->next;
- }
-}
-/* My entry code is create a stack frame:
- mov ip, sp
- stmfd sp!, {r4, fp, ip, lr, pc}
- sub fp, ip, #4
- Then store the first parameter (pointer to the interpreter) in r4.
- mov r4, r0
-*/
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, REG12_ip, REG13_sp);
- jit_info->native_ptr = emit_ldmstm(jit_info->native_ptr,
- cond_AL, is_store, dir_FD,
- is_writeback,
- REG13_sp,
- reg2mask(4) | reg2mask(REG11_fp)
- | reg2mask(REG12_ip)
- | reg2mask(REG14_lr)
- | reg2mask(REG15_pc));
- jit_info->native_ptr = emit_arith_immediate(jit_info->native_ptr, cond_AL,
- SUB, 0, REG11_fp, REG12_ip,
- 4, 0);
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, 4, 0);
- /* TODO emit restart code s. i386
- *
- * emit get r0 from stack
- * Parrot_jump_to_op_in_reg(jit_info, interp, r0);
- */
-}
-
-/* I'm going to load registers to call functions in general like this:
- adr r14, .L1
- ldmia r14!, {r0, r1, r2, pc} ; register list built by jit
- .L1: r0 data
- r1 data
- r2 data
- <where ever> ; address of function.
- .L2: ; next instruction - return point from func.
-
- here I'm going to do
-
- mov r1, r4 ; current interpreter is arg 1
- adr r14, .L1
- ldmia r14!, {r0, pc}
- .L1: address of current opcode
- <where ever> ; address of function for op
- .L2: ; next instruction - return point from func.
-*/
-
-/*
-XXX no.
-need to adr beyond:
-
- mov r1, r4 ; current interpreter is arg 1
- adr r14, .L1
- ldmda r14!, {r0, ip}
- mov pc, ip
- .L1 address of current opcode
- dcd <where ever> ; address of function for op
- .L2: ; next instruction - return point from func.
-*/
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, r1, r4);
-# ifndef ARM_K_BUG
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, REG14_lr, REG15_pc);
- jit_info->native_ptr = emit_ldmstm(jit_info->native_ptr,
- cond_AL, is_load, dir_IA,
- is_writeback,
- REG14_lr,
- reg2mask(0) | reg2mask(REG15_pc));
-# else
- jit_info->native_ptr = emit_arith_immediate(jit_info->native_ptr, cond_AL,
- ADD, 0, REG14_lr, REG15_pc,
- 4, 0);
- jit_info->native_ptr = emit_ldmstm(jit_info->native_ptr,
- cond_AL, is_load, dir_IA,
- is_writeback,
- REG14_lr,
- reg2mask(0) | reg2mask(REG12_ip));
- jit_info->native_ptr = emit_mov(jit_info->native_ptr, REG15_pc, REG12_ip);
-# endif /* ARM_K_BUG */
- jit_info->native_ptr
- = emit_word(jit_info->native_ptr, (int) jit_info->cur_op);
- jit_info->native_ptr
- = emit_word(jit_info->native_ptr,
- (int) interp->op_func_table[*(jit_info->cur_op)]);
-}
-
-/* We get back address of opcode in bytecode.
- We want address of equivalent bit of jit code, which is stored as an
- address at the same offset in a jit table. */
-void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
- Parrot_jump_to_op_in_reg(jit_info, interp, r0);
-}
-
-/* move reg to mem (i.e. intreg) */
-void
-Parrot_jit_emit_mov_mr(PARROT_INTERP, char *mem, int reg)
-{
-}
-
-/* move mem (i.e. intreg) to reg */
-void
-Parrot_jit_emit_mov_rm(PARROT_INTERP, int reg, char *mem)
-{
-}
-
-/* move reg to mem (i.e. numreg) */
-void
-Parrot_jit_emit_mov_mr_n(PARROT_INTERP, char *mem, int reg)
-{
-}
-
-/* move mem (i.e. numreg) to reg */
-void
-Parrot_jit_emit_mov_rm_n(PARROT_INTERP, int reg, char *mem)
-{
-}
-
-#endif /* JIT_EMIT == 2 */
-#if JIT_EMIT == 0
-
-# define REQUIRES_CONSTANT_POOL 0
-# define INT_REGISTERS_TO_MAP 10
-
-/* XXX NOTE before actually mapping things
-
- 1: currently the code has r4 (INTERP_STRUCT_ADDR_REG) is in use
- 2: r12 is trashed over any function call
- 3: currently the entry code doesn't save r5, r6, r7, r8 (or r9) - if the
- mapping code uses them then it must arrange to save (and restore them)
-
- and as we're not generating re-entrant code (I assume) surely we can also
- map r9?
-
- NWC
-*/
-
-# ifndef JIT_IMCC
-
-char intval_map[INT_REGISTERS_TO_MAP] =
- { r0, r1, r2, r3, r4, r5, r6, r7, r8, r12 };
-
-static void
-arm_sync_d_i_cache(void *start, void *end)
-{
- /* Strictly this is only needed for StrongARM and later (not sure about
- * ARM8) because earlier cores don't have separate D and I caches.
- * However there aren't that many ARM7 or earlier devices around that
- * we'll be running on. */
-# ifdef __linux
-# ifdef __GNUC__
- int result;
- /* swi call based on code snippet from Russell King. Description
- verbatim: */
- /*
- * Flush a region from virtual address 'r0' to virtual address 'r1'
- * _inclusive_. There is no alignment requirement on either address;
- * user space does not need to know the hardware cache layout.
- *
- * r2 contains flags. It should ALWAYS be passed as ZERO until it
- * is defined to be something else. For now we ignore it, but may
- * the fires of hell burn in your belly if you break this rule. ;)
- *
- * (at a later date, we may want to allow this call to not flush
- * various aspects of the cache. Passing '0' will guarantee that
- * everything necessary gets flushed to maintain consistency in
- * the specified region).
- */
-
- /* The value of the SWI is actually available by in
- __ARM_NR_cacheflush defined in <asm/unistd.h>, but quite how to
- get that to interpolate as a number into the ASM string is beyond
- me. */
- /* I'm actually passing in exclusive end address, so subtract 1 from
- it inside the assembler. */
- __asm__ __volatile__(
- "mov r0, %1\n"
- "sub r1, %2, #1\n"
- "mov r2, #0\n"
- "swi " __sys1(__ARM_NR_cacheflush) "\n"
- "mov %0, r0\n"
- : "=r" (result)
- : "r" ((long)start), "r" ((long)end)
- : "r0", "r1", "r2");
-
- if (result < 0)
- Parrot_ex_throw_from_c_args(interp, NULL, JIT_ERROR,
- "Synchronising I and D caches failed with errno=%d\n", -result);
-# else
-# error "ARM needs to sync D and I caches, and I don't know how to embed assembler on this C compiler"
-# endif
-# else
-/* Not strictly true - on RISC OS it's OS_SynchroniseCodeAreas */
-# error "ARM needs to sync D and I caches, and I don't know how to on this OS"
-# endif
-}
-
-# endif
-#endif /* JIT_EMIT == 0 */
-#endif /* PARROT_ARM_JIT_EMIT_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/hppa/core.jit
==============================================================================
--- trunk/src/jit/hppa/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,151 +0,0 @@
-;
-; hppa/core.jit
-;
-;
-; $Id$
-;
-
-Parrot_end {
- jit_emit_end(NATIVECODE);
-}
-
-Parrot_set_i_ic {
- if (MAP[1]) {
- jit_emit_mov_ri_i(NATIVECODE, MAP[1], *INT_CONST[2]);
- }
- else {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_set_i_i {
- if (MAP[1] && MAP[2]) {
- jit_emit_mov_rr(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, MAP[1], ROFFS_INT(2));
- }
- else if (MAP[2]) {
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), MAP[2]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-TEMPLATE Parrot_binop_x_x {
- if (MAP[1] && MAP[2]) {
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[1], <s1>);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(1));
- jit_emit_<op>_rrr(NATIVECODE, <s1>, <s1>, MAP[2]);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(1));
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
- jit_emit_<op>_rrr(NATIVECODE, <s1>, <s2>, <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
-}
-
-TEMPLATE Parrot_binop_x_x_x {
- if (MAP[1] && MAP[2] && MAP[3]) {
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[2], MAP[3]);
- }
- else if (MAP[1] && MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[2], <s1>);
- }
- else if (MAP[1] && MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], <s1>, MAP[3]);
- }
- else if (MAP[2] && MAP[3]) {
- jit_emit_<op>_rrr(NATIVECODE, <s1>, MAP[2], MAP[3]);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(3), <s1>);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], <s2>, <s1>);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
- jit_emit_<op>_rrr(NATIVECODE, <s1>, MAP[2], <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
- else if (MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
- jit_emit_<op>_rrr(NATIVECODE, <s1>, <s1>, MAP[3]);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
- jit_emit_<op>_rrr(NATIVECODE, <s1>, <s2>, <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
-}
-
-Parrot_band_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bor_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bxor_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_add_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_sub_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_band_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bor_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bxor_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_add_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_sub_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-TEMPLATE Parrot_ifunless_i_ic {
- if (!MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- }
- jit_emit_bc(jit_info, ISR1, r0, <COND>, *INT_CONST[2]);
-}
-
-Parrot_if_i_ic {
- Parrot_ifunless_i_ic s/<COND>/emit_EQ/
-}
-
-Parrot_unless_i_ic {
- Parrot_ifunless_i_ic s/<COND>/emit_NE/
-}
Deleted: trunk/src/jit/hppa/jit_defs.c
==============================================================================
--- trunk/src/jit/hppa/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,13 +0,0 @@
-/* Stub file for RT#38929 fixes */
-/*
-Copyright (C) 2008, Parrot Foundation.
-$Id$
-*/
-/* HEADERIZER HFILE: none */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/hppa/jit_emit.h
==============================================================================
--- trunk/src/jit/hppa/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,786 +0,0 @@
-/*
- * Copyright (C) 2004-2009, Parrot Foundation.
- */
-
-/*
- * jit_emit.h
- *
- * HPPA
- *
- * $Id$
- */
-
-#ifndef PARROT_HPPA_JIT_EMIT_H_GUARD
-#define PARROT_HPPA_JIT_EMIT_H_GUARD
-
-
-/*
- * r0 Zero
- * r26 Argument 1
- * r25 Argument 2
- * r24 Argument 3
- * r23 Argument 4
- * r28 Return value 0
- * r29 Return value 1
- */
-
-typedef enum {
- r0,
- r1,
- r2,
- r3,
- r4,
- r5,
- r6,
- r7,
- r8,
- r9,
- r10,
- r11,
- r12,
- r13,
- r14,
- r15,
- r16,
- r17,
- r18,
- r19,
- r20,
- r21,
- r22,
- r23,
- r24,
- r25,
- r26,
- r27,
- r28,
- r29,
- r30,
- r31
-} hppa_iregister_t;
-
-typedef enum {
- f0,
- f1,
- f2,
- f3,
- f4,
- f5,
- f6,
- f7,
- f8,
- f9,
- f10,
- f11,
- f12,
- f13,
- f14,
- f15,
- f16,
- f17,
- f18,
- f19,
- f20,
- f21,
- f22,
- f23,
- f24,
- f25,
- f26,
- f27,
- f28,
- f29,
- f30,
- f31
-} hppa_fregister_t;
-
-enum { JIT_HPPA_BRANCH, JIT_HPPA_CALL };
-
-/* BASE: interpreter address
- * CIR: call index register
- */
-# define BASE r4
-# define CIR r5
-# define ISR1 r21
-# define ISR2 r22
-# define RET0 r28
-
-# define Parrot_jit_emit_get_base_reg_no(pc) BASE
-
-/* Load / Store.
- *
- *
- *
- * +--------------------------------------------------------------------+
- * | op | b | t/r | s | im14 |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 17 18 31
- *
- * ldw (load word)
- * op = 18
- * ldo (load offset)
- * op = 13
- * stw (store word)
- * op = 26
- */
-
-# define emit_ls(pc, op, b, tr, s, im14) \
- *((pc)++) = (op) << 2 | (b) >> 3; \
- *((pc)++) = (char)((b) << 5 | (tr)); \
- *((pc)++) = (s) << 6 | (((im14) >> 7) & 0x3f) ; \
- if ((im14) < 0) \
- *((pc)++) = (char)((im14) << 1) + 1; \
- else \
- *((pc)++) = (char)(im14) << 1
-
-# define emit_ldw(pc, b, t, d) \
- emit_ls((pc), 18, (b), (t), 0, (d))
-
-# define emit_ldo(pc, b, t, d) \
- emit_ls((pc), 13, (b), (t), 0, (d))
-
-# define emit_stw(pc, b, r, d) \
- emit_ls((pc), 26, (b), (r), 0, (d))
-
-# define emit_stwm(pc, b, r, d) \
- emit_ls((pc), 27, (b), (r), 0, (d))
-
-# define emit_ldwm(pc, b, r, d) \
- emit_ls((pc), 19, (b), (r), 0, (d))
-
-# define emit_ldd(pc, b, t, d) \
- emit_ls((pc), 20, (b), (t), 0, (d))
-
-# define emit_std(pc, b, r, d) \
- emit_ls((pc), 28, (b), (r), 0, (d))
-
-/* Load / Store Indexed.
- *
- *
- *
- * +--------------------------------------------------------------------+
- * | op | b | x | s |u| 0 |cc| 2 |m| t |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 17 18 19 20 22 26 27 31
- *
- */
-
-# define emit_lsi(pc, op, b, x, tr) \
- *((pc)++) = (op) << 2 | (b) >> 3; \
- *((pc)++) = (char)((b) << 5 | (x)); \
- (pc)++; \
- *((pc)++) = (2 << 6) | (tr);
-
-
-/* 21 bit immediates.
- *
- *
- *
- * +--------------------------------------------------------------------+
- * | op | t / r | im21 |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 31
- *
- * ldil
- * op = 8
- */
-
-# define emit_im21(pc, op, r, imm) \
- *((pc)++) = (op) << 2 | (r) >> 3; \
- *((pc)++) = (char)((r) << 5 | (((imm) >> 2) & 0x1f)); \
- *((pc)++) = (char)(((((imm) >> 7) & 0x3) << 6) | (((imm) & 0x3) << 4) | \
- (((imm) >> 16) & 0xf)); \
- *((pc)++) = (char)(((((imm) >> 9) & 0x7f) << 1) | (((imm) >> 20) & 1));
-
-# define emit_ldil(pc, r, imm) \
- emit_im21((pc), 8, (r), (imm))
-
-/* Arithmetic
- *
- *
- * +--------------------------------------------------------------------+
- * | op | r2 | r1 | c | f | ext6 | 0 | t |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 18 19 20 25 26 27 31
- *
- */
-
-# define emit_arith(pc, op, ext6, s2, s1, t) \
- *((pc)++) = (op) << 2 | (s2) >> 3; \
- *((pc)++) = (char)((s2) << 5 | (s1)); \
- *((pc)++) = (char)((ext6) >> 2); \
- *((pc)++) = (char)((ext6) << 6 | (t))
-
-# define jit_emit_add_rrr(pc, dst, src1, src2) \
- emit_arith((pc), 2, 0x18, (src2), (src1), (dst))
-
-# define jit_emit_sub_rrr(pc, dst, src1, src2) \
- emit_arith((pc), 2, 0x10, (src2), (src1), (dst))
-
-# define jit_emit_or_rrr(pc, dst, src1, src2) \
- emit_arith((pc), 2, 9, (src2), (src1), (dst))
-
-# define jit_emit_xor_rrr(pc, dst, src1, src2) \
- emit_arith((pc), 2, 0xA, (src2), (src1), (dst))
-
-# define jit_emit_and_rrr(pc, dst, src1, src2) \
- emit_arith((pc), 2, 8, (src2), (src1), (dst))
-
-/* Deposit / Extract
- *
- *
- * +--------------------------------------------------------------------+
- * | op | r | t | c | x | p | clen |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 18 19 21 22 26 27 31
- *
- */
-
-# define emit_depext(pc, op, r, t, x, p, clen) \
- *((pc)++) = (op) << 2 | (r) >> 3; \
- *((pc)++) = (char)((r) << 5 | (t)); \
- *((pc)++) = (char)((x) << 2 | (p) >> 3); \
- *((pc)++) = (char)((p) << 5 | (clen))
-
-# define emit_extu(pc, r, t, p, clen) \
- emit_depext((pc), 0x34, (r), (t), 6, (p), (clen));
-
-# define emit_exts(pc, r, t, p, clen) \
- emit_depext((pc), 0x34, (r), (t), 7, (p), (clen));
-
-/* Conditions */
-
-# define emit_NEVER 0
-# define emit_EQ 1
-# define emit_LT 2
-# define emit_LTE 3
-# define emit_LTU 4
-# define emit_LTEU 5
-# define emit_SV 6
-# define emit_ODD 7
-
-/* Fake conditions */
-
-# define emit_NE 8
-# define emit_GTE 9
-# define emit_GT 10
-# define emit_GTEU 11
-# define emit_GTU 12
-
-/* Compare and branch.
- *
- *
- *
- * +--------------------------------------------------------------------+
- * | op | r2 | r1 | c | im11 | n | w |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 18 19 29 30 31
- *
- * branch target = cat(w,im11[10], im11[0..9])
- */
-
-# define emit_cmpbch(pc, op, s2, s1, c, trg, n, w) \
- *((pc)++) = (op) << 2 | (s2) >> 3; \
- *((pc)++) = (char)((s2) << 5 | (s1)); \
- *((pc)++) = (c) << 5 | (trg) >> 6; \
- *((pc)++) = (char)((trg) << 3 | (n) << 1 | (w))
-
-# define jit_emit_cmpbt(pc, s2, s1, c, targ, n) \
- emit_cmpbch((pc), 0x20, (s2), (s1), (c), (targ), (n), (((targ) >> 11) & 1))
-
-# define jit_emit_cmpbf(pc, s2, s1, c, targ, n) \
- emit_cmpbch((pc), 0x22, (s2), (s1), (c), (targ), (n), (((targ) >> 11) & 1))
-
-/* Branch and link.
- *
- *
- *
- * +--------------------------------------------------------------------+
- * | op | t | w1 | 0 | w2 | n | w |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 18 19 29 30 31
- *
- * address is:
- * w1 * 8192
- * w2 = 10 . 0-9
- * w + -
- */
-
-# define _emit_bl(pc, op, t, w1, w2, n, w) \
- *((pc)++) = (op) << 2 | (t) >> 3; \
- *((pc)++) = (char)((t) << 5 | (w1)); \
- *((pc)++) = (w2) >> 6; \
- *((pc)++) = (char)((w2) << 3 | (n) << 1 | (w))
-
-# define emit_bl(pc, disp) \
- _emit_bl((pc), 0x3A, r2, \
- (((disp) >> 11) & 0x1f), ((((disp) & 0x3ff) << 1) + (((disp) >> 10) & 1)), \
- 0, (((disp) >> 31) & 1));
-
-# define emit_b(pc) \
- _emit_bl((pc), 0x3A, r2, 0, 0, 0, 0)
-
-/* Branch and Link Register.
- *
- *
- *
- * +--------------------------------------------------------------------+
- * | 0x3A | t | x | 2 | 0 | n | 0 |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 18 19 29 30 31
- *
- * t = curret_ip
- * IP = curret_ip + (x << 3) + 8
- * if (n) execute_next_instruction
- */
-
-# define emit_blr(pc, t, x, n) \
- *((pc)++) = 0x3a << 2 | (t) >> 3; \
- *((pc)++) = (char)((t) << 5 | (x)); \
- *((pc)++) = 2 << 5; \
- *((pc)++) = ((n) << 1)
-
-/* Move.
- XXX MOVE AND BRACH
- */
-
-# define jit_emit_mov_rr(pc, dst, src) \
- *((pc)++) = 8; \
- *((pc)++) = (src); \
- *((pc)++) = 2; \
- *((pc)++) = 0x40 + (dst)
-
-/*
- */
-
-# define emit_ret(pc) \
- *((pc)++) = 0xe8; \
- *((pc)++) = 0x40; \
- *((pc)++) = 0xc0; \
- *((pc)++) = 0x02
-
-/* Branch Vectored.
- *
- *
- *
- * +--------------------------------------------------------------------+
- * | op | b | x | 6 | 0 | n | 0 |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 18 19 29 30 31
- *
- * IP = (b << 3) + x
- *
- * No return address is saved.
- */
-
-# define _emit_bv(pc, op, b, x, n) \
- *((pc)++) = (op) << 2 | (b) >> 3; \
- *((pc)++) = (char)((b) << 5 | (x)); \
- *((pc)++) = 6 << 5; \
- *((pc)++) = (n) << 1
-
-# define emit_bv(pc, b, x, n) \
- _emit_bv((pc), 0x3A, (b), (x), (n));
-
-/* Immediate
- *
- *
- * +--------------------------------------------------------------------+
- * | op | r | t | c | f | 0 | imm11 |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 18 19 20 31
- *
- * imm11 is low_sign_ext ( ie. the sign bit is 0 )
- */
-
-# define _emit_imm11(pc, op, r, t, imm11) \
- *((pc)++) = (op) << 2 | (r) >> 3; \
- *((pc)++) = (char)((r) << 5 | (t)); \
- *((pc)++) = (char)((imm11) >> 7); \
- *((pc)++) = (char)((imm11) << 1)
-
-# define emit_addimm11(pc, r, t, imm11) \
- _emit_imm11(pc, 0x2d, r, t, imm11);
-
-/* Synchronize caches
- *
- *
- * +--------------------------------------------------------------------+
- * | 00 | rv | 0 | rv | 0 | 20 | 0 |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 12 15 16 18 19 26 27 31
- *
- */
-
-# define emit_sync(pc) \
- *((pc)++) = 0; \
- *((pc)++) = 0; \
- *((pc)++) = 0x4; \
- *((pc)++) = 0;
-
-
-/* Pseudo instructions. */
-
-# define jit_emit_nop(pc) \
- jit_emit_or_rrr((pc), 0, 0, 0)
-
-/* ldil loads a 21 bits immediate into the left part of a general register,
- * ldo loads a 14 bits offset into a general register, so we use it to add
- * the missing 11 bits.
- */
-
-# define jit_emit_mov_ri_i(pc, D, imm) \
- emit_ldil((pc), (D), (((imm) >> 11) & 0x1fffff)); \
- emit_ldo((pc), (D), (D), ((imm) & 0x7ff))
-
-# define jit_emit_mov_rm_i(pc, reg, offs) \
- emit_ldw((pc), BASE, (reg), (offs));
-
-# define jit_emit_mov_mr_i(pc, offs, reg) \
- emit_stw((pc), BASE, (reg), (offs));
-
-# define jit_emit_mov_mr_n(pc, offs, reg) \
- emit_std((pc), BASE, (reg), (offs));
-
-# define jit_emit_mov_rm_n(pc, offs, reg) \
- emit_ldd((pc), BASE, (reg), (offs));
-
-/* emit_cmpbranch
- *
- * Branches to dest if cond is satisfied.
- * Doesn't save a return address.
- */
-
-#define jit_emit_cmpbranch(pc, s1, s2, cond, dest) { \
- if ((cond) >= emit_GTE) { \
- jit_emit_cmpbf((pc), ((cond) - 7), (s2), (s1), 3, 0); \
- } \
- else { \
- jit_emit_cmpbf((pc), (cond), (s1), (s2), 3, 0); \
- } \
- jit_emit_nop(pc); \
- jit_emit_mov_ri_i((pc), ISR2, (dest)); \
- emit_bv((pc), ISR2, r0, 1); \
-}
-
-static void
-jit_emit_bc(Parrot_jit_info_t *jit_info, hppa_iregister_t s1,
- hppa_iregister_t s2, int cond, opcode_t disp)
-{
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_HPPA_BRANCH;
- jit_info->arena.fixups->param.opcode = jit_info->op_i + disp;
-
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- jit_emit_cmpbranch(jit_info->native_ptr, s1, s2, cond, 0);
-}
-
-static void
-Parrot_emit_jump_to_ret(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- /* This calculates (INDEX into op_map * 4) */
-
- /* we have to get the code pointer, which might change
- * due too intersegment branches
- */
- emit_ldw(jit_info->native_ptr, BASE, CIR,
- (offsetof(Interp, code)));
- emit_ldw(jit_info->native_ptr, CIR, ISR2,
- (offsetof(PackFile_Segment, data)));
- jit_emit_sub_rrr(jit_info->native_ptr, CIR, RET0, ISR2);
- /*
- * now we have the offset of the ins in CIR
- *
- * we have to get the op_map too at runtime
- */
- emit_ldw(jit_info->native_ptr, BASE, ISR1,
- (offsetof(Interp, code)));
- emit_ldo(jit_info->native_ptr, ISR1, ISR2,
- (offsetof(Parrot_jit_info_t, arena)));
- emit_ldw(jit_info->native_ptr, ISR2, ISR1,
- (offsetof(Parrot_jit_arena_t, op_map)));
- /* This jumps to the address in op_map[ISR1 + sizeof(void *) * INDEX] */
- emit_lsi(jit_info->native_ptr, 0x3, ISR1, CIR, ISR2);
- emit_bv(jit_info->native_ptr, ISR2, r0, 1);
- jit_emit_nop(jit_info->native_ptr);
-
-}
-
-/* Load the return address from the stack and return. */
-/* Restore the callee-save registers. */
-# define jit_emit_end(pc) \
- emit_ldo(jit_info->native_ptr, r30, r30, 0x40); \
- emit_ldw(jit_info->native_ptr, r30, r4, -0x4); \
- emit_ldw(jit_info->native_ptr, r30, r5, -0x8); \
- emit_ldw(jit_info->native_ptr, r30, r6, -0xc); \
- emit_ldw(jit_info->native_ptr, r30, r7, -0x10); \
- emit_ldw(jit_info->native_ptr, r30, r8, -0x14); \
- emit_ldw(jit_info->native_ptr, r30, r9, -0x18); \
- emit_ldw(jit_info->native_ptr, r30, r10, -0x1c); \
- emit_ldw(jit_info->native_ptr, r30, r11, -0x20); \
- emit_ldw(jit_info->native_ptr, r30, r12, -0x24); \
- emit_ldw(jit_info->native_ptr, r30, r13, -0x28); \
- emit_ldw(jit_info->native_ptr, r30, r14, -0x2c); \
- emit_ldw(jit_info->native_ptr, r30, r15, -0x30); \
- emit_ldw(jit_info->native_ptr, r30, r16, -0x34); \
- emit_ldw(jit_info->native_ptr, r30, r17, -0x38); \
- emit_ldw(jit_info->native_ptr, r30, r18, -0x40); \
- emit_ldw(jit_info->native_ptr, r3, r2, -0x14); \
- emit_ldo((pc), r3, r30, 0x40); \
- emit_ldwm((pc), r30, r4, -0x40); \
- emit_ret(pc)
-
-/*
- * For the JIT procedure calls are built using BRANCH AND LINK REGISTER,
- * specifically, we load the FDP (Function Descriptor Pointer) into ISR2,
- * get the address and r19 set, load the IP, and calculate the displacement
- * right shiff it by 3 and branch there.
- * The FDP will contain the actual function address the second time it's
- * called.
- * But for EXEC using BRANCH AND LINK, this is because the address of
- * the code generated in the JIT could (probably will) be 65535 * 4 bytes
- * farest than the called procedure, and this is won't happend for EXEC
- * (and if it does, it's ld's problem, not ours).
- */
-
-#if JIT_EMIT == 2
-
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- jit_emit_mov_rr(jit_info->native_ptr, r25, BASE);
- jit_emit_mov_ri_i(jit_info->native_ptr, r26, ((int)(jit_info->cur_op)));
-
- Parrot_jit_newfixup(jit_info);
-
- jit_info->arena.fixups->type = JIT_HPPA_CALL;
- jit_info->arena.fixups->param.fptr =
- (void (*)(void))interp->op_func_table[*(jit_info->cur_op)];
-
- jit_info->native_ptr += 32;
-}
-
-void
-Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
- Parrot_emit_jump_to_ret(jit_info, interp);
-}
-
-# undef Parrot_jit_restart_op
-void
-Parrot_jit_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- char *jmp_ptr, *sav_ptr;
-
- Parrot_jit_normal_op(jit_info, interp);
- /* remember PC */
- jmp_ptr = jit_info->native_ptr;
- jit_emit_cmpbf(jit_info->native_ptr, RET0, r0, emit_EQ, 0, 0);
- jit_emit_end(jit_info->native_ptr);
- /* fixup above jump */
- sav_ptr = jit_info->native_ptr;
- jit_info->native_ptr = jmp_ptr;
- jit_emit_cmpbf(jit_info->native_ptr, RET0, r0, emit_EQ,
- (long)(((sav_ptr - jmp_ptr) - 8) / 4), 0);
- jit_info->native_ptr = sav_ptr;
- Parrot_emit_jump_to_ret(jit_info, interp);
-}
-
-#endif /* JIT_EMIT */
-#if JIT_EMIT == 0
-
-# define FLOAT_REGISTERS_TO_MAP 4
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- /* Save the return address in the stack. */
- emit_stw(jit_info->native_ptr, r30, r2, -0x14);
- jit_emit_mov_rr(jit_info->native_ptr, r1, r3);
- jit_emit_mov_rr(jit_info->native_ptr, r3, r30);
- emit_stwm(jit_info->native_ptr, r30, r1, 0x40);
- emit_stw(jit_info->native_ptr, r3, r26, -0x24);
- emit_stw(jit_info->native_ptr, r3, r25, -0x28);
- /* Callee-save registers. */
- emit_ldo(jit_info->native_ptr, r30, r30, 0x40);
- emit_stw(jit_info->native_ptr, r30, r4, -0x4);
- emit_stw(jit_info->native_ptr, r30, r5, -0x8);
- emit_stw(jit_info->native_ptr, r30, r6, -0xc);
- emit_stw(jit_info->native_ptr, r30, r7, -0x10);
- emit_stw(jit_info->native_ptr, r30, r8, -0x14);
- emit_stw(jit_info->native_ptr, r30, r9, -0x18);
- emit_stw(jit_info->native_ptr, r30, r10, -0x1c);
- emit_stw(jit_info->native_ptr, r30, r11, -0x20);
- emit_stw(jit_info->native_ptr, r30, r12, -0x24);
- emit_stw(jit_info->native_ptr, r30, r13, -0x28);
- emit_stw(jit_info->native_ptr, r30, r14, -0x2c);
- emit_stw(jit_info->native_ptr, r30, r15, -0x30);
- emit_stw(jit_info->native_ptr, r30, r16, -0x34);
- emit_stw(jit_info->native_ptr, r30, r17, -0x38);
- emit_stw(jit_info->native_ptr, r30, r18, -0x3c);
- /* Move the interpreter to the base register. */
- jit_emit_mov_rr(jit_info->native_ptr, BASE, r26);
- jit_emit_mov_rr(jit_info->native_ptr, RET0, r25);
- Parrot_emit_jump_to_ret(jit_info, interp);
-}
-
-void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_jit_fixup_t *fixup;
- char *fixup_ptr;
- char *disp;
- long d;
-
- fixup = jit_info->arena.fixups;
-
- while (fixup) {
- switch (fixup->type) {
- case JIT_HPPA_BRANCH:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup) + 8;
- d = jit_info->arena.op_map[fixup->param.opcode].offset
- + jit_info->arena.start + fixup->skip;
- jit_emit_mov_ri_i(fixup_ptr, ISR2, d);
- break;
- case JIT_HPPA_CALL:
- /* Load the FDP. */
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = (long)fixup->param.fptr - 2;
- jit_emit_mov_ri_i(fixup_ptr, ISR2, d);
- emit_ldw(fixup_ptr, ISR2, CIR, 0);
- emit_ldw(fixup_ptr, ISR2, r19, 4);
- /* Save the return address in r2 */
- emit_bl(fixup_ptr, 0);
- /* Make the return address pass the actual branch */
- emit_addimm11(fixup_ptr, r2, r2, 8);
- /* Branch without modifying r2 */
- emit_bv(fixup_ptr, CIR, r0, 1);
- jit_emit_nop(fixup_ptr);
- break;
- default:
- exit_fatal(EXCEPTION_JIT_ERROR, "Unknown fixup type:%d\n",
- fixup->type);
- break;
- }
- fixup = fixup->next;
- }
-}
-
-/* move reg to mem (i.e. intreg) */
-static void
-jit_mov_mr_offs(Parrot_jit_info_t *jit_info, int base, INTVAL offs, int reg)
-{
- jit_emit_mov_mr_i(jit_info->native_ptr, offs, reg);
-}
-
-/* move mem (i.e. intreg) to reg */
-static void
-jit_mov_rm_offs(Parrot_jit_info_t *jit_info, int reg, int base, INTVAL offs)
-{
- jit_emit_mov_rm_i(jit_info->native_ptr, reg, offs);
-}
-
-/* move reg to mem (i.e. numreg) */
-static void
-jit_mov_mr_n_offs(Parrot_jit_info_t * jit_info, int base, INTVAL offs, int reg)
-{
- jit_emit_mov_mr_n(jit_info->native_ptr, offs, reg);
-}
-
-/* move mem (i.e. numreg) to reg */
-static void
-jit_mov_rm_n_offs(Parrot_jit_info_t * jit_info, int reg, int base, INTVAL offs)
-{
- jit_emit_mov_rm_n(jit_info->native_ptr, reg, offs);
-}
-
-
-# define REQUIRES_CONSTANT_POOL 0
-# define INT_REGISTERS_TO_MAP 14
-# define CACHELINESIZE 32
-
-# ifndef JIT_IMCC
-
-char intval_map[INT_REGISTERS_TO_MAP] =
- { r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18};
-
-char intval_map_sub[] =
- { r0, r1, r2, r3, r4, r5 };
-
-static void
-hppa_sync_cache(void *_start, void *_end)
-{
- char *start = (char*)(((int)_start) &~(CACHELINESIZE));
- char *end = (char *)((((int)_end)+CACHELINESIZE) &~(CACHELINESIZE));
- char *_sync;
-
- for (_sync = start; _sync < end; _sync += CACHELINESIZE) {
- __asm__ __volatile__("fdc %r0(%0)":: "r" ((long)_sync));
- }
-
- __asm__ __volatile__("sync");
-}
-
-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,
- hppa_sync_cache,
- {
- {
- Parrot_jit_begin,
- INT_REGISTERS_TO_MAP,
- INT_REGISTERS_TO_MAP,
- intval_map,
- 0,
- 0,
- NULL
- },
- {
- NULL,
- 0,
- 0,
- NULL,
- 0,
- 0,
- NULL
- },
- {
- NULL,
- 0,
- 0,
- NULL,
- 0,
- 0,
- NULL
- }
- }
-};
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info*
-Parrot_jit_init(PARROT_INTERP)
-{
- return &arch_info;
-}
-
-# endif
-
-#endif /* !JIT_EMIT */
-
-#endif /* PARROT_HPPA_JIT_EMIT_H_GUARD */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/i386/core.jit
==============================================================================
--- trunk/src/jit/i386/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,1754 +0,0 @@
-;
-; i386/core.jit
-;
-; $Id$
-;
-
-# TODO complete this
-#define P_ARITH ((PREV_OP == dec_i) || (PREV_OP == inc_i) || (PREV_OP == sub_i_i_i) || (PREV_OP == sub_i_i))
-
-#define CALL_FUNCTION(j, f) call_func(j, (void (*)(void)) & f)
-
-Parrot_end {
- jit_emit_end(NATIVECODE);
-}
-
-Parrot_noop {
- emit_nop(NATIVECODE);
-}
-
-
-TEMPLATE Parrot_set_x_x {
- if (MAP[1] && MAP[2]) {
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(2));
- }
- else if (MAP[2]) {
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), MAP[2]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_set_n_n {
- Parrot_set_x_x s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_set_i_i {
- Parrot_set_x_x s/<_N>/_i/
-}
-
-Parrot_set_p_p {
- Parrot_set_x_x s/<_N>/_i/ s/INT/PMC/
-}
-
-Parrot_set_s_s {
- Parrot_set_x_x s/<_N>/_i/ s/INT/STR/
-}
-
-TEMPLATE Parrot_set_x_ic {
- if (MAP[1]) {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, MAP[1], <typ>_CONST[2]);
- }
- else {
- jit_emit_mov_MI<_N>(interp, NATIVECODE, ROFFS_INT(1), <typ>_CONST[2]);
- }
-}
-
-Parrot_set_i_ic {
- Parrot_set_x_ic s/<_N>/_i/ s/<typ>/*INT/
-}
-
-Parrot_set_n_ic {
- Parrot_set_x_ic s/<_N>/_ni/ s/INT/NUM/ s/<typ>/&INT/
-}
-
-Parrot_set_n_nc {
- if (MAP[1]) {
- jit_emit_mov_ri_n(interp, NATIVECODE, MAP[1], &NUM_CONST[2]);
- }
- else {
- jit_emit_mov_ri_n(interp, NATIVECODE, FSR1, &NUM_CONST[2]);
- jit_emit_mov_MR_n(interp, NATIVECODE, ROFFS_NUM(1), FSR1);
- }
-}
-
-Parrot_set_p_pc {
- if (MAP[1]) {
- jit_emit_mov_rm_i(interp, NATIVECODE, MAP[1], &PMC_CONST[2]);
- }
- else {
- jit_emit_mov_rm_i(interp, NATIVECODE, ISR1, &PMC_CONST[2]);
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_PMC(1), ISR1);
- }
-}
-
-Parrot_set_n_i {
-; store mapped int
- if (MAP[2]) {
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(2), MAP[2]);
- }
- if (MAP[1]) {
- jit_emit_mov_RM_ni(interp, NATIVECODE, MAP[1], ROFFS_INT(2));
- }
- else {
- jit_emit_mov_RM_ni(interp, NATIVECODE, FSR1, ROFFS_INT(2));
- jit_emit_mov_MR_n(interp, NATIVECODE, ROFFS_NUM(1), FSR1);
- }
-}
-
-; these are wrong: fist does rounding, but we should truncate
-;Parrot_set_i_n {
-; if (MAP[2]) {
-; jit_emit_mov_MR_in(NATIVECODE, ROFFS_INT(1), MAP[2]);
-; }
-; else {
-; jit_emit_mov_RM_n(NATIVECODE, FSR1, ROFFS_NUM(2));
-; jit_emit_mov_MR_in(NATIVECODE, ROFFS_INT(1), FSR1);
-; }
-; if (MAP[1]) {
-; jit_emit_mov_RM_i(interp, NATIVECODE, MAP[1], ROFFS_INT(1));
-; }
-;}
-;
-;Parrot_set_i_nc {
-; jit_emit_mov_ri_n(interp, NATIVECODE, FSR1, &NUM_CONST[2]);
-; jit_emit_mov_MR_in(NATIVECODE, ROFFS_INT(1), FSR1);
-; if (MAP[1]) {
-; jit_emit_mov_RM_i(interp, NATIVECODE, MAP[1], ROFFS_INT(1));
-; }
-;}
-
-; -- null op.
-TEMPLATE Parrot_null_x {
- if (MAP[1]) {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, MAP[1], <val>);
- }
- else {
- jit_emit_mov_MI<_N>(interp, NATIVECODE, ROFFS_INT(1), <val>);
- }
-}
-
-Parrot_null_i {
- Parrot_null_x s/<_N>/_i/ s/<val>/0/
-}
-
-Parrot_null_p {
- Parrot_null_x s/<_N>/_i/ s/INT/PMC/ s/<val>/PMCNULL/
-}
-
-Parrot_null_s {
- Parrot_null_x s/<_N>/_i/ s/INT/STR/ s/<val>/NULL/
-}
-
-; TODO use fldz
-Parrot_null_n {
- static FLOATVAL zero = 0;
- if (MAP[1]) {
- jit_emit_mov_ri_n(interp, NATIVECODE, MAP[1], &zero);
- }
- else {
- jit_emit_mov_MI_ni(interp, NATIVECODE, ROFFS_NUM(1), &zero);
- }
-}
-
-TEMPLATE Parrot_binop_x_x {
- if (MAP[1] && MAP[2]) {
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(2));
- }
- else if (MAP[2]) {
-# ifdef jit_emit_<op>_MR<_N>
- jit_emit_<op>_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), MAP[2]);
-# else
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[2]);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
-# endif
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-TEMPLATE Parrot_divop_x_x {
- if (MAP[1]) {
- jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[1]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(1));
- }
- if (MAP[2]) {
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[2]);
- }
- else {
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- }
- if (MAP[1]) {
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_mul_i_i {
- Parrot_binop_x_x s/<op>/mul/ s/<_N>/_i/
-}
-
-Parrot_div_i_i {
- Parrot_divop_x_x s/<op>/div/ s/<_N>/_i/
-}
-
-Parrot_add_i_i {
- Parrot_binop_x_x s/<op>/add/ s/<_N>/_i/
-}
-
-Parrot_sub_i_i {
- Parrot_binop_x_x s/<op>/sub/ s/<_N>/_i/
-}
-
-Parrot_bor_i_i {
- Parrot_binop_x_x s/<op>/bor/ s/<_N>/_i/
-}
-
-Parrot_bxor_i_i {
- Parrot_binop_x_x s/<op>/bxor/ s/<_N>/_i/
-}
-
-Parrot_band_i_i {
- Parrot_binop_x_x s/<op>/band/ s/<_N>/_i/
-}
-
-Parrot_shl_i_i {
- Parrot_binop_x_x s/<op>/shl/ s/<_N>/_i/
-}
-
-Parrot_shr_i_i {
- Parrot_binop_x_x s/<op>/shr/ s/<_N>/_i/
-}
-
-Parrot_lsr_i_i {
- Parrot_binop_x_x s/<op>/lsr/ s/<_N>/_i/
-}
-
-Parrot_mul_n_n {
- Parrot_binop_x_x s/<op>/mul/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_add_n_n {
- Parrot_binop_x_x s/<op>/add/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_sub_n_n {
- Parrot_binop_x_x s/<op>/sub/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_div_n_n {
- Parrot_binop_x_x s/<op>/div/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_exchange_i_i {
- Parrot_binop_x_x s/<op>/xchg/ s/<_N>/_i/
-}
-
-Parrot_exchange_s_s {
- Parrot_binop_x_x s/<op>/xchg/ s/<_N>/_i/ s/INT/STR/
-}
-
-Parrot_exchange_p_p {
- Parrot_binop_x_x s/<op>/xchg/ s/<_N>/_i/ s/INT/PMC/
-}
-
-Parrot_exchange_n_n {
- Parrot_binop_x_x s/<op>/xchg/ s/<_N>/_n/ s/INT/NUM/
-}
-
-Parrot_mul_i_i_ic {
- if (MAP[1] && MAP[2]) {
- jit_emit_mul_rir_i(NATIVECODE, MAP[1], *INT_CONST[3], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mul_RIM_ii(NATIVECODE, MAP[1], *INT_CONST[3], ROFFS_INT(2));
- }
- else if (MAP[2]) {
- jit_emit_mul_rir_i(NATIVECODE, ISR1, *INT_CONST[3], MAP[2]);
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
- else {
- jit_emit_mov_RM_i(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_mul_rir_i(NATIVECODE, ISR1, *INT_CONST[3], ISR1);
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_mul_i_ic_i {
- if (MAP[1] && MAP[3]) {
- jit_emit_mul_rir_i(NATIVECODE, MAP[1], *INT_CONST[2], MAP[3]);
- }
- else if (MAP[1]) {
- jit_emit_mul_RIM_ii(NATIVECODE, MAP[1], *INT_CONST[2], ROFFS_INT(3));
- }
- else if (MAP[3]) {
- jit_emit_mul_rir_i(NATIVECODE, ISR1, *INT_CONST[2], MAP[3]);
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
- else {
- jit_emit_mul_RIM_ii(NATIVECODE, ISR1, *INT_CONST[2], ROFFS_INT(3));
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-TEMPLATE Parrot_binop_x_xc {
- if (MAP[1]) {
- jit_emit_<op>_ri<_N>(interp, NATIVECODE, MAP[1], <typ>_CONST[2]);
- }
- else {
-# ifdef jit_emit_<op>_MI_<_N>
- jit_emit_<op>_MI<_N>(NATIVECODE, ROFFS_INT(1), <typ>_CONST[2]);
-# else
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_<op>_ri<_N>(interp, NATIVECODE, ISR1, <typ>_CONST[2]);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1)
-# endif
- }
-}
-
-Parrot_add_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/add/ s/<typ>/*INT/
-}
-
-Parrot_mul_i_ic {
- if (MAP[1]) {
- jit_emit_mul_rir_i(NATIVECODE, MAP[1], *INT_CONST[2], MAP[1]);
- }
- else {
- jit_emit_mul_RIM_ii(NATIVECODE, ISR1, *INT_CONST[2], ROFFS_INT(1));
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_div_i_ic {
- if (MAP[1]) {
- jit_emit_mov_rr_i(NATIVECODE, ISR1, MAP[1]);
- }
- else {
- jit_emit_mov_RM_i(interp, NATIVECODE, ISR1, ROFFS_INT(1));
- }
- jit_emit_div_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- if (MAP[1]) {
- jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR_i(interp,NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_add_n_nc {
- Parrot_binop_x_xc s/<_N>/_n/ s/<op>/add/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_sub_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/sub/ s/<typ>/*INT/
-}
-
-Parrot_bor_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/bor/ s/<typ>/*INT/
-}
-
-Parrot_band_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/band/ s/<typ>/*INT/
-}
-
-Parrot_bxor_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/bxor/ s/<typ>/*INT/
-}
-
-Parrot_shl_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/shl/ s/<typ>/*INT/
-}
-
-Parrot_shr_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/shr/ s/<typ>/*INT/
-}
-
-Parrot_lsr_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/lsr/ s/<typ>/*INT/
-}
-
-Parrot_sub_n_nc {
- Parrot_binop_x_xc s/<_N>/_n/ s/<op>/sub/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_mul_n_nc {
- Parrot_binop_x_xc s/<_N>/_n/ s/<op>/mul/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_div_n_nc {
- Parrot_binop_x_xc s/<_N>/_n/ s/<op>/div/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-TEMPLATE Parrot_binop_i_ic_ic {
- if (MAP[1]) {
- jit_emit_mov_ri_i(interp, NATIVECODE, MAP[1], (INTVAL)((uicast)*INT_CONST[2] <op> *INT_CONST[3]));
- }
- else {
- jit_emit_mov_MI_i(interp, NATIVECODE, ROFFS_INT(1), (INTVAL)((uicast)*INT_CONST[2] <op> *INT_CONST[3]));
- }
-}
-Parrot_mul_i_ic_ic {
- Parrot_binop_i_ic_ic s!<op>!*! s/uicast/INTVAL/
-}
-
-Parrot_add_i_ic_ic {
- Parrot_binop_i_ic_ic s/<op>/+/ s/uicast/INTVAL/
-}
-
-Parrot_sub_i_ic_ic {
- Parrot_binop_i_ic_ic s/<op>/-/ s/uicast/INTVAL/
-}
-
-Parrot_cmod_i_ic_ic {
- Parrot_binop_i_ic_ic s!<op>!%! s/uicast/INTVAL/
-}
-
-Parrot_band_i_ic_ic {
- Parrot_binop_i_ic_ic s/<op>/&/ s/uicast/INTVAL/
-}
-
-Parrot_bor_i_ic_ic {
- Parrot_binop_i_ic_ic s/<op>/|/ s/uicast/INTVAL/
-}
-
-Parrot_bxor_i_ic_ic {
- Parrot_binop_i_ic_ic s/<op>/^/ s/uicast/INTVAL/
-}
-
-Parrot_shl_i_ic_ic {
- Parrot_binop_i_ic_ic s/<op>/<</ s/uicast/INTVAL/
-}
-
-Parrot_shr_i_ic_ic {
- Parrot_binop_i_ic_ic s/<op>/>>/ s/uicast/INTVAL/
-}
-
-Parrot_lsr_i_ic_ic {
- Parrot_binop_i_ic_ic s/<op>/>>/ s/uicast/UINTVAL/
-}
-
-TEMPLATE Parrot_binop_n_nc_nc {
- if (MAP[1]) {
- jit_emit_mov_ri_n(interp, NATIVECODE, MAP[1], &NUM_CONST[2]);
- jit_emit_<op>_ri_n(interp, NATIVECODE, MAP[1], &NUM_CONST[3]);
- }
- else {
- jit_emit_mov_ri_n(interp, NATIVECODE, FSR1, &NUM_CONST[2]);
- jit_emit_<op>_ri_n(interp, NATIVECODE, FSR1, &NUM_CONST[3]);
- jit_emit_mov_MR_n(interp, NATIVECODE, ROFFS_NUM(1), FSR1)
- }
-}
-
-Parrot_add_n_nc_nc {
- Parrot_binop_n_nc_nc s/<op>/add/
-}
-
-Parrot_sub_n_nc_nc {
- Parrot_binop_n_nc_nc s/<op>/sub/
-}
-
-Parrot_mul_n_nc_nc {
- Parrot_binop_n_nc_nc s/<op>/mul/
-}
-
-Parrot_cmod_n_nc_nc {
- Parrot_binop_n_nc_nc s/<op>/cmod/
-}
-
-TEMPLATE Parrot_binop_x_x_xc {
- if (MAP[1] && MAP[2]) {
- if (*CUR_OPCODE == PARROT_OP_add_i_i_ic) {
- emitm_lea_m_r(interp, NATIVECODE, MAP(1), MAP(2), 0, 1, CUR_OPCODE[3]);
- }
- else if (*CUR_OPCODE == PARROT_OP_sub_i_i_ic) {
- emitm_lea_m_r(interp, NATIVECODE, MAP(1), MAP(2), 0, 1, -CUR_OPCODE[3]);
- }
- else {
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
- jit_emit_<op>_ri<_N>(interp, NATIVECODE, MAP[1], <typ>_CONST[3]);
- }
- }
- else if (MAP[1]) {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(2));
- jit_emit_<op>_ri<_N>(interp, NATIVECODE, MAP[1], <typ>_CONST[3]);
- }
- else {
- if (MAP[2]) {
- jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- }
- jit_emit_<op>_ri<_N>(interp, NATIVECODE, ISR1, <typ>_CONST[3]);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1)
- }
-}
-
-TEMPLATE Parrot_divop_x_x_xc {
- if (MAP[2]) {
- jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- }
- jit_emit_<op>_ri<_N>(NATIVECODE, ISR1, <typ>_CONST[3]);
- if (MAP[1]) {
- jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_add_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/add/ s/<typ>/*INT/
-}
-
-Parrot_add_n_n_nc {
- Parrot_binop_x_x_xc s/<_N>/_n/ s/<op>/add/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_sub_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/sub/ s/<typ>/*INT/
-}
-
-Parrot_sub_n_n_nc {
- Parrot_binop_x_x_xc s/<_N>/_n/ s/<op>/sub/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_div_i_i_ic {
- Parrot_divop_x_x_xc s/<_N>/_i/ s/<op>/div/ s/<typ>/*INT/
-}
-
-Parrot_mul_n_n_nc {
- Parrot_binop_x_x_xc s/<_N>/_n/ s/<op>/mul/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_div_n_n_nc {
- Parrot_binop_x_x_xc s/<_N>/_n/ s/<op>/div/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_cmod_i_i_ic {
- Parrot_divop_x_x_xc s/<_N>/_i/ s/<op>/cmod/ s/<typ>/*INT/
-}
-
-Parrot_cmod_n_n_nc {
- Parrot_binop_x_x_xc s/<_N>/_n/ s/<op>/cmod/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_bor_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/bor/ s/<typ>/*INT/
-}
-
-Parrot_bxor_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/bxor/ s/<typ>/*INT/
-}
-
-Parrot_band_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/band/ s/<typ>/*INT/
-}
-
-Parrot_shl_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/shl/ s/<typ>/*INT/
-}
-
-Parrot_shr_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/shr/ s/<typ>/*INT/
-}
-
-Parrot_lsr_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/lsr/ s/<typ>/*INT/
-}
-
-Parrot_rot_i_i_ic_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/rol/ s/<typ>/*INT/
-}
-
-TEMPLATE Parrot_binop_x_xc_x {
- if (MAP[1] && MAP[3]) {
- if (*CUR_OPCODE == PARROT_OP_add_i_ic_i) {
- emitm_lea_m_r(interp, NATIVECODE, MAP(1), MAP(3), 0, 1, CUR_OPCODE[2]);
- }
-#ifdef emitm_f<op>
- else if (*CUR_OPCODE == PARROT_OP_<op>_n_nc_n && *&NUM_CONST[2] == 1.0) {
- emitm_fld1(NATIVECODE);
- emitm_f<op>(NATIVECODE, (MAP[3]+1));
- emitm_fstp(NATIVECODE, (MAP[1]+1));
- }
-#endif
- else {
- if (MAP[1] == MAP[3]) {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, ISR1, <typ>_CONST[2]);
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[3]);
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], ISR1)
- }
- else {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, MAP[1], <typ>_CONST[2]);
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, MAP[1], MAP[3]);
- }
- }
- }
- else if (MAP[1]) {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, MAP[1], <typ>_CONST[2]);
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(3));
- }
- else if (MAP[3]) {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, ISR1, <typ>_CONST[2]);
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[3]);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1)
- }
- else {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, ISR1, <typ>_CONST[2]);
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(3));
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_add_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/add/ s/<typ>/*INT/
-}
-
-Parrot_add_n_nc_n {
- Parrot_binop_x_xc_x s/<_N>/_n/ s/<op>/add/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_sub_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/sub/ s/<typ>/*INT/
-}
-
-Parrot_sub_n_nc_n {
- Parrot_binop_x_xc_x s/<_N>/_n/ s/<op>/sub/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_mul_n_nc_n {
- Parrot_binop_x_xc_x s/<_N>/_n/ s/<op>/mul/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_div_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/div/ s/<typ>/*INT/
-}
-
-Parrot_div_n_nc_n {
- Parrot_binop_x_xc_x s/<_N>/_n/ s/<op>/div/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_cmod_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/cmod/ s/<typ>/*INT/
-}
-
-Parrot_cmod_n_nc_n {
- Parrot_binop_x_xc_x s/<_N>/_n/ s/<op>/cmod/ s/INT/NUM/ s/<typ>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_bor_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/bor/ s/<typ>/*INT/
-}
-
-Parrot_bxor_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/bxor/ s/<typ>/*INT/
-}
-
-Parrot_band_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/band/ s/<typ>/*INT/
-}
-
-Parrot_shl_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/shl/ s/<typ>/*INT/
-}
-
-Parrot_shr_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/shr/ s/<typ>/*INT/
-}
-
-Parrot_lsr_i_ic_i {
- Parrot_binop_x_xc_x s/<_N>/_i/ s/<op>/lsr/ s/<typ>/*INT/
-}
-
-
-
-TEMPLATE Parrot_binop_x_x_x {
- if (MAP[1] && MAP[2] && MAP[3]) {
- if (MAP[1] == MAP[3]) {
- jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[3]);
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, MAP[1], MAP[3]);
- }
- }
- else if (MAP[1] && MAP[2]) {
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(3));
- }
- else if (MAP[1] && MAP[3]) {
- if (MAP[1] == MAP[3]) {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[3]);
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(2));
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, MAP[1], MAP[3]);
- }
- }
- else if (MAP[2] && MAP[3]) {
- jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[3]);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
- else if (MAP[1]) {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(2));
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(3));
- }
- else if (MAP[2]) {
- jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(3));
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
- else if (MAP[3]) {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[3]);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(3));
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-TEMPLATE Parrot_divop_x_x_x {
- if (MAP[2]) {
- jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- }
- if (MAP[3]) {
- jit_emit_<op>_rr<_N>(interp, NATIVECODE, ISR1, MAP[3]);
- }
- else {
- jit_emit_<op>_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(3));
- }
- if (MAP[1]) {
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_mul_i_i_i {
- Parrot_binop_x_x_x s/<op>/mul/ s/<_N>/_i/
-}
-
-Parrot_add_i_i_i {
- Parrot_binop_x_x_x s/<op>/add/ s/<_N>/_i/
-}
-
-Parrot_sub_i_i_i {
- Parrot_binop_x_x_x s/<op>/sub/ s/<_N>/_i/
-}
-
-Parrot_div_i_i_i {
- Parrot_divop_x_x_x s/<op>/div/ s/<_N>/_i/
-}
-
-Parrot_bor_i_i_i {
- Parrot_binop_x_x_x s/<op>/bor/ s/<_N>/_i/
-}
-
-Parrot_bxor_i_i_i {
- Parrot_binop_x_x_x s/<op>/bxor/ s/<_N>/_i/
-}
-
-Parrot_band_i_i_i {
- Parrot_binop_x_x_x s/<op>/band/ s/<_N>/_i/
-}
-
-Parrot_shl_i_i_i {
- Parrot_binop_x_x_x s/<op>/shl/ s/<_N>/_i/
-}
-
-Parrot_shr_i_i_i {
- Parrot_binop_x_x_x s/<op>/shr/ s/<_N>/_i/
-}
-
-Parrot_lsr_i_i_i {
- Parrot_binop_x_x_x s/<op>/lsr/ s/<_N>/_i/
-}
-
-Parrot_cmod_i_i_i {
- Parrot_divop_x_x_x s/<op>/cmod/ s/<_N>/_i/
-}
-
-Parrot_sub_n_n_n {
- Parrot_binop_x_x_x s/<op>/sub/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_add_n_n_n {
- Parrot_binop_x_x_x s/<op>/add/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_mul_n_n_n {
- Parrot_binop_x_x_x s/<op>/mul/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_div_n_n_n {
- Parrot_binop_x_x_x s/<op>/div/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-Parrot_cmod_n_n_n {
- Parrot_binop_x_x_x s/<op>/cmod/ s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/
-}
-
-TEMPLATE unary_x {
- if (MAP[1]) {
- jit_emit_<op>_r<_N>(NATIVECODE, MAP[1]);
- }
- else {
-#ifdef jit_emit_<op>_M<_N>
- jit_emit_<op>_M<_N>(interp, NATIVECODE, ROFFS_INT(1));
-#else
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_<op>_r<_N>(NATIVECODE, ISR1);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
-#endif
- }
-}
-
-Parrot_neg_i {
- unary_x s/<_N>/_i/ s/<op>/neg/
-}
-
-Parrot_neg_n {
- unary_x s/<_N>/_n/ s/INT/NUM/ s/<op>/neg/
-}
-
-
-Parrot_bnot_i {
- unary_x s/<_N>/_i/ s/<op>/not/
-}
-
-Parrot_abs_i {
- unary_x s/<_N>/_i/ s/<op>/abs/
-}
-
-Parrot_abs_n {
- unary_x s/<_N>/_n/ s/INT/NUM/ s/<op>/abs/
-}
-
-TEMPLATE unary_x_x {
- if (MAP[1] && MAP[2]) {
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
- jit_emit_<op>_r<_N>(NATIVECODE, MAP[1]);
- }
- else if (MAP[1]) {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_INT(2));
- jit_emit_<op>_r<_N>(NATIVECODE, MAP[1]);
- }
- else if (MAP[2]) {
- jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
- jit_emit_<op>_r<_N>(NATIVECODE, ISR1);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_<op>_r<_N>(NATIVECODE, ISR1);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_bnot_i_i {
- unary_x_x s/<_N>/_i/ s/<op>/not/
-}
-
-Parrot_neg_i_i {
- unary_x_x s/<_N>/_i/ s/<op>/neg/
-}
-
-Parrot_abs_i_i {
- unary_x_x s/<_N>/_i/ s/<op>/abs/
-}
-Parrot_neg_n_n {
- unary_x_x s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/ s/<op>/neg/
-}
-
-Parrot_abs_n_n {
- unary_x_x s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/ s/<op>/abs/
-}
-
-Parrot_sin_n_n {
- unary_x_x s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/ s/<op>/sin/
-}
-
-Parrot_cos_n_n {
- unary_x_x s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/ s/<op>/cos/
-}
-
-Parrot_sqrt_n_n {
- unary_x_x s/<_N>/_n/ s/ISR/FSR/ s/INT/NUM/ s/<op>/sqrt/
-}
-
-
-TEMPLATE Parrot_ifunless_x_ic {
- if ( P_ARITH && jit_info->prev_op[1] == jit_info->cur_op[1]) {
- jit_emit_jcc(jit_info, <jnz>, *INT_CONST[2]);
- }
- else if (MAP[1]) {
- jit_emit_test_r<_N>(NATIVECODE, MAP[1]);
- jit_emit_jcc(jit_info, <jne>, *INT_CONST[2]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_<t>(1));
- jit_emit_test_r<_N>(NATIVECODE, ISR1);
- jit_emit_jcc(jit_info, <jne>, *INT_CONST[2]);
- }
-}
-
-Parrot_if_i_ic {
- Parrot_ifunless_x_ic s/<jnz>/emitm_jnz/ s/<jne>/emitm_jne/ s/<_N>/_i/ s/<t>/INT/
-}
-
-Parrot_unless_i_ic {
- Parrot_ifunless_x_ic s/<jnz>/emitm_jz/ s/<jne>/emitm_je/ s/<_N>/_i/ s/<t>/INT/
-}
-
-Parrot_if_n_ic {
- Parrot_ifunless_x_ic s/<jnz>/emitm_jnz/ s/<jne>/emitm_jnz/ s/<_N>/_n/ s/<t>/NUM/ s/ISR/FSR/ s/P_ARITH/0/
-}
-
-Parrot_unless_n_ic {
- Parrot_ifunless_x_ic s/<jnz>/emitm_jz/ s/<jne>/emitm_jz/ s/<_N>/_n/ s/<t>/NUM/ s/ISR/FSR/ s/P_ARITH/0/
-}
-
-TEMPLATE Parrot_cmp_x_xc_ic {
- if (MAP[1]) {
- jit_emit_cmp_ri<_N>(interp, NATIVECODE, MAP[1], <c>_CONST[2]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_<t>(1));
- jit_emit_cmp_ri<_N>(interp, NATIVECODE, ISR1, <c>_CONST[2]);
- }
- jit_emit_jcc(jit_info, <je>, *INT_CONST[3]);
-}
-
-Parrot_eq_i_ic_ic {
- Parrot_cmp_x_xc_ic s/<_N>/_i/ s/<je>/emitm_je/ s/<c>/*INT/ s/<t>/INT/
-}
-
-Parrot_eq_n_nc_ic {
- Parrot_cmp_x_xc_ic s/<_N>/_n/ s/<je>/emitm_je/ s/<t>/NUM/ s/<c>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_ne_i_ic_ic {
- Parrot_cmp_x_xc_ic s/<_N>/_i/ s/<je>/emitm_jne/ s/<c>/*INT/ s/<t>/INT/
-}
-
-Parrot_ne_n_nc_ic {
- Parrot_cmp_x_xc_ic s/<_N>/_n/ s/<je>/emitm_jne/ s/<t>/NUM/ s/<c>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_lt_i_ic_ic {
- Parrot_cmp_x_xc_ic s/<_N>/_i/ s/<je>/emitm_jl/ s/<c>/*INT/ s/<t>/INT/
-}
-
-Parrot_lt_n_nc_ic {
- Parrot_cmp_x_xc_ic s/<_N>/_n/ s/<je>/emitm_jb/ s/<t>/NUM/ s/<c>/&NUM/ s/ISR/FSR/
-}
-
-Parrot_le_i_ic_ic {
- Parrot_cmp_x_xc_ic s/<_N>/_i/ s/<je>/emitm_jle/ s/<c>/*INT/ s/<t>/INT/
-}
-
-Parrot_le_n_nc_ic {
- Parrot_cmp_x_xc_ic s/<_N>/_n/ s/<je>/emitm_jbe/ s/<c>/&NUM/ s/ISR/FSR/ s/<t>/NUM/
-}
-
-TEMPLATE Parrot_cmp_xc_x_ic {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, ISR1,<c>_CONST[1]);
- if (MAP[2]) {
- jit_emit_cmp_rr<_N>(NATIVECODE, ISR1, MAP[2]);
- }
- else {
- jit_emit_cmp_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_<t>(2));
- }
- jit_emit_jcc(jit_info, <je>, *INT_CONST[3]);
-}
-
-Parrot_eq_ic_i_ic {
- Parrot_cmp_xc_x_ic s/<_N>/_i/ s/<je>/emitm_je/ s/<c>/*INT/ s/<t>/INT/
-}
-
-Parrot_eq_nc_n_ic {
- Parrot_cmp_xc_x_ic s/<_N>/_n/ s/<je>/emitm_je/ s/<c>/&NUM/ s/ISR/FSR/ s/<t>/NUM/
-}
-
-Parrot_ne_ic_i_ic {
- Parrot_cmp_xc_x_ic s/<_N>/_i/ s/<je>/emitm_jne/ s/<c>/*INT/ s/<t>/INT/
-}
-
-Parrot_ne_nc_n_ic {
- Parrot_cmp_xc_x_ic s/<_N>/_n/ s/<je>/emitm_jne/ s/<c>/&NUM/ s/ISR/FSR/ s/<t>/NUM/
-}
-
-Parrot_lt_ic_i_ic {
- Parrot_cmp_xc_x_ic s/<_N>/_i/ s/<je>/emitm_jl/ s/<c>/*INT/ s/<t>/INT/
-}
-
-Parrot_lt_nc_n_ic {
- Parrot_cmp_xc_x_ic s/<_N>/_n/ s/<je>/emitm_jb/ s/<c>/&NUM/ s/ISR/FSR/ s/<t>/NUM/
-}
-
-Parrot_le_ic_i_ic {
- Parrot_cmp_xc_x_ic s/<_N>/_i/ s/<je>/emitm_jle/ s/<c>/*INT/ s/<t>/INT/
-}
-
-Parrot_le_nc_n_ic {
- Parrot_cmp_xc_x_ic s/<_N>/_n/ s/<je>/emitm_jbe/ s/<c>/&NUM/ s/ISR/FSR/ s/<t>/NUM/
-}
-
-TEMPLATE Parrot_cmp_x_x_ic {
- if (MAP[1] && MAP[2]) {
- jit_emit_cmp_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_cmp_RM<_N>(interp, NATIVECODE, MAP[1], ROFFS_<typ>(2));
- }
- else if (MAP[2]) {
- jit_emit_cmp_MR<_N>(interp, NATIVECODE, ROFFS_<typ>(1), MAP[2]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_<typ>(1));
- jit_emit_cmp_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_<typ>(2));
- }
- jit_emit_jcc(jit_info, <je>, *INT_CONST[3]);
-}
-
-Parrot_eq_i_i_ic {
- Parrot_cmp_x_x_ic s/<_N>/_i/ s/<je>/emitm_je/ s/<typ>/INT/
-}
-
-Parrot_eq_n_n_ic {
- Parrot_cmp_x_x_ic s/<_N>/_n/ s/<je>/emitm_je/ s/<typ>/NUM/ s/ISR/FSR/
-}
-
-Parrot_ne_i_i_ic {
- Parrot_cmp_x_x_ic s/<_N>/_i/ s/<je>/emitm_jne/ s/<typ>/INT/
-}
-
-Parrot_ne_n_n_ic {
- Parrot_cmp_x_x_ic s/<_N>/_n/ s/<je>/emitm_jne/ s/<typ>/NUM/ s/ISR/FSR/
-}
-
-Parrot_lt_i_i_ic {
- Parrot_cmp_x_x_ic s/<_N>/_i/ s/<je>/emitm_jl/ s/<typ>/INT/
-}
-
-Parrot_lt_n_n_ic {
- Parrot_cmp_x_x_ic s/<_N>/_n/ s/<je>/emitm_jb/ s/<typ>/NUM/ s/ISR/FSR/
-}
-
-Parrot_le_i_i_ic {
- Parrot_cmp_x_x_ic s/<_N>/_i/ s/<je>/emitm_jle/ s/<typ>/INT/
-}
-
-Parrot_le_n_n_ic {
- Parrot_cmp_x_x_ic s/<_N>/_n/ s/<je>/emitm_jbe/ s/<typ>/NUM/ s/ISR/FSR/
-}
-
-Parrot_branch_ic {
- emit_jump(jit_info, *INT_CONST[1]);
-}
-
-TEMPLATE Parrot_incdec_x {
- if (MAP[1]) {
- jit_emit_<op>_r<_N>(NATIVECODE, MAP[1]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_<op>_r<_N>(NATIVECODE, ISR1);
- jit_emit_mov_MR<_N>(interp, NATIVECODE, ROFFS_INT(1), ISR1)
- }
-}
-
-Parrot_inc_i {
- Parrot_incdec_x s/<op>/inc/ s/<_N>/_i/
-}
-
-Parrot_dec_i {
- Parrot_incdec_x s/<op>/dec/ s/<_N>/_i/
-}
-
-Parrot_inc_n {
- Parrot_incdec_x s/<op>/inc/ s/<_N>/_n/ s/INT/NUM/ s/ISR/FSR/
-}
-
-Parrot_dec_n {
- Parrot_incdec_x s/<op>/dec/ s/<_N>/_n/ s/INT/NUM/ s/ISR/FSR/
-}
-
-
-; string funcs
-;
-Parrot_set_s_sc {
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_ECX);
- emitm_pushl_i(NATIVECODE, CONST(2)->u.string);
- emitm_pushl_r(NATIVECODE, emit_ECX);
- CALL_FUNCTION(jit_info, Parrot_str_copy);
- emitm_addb_i_r(NATIVECODE, 8, emit_ESP);
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_STR(1), emit_EAX );
-}
-
-TEMPLATE Parrot_cmp_sx_sx_ic {
-# define push_r(i) \
- jit_emit_mov_RM_i(interp, NATIVECODE, emit_EAX, ROFFS_STR(i)); \
- emitm_pushl_r(NATIVECODE, emit_EAX)
-# define push_c(i) emitm_pushl_i(NATIVECODE, CONST(i)->u.string)
-
- push_<typ2>(2);
- push_<typ1>(1);
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_ECX);
- emitm_pushl_r(NATIVECODE, emit_ECX);
- CALL_FUNCTION(jit_info, Parrot_str_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]);
-#undef push_r
-#undef push_c
-}
-
-TEMPLATE Parrot_eq_sx_sx_ic {
-# define push_r(i) \
- jit_emit_mov_RM_i(interp, NATIVECODE, emit_EAX, ROFFS_STR(i)); \
- emitm_pushl_r(NATIVECODE, emit_EAX)
-# define push_c(i) emitm_pushl_i(NATIVECODE, CONST(i)->u.string)
- push_<typ2>(2);
- push_<typ1>(1);
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_ECX);
- emitm_pushl_r(NATIVECODE, emit_ECX);
- CALL_FUNCTION(jit_info, Parrot_str_not_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]);
-#undef push_r
-#undef push_c
-}
-
-Parrot_eq_s_s_ic {
- Parrot_eq_sx_sx_ic s/<typ1>/r/ s/<typ2>/r/ s/<op>/emitm_jz/
-}
-
-Parrot_eq_s_sc_ic {
- Parrot_eq_sx_sx_ic s/<typ1>/r/ s/<typ2>/c/ s/<op>/emitm_jz/
-}
-
-Parrot_eq_sc_s_ic {
- Parrot_eq_sx_sx_ic s/<typ1>/c/ s/<typ2>/r/ s/<op>/emitm_jz/
-}
-
-Parrot_ne_s_s_ic {
- Parrot_eq_sx_sx_ic s/<typ1>/r/ s/<typ2>/r/ s/<op>/emitm_jnz/
-}
-
-Parrot_ne_s_sc_ic {
- Parrot_eq_sx_sx_ic s/<typ1>/r/ s/<typ2>/c/ s/<op>/emitm_jnz/
-}
-
-Parrot_ne_sc_s_ic {
- Parrot_eq_sx_sx_ic s/<typ1>/c/ s/<typ2>/r/ s/<op>/emitm_jnz/
-}
-
-Parrot_le_s_s_ic {
- Parrot_cmp_sx_sx_ic s/<typ1>/r/ s/<typ2>/r/ s/<op>/emitm_jle/
-}
-
-Parrot_le_s_sc_ic {
- Parrot_cmp_sx_sx_ic s/<typ1>/r/ s/<typ2>/c/ s/<op>/emitm_jle/
-}
-
-Parrot_le_sc_s_ic {
- Parrot_cmp_sx_sx_ic s/<typ1>/c/ s/<typ2>/r/ s/<op>/emitm_jle/
-}
-
-Parrot_lt_s_s_ic {
- Parrot_cmp_sx_sx_ic s/<typ1>/r/ s/<typ2>/r/ s/<op>/emitm_jl/
-}
-
-Parrot_lt_s_sc_ic {
- Parrot_cmp_sx_sx_ic s/<typ1>/r/ s/<typ2>/c/ s/<op>/emitm_jl/
-}
-
-Parrot_lt_sc_s_ic {
- Parrot_cmp_sx_sx_ic s/<typ1>/c/ s/<typ2>/r/ s/<op>/emitm_jl/
-}
-
-
-TEMPLATE Parrot_ifunless_sx_ic {
-# define push_r(i) \
- jit_emit_mov_RM_i(interp, NATIVECODE, emit_EAX, ROFFS_STR(i)); \
- emitm_pushl_r(NATIVECODE, emit_EAX)
-# define push_c(i) emitm_pushl_i(NATIVECODE, CONST(i)->u.string)
-
- push_<typ>(1);
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_ECX);
- emitm_pushl_r(NATIVECODE, emit_ECX);
- CALL_FUNCTION(jit_info, Parrot_str_boolean);
- 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]);
-
-#undef push_r
-#undef push_c
-}
-
-
-Parrot_if_s_ic {
- Parrot_ifunless_sx_ic s/<typ>/r/ s/<op>/emitm_jnz/
-}
-
-Parrot_unless_s_ic {
- Parrot_ifunless_sx_ic s/<typ>/r/ s/<op>/emitm_jz/
-}
-
-TEMPLATE Parrot_ord_i_sx {
-# define push_r(i) \
- jit_emit_mov_RM_i(interp, NATIVECODE, emit_EAX, ROFFS_STR(i)); \
- emitm_pushl_r(NATIVECODE, emit_EAX)
-# define push_c(i) emitm_pushl_i(NATIVECODE, CONST(i)->u.string)
-
- emitm_pushl_i(NATIVECODE, 0);
- push_<typ>(2);
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_ECX);
- emitm_pushl_r(NATIVECODE, emit_ECX);
- CALL_FUNCTION(jit_info, string_ord);
- emitm_addb_i_r(NATIVECODE, 12, emit_ESP);
- if (MAP[1]) {
- jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-#undef push_r
-#undef push_c
-}
-
-Parrot_ord_i_s {
- Parrot_ord_i_sx s/<typ>/r/
-}
-
-Parrot_ord_i_sc {
- Parrot_ord_i_sx s/<typ>/c/
-}
-
-TEMPLATE Parrot_ord_i_sx_i {
-# define push_r(i) \
- jit_emit_mov_RM_i(interp, NATIVECODE, emit_EAX, ROFFS_STR(i)); \
- emitm_pushl_r(NATIVECODE, emit_EAX)
-# define push_c(i) emitm_pushl_i(NATIVECODE, CONST(i)->u.string)
-
- if (MAP[3]) {
- emitm_pushl_r(NATIVECODE, MAP[3]);
- }
- else {
- jit_emit_mov_RM_i(interp, NATIVECODE, ISR1, ROFFS_INT(3));
- emitm_pushl_r(NATIVECODE, ISR1);
- }
- push_<typ>(2);
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_EAX);
- emitm_pushl_r(NATIVECODE, emit_EAX);
- CALL_FUNCTION(jit_info, string_ord);
- emitm_addb_i_r(NATIVECODE, 12, emit_ESP);
- if (MAP[1]) {
- jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-#undef push_r
-#undef push_c
-}
-
-Parrot_ord_i_s_i {
- char *L1, *L2, *L3, *L4, *L5, *Lpos, *L3a;
- /*
- * this opcode has a CALL_FUNCTION, so ext_call = -1
- * in src/jit.cpu.c for such ext_call types volatile
- * registers are stored back to Parrot registers: ecx, edx are usable
- */
-
- /*
- * movl $2, %ecx # %ecx := string
- * movl $3, %edx # %edx := offset
- * movl %ecx, %eax # %eax := Parrot_str_byte_length
- * cmpl #0, %ecx
- * je L1
- */
- jit_emit_mov_RM_i(interp, NATIVECODE, emit_ECX, ROFFS_STR(2));
- if (MAP[3]) {
- jit_emit_mov_rr_i(NATIVECODE, emit_EDX, MAP(3));
- }
- else {
- jit_emit_mov_RM_i(interp, NATIVECODE, emit_EDX, ROFFS_INT(3));
- }
- jit_emit_mov_rr_i(NATIVECODE, emit_EAX, emit_ECX);
- jit_emit_cmp_ri_i(interp, NATIVECODE, emit_ECX, 0);
- L1 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jz, 0);
- /*
- * mov (strlen)%ecx, %eax
- */
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_ECX, emit_None, 1,
- offsetof(STRING, strlen));
- /* L1: */
- L1[1] = (char)(NATIVECODE - L1 - 2);
- /*
- * cmpl #0, %eax
- * je L2
- */
- jit_emit_cmp_ri_i(interp, NATIVECODE, emit_EAX, 0);
- L2 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jz, 0);
- /*
- * cmp $edx, 0
- * jge Lpos
- * add %eax, %edx
- * js L3a
- * Lpos:
- * cmp %edx, %eax
- * jge L3
- */
- jit_emit_cmp_ri_i(interp, NATIVECODE, emit_EDX, 0);
- Lpos = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jnl, 0);
- jit_emit_add_rr_i(interp, NATIVECODE, emit_EDX, emit_EAX);
- L3a = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_js, 0);
- /* LPos: */
- Lpos[1] = (char)(NATIVECODE - Lpos - 2);
-
- jit_emit_cmp_rr_i(NATIVECODE, emit_EDX, emit_EAX);
- L3 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jnl, 0);
-
- /*
- * mov (encoding)%ecx, %eax
- * cmp fixed8, %ecx
- * jne L4
- */
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_ECX, emit_None, 1,
- offsetof(STRING, encoding));
- jit_emit_cmp_ri_i(interp, NATIVECODE, emit_EAX, Parrot_fixed_8_encoding_ptr);
- L4 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jnz, 0);
- /*
- * mov (strstart)%ecx, %ecx
- * xor %eax, %eax
- * movb (%ecx + %edx), %eax)
- */
- emitm_movl_m_r(interp, NATIVECODE, emit_ECX, emit_ECX, emit_None, 1,
- offsetof(STRING, strstart));
- jit_emit_bxor_rr_i(interp, NATIVECODE, emit_EAX, emit_EAX);
- emitm_movb_m_r(interp, NATIVECODE, emit_EAX, emit_ECX, emit_EDX, 1, 0);
- /*
- * branch L5
- */
- L5 = NATIVECODE;
- emitm_jumps(NATIVECODE, 0);
-
- L3a[1] = (char)(NATIVECODE - L3a - 2);
- /*
- * L3a:
- */
- jit_emit_sub_rr_i(interp, NATIVECODE, emit_EDX, emit_EAX);
-
- /*
- * L2:
- * L3:
- * L4:
- */
- L2[1] = (char)(NATIVECODE - L2 - 2);
- L3[1] = (char)(NATIVECODE - L3 - 2);
- L4[1] = (char)(NATIVECODE - L4 - 2);
- emitm_pushl_r(NATIVECODE, emit_EDX); /* offs */
- emitm_pushl_r(NATIVECODE, emit_ECX); /* string */
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_EAX);
- emitm_pushl_r(NATIVECODE, emit_EAX); /* interp */
- CALL_FUNCTION(jit_info, string_ord);
- emitm_addb_i_r(NATIVECODE, 12, emit_ESP); /* result in eax */
- /*
- * L5:
- */
- L5[1] = (char)(NATIVECODE - L5 - 2);
- if (MAP[1] && MAP[1] != emit_ECX && MAP[1] != emit_EDX) {
- jit_emit_mov_rr_i(NATIVECODE, MAP[1], emit_EAX);
- }
- else {
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), emit_EAX);
- }
-
-}
-
-Parrot_ord_i_sc_i {
- Parrot_ord_i_sx_i s/<typ>/c/
-}
-
-; the following 4 ops don't branch but are translated as cpfp
-; which adds unneeded overhead - convert to normal ops
-; or just JIT the 2 easy ones
-Parrot_set_args_pc {
- if (jit_info->code_type == JIT_CODE_FILE) {
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_EAX);
- emitm_movl_i_m(NATIVECODE, jit_info->cur_op, emit_EAX, emit_None, 1,
- offsetof(Interp, current_args));
- }
- else {
- jit_set_args_pc(jit_info, interp,
- jit_info->flags & JIT_CODE_RECURSIVE);
- }
-}
-
-extern Parrot_set_returns_pc {
- if (jit_info->code_type == JIT_CODE_FILE)
- Parrot_jit_normal_op(jit_info, interp);
- else {
- jit_set_returns_pc(jit_info, interp,
- jit_info->flags & JIT_CODE_RECURSIVE);
- }
-}
-
-extern Parrot_returncc {
- if (jit_info->code_type == JIT_CODE_FILE)
- Parrot_jit_restart_op(jit_info, interp);
- else {
- /* restore pushed regs if any */
- if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
- jit_restore_regs(jit_info, interp);
- /* no branch ret 0 */
- jit_emit_bxor_rr_i(interp, NATIVECODE, emit_EAX, emit_EAX);
- jit_emit_stack_frame_leave(NATIVECODE);
- }
- emitm_ret(NATIVECODE);
- }
-}
-
-Parrot_pic_callr___pc {
- int offset, here, op_i;
- PMC *sig_params, *sig_result;
- opcode_t *params;
- int skip;
-
- params = jit_info->optimizer->sections->begin;
- sig_params = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), params[1]);
- op_i = 2 + VTABLE_elements(interp, sig_params);
-
- offset = jit_info->arena.op_map[op_i].offset;
- /* TODO preserve necessary regs */
- assert(*CUR_OPCODE == PARROT_OP_get_results_pc);
- sig_result = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
- if (!VTABLE_elements(interp, sig_result))
- skip = -1;
- else
- skip = MAP(2); /* skip result - save rest */
- /* registers are saved in set_args */
-
- here = NATIVECODE - jit_info->arena.start;
- emitm_calll(NATIVECODE, offset - here - 5);
-
- jit_restore_regs_call(jit_info, interp, skip);
-}
-
-extern Parrot_get_params_pc {
- if (jit_info->code_type == JIT_CODE_FILE)
- Parrot_jit_normal_op(jit_info, interp);
- else if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
- jit_get_params_pc(jit_info, interp);
- }
-}
-
-Parrot_get_results_pc {
- if (jit_info->code_type == JIT_CODE_FILE) {
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_EAX);
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EAX, emit_None, 1,
- offsetof(Interp, ctx));
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EAX, emit_None, 1,
- offsetof(PMC, data));
- emitm_movl_i_m(NATIVECODE, jit_info->cur_op, emit_EAX, emit_None, 1,
- offsetof(Parrot_Context, current_results));
- }
- else {
- PMC *sig_result = Parrot_pcc_get_pmc_constant(interp,
- CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
-
- if (!VTABLE_elements(interp, sig_result))
- return;
- if (VTABLE_get_integer_keyed_int(interp, sig_result, 0) ==
- PARROT_ARG_FLOATVAL) {
- /* float result is in ISR1 */
- emitm_fst(NATIVECODE, MAP(2));
- }
- else {
- jit_emit_mov_rr_i(NATIVECODE, MAP(2), emit_EAX);
- }
- }
-}
-; TODO or,and,not,cmp
-
-TEMPLATE iscc_i_x_x {
- if (MAP[2] && MAP[3]) {
- jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], MAP[3]);
- }
- else if (MAP[2]) {
- jit_emit_cmp_RM<_N>(interp, NATIVECODE, MAP[2], ROFFS_<typ>(3));
- }
- else if (MAP[3]) {
- jit_emit_cmp_MR<_N>(interp, NATIVECODE, ROFFS_<typ>(2), MAP[3]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, <scr>, ROFFS_<typ>(2));
- jit_emit_cmp_RM<_N>(interp, NATIVECODE, <scr>, ROFFS_<typ>(3));
- }
- jit_emit_mov_ri_i(interp, NATIVECODE, ISR1, 0);
- jit_emit_setcc_r(NATIVECODE, <cc>, ISR1);
- if (MAP[1]) {
- jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_iseq_i_i_i {
- iscc_i_x_x s/<_N>/_i/ s/<cc>/emitm_je/ s/<typ>/INT/ s/<scr>/ISR1/
-}
-
-Parrot_isne_i_i_i {
- iscc_i_x_x s/<_N>/_i/ s/<cc>/emitm_jne/ s/<typ>/INT/ s/<scr>/ISR1/
-}
-
-Parrot_islt_i_i_i {
- iscc_i_x_x s/<_N>/_i/ s/<cc>/emitm_jl/ s/<typ>/INT/ s/<scr>/ISR1/
-}
-
-Parrot_isle_i_i_i {
- iscc_i_x_x s/<_N>/_i/ s/<cc>/emitm_jle/ s/<typ>/INT/ s/<scr>/ISR1/
-}
-
-Parrot_iseq_i_n_n {
- iscc_i_x_x s/<_N>/_n/ s/<cc>/emitm_je/ s/<typ>/NUM/ s/<scr>/FSR1/
-}
-
-Parrot_isne_i_n_n {
- iscc_i_x_x s/<_N>/_n/ s/<cc>/emitm_jne/ s/<typ>/NUM/ s/<scr>/FSR1/
-}
-
-Parrot_islt_i_n_n {
- iscc_i_x_x s/<_N>/_n/ s/<cc>/emitm_jb/ s/<typ>/NUM/ s/<scr>/FSR1/
-}
-
-Parrot_isle_i_n_n {
- iscc_i_x_x s/<_N>/_n/ s/<cc>/emitm_jbe/ s/<typ>/NUM/ s/<scr>/FSR1/
-}
-
-TEMPLATE iscc_i_x_xc {
- if (MAP[2]) {
- jit_emit_cmp_ri<_N>(interp, NATIVECODE, MAP[2], <c>_CONST[3]);
- }
- else {
- jit_emit_mov_RM<_N>(interp, NATIVECODE, <scr>, ROFFS_<typ>(2));
- jit_emit_cmp_ri<_N>(interp, NATIVECODE, <scr>, <c>_CONST[3]);
- }
- jit_emit_mov_ri_i(interp, NATIVECODE, ISR1, 0);
- jit_emit_setcc_r(NATIVECODE, <cc>, ISR1);
- if (MAP[1]) {
- jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_iseq_i_i_ic {
- iscc_i_x_xc s/<_N>/_i/ s/<cc>/emitm_je/ s/<typ>/INT/ s/<scr>/ISR1/ s/<c>/*INT/
-}
-
-Parrot_isne_i_i_ic {
- iscc_i_x_xc s/<_N>/_i/ s/<cc>/emitm_jne/ s/<typ>/INT/ s/<scr>/ISR1/ s/<c>/*INT/
-}
-
-Parrot_islt_i_i_ic {
- iscc_i_x_xc s/<_N>/_i/ s/<cc>/emitm_jl/ s/<typ>/INT/ s/<scr>/ISR1/ s/<c>/*INT/
-}
-
-Parrot_isle_i_i_ic {
- iscc_i_x_xc s/<_N>/_i/ s/<cc>/emitm_jle/ s/<typ>/INT/ s/<scr>/ISR1/ s/<c>/*INT/
-}
-
-Parrot_iseq_i_n_nc {
- iscc_i_x_xc s/<_N>/_n/ s/<cc>/emitm_je/ s/<typ>/NUM/ s/<scr>/FSR1/ s/<c>/&NUM/
-}
-
-Parrot_isne_i_n_nc {
- iscc_i_x_xc s/<_N>/_n/ s/<cc>/emitm_jne/ s/<typ>/NUM/ s/<scr>/FSR1/ s/<c>/&NUM/
-}
-
-Parrot_islt_i_n_nc {
- iscc_i_x_xc s/<_N>/_n/ s/<cc>/emitm_jb/ s/<typ>/NUM/ s/<scr>/FSR1/ s/<c>/&NUM/
-}
-
-Parrot_isle_i_n_nc {
- iscc_i_x_xc s/<_N>/_n/ s/<cc>/emitm_jbe/ s/<typ>/NUM/ s/<scr>/FSR1/ s/<c>/&NUM/
-}
-
-TEMPLATE iscc_i_xc_x {
- jit_emit_mov_ri<_N>(interp, NATIVECODE, <scr>, <c>_CONST[2]);
- if (MAP[3]) {
- jit_emit_cmp_rr<_N>(NATIVECODE, <scr>, MAP[3]);
- }
- else {
- jit_emit_cmp_RM<_N>(interp, NATIVECODE, <scr>, ROFFS_<typ>(3));
- }
- jit_emit_mov_ri_i(interp, NATIVECODE, ISR1, 0);
- jit_emit_setcc_r(NATIVECODE, <cc>, ISR1);
- if (MAP[1]) {
- jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_MR_i(interp, NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_iseq_i_ic_i {
- iscc_i_xc_x s/<_N>/_i/ s/<cc>/emitm_je/ s/<typ>/INT/ s/<scr>/ISR1/ s/<c>/*INT/
-}
-
-Parrot_isne_i_ic_i {
- iscc_i_xc_x s/<_N>/_i/ s/<cc>/emitm_jne/ s/<typ>/INT/ s/<scr>/ISR1/ s/<c>/*INT/
-}
-
-Parrot_islt_i_ic_i {
- iscc_i_xc_x s/<_N>/_i/ s/<cc>/emitm_jl/ s/<typ>/INT/ s/<scr>/ISR1/ s/<c>/*INT/
-}
-
-Parrot_isle_i_ic_i {
- iscc_i_xc_x s/<_N>/_i/ s/<cc>/emitm_jle/ s/<typ>/INT/ s/<scr>/ISR1/ s/<c>/*INT/
-}
-
-Parrot_iseq_i_nc_n {
- iscc_i_xc_x s/<_N>/_n/ s/<cc>/emitm_je/ s/<typ>/NUM/ s/<scr>/FSR1/ s/<c>/&NUM/
-}
-
-Parrot_isne_i_nc_n {
- iscc_i_xc_x s/<_N>/_n/ s/<cc>/emitm_jne/ s/<typ>/NUM/ s/<scr>/FSR1/ s/<c>/&NUM/
-}
-
-Parrot_islt_i_nc_n {
- iscc_i_xc_x s/<_N>/_n/ s/<cc>/emitm_jb/ s/<typ>/NUM/ s/<scr>/FSR1/ s/<c>/&NUM/
-}
-
-Parrot_isle_i_nc_n {
- iscc_i_xc_x s/<_N>/_n/ s/<cc>/emitm_jbe/ s/<typ>/NUM/ s/<scr>/FSR1/ s/<c>/&NUM/
-}
-
-;
-; TODO check alignment, and maybe move 1 msk into reg
-;
-Parrot_pow_n_n_i {
- int saved = 0;
- char *L1, *L2, *L3, *L4, *L5, *L6;
-
- emitm_fld1(NATIVECODE); /* res = 1.0 ST(1) */
- if (MAP[3]) {
- jit_emit_mov_rr_i(NATIVECODE, emit_EAX, MAP[3]);
- }
- else {
- jit_emit_mov_RM_i(interp, NATIVECODE, emit_EAX, ROFFS_INT(3));
- }
- jit_emit_test_r_i(NATIVECODE, emit_EAX); /* e == 0? */
- L1 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jz, 0); /* jz L1 */
- if (MAP[2]) {
- emitm_fld(NATIVECODE, (MAP[2] + 1));
- }
- else {
- jit_emit_fload_mb_n(interp, NATIVECODE, emit_EBX, ROFFS_NUM(2));
- } /* n2 = $2 ST(0) */
- if (intreg_is_used(jit_info, emit_ECX)) {
- emitm_pushl_r(NATIVECODE, emit_ECX);
- saved = 1;
- }
- jit_emit_mov_ri_i(interp, NATIVECODE, emit_ECX, 1); /* s = 1 */
- L2 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jg, 0); /* jg L2 */
- jit_emit_neg_r_i(NATIVECODE, emit_ECX); /* s = -1 */
- jit_emit_neg_r_i(NATIVECODE, emit_EAX); /* e = -e */
- L2[1] = NATIVECODE - L2 - 2;
- /* L2: */
- /* while (e) */
- jit_emit_test_r_i(NATIVECODE, emit_EAX); /* e == 0? */
- L4 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jz, 0); /* jz L4 */
- L3 = NATIVECODE;
- /* L3: */
- jit_emit_test_ri_i(NATIVECODE, emit_EAX, 1); /* e & 1 ? */
- L5 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jz, 0); /* jz L5 */
- jit_emit_mul_rr_n(interp, NATIVECODE, 1, 0); /* res *= n2 */
- /* L5: */
- L5[1] = (char)(NATIVECODE - L5 - 2);
- jit_emit_lsr_ri_i(interp, NATIVECODE, emit_EAX, 1); /* e >>= 1 */
- jit_emit_mul_rr_n(interp, NATIVECODE, 0, 0); /* n2 *= n2 */
- /* lsr is setting flags - branch past test at L3 */
- emitm_jxs(NATIVECODE, emitm_jnz, (L3 - NATIVECODE - 1)); /* jmp L3 */
- /* endwhile */
- L4[1] = (char)(NATIVECODE - L4 - 2);
- /* L4: */
- jit_emit_test_r_i(NATIVECODE, emit_ECX); /* s ? */
- L6 = NATIVECODE;
- emitm_jxs(NATIVECODE, emitm_jg, 0); /* jg L6 */
- emitm_fld1(NATIVECODE); /* push 1.0 */
- emitm_fxch(NATIVECODE, 2);
- emitm_fdivp(NATIVECODE, 2); /* res = 1.0/res */
- L6[1] = (char)(NATIVECODE - L6 - 2);
- /* L6: */
- emitm_fstp(NATIVECODE, 0); /* pop n2 */
- L1[1] = (char)(NATIVECODE - L1 - 2);
- /* L1: */
- if (MAP[1]) {
- emitm_fstp(NATIVECODE, (MAP[1] + 1)); /* store res */
- }
- else {
- jit_emit_fstore_m_n(interp, NATIVECODE, ROFFS_NUM(1));
- }
- if (saved)
- emitm_popl_r(NATIVECODE, emit_ECX);
-}
-
-/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/i386/exec_dep.c
==============================================================================
--- trunk/src/jit/i386/exec_dep.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2003-2009, Parrot Foundation.
- */
-
-/*
- * exec_dep.c
- *
- * SVN Info
- * $Id$
- * Overview:
- * i386 dependent functions to emit an executable.
- * History:
- * Initial version by Daniel Grunblatt on 2003.6.9
- * Notes:
- * References:
- */
-
-#include "parrot/parrot.h"
-#include "jit.h"
-#define JIT_EMIT 1
-#include "jit_emit.h"
-#include "exec_dep.h"
-
-/* HEADERIZER HFILE: src/jit/i386/exec_dep.h */
-
-#ifdef JIT_CGP
-
-void
-Parrot_exec_normal_op(ARGIN(Parrot_jit_info_t *jit_info), PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_exec_normal_op)
- Parrot_jit_optimizer_section_ptr cur_section =
- jit_info->optimizer->cur_section;
- int i, j, last_is_branch = 0;
- void ** offset;
-
- assert(op_jit[*jit_info->cur_op].extcall == 1);
- if (cur_section->done == 1)
- return;
- else if (cur_section->done == -1 && --cur_section->ins_count > 0)
- return;
-
- /* check where section ends */
- if (interp->op_info_table[*cur_section->end].jump)
- last_is_branch = 1;
- else if (cur_section->next && !cur_section->next->isjit)
- last_is_branch = 1;
-
- /* if more then 1 op, then jump to CGP, branches are never
- * executed in CGP, they are handled below */
- if (cur_section->done >= 0
- && (INTVAL)cur_section->op_count >= 2 + last_is_branch) {
- int saved = 0;
- offset = (void **)((int)jit_info->cur_op -
- (int)interp->code->base.data);
-
- jit_emit_mov_ri_i(jit_info->native_ptr, emit_ESI, offset);
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_COM, "exec_prederef_code", -4);
-
- emitm_callm(jit_info->native_ptr, emit_ESI, 0, 0, 0);
-
- /* now patch a B<cpu_ret> opcode after the end of the
- * prederefed (non JIT) section */
- if (last_is_branch) {
- offset = (cur_section->end - interp->code->base.data) +
- interp->code->prederef.code;
- cur_section->done = -1;
-
- /* ins to skip */
- cur_section->ins_count = cur_section->op_count - 1;
- }
- else {
- /* There must be a next section: either we have a B<end>
- * or a JITed branch,
- * when the branch is non JIT, we are in the above case
- */
- offset = (cur_section->next->begin - interp->code->base.data)
- + interp->code->prederef.code;
- cur_section->done = 1;
- }
-
- i = (int)(((op_func_t*)interp->op_lib->op_func_table)[PARROT_OP_cpu_ret]);
- j = (int)cgp_core;
-
- *offset = (void *)(i - j);
- }
- else {
-
- /* else call normal funtion */
- emitm_pushl_i(jit_info->native_ptr, 0x0);
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_COM, "interpre", -4);
- emitm_pushl_i(jit_info->native_ptr,
- jit_info->objfile->bytecode_header_size +
- jit_info->op_i * sizeof (opcode_t));
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_DATA, "program_code", -4);
-
- Parrot_exec_add_text_rellocation_func(jit_info->objfile,
- jit_info->native_ptr,
- interp->op_info_table[*jit_info->cur_op].func_name);
- emitm_calll(jit_info->native_ptr, EXEC_CALLDISP);
- emitm_addb_i_r(jit_info->native_ptr, 8, emit_ESP);
-
- /* when this was a branch, then EAX is now the offset
- * in the byte_code */
- }
-}
-
-#else /* JIT_CGP */
-
-void
-Parrot_exec_normal_op(ARGIN(Parrot_jit_info_t *jit_info),
- PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_exec_normal_op)
- emitm_pushl_i(jit_info->native_ptr,
- jit_info->objfile->bytecode_header_size +
- jit_info->op_i * sizeof (opcode_t));
- Parrot_exec_add_text_rellocation(jit_info->objfile, jit_info->native_ptr,
- RTYPE_DATA, "program_code", -4);
-
- Parrot_exec_add_text_rellocation_func(jit_info->objfile,
- jit_info->native_ptr,
- interp->op_info_table[*jit_info->cur_op].func_name);
- emitm_calll(jit_info->native_ptr, EXEC_CALLDISP);
- emitm_addb_i_r(jit_info->native_ptr, 4, emit_ESP);
-}
-
-#endif /* JIT_CGP */
-
-void
-Parrot_exec_cpcf_op(ARGIN(Parrot_jit_info_t *jit_info),
- PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_exec_cpcf_op)
- Parrot_exec_normal_op(jit_info, interp);
- Parrot_emit_jump_to_eax(jit_info, interp);
-}
-
-void
-Parrot_exec_restart_op(ARGIN(Parrot_jit_info_t *jit_info),
- PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_exec_restart_op)
- char *jmp_ptr, *sav_ptr;
-
- Parrot_exec_normal_op(jit_info, interp);
-
- /* test eax, if zero (e.g after trace), return from JIT */
- jit_emit_test_r_i(jit_info->native_ptr, emit_EAX);
-
- /* remember PC */
- jmp_ptr = jit_info->native_ptr;
-
- /* emit jump past exit code, dummy offset
- * this assumes exit code is not longer then a short jump (126 bytes) */
- emitm_jxs(jit_info->native_ptr, emitm_jnz, 0);
- exec_emit_end(jit_info->native_ptr);
-
- /* fixup above jump */
- sav_ptr = jit_info->native_ptr;
- jit_info->native_ptr = jmp_ptr;
- emitm_jxs(jit_info->native_ptr, emitm_jnz, (long)(sav_ptr - jmp_ptr) - 2);
-
- /* restore PC */
- jit_info->native_ptr = sav_ptr;
- Parrot_emit_jump_to_eax(jit_info, interp);
-}
-
-/* Assign the offset of the program_code */
-void
-offset_fixup(ARGIN(Parrot_exec_objfile_t *obj))
-{
- ASSERT_ARGS(offset_fixup)
- int i;
-
- for (i = 0; i < obj->data_count; i++) {
- int j;
-#ifdef EXEC_A_OUT
- obj->symbol_table[i].value = obj->text.size;
-#endif
- for (j = 0; j < i; j++)
- obj->symbol_table[i].value += obj->data_size[j];
- }
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/i386/exec_dep.h
==============================================================================
--- trunk/src/jit/i386/exec_dep.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,72 +0,0 @@
-/*
- Copyright (C) 2003-2008, Parrot Foundation.
- $Id$
-*/
-
-/*
- * exec_dep.h
- *
- * Overview:
- * i386 dependent functions to emit an executable.
- * History:
- * Initial version by Daniel Grunblatt on 2003.6.9
- * Notes:
- * References:
- */
-
-#ifndef PARROT_I386_EXEC_DEP_H_GUARD
-#define PARROT_I386_EXEC_DEP_H_GUARD
-
-/* HEADERIZER BEGIN: src/exec_dep.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-
-void offset_fixup(ARGIN(Parrot_exec_objfile_t *obj))
- __attribute__nonnull__(1);
-
-void Parrot_exec_cpcf_op(ARGIN(Parrot_jit_info_t *jit_info), PARROT_INTERP)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-void Parrot_exec_normal_op(
- ARGIN(Parrot_jit_info_t *jit_info),
- PARROT_INTERP)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-void Parrot_exec_normal_op(
- ARGIN(Parrot_jit_info_t *jit_info),
- PARROT_INTERP)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-void Parrot_exec_restart_op(
- ARGIN(Parrot_jit_info_t *jit_info),
- PARROT_INTERP)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-#define ASSERT_ARGS_offset_fixup __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(obj)
-#define ASSERT_ARGS_Parrot_exec_cpcf_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(jit_info) \
- || PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_exec_normal_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(jit_info) \
- || PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_exec_normal_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(jit_info) \
- || PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_exec_restart_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(jit_info) \
- || PARROT_ASSERT_ARG(interp)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-/* HEADERIZER END: src/exec_dep.c */
-
-#endif /* PARROT_I386_EXEC_DEP_H_GUARD */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/i386/jit_defs.c
==============================================================================
--- trunk/src/jit/i386/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,2497 +0,0 @@
-/*
-Copyright (C) 2008-2009, Parrot Foundation.
-$Id$
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include <assert.h>
-#include "parrot/parrot.h"
-#include "parrot/hash.h"
-#include "parrot/oplib/ops.h"
-#include "pmc/pmc_fixedintegerarray.h"
-#include "pmc/pmc_unmanagedstruct.h"
-#include "pmc/pmc_pointer.h"
-#include "jit.h"
-#include "jit_emit.h"
-
-INTVAL
-get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_int(st->val);
-}
-
-FLOATVAL
-get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_num(st->val);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-STRING*
-get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- /* TODO or act like below? */
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_str(st->val);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC*
-get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- /*
- * excessive args are passed as NULL
- * used by e.g. MMD infix like __add
- */
- if (n < st->src.n)
- Parrot_fetch_arg_nci(interp, st);
- else
- UVal_pmc(st->val) = PMCNULL;
-
- return UVal_pmc(st->val);
-}
-
-/*
- * set return value
- */
-void
-set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val)
-{
- Parrot_init_ret_nci(interp, st, "I");
- if (st->dest.i < st->dest.n) {
- UVal_int(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-void
-set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val)
-{
- Parrot_init_ret_nci(interp, st, "N");
- if (st->dest.i < st->dest.n) {
- UVal_num(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-void
-set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val)
-{
- Parrot_init_ret_nci(interp, st, "S");
- if (st->dest.i < st->dest.n) {
- UVal_str(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-void
-set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val)
-{
- Parrot_init_ret_nci(interp, st, "P");
- if (st->dest.i < st->dest.n) {
- UVal_pmc(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-int
-emit_is8bit(long disp)
-{
- return disp >= -128 && disp <= 127;
-}
-
-char *
-emit_disp8_32(char *pc, int disp)
-{
- if (emit_is8bit(disp)) {
- *(pc++) = (char)disp;
- return pc;
- }
- else {
- *(long *)pc = disp;
- return pc + 4;
- }
-}
-
-void
-emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base)
-{
- int scale_byte;
-
- switch (scale) {
- case 1:
- scale_byte = emit_Scale_1;
- break;
- case 2:
- scale_byte = emit_Scale_2;
- break;
- case 4:
- scale_byte = emit_Scale_4;
- break;
- case 8:
- scale_byte = emit_Scale_8;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Invalid scale factor %d\n", scale);
- return;
- }
-
- *pc = (char)(scale_byte | (i == emit_None ? emit_Index_None : emit_reg_Index(i)) |
- emit_reg_Base(base));
-}
-
-char *
-emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i, int scale, long disp)
-{
- if (i && !scale)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "emit_r_X passed invalid scale+index combo\n");
-
- if (base == emit_EBP) {
- /* modrm disp */
- if (i == emit_None) {
- *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
- | reg_opcode | emit_reg_rm(emit_EBP));
- return emit_disp8_32(pc, disp);
- }
- /* modrm sib disp */
- else {
- *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
- | reg_opcode | emit_b100);
- emit_sib(interp, pc++, scale, i, base);
- return emit_disp8_32(pc, disp);
- }
- }
-
- /* modrm sib disp */
- if (base == emit_ESP) {
- *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10)
- | reg_opcode | emit_rm_b100);
- emit_sib(interp, pc++, scale, i, emit_ESP);
- return emit_disp8_32(pc, disp);
- }
-
- /* modrm disp32 */
- if (!base && !(i && scale)) {
- *(pc++) = (char)(emit_Mod_b00 | reg_opcode | emit_rm_b101);
- *(long *)pc = disp;
- return pc + 4;
- }
-
- /* Ok, everything should be more regular here */
- *(pc++) = (char)((disp == 0 ? emit_Mod_b00 :
- (emit_is8bit(disp) ?
- emit_Mod_b01 : emit_Mod_b10)) |
- reg_opcode |
- (!base || (scale && i) ? emit_rm_b100 : emit_reg_rm(base)));
-
- if (!base || (scale && i)) {
- emit_sib(interp, pc++, scale, i, base);
- }
- if (disp)
- pc = emit_disp8_32(pc, disp);
-
- return pc;
-}
-
-char *
-emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg)
-{
- if (opcode == emit_b000 && imm < 0) {
- opcode = emit_b001; /* -rol => 32 + ror */
- imm = -imm;
- }
-
- if (imm == 0) {
- /* noop */
- }
- else if (imm == 1) {
- *(pc++) = (char) 0xd1;
- *(pc++) = (char) emit_alu_X_r(opcode, reg);
- }
- else if (imm > 1 && imm < 33) {
- *(pc++) = (char) 0xc1;
- *(pc++) = (char) emit_alu_X_r(opcode, reg);
- *(pc++) = (char)imm;
- }
- else {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "emit_shift_i_r passed invalid shift\n");
- }
-
- return pc;
-}
-
-char *
-emit_shift_i_m(PARROT_INTERP, char *pc, int opcode, int imm,
- int base, int i, int scale, long disp)
-{
- if (imm == 0) {
- /* noop */
- }
- else if (imm == 1) {
- *(pc++) = (char) 0xd1;
- pc = emit_r_X(interp, pc, opcode, base, i, scale, disp);
- }
- else if (imm > 1 && imm < 33) {
- *(pc++) = (char) 0xc1;
- pc = emit_r_X(interp, pc, opcode, base, i, scale, disp);
- *(pc++) = (char)imm;
- }
- else {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "emit_shift_i_m passed invalid shift\n");
- }
-
- return pc;
-}
-
-char *
-emit_shift_r_r(PARROT_INTERP, char *pc, int opcode, int reg1, int reg2)
-{
- if (reg1 != emit_ECX)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "emit_shift_r_r passed invalid register\n");
-
- *(pc++) = (char) 0xd3;
- *(pc++) = (char) emit_alu_X_r(opcode, reg2);
-
- return pc;
-}
-
-char *
-emit_shift_r_m(PARROT_INTERP, char *pc, int opcode, int reg,
- int base, int i, int scale, long disp)
-{
- if (reg != emit_ECX)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "emit_shift_r_m passed invalid register\n");
-
- *(pc++) = (char) 0xd3;
- pc = emit_r_X(interp, pc, opcode, base, i, scale, disp);
-
- return pc;
-}
-
-char *
-emit_pushl_m(PARROT_INTERP, char *pc, int base, int i, int scale, long disp)
-{
- *(pc++) = (char) 0xff;
- return emit_r_X(interp, pc, emit_reg(emit_b110), base, i, scale, disp);
-}
-
-char *
-emit_popl_r(char *pc, int reg)
-{
- *(pc++) = (char)(0x58 | (reg - 1));
- return pc;
-}
-
-char *
-emit_popl_m(PARROT_INTERP, char *pc, int base, int i, int scale, long disp)
-{
- *(pc++) = (char) 0x8f;
- return emit_r_X(interp, pc, emit_reg(emit_b000), base, i, scale, disp);
-}
-
-char *
-emit_movb_r_r(char *pc, int reg1, int reg2)
-{
- *(pc++) = (char) 0x88;
- *(pc++) = (char) emit_alu_r_r(reg1, reg2);
- return pc;
-}
-
-char *
-emit_movb_i_r(char *pc, char imm, int reg)
-{
- *(pc++) = (char)(0xb0 | (reg - 1));
- *(pc++) = imm;
- return pc;
-}
-
-char *
-emit_movb_i_m(PARROT_INTERP, char *pc, char imm, int base, int i, int scale, long disp)
-{
- *(pc++) = (char) 0xc6;
- pc = emit_r_X(interp, pc, emit_reg(emit_b000), base, i, scale, disp);
- *(pc++) = imm;
- return pc;
-}
-
-char *
-opt_mul(PARROT_INTERP, char *pc, int dest, INTVAL imm, int src)
-{
- UINTVAL ld2 = ld((UINTVAL) imm);
-
- if (imm == 0) {
- jit_emit_mov_ri_i(interp, pc, dest, 0);
- }
- else if (imm > 0 && !(imm & (imm - 1))) {
- /* positive power of 2 - do a shift */
- jit_emit_mov_rr_i(pc, dest, src);
- pc = emit_shift_i_r(interp, pc, emit_b100, ld2, dest);
- }
- else {
- /* special small numbers */
- switch (imm) {
- case 3:
- /* LEA dest, base, index, scale, displace
- * note: src may be dest, so can't be reused
- *
- * dest = src + src*2 */
- emitm_lea_m_r(interp, pc, dest, src, src, 2, 0);
- break;
- case 5: /* dest = src + src*4 */
- emitm_lea_m_r(interp, pc, dest, src, src, 4, 0);
- break;
- case 6: /* dest = src*3; dest += dest */
- emitm_lea_m_r(interp, pc, dest, src, src, 2, 0);
- jit_emit_add_rr_i(interp, pc, dest, dest);
- break;
- case 9: /* dest = src + src*8 */
- emitm_lea_m_r(interp, pc, dest, src, src, 8, 0);
- break;
- case 10: /* dest = src + src*4 ; dest+= dest */
- emitm_lea_m_r(interp, pc, dest, src, src, 4, 0);
- jit_emit_add_rr_i(interp, pc, dest, dest);
- break;
- case 12: /* dest= src*3; dest <<= 2 */
- emitm_lea_m_r(interp, pc, dest, src, src, 2, 0);
- pc = emit_shift_i_r(interp, pc, emit_b100, 2, dest);
- break;
- case 100: /* dest = src + src*4 ; dest <<= 2; dest = 5*dest*/
- emitm_lea_m_r(interp, pc, dest, src, src, 4, 0);
- pc = emit_shift_i_r(interp, pc, emit_b100, 2, dest);
- emitm_lea_m_r(interp, pc, dest, dest, dest, 4, 0);
- break;
- default:
- emitm_alul_r_r(pc, 0x69, dest, src);
- *(long *)(pc) = (long)imm;
- pc += 4;
- }
- }
- return pc;
-}
-
-int
-intreg_is_used(Parrot_jit_info_t *jit_info, char reg)
-{
- int i;
- const jit_arch_regs *reg_info;
- Parrot_jit_register_usage_t *ru = jit_info->optimizer->cur_section->ru;
-
- reg_info = jit_info->arch_info->regs + jit_info->code_type;
-
- for (i = 0; i < ru[0].registers_used; ++i) {
- if (reg_info->map_I[i] == reg) {
- return 1;
- }
- }
- return 0;
-}
-
-char *
-opt_shift_rr(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest, int count, int op)
-{
- char *pc = jit_info->native_ptr;
- if (count == emit_ECX) {
- pc = emit_shift_r_r(interp, pc, op, count, dest);
- }
- else {
- int saved = 0;
- PARROT_ASSERT(count != emit_EAX);
- if (dest == emit_EAX) {
- if (intreg_is_used(jit_info, emit_ECX)) {
- emitm_pushl_r(pc, emit_ECX);
- saved = 1;
- }
- jit_emit_mov_rr_i(pc, emit_ECX, count);
- pc = emit_shift_r_r(interp, pc, op, emit_ECX, dest);
- if (saved) {
- emitm_popl_r(pc, emit_ECX);
- }
-
- }
- else if (dest == emit_ECX) {
- jit_emit_xchg_rr_i(interp, pc, dest, count);
- pc = emit_shift_r_r(interp, pc, op, dest, count);
- jit_emit_xchg_rr_i(interp, pc, dest, count);
- }
- else {
- jit_emit_mov_rr_i(pc, emit_EAX, emit_ECX);
- jit_emit_mov_rr_i(pc, emit_ECX, count);
- pc = emit_shift_r_r(interp, pc, op, emit_ECX, dest);
- jit_emit_mov_rr_i(pc, emit_ECX, emit_EAX);
- }
- }
- return pc;
-}
-
-char *
-opt_shift_rm(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest, int offs, int op)
-{
- char *pc = jit_info->native_ptr;
- int saved = 0;
- /* if ECX is mapped, save it */
- if (dest != emit_ECX && intreg_is_used(jit_info, emit_ECX)) {
- emitm_pushl_r(pc, emit_ECX);
- saved = 1;
- }
- if (dest == emit_ECX) {
- /* jit_emit_mov_RM_i(pc, emit_EAX, count); */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBX, emit_None, 1, offs);
- jit_emit_xchg_rr_i(interp, pc, dest, emit_EAX);
- pc = emit_shift_r_r(interp, pc, op, emit_ECX, emit_EAX);
- jit_emit_xchg_rr_i(interp, pc, dest, emit_EAX);
- }
- else {
- /* jit_emit_mov_RM_i(pc, emit_ECX, count); */
- emitm_movl_m_r(interp, pc, emit_ECX, emit_EBX, emit_None, 1, offs);
- pc = emit_shift_r_r(interp, pc, op, emit_ECX, dest);
- }
- if (saved) {
- emitm_popl_r(pc, emit_ECX);
- }
- return pc;
-}
-
-void call_func(Parrot_jit_info_t *jit_info, void (*addr) (void))
-{
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_X86CALL;
- jit_info->arena.fixups->param.fptr = D2FPTR(addr);
- emitm_calll(jit_info->native_ptr, 0xdeafc0de);
-}
-
-void jit_emit_real_exception(Parrot_jit_info_t *jit_info)
-{
- call_func(jit_info, (void (*) (void)) & Parrot_ex_throw_from_c_args);
-}
-
-unsigned char *lastpc;
-
-/* ST(r1) /= ST(r2) */
-char *
-div_rr_n(PARROT_INTERP, Parrot_jit_info_t *jit_info, int r1)
-{
- char *L1;
- static const char div_by_zero[] = "Divide by zero";
- char *pc = jit_info->native_ptr;
-
- jit_emit_test_r_n(pc, (char)0); /* TOS */
- L1 = pc;
- emitm_jxs(pc, emitm_jnz, 0);
- emitm_pushl_i(pc, div_by_zero);
- emitm_pushl_i(pc, EXCEPTION_DIV_BY_ZERO);
- emitm_pushl_i(pc, 0); /* NULL */
- Parrot_jit_emit_get_INTERP(interp, pc, emit_ECX);
- emitm_pushl_r(pc, emit_ECX);
- jit_info->native_ptr = pc;
- jit_emit_real_exception(jit_info);
- pc = jit_info->native_ptr;
- /* L1: */
- L1[1] = (char)(pc - L1 - 2);
- emitm_fdivp(pc, (r1+1));
- return pc;
-}
-
-char *
-mod_rr_n(PARROT_INTERP, Parrot_jit_info_t *jit_info, int r)
-{
- char *L1;
- static const char div_by_zero[] = "Divide by zero";
- char *pc = jit_info->native_ptr;
-
- jit_emit_test_r_n(pc, (char)0); /* TOS */
- L1 = pc;
- emitm_jxs(pc, emitm_jnz, 0);
- emitm_pushl_i(pc, div_by_zero);
- emitm_pushl_i(pc, EXCEPTION_DIV_BY_ZERO);
- emitm_pushl_i(pc, 0); /* NULL */
- Parrot_jit_emit_get_INTERP(interp, pc, emit_ECX);
- emitm_pushl_r(pc, emit_ECX);
- jit_info->native_ptr = pc;
- jit_emit_real_exception(jit_info);
- pc = jit_info->native_ptr;
- /* L1: */
- L1[1] = (char)(pc - L1 - 2);
- /* L2: */
- emitm_fxch(pc, (char)1);
- emitm_fprem(pc);
- emitm_fstw(pc);
- emitm_sahf(pc);
- emitm_jxs(pc, emitm_jp, -7); /* jo L2 */
- emitm_fstp(pc, (r+1));
- return pc;
-}
-
-/* dest /= src
- * edx:eax /= src, quotient => eax, rem => edx
- */
-char *
-opt_div_rr(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest, int src, int is_div)
-{
- char *pc = jit_info->native_ptr;
- int saved = 0;
- int div_ecx = 0;
- char *L1, *L2, *L3;
- static const char div_by_zero[] = "Divide by zero";
-
- PARROT_ASSERT(src != emit_EAX);
-
- if (dest != emit_EAX) {
- jit_emit_mov_rr_i(pc, emit_EAX, dest);
- }
- if (dest == emit_EDX) {
- /* all ok, we can globber it */
- }
- else {
- /* if ECX is not mapped use it */
- if (!intreg_is_used(jit_info, emit_ECX) && src == emit_EDX) {
- jit_emit_mov_rr_i(pc, emit_ECX, emit_EDX);
- div_ecx = 1;
- }
- else
- /* if EDX is mapped, preserve EDX on stack */
- if (intreg_is_used(jit_info, emit_EDX)) {
- emitm_pushl_r(pc, emit_EDX);
- saved = 1;
- /* if EDX is the src, we need another temp register: ECX */
- if (src == emit_EDX) {
- /* if ECX is mapped save it, but not if it's dest */
- if (intreg_is_used(jit_info, emit_ECX) &&
- dest != emit_ECX) {
- emitm_pushl_r(pc, emit_ECX);
- saved = 2;
- }
- /* else just use it */
- jit_emit_mov_rr_i(pc, emit_ECX, emit_EDX);
- div_ecx = 1;
- }
- }
- }
- /* this sequence allows 2 other instructions to run parallel */
- if (dest != emit_EDX) {
- jit_emit_mov_rr_i(pc, emit_EDX, emit_EAX);
- }
- pc = emit_shift_i_r(interp, pc, emit_b111, 31, emit_EDX); /* SAR 31 */
- if (div_ecx) {
- jit_emit_test_r_i(pc, emit_ECX);
- L1 = pc;
- emitm_jxs(pc, emitm_jz, 0);
- emitm_sdivl_r(pc, emit_ECX);
- L3 = pc;
- emitm_jumps(pc, 0);
- /* L1: */
- L1[1] = (char)(pc - L1 - 2);
- }
- else {
- jit_emit_test_r_i(pc, src);
- L2 = pc;
- emitm_jxs(pc, emitm_jz, 0);
- emitm_sdivl_r(pc, src);
- L3 = pc;
- emitm_jumps(pc, 0);
- /* L2: */
- L2[1] = (char)(pc - L2 - 2);
- }
- /* TODO Parrot_ex_throw_from_c_args */
- emitm_pushl_i(pc, div_by_zero);
- emitm_pushl_i(pc, EXCEPTION_DIV_BY_ZERO);
- emitm_pushl_i(pc, 0); /* NULL */
- Parrot_jit_emit_get_INTERP(interp, pc, emit_ECX);
- emitm_pushl_r(pc, emit_ECX);
- jit_info->native_ptr = pc;
- jit_emit_real_exception(jit_info);
- pc = jit_info->native_ptr;
- /* L3: */
- L3[1] = (char)(pc - L3 - 2);
- if (saved == 2) {
- emitm_popl_r(pc, emit_ECX);
- }
- if (is_div) {
- /* result = quotient in EAX */
- if (saved) {
- emitm_popl_r(pc, emit_EDX);
- }
- if (dest != emit_EAX) {
- jit_emit_mov_rr_i(pc, dest, emit_EAX);
- }
- }
- else {
- /* result = remainder in EDX */
- if (saved) {
- emitm_popl_r(pc, emit_EAX);
- jit_emit_mov_rr_i(pc, dest, emit_EDX);
- jit_emit_mov_rr_i(pc, emit_EDX, emit_EAX);
- }
- else {
- if (dest != emit_EDX)
- jit_emit_mov_rr_i(pc, dest, emit_EDX);
- }
- }
- if (!saved && div_ecx) {
- /* restore EDX */
- jit_emit_mov_rr_i(pc, emit_EDX, emit_ECX);
- }
- return pc;
-}
-
-char *
-opt_div_ri(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest, INTVAL imm, int is_div)
-{
- char *pc = jit_info->native_ptr;
-
- UINTVAL ld2 = ld((UINTVAL) imm);
- if (is_div && imm > 1 && !(imm & (imm - 1))) {
- /* positive power of 2 - do a shift */
- pc = emit_shift_i_r(interp, pc, emit_b101, ld2, dest);
- }
- else {
- if (dest != emit_EBX) {
- emitm_pushl_r(pc, emit_EBX);
- jit_emit_mov_ri_i(interp, pc, emit_EBX, imm);
- jit_info->native_ptr = pc;
- pc = opt_div_rr(interp, jit_info, dest, emit_EBX, is_div);
- pc = emit_popl_r(pc, emit_EBX);
- }
- else {
- emitm_pushl_r(pc, emit_EDI);
- jit_emit_mov_ri_i(interp, pc, emit_EDI, imm);
- jit_info->native_ptr = pc;
- pc = opt_div_rr(interp, jit_info, dest, emit_EDI, is_div);
- pc = emit_popl_r(pc, emit_EDI);
- }
- }
- return pc;
-}
-
-char *
-opt_div_RM(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest, int offs, int is_div)
-{
- char *pc = jit_info->native_ptr;
- int saved = 0;
-
- if (dest != emit_EAX) {
- jit_emit_mov_rr_i(pc, emit_EAX, dest);
- }
- if (dest == emit_EDX) {
- /* all ok, we can globber it */
- }
- else {
- /* if ECX is mapped, push EDX on stack */
- if (intreg_is_used(jit_info, emit_ECX)) {
- emitm_pushl_r(pc, emit_EDX);
- saved = 2;
- }
- /* if EDX is mapped, save it in ECX */
- else if (intreg_is_used(jit_info, emit_EDX)) {
- saved = 1;
- jit_emit_mov_rr_i(pc, emit_ECX, emit_EDX);
- }
- }
- /* this sequence allows 2 other instructions to run parallel */
- jit_emit_mov_rr_i(pc, emit_EDX, emit_EAX);
- pc = emit_shift_i_r(interp, pc, emit_b111, 31, emit_EDX); /* SAR 31 */
-
- emitm_sdivl_m(pc, emit_EBX, 0, 1, offs);
-
- if (is_div) {
- /* result = quotient in EAX */
- if (saved == 1) {
- jit_emit_mov_rr_i(pc, emit_EDX, emit_ECX);
- }
- if (dest != emit_EAX) {
- jit_emit_mov_rr_i(pc, dest, emit_EAX);
- }
- if (saved == 2) {
- emitm_popl_r(pc, emit_EDX);
- }
- }
- else {
- /* result = remainder in EDX */
- if (dest != emit_EDX) {
- jit_emit_mov_rr_i(pc, dest, emit_EDX);
- if (saved == 1) {
- jit_emit_mov_rr_i(pc, emit_EDX, emit_ECX);
- }
- else if (saved == 2)
- emitm_popl_r(pc, emit_EDX);
- }
- }
- return pc;
-}
-
-void
-jit_emit_jcc(Parrot_jit_info_t *jit_info, int code, opcode_t disp)
-{
- long offset;
- opcode_t opcode;
-
- opcode = jit_info->op_i + disp;
-
- if (opcode <= jit_info->op_i) {
- offset = jit_info->arena.op_map[opcode].offset -
- (jit_info->native_ptr - jit_info->arena.start);
-
- /* If we are here, the current section must have a branch_target
- section, I think. */
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- offset +=
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- if (emit_is8bit(offset - 2)) {
- emitm_jxs(jit_info->native_ptr, code, offset - 2);
- }
- else {
- emitm_jxl(jit_info->native_ptr, code, offset - 6);
- }
-
- return;
- }
-
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_X86BRANCH;
- jit_info->arena.fixups->param.opcode = opcode;
- /* If the branch is to the current section, skip the load instructions. */
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- (char)jit_info->optimizer->cur_section->branch_target->load_size;
-
- emitm_jxl(jit_info->native_ptr, code, 0xc0def00d);
-}
-
-void
-emit_jump(Parrot_jit_info_t *jit_info, opcode_t disp)
-{
- long offset;
- opcode_t opcode;
-
- opcode = jit_info->op_i + disp;
-
- if (opcode <= jit_info->op_i) {
- offset = jit_info->arena.op_map[opcode].offset -
- (jit_info->native_ptr - jit_info->arena.start);
- if (emit_is8bit(offset - 2)) {
- emitm_jumps(jit_info->native_ptr, (char)(offset - 2));
- }
- else {
- emitm_jumpl(jit_info->native_ptr, offset - 5);
- }
- return;
- }
-
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_X86JUMP;
- jit_info->arena.fixups->param.opcode = opcode;
- /* If the branch is to the current section, skip the load instructions. */
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- (char)jit_info->optimizer->cur_section->branch_target->load_size;
- emitm_jumpl(jit_info->native_ptr, 0xc0def00d);
-}
-
-void
-Parrot_emit_jump_to_eax(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- /* we have to get the code pointer, which might change
- * due to intersegment branches
- */
-
- /* get interpreter
- */
- emitm_movl_m_r(interp, jit_info->native_ptr,
- emit_EBX, emit_EBP, emit_None, 1, INTERP_BP_OFFS);
- if (!jit_info->objfile) {
- /*
- * emit interp->code->base.data
- */
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_ECX, emit_EBX, 0, 1,
- offsetof(Interp, code));
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EDX, emit_ECX, 0, 1,
- offsetof(PackFile_Segment, data));
- /* calc code offset */
- jit_emit_sub_rr_i(interp, jit_info->native_ptr, emit_EAX, emit_EDX);
- /*
- * now we have the offset of the ins in EAX
- *
- * interp->code->jit_info->arena->op_map
- *
- * TODO interleave these 2 calculations
- */
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EDX, emit_ECX, 0, 1,
- offsetof(PackFile_ByteCode, jit_info));
- emitm_lea_m_r(interp, jit_info->native_ptr, emit_EDX, emit_EDX, 0, 1,
- offsetof(Parrot_jit_info_t, arena));
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EDX, emit_EDX, 0, 1,
- offsetof(Parrot_jit_arena_t, op_map));
-
- }
-#if EXEC_CAPABLE
- else {
- int *reg;
- emitm_subl_i_r(jit_info->native_ptr,
- jit_info->objfile->bytecode_header_size, emit_EAX);
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_DATA, "program_code", -4);
- reg = Parrot_exec_add_text_rellocation_reg(jit_info->objfile,
- jit_info->native_ptr, "opcode_map", 0, 0);
- jit_emit_mov_ri_i(interp, jit_info->native_ptr, emit_EDX, (long) reg);
- }
-#endif
- /* get base pointer */
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EBX, emit_EBX, 0, 1,
- offsetof(Interp, ctx));
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EBX, emit_EBX, 0, 1,
- offsetof(PMC, data));
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EBX, emit_EBX, 0, 1,
- offsetof(Parrot_Context, bp));
-
- /* This jumps to the address in op_map[EDX + sizeof (void *) * INDEX] */
- emitm_jumpm(jit_info->native_ptr, emit_EDX, emit_EAX,
- sizeof (*jit_info->arena.op_map) / 4, 0);
-}
-
-# define CONST(i) (int *)(jit_info->cur_op[i] * \
- sizeof (PackFile_Constant) + \
- offsetof(PackFile_Constant, u))
-
-/* for vtable calls registers are already saved back */
-void
-Parrot_jit_vtable_n_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int n, int *args)
-{
- int nvtable = op_jit[*jit_info->cur_op].extcall;
- size_t offset;
- op_info_t *op_info = &interp->op_info_table[*jit_info->cur_op];
- int pi;
- int idx, i, op;
- int st = 0; /* stack pop correction */
- char *L4 = NULL;
-
- /* get the offset of the first vtable func */
- offset = offsetof(VTABLE, absolute);
- offset += nvtable * sizeof (void *);
- op = *jit_info->cur_op;
-
- /* get params $i, 0 is opcode */
- for (idx = n; idx > 0; idx--) {
- i = args[idx-1];
- pi = *(jit_info->cur_op + i);
-
- switch (op_info->types[i - 1]) {
- case PARROT_ARG_S:
- emitm_movl_m_r(interp, jit_info->native_ptr,
- emit_EAX, emit_EBX, emit_None, 1, REG_OFFS_STR(pi));
- emitm_pushl_r(jit_info->native_ptr, emit_EAX);
- break;
- case PARROT_ARG_K:
- case PARROT_ARG_P:
- emitm_movl_m_r(interp, jit_info->native_ptr,
- emit_EAX, emit_EBX, emit_None, 1, REG_OFFS_PMC(pi));
- /* push $i, the left most Pi stays in eax, which is used
- * below, to call the vtable method
- */
- emitm_pushl_r(jit_info->native_ptr, emit_EAX);
- break;
- case PARROT_ARG_KI:
- case PARROT_ARG_I:
- if (MAP(i))
- emitm_pushl_r(jit_info->native_ptr, MAP(i));
- else {
- emitm_movl_m_r(interp, jit_info->native_ptr,
- emit_EAX, emit_EBX, emit_None, 1, REG_OFFS_INT(pi));
- emitm_pushl_r(jit_info->native_ptr, emit_EAX);
- }
- break;
- break;
- case PARROT_ARG_KIC:
- case PARROT_ARG_IC:
- /* XXX INTVAL_SIZE */
- /* push value */
- emitm_pushl_i(jit_info->native_ptr, pi);
- break;
- case PARROT_ARG_N:
- /* push num on st(0) */
- if (MAP(i))
- emitm_fld(jit_info->native_ptr, MAP(i));
- else
- jit_emit_fload_mb_n(interp, jit_info->native_ptr,
- emit_EBX, REG_OFFS_NUM(pi));
- goto store;
- case PARROT_ARG_NC:
- /*
- * TODO not all constants are shared between interpreters
- */
-#if EXEC_CAPABLE
- if (jit_info->objfile) {
- jit_emit_fload_m_n(interp, jit_info->native_ptr, CONST(i));
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_DATA, "const_table", -4);
- }
- else
-#endif
- jit_emit_fload_m_n(interp, jit_info->native_ptr,
- &interp->code->const_table->
- constants[pi]->u.number);
-store:
-#if NUMVAL_SIZE == 8
- /* make room for double */
- emitm_addb_i_r(jit_info->native_ptr, -8, emit_ESP);
- emitm_fstpl(interp, jit_info->native_ptr, emit_ESP, emit_None, 1, 0);
- /* additional stack adjustment */
- st += 4;
-#else
- emitm_addb_i_r(jit_info->native_ptr, -12, emit_ESP);
- emitm_fstpt(jit_info->native_ptr, emit_ESP, emit_None, 1, 0);
- st += 8;
-#endif
- break;
-
- case PARROT_ARG_SC:
-#if EXEC_CAPABLE
- if (jit_info->objfile) {
- emitm_pushl_m(jit_info->native_ptr, CONST(i));
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_DATA, "const_table", -4);
- }
- else
-#endif
- emitm_pushl_i(jit_info->native_ptr,
- interp->code->const_table->
- constants[pi]->u.string);
- break;
-
- case PARROT_ARG_KC:
- case PARROT_ARG_PC:
-#if EXEC_CAPABLE
- if (jit_info->objfile) {
- emitm_pushl_m(jit_info->native_ptr, CONST(i));
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_DATA,
- "const_table", -4);
- }
- else
-#endif
- emitm_pushl_i(jit_info->native_ptr,
- interp->code->const_table->
- constants[pi]->u.key);
- break;
-
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, 1,
- "jit_vtable_n_op: unimp type %d, arg %d vtable %d",
- op_info->types[i - 1], i, nvtable);
- break;
- }
- }
-
- /* push interpreter */
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_ECX);
- emitm_pushl_r(jit_info->native_ptr, emit_ECX);
-
- if (L4) {
- emitm_callr(jit_info->native_ptr, emit_ESI);
- }
- else {
- /* mov (offs)%eax, %eax i.e. $1->vtable */
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EAX, emit_EAX, emit_None, 1,
- offsetof(struct PMC, vtable));
- /* call *(offset)eax */
- emitm_callm(jit_info->native_ptr, emit_EAX, emit_None, emit_None, offset);
- }
-
- emitm_addb_i_r(jit_info->native_ptr,
- st + sizeof (void *) * (n + 1), emit_ESP);
-
- /* L4: */
- if (L4)
- L4[1] = (char)(jit_info->native_ptr - L4 - 2);
-}
-
-void
-Parrot_jit_store_retval(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- op_info_t *op_info = &interp->op_info_table[*jit_info->cur_op];
- int p1 = *(jit_info->cur_op + 1);
-
- /* return result is in EAX or ST(0) */
- switch (op_info->types[0]) {
- case PARROT_ARG_I:
- emitm_movl_r_m(interp, jit_info->native_ptr,
- emit_EAX, emit_EBX, emit_None, 1, REG_OFFS_INT(p1));
- break;
- case PARROT_ARG_S:
- emitm_movl_r_m(interp, jit_info->native_ptr,
- emit_EAX, emit_EBX, emit_None, 1, REG_OFFS_STR(p1));
- break;
- case PARROT_ARG_P:
- emitm_movl_r_m(interp, jit_info->native_ptr,
- emit_EAX, emit_EBX, emit_None, 1, REG_OFFS_PMC(p1));
- break;
- case PARROT_ARG_N:
- jit_emit_fstore_mb_n(interp, jit_info->native_ptr, emit_EBX,
- REG_OFFS_NUM(p1));
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, 1, "jit_vtable1r: ill LHS");
- break;
- }
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1)
- */
-void
-Parrot_jit_vtable1_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 1, a);
-}
-
-/* emit a call to a vtable func
- * $1 = $2->vtable(interp, $2)
- */
-void
-Parrot_jit_vtable1r_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 2 };
- Parrot_jit_vtable_n_op(jit_info, interp, 1, a);
- Parrot_jit_store_retval(jit_info, interp);
-}
-
-
-/* emit a call to a vtable func
- * $1 = $2->vtable(interp, $2, $3)
- */
-void
-Parrot_jit_vtable_1r223_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 2 , 3};
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
- Parrot_jit_store_retval(jit_info, interp);
-}
-
-/* emit a call to a vtable func
- * $1 = $3->vtable(interp, $3, $2)
- */
-void
-Parrot_jit_vtable_1r332_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 3 , 2};
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
- Parrot_jit_store_retval(jit_info, interp);
-}
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2)
- */
-void
-Parrot_jit_vtable_112_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1, 2 };
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $1)
- */
-void
-Parrot_jit_vtable_111_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1, 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
-}
-/* emit a call to a vtable func
- * $2->vtable(interp, $2, $1)
- */
-void
-Parrot_jit_vtable_221_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 2, 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
-}
-
-/* emit a call to a vtable func
- * $2->vtable(interp, $2, $3, $1)
- */
-void
-Parrot_jit_vtable_2231_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 2, 3, 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2, $3)
- */
-void
-Parrot_jit_vtable_1123_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1, 2, 3 };
- Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2, $1)
- */
-void
-Parrot_jit_vtable_1121_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1, 2, 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
-}
-
-
-/* if_p_ic, unless_p_ic */
-void
-Parrot_jit_vtable_if_unless_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int unless)
-{
- int ic = *(jit_info->cur_op + 2); /* branch offset */
-
- /* emit call vtable function i.e. get_bool, result eax */
- Parrot_jit_vtable1_op(jit_info, interp);
- /* test result */
- jit_emit_test_r_i(jit_info->native_ptr, emit_EAX);
- jit_emit_jcc(jit_info, unless ? emitm_jz : emitm_jnz, ic);
-}
-
-/* unless_p_ic */
-void
-Parrot_jit_vtable_unlessp_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_vtable_if_unless_op(jit_info, interp, 1);
-}
-
-/* if_p_ic */
-void
-Parrot_jit_vtable_ifp_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_vtable_if_unless_op(jit_info, interp, 0);
-}
-
-# define CALL(f) Parrot_exec_add_text_rellocation_func(jit_info->objfile, \
- jit_info->native_ptr, (f)); \
- emitm_calll(jit_info->native_ptr, EXEC_CALLDISP);
-
-# undef IREG
-# undef NREG
-# undef SREG
-# undef PREG
-# undef CONST
-# undef CALL
-
-# define NATIVECODE jit_info->native_ptr
-# define CUR_OPCODE jit_info->cur_op
-# define CONST(i) PCONST(jit_info->cur_op[(i)])
-
-void
-jit_get_params_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- PMC *sig_pmc;
- INTVAL *sig_bits, i, n;
-
- sig_pmc = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
- GETATTR_FixedIntegerArray_int_array(interp, sig_pmc, sig_bits);
- n = VTABLE_elements(interp, sig_pmc);
- jit_info->n_args = n;
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EBP, emit_None, 1, 16);
- for (i = 0; i < n; ++i) {
- switch (sig_bits[i] & PARROT_ARG_TYPE_MASK) {
- case PARROT_ARG_INTVAL:
- emitm_movl_m_r(interp, NATIVECODE, MAP(2+i), emit_EAX, emit_None,
- 1, 4 + i*4);
- break;
- case PARROT_ARG_FLOATVAL:
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EAX, emit_None,
- 1, 4+ i*4);
- jit_emit_fload_mb_n(interp, NATIVECODE, emit_EAX, 0);
- emitm_fstp(NATIVECODE, (MAP(2+i) + 1));
- if (i < n - 1)
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EBP,
- emit_None, 1, 16);
- break;
- default:
- break;
- }
- }
-}
-
-/*
- * preserve registers
- * a) all callee saved on function entry
- */
-void
-jit_save_regs(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- int i, used_i, save_i;
- const jit_arch_regs *reg_info;
-
- used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
- reg_info = &jit_info->arch_info->regs[jit_info->code_type];
- save_i = reg_info->n_preserved_I;
- for (i = save_i; i < used_i; ++i) {
- emitm_pushl_r(jit_info->native_ptr, reg_info->map_I[i]);
- }
-}
-
-/* restore saved regs, see above */
-void
-jit_restore_regs(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
-
- int i, used_i, save_i;
- const jit_arch_regs *reg_info;
-
- used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
- reg_info = &jit_info->arch_info->regs[jit_info->code_type];
- save_i = reg_info->n_preserved_I;
- /* note - reversed order of jit_save_regs */
- for (i = used_i - 1; i >= save_i; --i) {
- emitm_popl_r(jit_info->native_ptr, reg_info->map_I[i]);
- }
-}
-
-/*
- * preserve registers around a functioncall
- *
- * all used register around a call (skip >= 0 := return result
- *
- * TODO factor out common code
- * use jit_emit_mov_RM_{in} functions (load/store base indexed)
- * and a macro to retrieve sp
- */
-int
-jit_save_regs_call(Parrot_jit_info_t *jit_info, PARROT_INTERP, int skip)
-{
- int i, used_i, used_n;
- const jit_arch_regs *reg_info;
-
- used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
- used_n = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM);
- jit_emit_sub_ri_i(interp, jit_info->native_ptr, emit_ESP,
- (used_i * sizeof (INTVAL) + used_n * sizeof (FLOATVAL)));
- reg_info = &jit_info->arch_info->regs[jit_info->code_type];
- for (i = 0; i < used_i; ++i) {
- /* XXX need 2 skip vars */
- if (reg_info->map_I[i] == skip)
- continue;
- emitm_movl_r_m(interp, NATIVECODE, reg_info->map_I[i], emit_ESP,
- emit_None, 1,
- (used_n * sizeof (FLOATVAL) +
- i * sizeof (INTVAL)));
- }
- for (i = 0; i < used_n; ++i) {
- if (reg_info->map_F[i] == skip)
- continue;
- emitm_fld(NATIVECODE, reg_info->map_F[i]);
- jit_emit_fstore_mb_n(interp, NATIVECODE, emit_ESP, (i * sizeof (FLOATVAL)));
- }
- return used_n;
-}
-
-void
-jit_restore_regs_call(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int skip)
-{
-
- int i, used_i, used_n;
- const jit_arch_regs *reg_info;
-
- used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
- used_n = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM);
- reg_info = &jit_info->arch_info->regs[jit_info->code_type];
-
- for (i = 0; i < used_i; ++i) {
- if (reg_info->map_I[i] == skip)
- continue;
- emitm_movl_m_r(interp, NATIVECODE, reg_info->map_I[i], emit_ESP,
- emit_None, 1,
- (used_n * sizeof (FLOATVAL) +
- i * sizeof (INTVAL)));
- }
- for (i = 0; i < used_n; ++i) {
- if (reg_info->map_F[i] == skip)
- continue;
- jit_emit_fload_mb_n(interp, NATIVECODE, emit_ESP, (i * sizeof (FLOATVAL)));
- emitm_fstp(NATIVECODE, (1+reg_info->map_F[i]));
- }
-
- jit_emit_add_ri_i(interp, jit_info->native_ptr, emit_ESP,
- (used_i * sizeof (INTVAL) + used_n * sizeof (FLOATVAL)));
-}
-
-void
-jit_set_returns_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int recursive)
-{
- PMC *sig_pmc;
- INTVAL *sig_bits, sig;
-
- sig_pmc = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
- if (!VTABLE_elements(interp, sig_pmc))
- return;
- GETATTR_FixedIntegerArray_int_array(interp, sig_pmc, sig_bits);
- sig = sig_bits[0];
- if (!recursive) {
- /* mov 16(%ebp), %eax - fetch args ptr */
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EBP, emit_None, 1, 16);
- emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EAX, emit_None, 1, 0);
- }
- /*
- * recursive returns according to ABI */
- switch (sig & (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT)) {
- case PARROT_ARG_INTVAL:
- if (recursive) {
- jit_emit_mov_rr_i(NATIVECODE, emit_EAX, MAP(2));
- }
- else {
- emitm_movl_r_m(interp, NATIVECODE, MAP(2), emit_EAX, 0, 1, 0);
- }
- break;
- case PARROT_ARG_INTVAL|PARROT_ARG_CONSTANT:
- if (recursive) {
- jit_emit_mov_ri_i(interp, NATIVECODE, emit_EAX, CUR_OPCODE[2]);
- }
- else {
- emitm_movl_i_m(NATIVECODE, CUR_OPCODE[2], emit_EAX, 0, 1, 0);
- }
- break;
- case PARROT_ARG_FLOATVAL:
- if (recursive) {
- jit_emit_mov_rr_n(NATIVECODE, FSR1, MAP(2));
- }
- else {
- emitm_fld(NATIVECODE, MAP(2));
- jit_emit_fstore_mb_n(interp, NATIVECODE, emit_EAX, 0);
- }
- break;
- case PARROT_ARG_FLOATVAL|PARROT_ARG_CONSTANT:
- if (recursive) {
- jit_emit_mov_ri_n(interp, NATIVECODE, FSR1, &CONST(2)->u.number);
- }
- else {
- jit_emit_mov_ri_n(interp, NATIVECODE, FSR1, &CONST(2)->u.number);
- jit_emit_fstore_mb_n(interp, NATIVECODE, emit_EAX, 0);
- }
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, 1,
- "set_returns_jit - unknown typ");
- break;
- }
-}
-
-void
-jit_set_args_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int recursive)
-{
- PMC *sig_args, *sig_params, *sig_result;
- INTVAL *sig_bits, sig, i, n;
- opcode_t *params, *result;
- char params_map;
- int skip, used_n;
- char collision[16];
- const jit_arch_regs *reg_info;
-
- reg_info = &jit_info->arch_info->regs[jit_info->code_type];
-
- /* create args array */
- if (!recursive)
- Parrot_ex_throw_from_c_args(interp, NULL, 1,
- "set_args_jit - can't do that yet ");
-
- sig_args = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
-
- if (!VTABLE_elements(interp, sig_args))
- return;
- params = jit_info->optimizer->sections->begin;
- sig_params = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), params[1]);
- ASSERT_SIG_PMC(sig_params);
- GETATTR_FixedIntegerArray_int_array(interp, sig_args, sig_bits);
- n = VTABLE_elements(interp, sig_args);
- /*
- * preserve registers - need get_results, because we skip the
- * return value
- */
- result = CUR_OPCODE + 2 + n + 3; /* set_args, set_p_pc */
- PARROT_ASSERT(*result == PARROT_OP_get_results_pc);
- sig_result = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), result[1]);
- ASSERT_SIG_PMC(sig_result);
-
- if (!VTABLE_elements(interp, sig_result))
- skip = -1;
- else
- skip = MAP(2 + n + 3 + 2);
- used_n = jit_save_regs_call(jit_info, interp, skip);
- memset(collision, 0, 16);
- for (i = 0; i < n; ++i) {
- sig = sig_bits[i];
- /* move args to params regs */
- params_map = jit_info->optimizer->map_branch[2 + i];
- switch (sig & (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT)) {
- case PARROT_ARG_INTVAL:
- /* if the arg was already set,
- * we can't use the src again - fetch from stack
- *
- * XXX skip
- *
- * TODO write a general reg_move
- */
- if (collision[(int)MAP(2+i)]) {
- int j;
- for (j = 0; j < reg_info->n_mapped_I; ++j) {
- if (reg_info->map_I[j] == MAP(2+i)) {
- emitm_movl_m_r(interp, NATIVECODE, params_map, emit_ESP,
- emit_None, 1,
- (used_n * sizeof (FLOATVAL) +
- j * sizeof (INTVAL)));
- break;
- }
- }
- }
- else {
- if (params_map != MAP(2+i)) {
- jit_emit_mov_rr_i(NATIVECODE, params_map, MAP(2 + i));
- }
- }
- collision[(int)params_map] = 1;
- break;
- case PARROT_ARG_INTVAL|PARROT_ARG_CONSTANT:
- /* TODO move constants last */
- jit_emit_mov_ri_i(interp, NATIVECODE, params_map, CUR_OPCODE[2 + i]);
- break;
- case PARROT_ARG_FLOATVAL:
- if (collision[(int)MAP(2+i)]) {
- int j;
- for (j = 0; j < reg_info->n_mapped_F; ++j) {
- if (reg_info->map_F[j] == MAP(2+i)) {
- jit_emit_fload_mb_n(interp, NATIVECODE, emit_ESP,
- (j * sizeof (FLOATVAL)));
- emitm_fstp(NATIVECODE, (1+params_map));
- break;
- }
- }
- }
- else {
- jit_emit_mov_rr_n(NATIVECODE, params_map, MAP(2 + i));
- }
- collision[(int)params_map] = 1;
- break;
- case PARROT_ARG_FLOATVAL|PARROT_ARG_CONSTANT:
- jit_emit_mov_ri_n(interp, NATIVECODE, params_map,
- &CONST(2 + i)->u.number);
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, 1,
- "set_args_jit - unknown type");
- break;
- }
- }
-}
-
-# undef CONST
-
-void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_jit_fixup_t *fixup, *next;
- char *fixup_ptr;
-
- fixup = jit_info->arena.fixups;
-
- while (fixup) {
- switch (fixup->type) {
- /* This fixes-up a branch to a known opcode offset -
- 32-bit displacement only */
- case JIT_X86BRANCH:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup) + 2;
- *(long *)(fixup_ptr) =
- jit_info->arena.op_map[fixup->param.opcode].offset
- - (fixup->native_offset + 6) + fixup->skip;
- break;
- case JIT_X86JUMP:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup) + 1;
- *(long *)(fixup_ptr) =
- jit_info->arena.op_map[fixup->param.opcode].offset
- - (fixup->native_offset + 5) + fixup->skip;
- break;
- case JIT_X86CALL:
- fixup_ptr = jit_info->arena.start + fixup->native_offset + 1;
- *(long *)(fixup_ptr) = (long)fixup->param.fptr -
- (long)fixup_ptr - 4;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Unknown fixup type:%d\n", fixup->type);
- break;
- }
- next = fixup->next;
- free(fixup);
- fixup = next;
- }
- jit_info->arena.fixups = NULL;
-}
-
-int control_word = 0x27f;
-
-#ifdef JIT_CGP
-
-/*
- * This is the somewhat complicated program flow
- *
- * JIT code prederef code
- * 1) jit_begin
- * stack_enter
- * call cgp_core --> set stack frame
- * jump to retaddr
- * test EAX, 0 <-- also from HALT
- * jnz code_start
- * stack_leave
- * ret
- * code_start: of JIT code
- * jit code
- * ....
- *
- * 2) normal_op
- * mov prederef_code_ptr, esi
- * call *(esi) ----> prederefed (non JITted code)
- * ....
- * .... <---- ret
- * jit_code
- * ....
- * 3) HALT == jit_end
- * mov prederefed_op_func[0], esi
- * jump *esi -----> cleanup prederef stack frame
- * xor eax,eax ; return 0
- * ret (--> after call cgp_core in 1)
- *
- */
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- jit_emit_stack_frame_enter(jit_info->native_ptr);
- emitm_fldcw(interp, jit_info->native_ptr, &control_word);
- emitm_pushl_r(jit_info->native_ptr, emit_EBX);
- /* get the pc from stack: mov 12(%ebp), %ebx */
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EBX, emit_EBP, emit_None, 1, 12);
- /* emit cgp_core(1, interp) */
- /* get the interpreter from stack: mov 8(%ebp), %eax */
- emitm_movl_m_r(interp, jit_info->native_ptr, emit_EAX, emit_EBP, emit_None, 1, 8);
- emitm_pushl_r(jit_info->native_ptr, emit_EAX);
- /*
- * TODO define the offset of the interpreter on the stack
- * relative to %ebp
- */
- emitm_pushl_i(jit_info->native_ptr, 1);
- /* use EAX as flag, when jumping back on init, EAX==1 */
- jit_emit_mov_ri_i(interp, jit_info->native_ptr, emit_EAX, 1);
- if (!jit_info->objfile)
- call_func(jit_info, (void (*)(void))cgp_core);
-# if EXEC_CAPABLE
- else {
- Parrot_exec_add_text_rellocation_func(jit_info->objfile,
- jit_info->native_ptr, "cgp_core");
- emitm_calll(jit_info->native_ptr, EXEC_CALLDISP);
- }
-# endif
- /* when cur_opcode == 1, cgp_core jumps back here
- * when EAX == 0, the official return from HALT was called */
- jit_emit_test_r_i(jit_info->native_ptr, emit_EAX);
- emitm_jxs(jit_info->native_ptr, emitm_jnz, 5);
- emitm_popl_r(jit_info->native_ptr, emit_EBX);
- jit_emit_stack_frame_leave(jit_info->native_ptr);
- emitm_ret(jit_info->native_ptr);
- /* get PC = ebx to eax, jump there */
- jit_emit_mov_rr_i(jit_info->native_ptr, emit_EAX, emit_EBX);
- Parrot_emit_jump_to_eax(jit_info, interp);
-
-/* code_start: */
-}
-
-#else /* JIT_CGP */
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- /* the generated code gets called as:
- * (jit_code)(interp, 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(interp, 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(interp, 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(interp, 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, interp);
-}
-
-#endif /* JIT_CGP */
-
-/*
- * create a JITted version of a PIR sub, where everything
- * resided in registers
- *
- * The sub is called as
- *
- * opcode_t * func(Interp *i, INTVAL *sig_bits, void **args);
- *
- * args[0] ... NULL / return value address
- * args[1..n] ... addresses of n arguments
- * args[n + 1] .. opcode_t* next - usually just returned
- */
-
-void
-Parrot_jit_begin_sub_regs(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- jit_emit_stack_frame_enter(jit_info->native_ptr);
- /* stack:
- * 16 args
- * 12 sig_bits
- * 8 interpreter
- * 4 retaddr
- * 0 ebp <----- ebp
- * [ -4 ebx .. preserved regs ]
- * [ -8 edi .. preserved regs ]
- */
- /*
- * check register usage of the subroutine
- * how many we have to preserve
- */
- jit_save_regs(jit_info, interp);
- /* when it's a recursive sub, we fetch params to registers
- * and all a inner helper sub, which run with registers only
- */
- if (jit_info->flags & JIT_CODE_RECURSIVE) {
- char * L1;
- PMC *sig_result;
- opcode_t *result;
-
- jit_get_params_pc(jit_info, interp);
- /* remember fixup position - call sub */
- L1 = NATIVECODE;
- emitm_calll(NATIVECODE, 0);
- /* check type of return value */
- result = Parrot_pcc_get_results(interp, CURRENT_CONTEXT(interp));
- sig_result = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), result[1]);
- if (!VTABLE_elements(interp, sig_result))
- goto no_result;
- /* fetch args to %edx */
- emitm_movl_m_r(interp, NATIVECODE, emit_EDX, emit_EBP, emit_None, 1, 16);
- emitm_movl_m_r(interp, NATIVECODE, emit_ECX, emit_EDX, emit_None, 1, 0);
- if (VTABLE_get_integer_keyed_int(interp, sig_result, 0) ==
- PARROT_ARG_FLOATVAL) {
- jit_emit_fst_mb_n(interp, jit_info->native_ptr, emit_ECX, 0);
- }
- else {
- emitm_movl_r_m(interp, NATIVECODE, emit_EAX, emit_ECX, 0, 1, 0);
- }
-no_result:
- /* return 0 - no branch */
- jit_emit_bxor_rr_i(interp, NATIVECODE, emit_EAX, emit_EAX);
- /* restore pushed callee saved */
- jit_restore_regs(jit_info, interp);
- jit_emit_stack_frame_leave(NATIVECODE);
- emitm_ret(NATIVECODE);
- /* align the inner sub */
-#if SUB_ALIGN
- while ((long)jit_info->native_ptr & ((1<<SUB_ALIGN) - 1)) {
- jit_emit_noop(jit_info->native_ptr);
- }
-#endif
- /* fixup call statement */
- L1[1] = NATIVECODE - L1 - 5;
- }
- /* TODO be sure we got a label here in map_branch */
-}
-
-void
-Parrot_jit_begin_sub(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
-}
-
-void
-jit_mov_mr_n_offs(PARROT_INTERP, 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(interp, jit_info->native_ptr, base_reg, offs);
-}
-
-void
-jit_mov_mr_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg)
-{
- emitm_movl_r_m(interp, jit_info->native_ptr,
- src_reg, base_reg, emit_None, 1, offs);
-}
-
-void
-jit_mov_rm_n_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs)
-{
- jit_emit_fload_mb_n(interp, jit_info->native_ptr, base_reg, offs);
- emitm_fstp(jit_info->native_ptr, (dst_reg+1));
-}
-
-void
-jit_mov_rm_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs)
-{
- emitm_movl_m_r(interp, jit_info->native_ptr,
- dst_reg, base_reg, emit_None, 1, offs);
-}
-
-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'
- * are recognized as one non JITted block
- */
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_optimizer_section_ptr cur_section =
- jit_info->optimizer->cur_section;
- int last_is_branch = 0;
- void ** offset;
-
- PARROT_ASSERT(op_jit[*jit_info->cur_op].extcall == 1);
- if (cur_section->done == 1)
- return;
- else if (cur_section->done == -1 && --cur_section->ins_count > 0)
- return;
- /* check, where section ends
- */
- if (interp->op_info_table[*cur_section->end].jump)
- last_is_branch = 1;
- else if (cur_section->next && !cur_section->next->isjit)
- last_is_branch = 1;
- /* if more then 1 op, then jump to CGP, branches are never
- * executed in CGP, they are handled below */
- if (cur_section->done >= 0 &&
- (INTVAL)cur_section->op_count >= 2 + last_is_branch) {
- int saved = 0;
- offset = (jit_info->cur_op - interp->code->base.data) +
- interp->code->prederef.code;
-
- jit_emit_mov_ri_i(interp, jit_info->native_ptr, emit_ESI, offset);
- emitm_callm(jit_info->native_ptr, emit_ESI, 0, 0, 0);
- /* now patch a B<cpu_ret> opcode after the end of the
- * prederefed (non JIT) section */
- if (last_is_branch) {
- offset = (cur_section->end - interp->code->base.data) +
- interp->code->prederef.code;
- cur_section->done = -1;
- /* ins to skip */
- cur_section->ins_count = cur_section->op_count - 1;
- }
- else {
- /* There must be a next section: either we have a B<end>
- * or a JITed branch,
- * when the branch is non JIT, we are in the above case
- */
- offset = (cur_section->next->begin - interp->code->base.data)
- + interp->code->prederef.code;
- cur_section->done = 1;
- }
- *offset = ((op_func_t*)interp->op_lib->op_func_table)[PARROT_OP_cpu_ret];
- }
- else {
- /* else call normal funtion */
- emitm_pushl_i(jit_info->native_ptr, interp);
- emitm_pushl_i(jit_info->native_ptr, jit_info->cur_op);
- call_func(jit_info,
- (void (*)(void))interp->op_func_table[*(jit_info->cur_op)]);
- emitm_addb_i_r(jit_info->native_ptr, 8, emit_ESP);
- /* when this was a branch, then EAX is now the offset
- * in the byte_code
- */
- }
-}
-
-#else /* JIT_CGP */
-extern int jit_op_count(void);
-
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int cur_op = *jit_info->cur_op;
- static int check;
-
- if (cur_op >= jit_op_count()) {
- cur_op = CORE_OPS_wrapper__;
- }
-
- if ((++check & 0x7) == 0) {
- /*
- * every 8 ??? normal ops, we emit a check for event processing
- */
-
-/*
- * There is an optimization to reuse arguments on the stack. Compilers may
- * decide to reuse the argument space though. If you are *absolutely sure*
- * this does not happen define PARROT_JIT_STACK_REUSE_INTERP.
- */
-# ifdef PARROT_JIT_STACK_REUSE_INTERP
- /*
- * op functions have the signature (cur_op, interp)
- * we use the interpreter already on stack and only push the
- * cur_op
- */
-# else
- /* push interpreter */
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_ECX);
- emitm_pushl_r(jit_info->native_ptr, emit_ECX);
-# endif
-
- emitm_pushl_i(jit_info->native_ptr, CORE_OPS_check_events);
-
- call_func(jit_info,
- (void (*) (void)) (interp->op_func_table[CORE_OPS_check_events]));
-# ifdef PARROT_JIT_STACK_REUSE_INTERP
- emitm_addb_i_r(jit_info->native_ptr, 4, emit_ESP);
-# else
- emitm_addb_i_r(jit_info->native_ptr, 8, emit_ESP);
-# endif
- }
-
-# ifdef PARROT_JIT_STACK_REUSE_INTERP
- /*
- * op functions have the signature (cur_op, interp)
- * we use the interpreter already on stack and only push the
- * cur_op
- */
-# else
- Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_ECX);
- emitm_pushl_r(jit_info->native_ptr, emit_ECX);
-# endif
-
- emitm_pushl_i(jit_info->native_ptr, jit_info->cur_op);
-
- call_func(jit_info,
- (void (*) (void))(interp->op_func_table[cur_op]));
-# ifdef PARROT_JIT_STACK_REUSE_INTERP
- emitm_addb_i_r(jit_info->native_ptr, 4, emit_ESP);
-# else
- emitm_addb_i_r(jit_info->native_ptr, 8, emit_ESP);
-# endif
-}
-
-#endif /* JIT_CGP */
-
-void
-Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
- Parrot_emit_jump_to_eax(jit_info, interp);
-}
-
-void
-Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- char *jmp_ptr, *sav_ptr;
-
- Parrot_jit_normal_op(jit_info, interp);
- /* test eax, if zero (e.g after trace), return from JIT */
- jit_emit_test_r_i(jit_info->native_ptr, emit_EAX);
- /* remember PC */
- jmp_ptr = jit_info->native_ptr;
- /* emit jump past exit code, dummy offset
- * this assumes exit code is not longer then a short jump (126 bytes) */
- emitm_jxs(jit_info->native_ptr, emitm_jnz, 0);
- jit_emit_end(jit_info->native_ptr);
- /* fixup above jump */
- sav_ptr = jit_info->native_ptr;
- jit_info->native_ptr = jmp_ptr;
- emitm_jxs(jit_info->native_ptr, emitm_jnz, (long)(sav_ptr - jmp_ptr) - 2);
- /* restore PC */
- jit_info->native_ptr = sav_ptr;
- Parrot_emit_jump_to_eax(jit_info, interp);
-}
-
-/*
- * params are put rigth to left on the stack
- * parrot registers are counted left to right
- * so this function returns for a given register type
- * the needed register number
- * TODO handel overflow params
- */
-
-int
-count_regs(PARROT_INTERP, char *sig, char *sig_start)
-{
- const char *typs[] = {
- "Ilisc", /* I */
- "StbB", /* S */
- "pP234", /* P */
- "Nfd" /* N */
- };
- int first_reg = 0;
- int i, found;
-
- /* char at sig is the type to look at */
- for (found = -1, i = 0; i < 4; i++) {
- if (strchr(typs[i], *sig)) {
- found = i;
- break;
- }
- }
-
- if (found == -1)
- Parrot_ex_throw_from_c_args(interp, NULL, 1,
- "Parrot_jit_build_call_func: sig char not found\n");
-
- for (--sig; sig > sig_start; --sig) {
- if (strchr(typs[found], *sig)) {
- ++first_reg;
- }
- }
- return first_reg;
-}
-
-size_t
-calc_signature_needs(const char *sig, int *strings)
-{
- size_t stack_size = 0;
- while (*sig) {
- switch (*sig) {
- case 't':
- (*strings)++;
- stack_size +=4;
- break;
- case 'd':
- stack_size +=8;
- break;
- default:
- stack_size +=4;
- break;
- }
- sig++;
- }
- return stack_size;
-
-}
-
-/*
- * The function generated here is called as func(interp, nci_info)
- * interp ... 8(%ebp)
- * nci_info ... 12(%ebp)
- *
- * The generate function for a specific signature looks quite similar to
- * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles
- * just compare the disassembly.
- *
- * If a non-NULL sizeptr is passed, the integer it points to will be written
- * with the size of the allocated execmem buffer.
- */
-
-void *
-Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, int *sizeptr)
-{
- Parrot_jit_info_t jit_info;
- char *pc;
- int i = 0;
- int arg_count = 0;
- int string_buffer_count = 0;
- const int ST_SIZE_OF = 124;
- const int JIT_ALLOC_SIZE = 1024;
-
- char *signature_str = Parrot_str_to_cstring(interp, signature);
- /* skip over the result */
- char *sig = signature_str + 1;
- size_t stack_space_needed = calc_signature_needs(sig,
- &string_buffer_count);
-
- int base_offset = 0;
- int strings_offset = base_offset - (sizeof (char *) * string_buffer_count);
- int st_offset = strings_offset - ST_SIZE_OF;
- int args_offset = st_offset - stack_space_needed;
- int temp_calls_offset = args_offset - 16;
- int total_stack_needed = -temp_calls_offset;
-
- /*
- * ESP
- * 0-15, 16 bytes for utility calls
- * stack_space_needed for actual NCI call
- * st
- * STRINGS -> char * holding space
- * EBP
- */
-
- /* this ought to be enough - the caller of this function
- * should free the function pointer returned here
- */
- pc = jit_info.native_ptr = jit_info.arena.start = (char *)mem_alloc_executable(JIT_ALLOC_SIZE);
- if (! pc)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Cannot allocate executable memory");
-
-
- /* this generated jit function will be called as (INTERP (EBP 8), func_ptr
- * (ESP 12), args signature (ESP 16)) */
-
- /* make stack frame, preserve %ebx */
- jit_emit_stack_frame_enter(pc);
-
- emitm_subl_i_r(pc, total_stack_needed, emit_ESP);
-
- /* Parrot_init_arg_nci(interp, &st, "S"); */
- /* args signature "S" */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 16);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
- /*&st*/
- emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
- /*interpreter*/
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
-
- if (sig && *sig)
- emitm_call_cfunc(pc, Parrot_init_arg_nci);
-
- while (*sig) {
- emitm_movl_i_m(pc, arg_count, emit_EBP, 0, 1, temp_calls_offset + 8);
-
- switch (*sig) {
- case '0': /* null ptr or such - doesn't consume a reg */
- jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- break;
- case 'f':
- emitm_call_cfunc(pc, get_nci_N);
- emitm_fstps(interp, pc, emit_EBP, 0, 1, args_offset);
- break;
- case 'N':
- case 'd':
- emitm_call_cfunc(pc, get_nci_N);
- emitm_fstpl(interp, pc, emit_EBP, 0, 1, args_offset);
- args_offset += 4;
- break;
- case 'I': /* INTVAL */
- case 'l': /* long */
- case 'i': /* int */
- emitm_call_cfunc(pc, get_nci_I);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- break;
- case 't': /* string, pass a cstring */
- emitm_call_cfunc(pc, get_nci_S);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
- emitm_call_cfunc(pc, string_to_cstring_nullable);
-
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- /* save off temporary allocation address */
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset);
- strings_offset += 4;
-
- /* reset ESP(4) */
- emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
- break;
- case 's': /* short: movswl intreg_o(base), %eax */
- emitm_call_cfunc(pc, get_nci_I);
- emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- break;
- case 'c': /* char: movsbl intreg_o(base), %eax */
- emitm_call_cfunc(pc, get_nci_I);
- emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- break;
- case 'J': /* interpreter */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- arg_count--;
- break;
- case 'p': /* push pmc->data */
- emitm_call_cfunc(pc, get_nci_P);
- /* save off PMC* */
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
- /* lookup get_pointer in VTABLE */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable));
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer));
- emitm_callr(pc, emit_EAX);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- /* reset ESP(4) */
- emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
- break;
- case 'O': /* push PMC * object in P2 */
- case 'P': /* push PMC * */
- case '@':
- emitm_call_cfunc(pc, get_nci_P);
-#if PARROT_CATCH_NULL
- /* PMCNULL is a global */
- jit_emit_cmp_rm_i(pc, emit_EAX, &PMCNULL);
- emitm_jxs(pc, emitm_jne, 2); /* skip the xor */
- jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
-#endif
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- break;
- case 'v':
- break;
- case 'b': /* buffer (void*) pass Buffer_bufstart(SReg) */
- emitm_call_cfunc(pc, get_nci_S);
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
- (size_t) &Buffer_bufstart((STRING *) NULL));
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- break;
- case 'B': /* buffer (void**) pass &Buffer_bufstart(SReg) */
- emitm_call_cfunc(pc, get_nci_S);
- emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
- (size_t) &Buffer_bufstart((STRING *) NULL));
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- break;
- case 'S':
- emitm_call_cfunc(pc, get_nci_S);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
- break;
-
-
- /* I have no idea how to handle these */
- case '2':
- case '3':
- case '4':
- case 'V':
- mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
- Parrot_str_free_cstring(signature_str);
- return NULL;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Unknown arg Signature %c\n", *sig);
- /*
- * oops unknown signature:
- * cleanup and try nci.c
- */
- mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
- Parrot_str_free_cstring(signature_str);
- return NULL;
- }
- args_offset +=4;
- arg_count++;
- sig++;
- }
-
- /* prepare to call VTABLE_get_pointer, set up args */
- /* interpreter - movl 8(%ebp), %eax */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
-
- /* pmc - movl 12(%ebp), %eax */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 12);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
- /* get the get_pointer() pointer from the pmc's vtable */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable));
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer));
-
- /* call get_pointer(), result goes into eax */
- emitm_callr(pc, emit_EAX);
- emitm_addl_i_r(pc, 16, emit_ESP);
-
- /* call the resulting function pointer */
- emitm_callr(pc, emit_EAX);
- emitm_subl_i_r(pc, 16, emit_ESP);
-
- /* SAVE OFF EAX */
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
- /*&st*/
- emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
- /*interpreter*/
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
-
- /* RESTORE BACK EAX */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
- /* now place return value in registers */
- /* first in signature is the return value */
- sig = signature_str; /* the result */
- switch (*sig) {
- /* I have no idea how to handle these */
- case '2':
- case '3':
- case '4':
- /* get integer from pointer - untested */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0);
- if (*sig == 2) /* short */
- emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
- emitm_call_cfunc(pc, set_nci_I);
- break;
- case 'f':
- case 'd':
- jit_emit_fstore_mb_n(interp, pc, emit_EBP, temp_calls_offset + 8);
- emitm_call_cfunc(pc, set_nci_N);
- /* pop num from st(0) and mov to reg */
- break;
- case 's':
- /* movswl %ax, %eax */
- emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
- emitm_call_cfunc(pc, set_nci_I);
- break;
- case 'c':
- /* movsbl %al, %eax */
- emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
- emitm_call_cfunc(pc, set_nci_I);
- break;
- case 'I': /* INTVAL */
- case 'l':
- case 'i':
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
- emitm_call_cfunc(pc, set_nci_I);
- break;
- case 'v': /* void - do nothing */
- break;
- case 'P':
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
- emitm_call_cfunc(pc, set_nci_P);
- break;
- case 'p': /* make a new unmanaged struct */
- /* save return value on stack */
-
- /* save pointer p */
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 12);
-
- /* make new pmc */
- emitm_movl_i_m(pc, enum_class_UnManagedStruct, emit_EBP, 0, 1, temp_calls_offset + 4);
- emitm_call_cfunc(pc, pmc_new);
-
- /* restore pointer p to EDX */
- emitm_movl_m_r(interp, pc, emit_EDX, emit_EBP, 0, 1, temp_calls_offset + 12);
-
- /* copy UnManagedStruct to stack for set_nci_P call */
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
- /* eax = PMC, get return value into edx */
- /* mov data(%eax), %eax
- mov %edx, ptr(%eax) */
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));
- emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1,
- offsetof(struct Parrot_UnManagedStruct_attributes, ptr));
-
- /* reset EBP(4) */
- emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
- emitm_call_cfunc(pc, set_nci_P);
- break;
- case 'S':
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
- emitm_call_cfunc(pc, set_nci_S);
- break;
- case 't': /* string */
- /* EAX is char* */
- emitm_movl_i_m(pc, 0, emit_EBP, 0, 1, temp_calls_offset + 8); /* len */
-
- /* overwrites address of st in EBP(4) */
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
- emitm_call_cfunc(pc, Parrot_str_new);
-
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);
-
- /* reset EBP(4) */
- emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
-
- emitm_call_cfunc(pc, set_nci_S);
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
- "Unknown return Signature %c\n", *sig);
- /*
- * oops unknown signature:
- * cleanup and try nci.c
- */
- Parrot_str_free_cstring(signature_str);
- mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
- return NULL;
- }
-
- /* free temporary strings */
- strings_offset = st_offset + ST_SIZE_OF;
- for (i=0; i<string_buffer_count; i++) {
- emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset);
- emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
- emitm_call_cfunc(pc, Parrot_str_free_cstring);
- strings_offset += 4;
- }
-
- jit_emit_stack_frame_leave(pc);
- emitm_ret(pc);
- PARROT_ASSERT(pc - jit_info.arena.start <= JIT_ALLOC_SIZE);
-
- /* could shrink arena.start here to used size */
-
- if (sizeptr)
- *sizeptr = JIT_ALLOC_SIZE;
- Parrot_str_free_cstring(signature_str);
- return (void *)D2FPTR(jit_info.arena.start);
-}
-
-const char i_map[] =
- { emit_EDI, emit_ESI, emit_EDX, emit_ECX };
-const char floatval_map[] =
- { 1, 2, 3, 4, 5 }; /* ST(1) .. (ST(4) */
-
-const char i_map_sub[] =
- { emit_EDX, emit_ECX, emit_EBX, emit_EDI, emit_ESI };
-
-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 */
- i_map,
- 4, /* 4 mapped float regs */
- 0, /* ABI sez it's not preserved */
- floatval_map
- },
- /* unused */
- {
- Parrot_jit_begin_sub, /* emit code prologue */
- 4, /* 4 mapped ints */
- 2, /* first 2 are *non*preserved */
- i_map_sub,
- 4, /* 4 mapped float regs */
- 0, /* ABI sez it's not preserved */
- floatval_map
- },
- /*
- * compile a sub to registers only
- * if a mapped count is 0, code containing this register kind
- * will not be created
- *
- * TODO implement FLOATVAL arg passing and set mapped
- * register count.
- */
- {
- Parrot_jit_begin_sub_regs, /* emit code prologue */
- 5, /* 5 mapped ints */
- 2, /* first 2 are *non*preserved */
- i_map_sub,
- 5, /* TODO 0 mapped float regs */
- 5, /* ABI sez it's not preserved */
- floatval_map
- }
- }
-};
-
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info *
-Parrot_jit_init(PARROT_INTERP)
-{
- return &arch_info;
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/i386/jit_emit.h
==============================================================================
--- trunk/src/jit/i386/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,1909 +0,0 @@
-/*
- * Copyright (C) 2002-2009, Parrot Foundation.
- */
-
-/*
- * jit_emit.h
- *
- * i386
- *
- * $Id$
- */
-
-#ifndef PARROT_I386_JIT_EMIT_H_GUARD
-#define PARROT_I386_JIT_EMIT_H_GUARD
-
-#if defined(__cplusplus)
-# define EXTERN extern "C"
-#else
-# define EXTERN
-#endif
-
-#include <assert.h>
-#include "parrot/parrot.h"
-#include "parrot/hash.h"
-#include "parrot/oplib/ops.h"
-
-/* Scale factor values */
-#define emit_Scale(scale) ((scale) << 6)
-#define emit_Scale_1 emit_Scale(0)
-#define emit_Scale_2 emit_Scale(1)
-#define emit_Scale_4 emit_Scale(2)
-#define emit_Scale_8 emit_Scale(3)
-
-/* Scale factor values */
-#define emit_Scale(scale) ((scale) << 6)
-#define emit_Scale_1 emit_Scale(0)
-#define emit_Scale_2 emit_Scale(1)
-#define emit_Scale_4 emit_Scale(2)
-#define emit_Scale_8 emit_Scale(3)
-
-/* ESIB byte */
-#define emit_reg_Index(x) (((x)-1) << 3)
-#define emit_reg_Base(x) ((x)-1)
-#define emit_Index_None ((emit_b100) << 3)
-
-/*
- * helper funcs - get argument n
- */
-INTVAL get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n);
-
-FLOATVAL get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n);
-;
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-STRING*
-get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-PMC*
-get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n);
-
-/*
- * set return value
- */
-void set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val);
-
-void set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val);
-
-void set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val);
-
-void set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val);
-
-
-#if defined HAVE_COMPUTED_GOTO && defined __GNUC__ && PARROT_I386_JIT_CGP
-# define JIT_CGP
-#endif
-
-void call_func(Parrot_jit_info_t *jit_info, void (*addr) (void));
-
-void jit_emit_real_exception(Parrot_jit_info_t *jit_info);
-
-/*
- * get the register frame pointer
- */
-#define Parrot_jit_emit_get_base_reg_no(pc) \
- emit_EBX
-
-/*
- * get the *runtime* interpreter
- */
-
-#define Parrot_jit_emit_get_INTERP(interp, pc, dest) \
- emitm_movl_m_r((interp), (pc), (dest), emit_EBP, emit_None, 1, INTERP_BP_OFFS)
-
-/* see jit_begin */
-#ifdef JIT_CGP
-# define INTERP_BP_OFFS todo
-#else
-# define INTERP_BP_OFFS -16
-#endif
-
-/*
- * if we have a delegated method like typeof_i_p, that returns an INTVAL
- * and that is all in a sequence of JITted opcodes, and when these INTVAL
- * is MAPped, we got a problem. So the EXT_CALL flag is disabled - mapped
- * registers are saved/restored around vtable calls.
- */
-#define JIT_VTABLE_OPS 1
-
-/* EXEC_SHARED generates code to be used with libparrot.so
- * It grabs the real address of cgp_core from the gcc generated code
- * x/1i cgp_code
- * jmp *0xXXXX
- * x/1wx 0xXXXX
- * real address of cpg_core
- * s. exec_emit_end
- * XXX This should be a command line option.
- */
-#undef EXEC_SHARED
-
-extern UINTVAL ld(UINTVAL);
-
-#define NEG_MINUS_ZERO
-/* #define NEG_ZERO_SUB */
-
-/* Register codes */
-#define emit_None 0
-
-/* These are + 1 the real values */
-#define emit_EAX 1
-#define emit_ECX 2
-#define emit_EDX 3
-#define emit_EBX 4
-#define emit_ESP 5
-#define emit_EBP 6
-#define emit_ESI 7
-#define emit_EDI 8
-
-#define INT_REGISTERS_TO_MAP 4
-
-/* Scratch register. */
-
-#define ISR1 emit_EAX
-#define FSR1 0
-
-#define emit_b00 0
-#define emit_b01 1
-#define emit_b10 2
-#define emit_b11 3
-
-#define emit_b000 0
-#define emit_b001 1
-#define emit_b010 2
-#define emit_b011 3
-#define emit_b100 4
-#define emit_b101 5
-#define emit_b110 6
-#define emit_b111 7
-
-/* Mod R/M byte */
-#define emit_reg(x) ((x) << 3)
-#define emit_Mod(Mod) ((Mod) << 6)
-#define emit_reg_rm(x) ((x)-1)
-
-/* Mod values for Mod R/M Byte */
-#define emit_Mod_b00 emit_Mod(emit_b00)
-#define emit_Mod_b01 emit_Mod(emit_b01)
-#define emit_Mod_b10 emit_Mod(emit_b10)
-
-/* special R/M values */
-#define emit_rm_b101 emit_b101
-#define emit_rm_b100 emit_b100
-
-#define emit_r_m(interp, pc, reg1, b, i, s, d) \
- emit_r_X((interp), (pc), emit_reg((reg1)-1), (b), (i), (s), (d))
-
-#define emit_alu_X_r(X, reg) ((emit_b11 << 6) | ((X) << 3) | ((reg) - 1))
-
-#define emit_alu_r_r(reg1, reg2) emit_alu_X_r(((reg1) - 1), (reg2))
-
-int emit_is8bit(long disp);
-
-char * emit_disp8_32(char *pc, int disp);
-
-void emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base);
-
-char * emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i,
- int scale, long disp);
-
-char * emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg);
-
-char * emit_shift_i_m(PARROT_INTERP, char *pc, int opcode, int imm,
- int base, int i, int scale, long disp);
-
-char * emit_shift_r_r(PARROT_INTERP, char *pc, int opcode, int reg1, int reg2);
-
-char * emit_shift_r_m(PARROT_INTERP, char *pc, int opcode, int reg,
- int base, int i, int scale, long disp);
-
-/* CDQ - need this to do multiply */
-#define emitm_cdq(pc) *((pc)++) = (char) 0x99
-
-/* RET */
-#define emitm_ret(pc) *((pc)++) = (char) 0xc3
-
-/* NOP */
-#define emit_nop(pc) *((pc)++) = (char) 0x90
-
-/* PUSHes */
-
-#define emitm_pushl_r(pc, reg) \
- *((pc)++) = (char) 0x50 | ((reg) - 1)
-
-#define emitm_pushl_i(pc, imm) { \
- *((pc)++) = (char) 0x68; \
- *(long *)(pc) = (long)(imm); \
- (pc) += 4; }
-
-#if EXEC_CAPABLE
-# define emitm_pushl_m(pc, mem) { \
- *((pc)++) = (char) 0xff; \
- *((pc)++) = (char) 0x35; \
- *(long *)(pc) = (long)(mem); \
- (pc) += 4; }
-#else /* EXEC_CAPABLE */
-# define emitm_pushl_m(pc, mem) { \
- *((pc)++) = (char) 0xff; \
- *((pc)++) = (char) 0x35; \
- *(long *)(pc) = (long)(mem); \
- (pc) += 4; }
-#endif /* EXEC_CAPABLE */
-
-char * emit_pushl_m(PARROT_INTERP, char *pc, int base, int i, int scale,
- long disp);
-
-/* POPs */
-
-char * emit_popl_r(char *pc, int reg);
-
-# define emitm_popl_r(pc, reg) \
- (pc) = emit_popl_r((pc), (reg))
-
-char * emit_popl_m(PARROT_INTERP, char *pc, int base, int i, int scale,
- long disp);
-
-/* MOVes */
-
-char * emit_movb_r_r(char *pc, int reg1, int reg2);
-
-# define jit_emit_mov_rr_i(pc, reg2, reg1) if ((reg1) != (reg2)) { \
- *((pc)++) = (char) 0x89; \
- *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); }
-
-char * emit_movb_i_r(char *pc, char imm, int reg);
-
-# define jit_emit_mov_ri_i(interp, pc, reg, imm) { \
- *((pc)++) = (char)(0xb8 | ((reg) - 1)); \
- *(long *)(pc) = (long)(imm); (pc) += 4; }
-
-# define emitm_movX_Y_Z(interp, op, pc, reg1, b, i, s, d) { \
- *((pc)++) = (char) (op); \
- (pc) = emit_r_m((interp), (pc), (reg1), (b), (i), (s), (long)(d)); }
-
-# define emitm_movb_r_m(interp, pc, reg1, b, i, s, d) \
- emitm_movX_Y_Z((interp), 0x88, (pc), (reg1), (b), (i), (s), (d))
-
-# define emitm_movl_r_m(interp, pc, reg1, b, i, s, d) \
- emitm_movX_Y_Z((interp), 0x89, (pc), (reg1), (b), (i), (s), (d))
-
-/* move byte/word with sign extension */
-# define emitm_movsbl_r_m(interp, pc, reg1, b, i, s, d) { \
- *((pc)++) = (char) 0x0f; \
- emitm_movX_Y_Z((interp), 0xBE, (pc), (reg1), (b), (i), (s), (d)); \
-}
-
-# define emitm_movswl_r_m(interp, pc, reg1, b, i, s, d) { \
- *((pc)++) = (char) 0x0f; \
- emitm_movX_Y_Z((interp), 0xBF, (pc), (reg1), (b), (i), (s), (d)); \
-}
-
-# define emitm_movsbl_r_r(pc, reg1, reg2) { \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0xbe; \
- *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); \
-}
-
-# define emitm_movswl_r_r(pc, reg1, reg2) { \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char) 0xbf; \
- *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); \
-}
-
-# define emitm_movb_m_r(interp, pc, reg1, b, i, s, d) \
- emitm_movX_Y_Z((interp), 0x8a, (pc), (reg1), (b), (i), (s), (d))
-
-# define emitm_movl_m_r(interp, pc, reg1, b, i, s, d) \
- emitm_movX_Y_Z((interp), 0x8b, (pc), (reg1), (b), (i), (s), (d))
-
-# define emitm_lea_m_r(interp, pc, reg1, b, i, s, d) \
- emitm_movX_Y_Z((interp), 0x8d, (pc), (reg1), (b), (i), (s), (d))
-
-char * emit_movb_i_m(PARROT_INTERP, char *pc, char imm, int base, int i,
- int scale, long disp);
-
-# define emitm_movl_i_m(pc, imm, b, i, s, d) { \
- *((pc)++) = (char) 0xc7; \
- (pc) = emit_r_X((interp), (pc), emit_reg(emit_b000), (b), (i), (s), (long)(d)); \
- *(long *)(pc) = (long)(imm); (pc) += 4; }
-
-/* Various ALU formats */
-
-# define emitm_alul_r_r(pc, op, reg1, reg2) { \
- *((pc)++) = (char) (op); *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); }
-
-# define emitm_alub_i_r(pc, op1, op2, imm, reg) { \
- *((pc)++) = (char) (op1); *((pc)++) = (char) emit_alu_X_r((op2), (reg)); *((pc)++) = (char)(imm); }
-
-# define emitm_alul_i_r(pc, op1, op2, imm, reg) { \
- *((pc)++) = (char) (op1); \
- *((pc)++) = (char) emit_alu_X_r((op2), (reg)); \
- *(long *)((pc)) = (long)(imm); (pc) += 4; }
-
-# define emitm_alul_i_m(pc, op1, op2, imm, b, i, s, d) { \
- *((pc)++) = (char) (op1); \
- (pc) = emit_r_X((interp), (pc), emit_reg(op2), (b), (i), (s), (d)); \
- *(long *)(pc) = (long)(imm); (pc) += 4; }
-
-# define emitm_alul_r_m(pc, op, reg, b, i, s, d) { \
- *((pc)++) = (char) (op); \
- (pc) = emit_r_X((interp), (pc), emit_reg((reg)-1), (b), (i), (s), (long)(d)); }
-
-/* ADDs */
-
-# define emitm_addb_r_r(pc, reg1, reg2) \
- emitm_alul_r_r((pc), 0x00, (reg1), (reg2))
-
-# define emitm_addb_i_r(pc, imm, reg) \
- emitm_alub_i_r((pc), 0x83, emit_b000, (imm), (reg))
-
-# define jit_emit_add_rr_i(interp, pc, reg1, reg2) \
- emitm_alul_r_r((pc), 0x01, (reg2), (reg1))
-
-# define jit_emit_add_ri_i(interp, pc, reg, imm) \
- emitm_alul_i_r((pc), 0x81, emit_b000, (imm), (reg))
-
-# define emitm_addl_i_r(pc, imm, reg) \
- emitm_alul_i_r((pc), 0x81, emit_b000, (imm), (reg))
-
-# define emitm_addl_i_m(pc, imm, b, i, s, d) \
- emitm_alul_i_m((pc), 0x81, emit_b000, (imm), (b), (i), (s), (d))
-
-# define emitm_addl_r_m(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x01, (reg), (b), (i), (s), (d))
-
-# define emitm_addl_m_r(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x03, (reg), (b), (i), (s), (d))
-
-/* SUBs */
-
-# define jit_emit_sub_rr_i(interp, pc, reg1, reg2) \
- emitm_alul_r_r((pc), 0x29, (reg2), (reg1))
-
-# define emitm_subl_i_r(pc, imm, reg) \
- emitm_alul_i_r((pc), 0x81, emit_b101, (imm), (reg))
-
-# define jit_emit_sub_ri_i(interp, pc, r, i) emitm_subl_i_r((pc), (i), (r))
-
-# define emitm_subl_r_m(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x29, (reg), (b), (i), (s), (d))
-
-# define emitm_subl_m_r(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x2b, (reg), (b), (i), (s), (d))
-
-# define emitm_subl_i_m(pc, imm, b, i, s, d) \
- emitm_alul_i_m((pc), 0x81, emit_b101, (imm), (b), (i), (s), (d))
-
-/* These are used by both signed and unsigned EDIV, but only unsigned MUL */
-# define emitm_alu_imp_r(pc, op, reg) { \
- *((pc)++) = (char) 0xf7; \
- *((pc)++) = (char) emit_alu_X_r((op), (reg)); }
-
-# define emitm_alu_imp_m(pc, op, b, i, s, d) { \
- *((pc)++) = (char) 0xf7; \
- (pc) = emit_r_X((interp), (pc), emit_reg(op), (b), (i), (s), (d)); }
-
-/* Unsigned MUL and EDIV */
-/* EAX implicit destination in multiply and divide */
-
-# define emitm_umull_r(pc, reg2) emitm_alu_imp_r((pc), emit_b100, (reg2))
-
-# define emitm_udivl_r(pc, reg2) emitm_alu_imp_r((pc), emit_b110, (reg2))
-
-# define emitm_umull_m(pc, b, i, s, d) \
- emitm_alu_imp_m((pc), emit_b100, (b), (i), (s), (d))
-
-# define emitm_udivl_m(pc, b, i, s, d) \
- emitm_alu_imp_m((pc), emit_b110, (b), (i), (s), (d))
-
-/* Signed MUL and EDIV */
-
-# define emitm_sdivl_r(pc, reg2) emitm_alu_imp_r((pc), emit_b111, (reg2))
-
-# define emitm_sdivl_m(pc, b, i, s, d) \
- emitm_alu_imp_m((pc), emit_b111, (b), (i), (s), (d))
-
-# define jit_emit_cdq(pc) *(pc)++ = 0x99
-
-/* TEST for zero */
-# define jit_emit_test_r_i(pc, reg1) emitm_alul_r_r((pc), 0x85, (reg1), (reg1))
-
-# define emitm_smull_r(pc, reg2) emitm_alu_imp_r((pc), emit_b101, (reg2))
-
-# define jit_emit_mul_rr_i(interp, pc, reg1, reg2) { \
- *(pc)++ = 0xf; \
- emitm_alul_r_r((pc), 0xaf, (reg1), (reg2)); }
-
-# define emitm_smull_r_m(pc, reg1, b, i, s, d) { \
- *(pc)++ = 0xf; \
- emitm_alul_r_m((pc), 0xaf, (reg1), (b), (i), (s), (d)); }
-
-char * opt_mul(PARROT_INTERP, char *pc, int dest, INTVAL imm, int src);
-
-# define jit_emit_mul_rir_i(pc, dest, imm, src) \
- (pc) = opt_mul(interp, (pc), (dest), (imm), (src))
-
-
-# define jit_emit_mul_ri_i(pc, r, imm) jit_emit_mul_rir_i((pc), (r), (imm), (r))
-
-# define jit_emit_mul_RIM_ii(pc, reg, imm, ofs) \
- emitm_alul_r_m((pc), 0x69, (reg), emit_EBX, emit_None, 1, (ofs)); \
- *(long *)(pc) = (long)(imm); \
- (pc) += 4;
-
-/* NEG */
-
-# define jit_emit_neg_r_i(pc, reg) emitm_alu_imp_r((pc), emit_b011, (reg))
-
-# define emitm_negl_m(pc, b, i, s, d) \
- emitm_alu_imp_m((pc), emit_b011, (b), (i), (s), (d))
-
-/* AND */
-
-# define emit_andl_r_r(pc, reg1, reg2) emitm_alul_r_r((pc), 0x21, (reg1), (reg2))
-# define jit_emit_band_rr_i(interp, pc, r1, r2) emit_andl_r_r((pc), (r2), (r1))
-
-# define jit_emit_band_ri_i(interp, pc, reg, imm) \
- emitm_alul_i_r((pc), 0x81, emit_b100, (imm), (reg))
-
-# define emitm_andl_r_m(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x21, (reg), (b), (i), (s), (d))
-
-# define emitm_andl_m_r(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x23, (reg), (b), (i), (s), (d))
-
-# define emitm_andl_i_m(pc, imm, b, i, s, d) \
- emitm_alul_i_m((pc), 0x81, emit_b100, (imm), (b), (i), (s), (d))
-
-/* TEST op */
-# define jit_emit_test_rr_i(pc, r1, r2) emitm_alul_r_r((pc), 0x85, (r1), (r2))
-
-# define jit_emit_test_ri_i(pc, r, im) \
- emitm_alul_i_r((pc), 0xF7, emit_b000, (im), (r))
-
-# define jit_emit_test_RM_i(pc, r, offs) \
- emitm_alul_r_m((pc), 0x85, (r), emit_EBX, 0, 1, (offs))
-
-/* OR */
-
-# define jit_emit_bor_rr_i(interp, pc, reg1, reg2) emitm_alul_r_r((pc), 0x9, (reg2), (reg1))
-
-# define jit_emit_bor_ri_i(interp, pc, reg, imm) \
- emitm_alul_i_r((pc), 0x81, emit_b001, (imm), (reg))
-
-# define emitm_orl_r_m(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x09, (reg), (b), (i), (s), (d))
-
-# define emitm_orl_m_r(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x0b, (reg), (b), (i), (s), (d))
-
-# define emitm_orl_i_m(pc, imm, b, i, s, d) \
- emitm_alul_i_m((pc), 0x81, emit_b001, (imm), (b), (i), (s), (d))
-
-/* XOR */
-
-# define jit_emit_bxor_rr_i(interp, pc, reg1, reg2) \
- emitm_alul_r_r((pc), 0x31, (reg2), (reg1))
-
-# define jit_emit_bxor_ri_i(intepr, pc, reg, imm) \
- emitm_alul_i_r((pc), 0x81, emit_b110, (imm), (reg))
-
-# define emitm_xorl_r_m(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x31, (reg), (b), (i), (s), (d))
-
-# define emitm_xorl_m_r(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x33, (reg), (b), (i), (s), (d))
-
-# define emitm_xorl_i_m(pc, imm, b, i, s, d) \
- emitm_alul_i_m((pc), 0x81, emit_b110, (imm), (b), (i), (s), (d))
-
-/* NOT */
-
-# define jit_emit_not_r_i(pc, reg) emitm_alu_imp_r((pc), emit_b010, (reg))
-# define emitm_notl_m(pc, b, i, s, d) \
- emitm_alu_imp_m((pc), emit_b010, (b), (i), (s), (d))
-
-# define jit_emit_not_M_i(interp, pc, offs) emitm_notl_m((pc), emit_EBX, 0, 1, (offs))
-
-/* XCHG */
-# define jit_emit_xchg_rr_i(interp, pc, r1, r2) { \
- if ((r1) != (r2)) { \
- *((pc)++) = (char) 0x87; \
- *((pc)++) = (char) emit_alu_r_r((r1), (r2)); \
- } \
-}
-
-# define jit_emit_xchg_rm_i(pc, r, m) { \
- emitm_alul_r_m((pc), 0x87, (r), emit_None, emit_None, emit_None, (m)) \
-}
-# define jit_emit_xchg_RM_i(interp, pc, r, offs) { \
- emitm_alul_r_m((pc), 0x87, (r), emit_EBX, emit_None, 1, (offs)) \
-}
-# define jit_emit_xchg_MR_i(interp, pc, offs, r) jit_emit_xchg_RM_i((interp), (pc), (r), (offs))
-
-/* SHL */
-
-# define jit_emit_shl_ri_i(interp, pc, reg, imm) \
- { (pc) = emit_shift_i_r((interp), (pc), emit_b100, (imm), (reg)); }
-
-# define emitm_shll_i_m(pc, imm, b, i, s, d) \
- { (pc) = emit_shift_i_m((pc), emit_b100, (imm), (b), (i), (s), (d)); }
-
-# define emitm_shll_r_r(interp, pc, reg1, reg2) \
- { (pc) = emit_shift_r_r((interp), (pc), emit_b100, (reg1), (reg2)); }
-
-# define emitm_shll_r_m(pc, reg, b, i, s, d) \
- { (pc) = emit_shift_r_m((pc), emit_b100, (reg), (b), (i), (s), (d)); }
-
-/* SHR */
-
-# define jit_emit_lsr_ri_i(interp, pc, reg, imm) \
- { (pc) = emit_shift_i_r((interp), (pc), emit_b101, (imm), (reg)); }
-
-# define emitm_shrl_i_m(pc, imm, b, i, s, d) \
- { (pc) = emit_shift_i_m((pc), emit_b101, (imm), (b), (i), (s), (d)); }
-
-# define emitm_shrl_r_r(interp, pc, reg1, reg2) \
- { (pc) = emit_shift_r_r((interp), (pc), emit_b101, (reg1), (reg2)); }
-
-# define emitm_shrl_r_m(pc, reg, b, i, s, d) \
- { (pc) = emit_shift_r_m((pc), emit_b101, (reg), (b), (i), (s), (d)); }
-
-/* SAL */
-
-# define emitm_sall_i_r(interp, pc, imm, reg) \
- { (pc) = emit_shift_i_r((interp), (pc), emit_b100, (imm), (reg)); }
-
-# define emitm_sall_i_m(pc, imm, b, i, s, d) \
- { (pc) = emit_shift_i_m((pc), emit_b100, (imm), (b), (i), (s), (d)); }
-
-# define emitm_sall_r_r(interp, pc, reg1, reg2) \
- { (pc) = emit_shift_r_r((interp), (pc), emit_b100, (reg1), (reg2)); }
-
-# define emitm_sall_r_m(pc, reg, b, i, s, d) \
- { (pc) = emit_shift_r_m((pc), emit_b100, (reg), (b), (i), (s), (d)); }
-
-/* SAR */
-
-# define jit_emit_shr_ri_i(interp, pc, reg, imm) \
- { (pc) = emit_shift_i_r((interp), (pc), emit_b111, (imm), (reg)); }
-
-
-# define emitm_sarl_i_m(pc, imm, b, i, s, d) \
- { (pc) = emit_shift_i_m((pc), emit_b111, (imm), (b), (i), (s), (d)); }
-
-# define emitm_sarl_r_r(interp, pc, reg1, reg2) \
- { (pc) = emit_shift_r_r((interp), (pc), emit_b111, (reg1), (reg2)); }
-
-# define emitm_sarl_r_m(pc, reg, b, i, s, d) \
- { (pc) = emit_shift_r_m((pc), emit_b111, (reg), (b), (i), (s), (d)); }
-
-/* rotate */
-
-# define jit_emit_rol_ri_i(interp, pc, reg, imm) \
- { (pc) = emit_shift_i_r((interp), (pc), emit_b000, (imm), (reg)); }
-
-# define jit_emit_ror_ri_i(interp, pc, reg, imm) \
- { (pc) = emit_shift_i_r((interp), (pc), emit_b001, (imm), (reg)); }
-
-int intreg_is_used(Parrot_jit_info_t *jit_info, char reg);
-
-char * opt_shift_rr(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest,
- int count, int op);
-
-char * opt_shift_rm(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest,
- int offs, int op);
-
-/* interface, shift r1 by r2 bits */
-
-# define jit_emit_shl_rr_i(interp, pc, r1, r2) \
- (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b100)
-
-# define jit_emit_shl_RM_i(interp, pc, r1, offs) \
- (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b100)
-
-/* shr seems to be the arithmetic shift */
-# define jit_emit_shr_rr_i(interp, pc, r1, r2) \
- (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b111)
-
-# define jit_emit_shr_RM_i(interp, pc, r1, offs) \
- (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b111)
-
-# define jit_emit_lsr_rr_i(interp, pc, r1, r2) \
- (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b101)
-
-# define jit_emit_lsr_RM_i(interp, pc, r1, offs) \
- (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b101)
-
-/* MOV (reg), reg */
-# define emit_movm_r_r(pc, src, dest) \
- *((pc)++) = (char) 0x8b; \
- *((pc)++) = (char) (src) | (dest) << 3
-
-/* MOV X(reg), reg */
-# define emit_movb_i_r_r(pc, imm, src, dest) \
- *((pc)++) = (char)(0x8b); \
- *((p)c++) = (char)(0x40 | ((src) - 1) | ((dest) - 1) << 3); \
- *((pc)++) = (imm)
-
-/* INC / DEC */
-# define jit_emit_inc_r_i(pc, reg) *((pc)++) = (char)(0x40 | ((reg) - 1))
-# define jit_emit_dec_r_i(pc, reg) *((pc)++) = (char)(0x48 | ((reg) - 1))
-
-/* Floating point ops */
-
-# define emitm_floatop 0xd8 /* 11011000 */
-# define jit_emit_dec_fsp(pc) { *((pc)++) = (char) 0xD9; *((pc)++) = (char) 0xF6; }
-# define jit_emit_inc_fsp(pc) { *((pc)++) = (char) 0xD9; *((pc)++) = (char) 0xF7; }
-
-# define emitm_fl_2(interp, pc, mf, opa, opb, b, i, s, d) { \
- *((pc)++) = (char)(emitm_floatop | ((mf) << 1) | (opa)); \
- (pc) = emit_r_X((interp), (pc), emit_reg(opb), (b), (i), (s), (long)(d)); }
-
-# define emitm_fl_3(pc, d_p_opa, opb_r, sti) { \
- *((pc)++) = (char)(emitm_floatop | (d_p_opa)); \
- *((pc)++) = (char)(0xc0 | ((opb_r) << 3) | (sti)); }
-
-# define emitm_fl_4(pc, op) { \
- *((pc)++) = (char)(emitm_floatop | emit_b001); \
- *((pc)++) = (char)(0xe0 | (op)); }
-
-/* Integer loads and stores */
-# define emitm_fildl(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 1, emit_b000, (b), (i), (s), (d))
-
-# define emitm_fistpl(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 1, emit_b011, (b), (i), (s), (d))
-
-# define emitm_fistl(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 1, emit_b010, (b), (i), (s), (d))
-
-/* long long integer load/store */
-# define emitm_fildll(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b11, 1, emit_b101, (b), (i), (s), (d))
-
-# define emitm_fistpll(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b11, 1, emit_b111, (b), (i), (s), (d))
-
-/* Double loads and stores */
-# define emitm_fldl(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 1, emit_b000, (b), (i), (s), (d))
-
-# define emitm_fstpl(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 1, emit_b011, (b), (i), (s), (d))
-
-# define emitm_fstl(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 1, emit_b010, (b), (i), (s), (d))
-
-/* long double load / store */
-# define emitm_fldt(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 1, emit_b101, (b), (i), (s), (d))
-
-# define emitm_fstpt(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 1, emit_b111, (b), (i), (s), (d))
-
-/* short float load / store */
-# define emitm_flds(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b00, 1, emit_b000, (b), (i), (s), (d))
-
-# define emitm_fstps(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b00, 1, emit_b010, (b), (i), (s), (d))
-
-#if NUMVAL_SIZE == 8
-
-# define jit_emit_fload_m_n(interp, pc, address) \
- emitm_fldl((interp), (pc), emit_None, emit_None, emit_None, (address))
-
-# define jit_emit_fload_mb_n(interp, pc, base, offs) \
- emitm_fldl((interp), (pc), (base), emit_None, 1, (offs))
-
-# define jit_emit_fstore_m_n(interp, pc, address) \
- emitm_fstpl((interp), (pc), emit_None, emit_None, emit_None, (address))
-
-# define jit_emit_fstore_mb_n(interp, pc, base, offs) \
- emitm_fstpl((interp), (pc), (base), emit_None, 1, (offs))
-
-# define jit_emit_fst_mb_n(interp, pc, base, offs) \
- emitm_fstl((interp), (pc), (base), emit_None, 1, (offs))
-
-#else /* NUMVAL_SIZE */
-
-# define jit_emit_fload_m_n(interp, pc, address) \
- emitm_fldt((pc), emit_None, emit_None, emit_None, (address))
-
-# define jit_emit_fload_mb_n(interp, pc, base, offs) \
- emitm_fldt((pc), (base), emit_None, 1, (offs))
-
-# define jit_emit_fstore_m_n(pc, address) \
- emitm_fstpt((pc), emit_None, emit_None, emit_None, (address))
-
-# define jit_emit_fstore_mb_n(interp, pc, base, offs) \
- emitm_fstpt((pc), (base), emit_None, 1, (offs))
-
-# define jit_emit_fst_mb_n(interp, pc, base, offs) \
- emitm_fstt((pc), (base), emit_None, 1, (offs))
-
-#endif /* NUMVAL_SIZE */
-
-#if INTVAL_SIZE == 4
-
-# define jit_emit_fload_m_i(interp, pc, address) \
- emitm_fildl((interp), (pc), emit_None, emit_None, emit_None, (address))
-# define jit_emit_fload_mb_i(interp, pc, offs) \
- emitm_fildl((interp), (pc), emit_EBX, emit_None, 1, (offs))
-# define jit_emit_fstore_m_i(pc, m) \
- emitm_fistpl((pc), emit_None, emit_None, emit_None, (m))
-
-#else /* INTVAL_SIZE */
-
-# define jit_emit_fload_m_i(interp, pc, address) \
- emitm_fildll((interp), (pc), emit_None, emit_None, emit_None, (address))
-# define jit_emit_fload_mb_i(interp, pc, offs) \
- emitm_fildll((interp), (pc), emit_EBX, emit_None, 1, (offs))
-# define jit_emit_fstore_m_i(pc, m) \
- emitm_fistpll((pc), emit_None, emit_None, emit_None, (m))
-
-#endif /* INTVAL_SIZE */
-
-/* 0xD8 ops */
-# define emitm_fadd(pc, sti) emitm_fl_3((pc), emit_b000, emit_b000, (sti))
-# define emitm_fmul(pc, sti) emitm_fl_3((pc), emit_b000, emit_b001, (sti))
-# define emitm_fsub(pc, sti) emitm_fl_3((pc), emit_b000, emit_b100, (sti))
-# define emitm_fdiv(pc, sti) emitm_fl_3((pc), emit_b000, emit_b110, (sti))
-
-/* 0xD9 ops */
-# define emitm_fldz(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xee; }
-# define emitm_fld1(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xe8; }
-# define emitm_fsqrt(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xfa; }
-# define emitm_fsin(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xfe; }
-# define emitm_fcos(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xff; }
-# define emitm_fxam(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xe5; }
-
-/* FXCH ST, ST(i) , optimize 2 consecutive fxch with same reg */
-# define emitm_fxch(pc, sti) { \
- emitm_fl_3((pc), emit_b001, emit_b001, (sti)); \
-}
-
-/* FLD ST, ST(i), optimized FSTP(N+1);FLD(N) => FST(N+1) */
-extern unsigned char *lastpc;
-# define emitm_fld(pc, sti) do { \
- if ((unsigned char *)(pc) == (lastpc + 2) && \
- (int)(*lastpc) == (int)0xDD && \
- (int)lastpc[1] == (int)(0xD8+(sti)+1)) \
- lastpc[1] = 0xD0+(sti)+1; \
- else \
- emitm_fl_3((pc), emit_b001, emit_b000, (sti)); \
- } while (0)
-
-/* 0xDA, 0xDB ops */
-/* FCMOV*, FCOMI PPRO */
-
-/* 0xDC like 0xD8 with reversed operands */
-# define emitm_faddr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b000, (sti))
-# define emitm_fmulr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b001, (sti))
-# define emitm_fsubr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b100, (sti))
-
-/* 0xDD ops */
-/* FFree ST(i) */
-# define emitm_ffree(pc, sti) emitm_fl_3((pc), emit_b101, emit_b000, (sti))
-
-/* FST ST(i) = ST */
-# define emitm_fst(pc, sti) emitm_fl_3((pc), emit_b101, emit_b010, (sti))
-
-/* FSTP ST(i) = ST, POP */
-# define emitm_fstp(pc, sti) { \
- lastpc = (unsigned char*) (pc); \
- emitm_fl_3((pc), emit_b101, emit_b011, (sti)); \
-}
-
-/* FUCOM ST(i) <=> ST unordered compares */
-# define emitm_fucom(pc, sti) emitm_fl_3((pc), emit_b101, emit_b100, (sti))
-
-/* FUCOMP ST(i) <=> ST, POP */
-# define emitm_fucomp(pc, sti) emitm_fl_3((pc), emit_b101, emit_b101, (sti))
-
-/* 0xDE ops */
-/* FADDP Add ST(i) = ST + ST(i); POP */
-# define emitm_faddp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b000, (sti))
-
-/* FMULP Mul ST(i) = ST * ST(i); POP */
-# define emitm_fmulp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b001, (sti))
-
-/* FSUB ST = ST - ST(i) */
-
-/* FSUBRP SubR ST(i) = ST - ST(i); POP */
-# define emitm_fsubrp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b100, (sti))
-
-/* FSUBP Sub ST(i) = ST(i) - ST; POP */
-# define emitm_fsubp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b101, (sti))
-
-/* FDIVRP DivR ST(i) = ST(i) / ST(0); POP */
-# define emitm_fdivrp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b110, (sti))
-
-/* FDIVP Div ST(i) = ST(0) / ST(i); POP ST(0) */
-# define emitm_fdivp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b111, (sti))
-
-/* 0xDF OPS: FCOMIP, FUCOMIP PPRO */
-
-/* Negate - called change sign */
-# define emitm_fchs(pc) emitm_fl_4((pc), 0)
-
-/* ABS - ST(0) = ABS(ST(0)) */
-# define emitm_fabs(pc) emitm_fl_4((pc), 1)
-
-/* Comparisons */
-
-# define emitm_fcom(pc, sti) emitm_fl_3((pc), emit_b000, emit_b010, (sti))
-
-# define emitm_fcomp(pc, sti) emitm_fl_3((pc), emit_b000, emit_b011, (sti))
-
-#ifdef PARROT_HAS_JIT_FCOMIP
-# define emitm_fcomip(pc, sti) emitm_fl_3((pc), emit_b111, emit_b110, (sti))
-# define emitm_fcomi(pc, sti) emitm_fl_3((pc), emit_b011, emit_b110, (sti))
-#else
-# define emitm_fcomip(pc, sti) do { \
- emitm_fcomp((pc), (sti)); \
- emitm_fstw(pc); \
- emitm_sahf(pc); \
- } while (0)
-# define emitm_fcomi(pc, sti) do { \
- emitm_fcom((pc), (sti)); \
- emitm_fstw(pc); \
- emitm_sahf(pc); \
- } while (0)
-#endif
-
-# define emitm_fcompp(pc) { *((pc)++) = (char) 0xde; *((pc)++) = (char) 0xd9; }
-
-# define emitm_fcom_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 0, emit_b010, (b), (i), (s), (d))
-
-# define emitm_fcomp_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 0, emit_b011, (b), (i), (s), (d))
-
-/* ST -= real64 */
-# define emitm_fsub_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 0, emit_b100, (b), (i), (s), (d))
-
-/* ST -= int32_mem */
-# define emitm_fisub_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 0, emit_b100, (b), (i), (s), (d))
-
-# define emitm_fadd_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 0, emit_b000, (b), (i), (s), (d))
-
-/* ST += int32_mem */
-# define emitm_fiadd_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 0, emit_b000, (b), (i), (s), (d))
-
-/* ST *= real64 */
-# define emitm_fmul_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 0, emit_b001, (b), (i), (s), (d))
-
-/* ST *= int32_mem */
-# define emitm_fimul_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 0, emit_b001, (b), (i), (s), (d))
-
-/* ST /= real64 */
-# define emitm_fdiv_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b10, 0, emit_b110, (b), (i), (s), (d))
-
-/* ST /= int32_mem */
-# define emitm_fidiv_m(interp, pc, b, i, s, d) \
- emitm_fl_2((interp), (pc), emit_b01, 0, emit_b110, (b), (i), (s), (d))
-
-/* Ops Needed to support loading EFLAGs for conditional branches */
-# define emitm_fstw(pc) emitm_fl_3((pc), emit_b111, emit_b100, emit_b000)
-
-# define emitm_sahf(pc) *((pc)++) = (char) 0x9e
-
-/* misc float */
-# define emitm_ftst(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xE4; }
-# define emitm_fprem(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xF8; }
-# define emitm_fprem1(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xF5; }
-
-# define emitm_fldcw(interp, pc, mem) \
- emitm_fl_2((interp), (pc), emit_b00, 1, emit_b101, 0, 0, 0, (mem))
-
-#if defined(NEG_MINUS_ZERO)
-# define jit_emit_neg_r_n(pc, r) { \
- if (r) { \
- emitm_fld((pc), (r)); \
- } \
- emitm_fchs(pc); \
- if (r) { \
- emitm_fstp((pc), ((r)+1)); \
- } \
- }
-
-# define jit_emit_neg_M_n(interp, pc, mem) { \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \
- emitm_fchs(pc); \
- jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \
- }
-
-#elif defined(NEG_ZERO_SUB)
-
-# define jit_emit_neg_r_n(pc, r) { \
- emitm_fldz(pc); \
- emitm_fsubrp((pc), ((r)+1)); \
- }
-
-# define jit_emit_neg_M_n(interp, pc, mem) { \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \
- emitm_fldz(pc); \
- emitm_fsubrp((pc), 1); \
- jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \
- }
-#else
-
-# define jit_emit_neg_r_n(pc, r) { \
- if (r) { \
- emitm_fld((pc), (r)); \
- } \
- emitm_ftst(pc); \
- emitm_fstw(pc); \
- emitm_sahf(pc); \
- emitm_jxs((pc), emitm_jz, 2); \
- emitm_fchs(pc); \
- if (r) { \
- emitm_fstp((pc), ((r)+1)); \
- } \
- }
-
-# define jit_emit_neg_M_n(interp, pc, mem) { \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \
- emitm_ftst(pc); \
- emitm_fstw(pc); \
- emitm_sahf(pc); \
- emitm_jxs((pc), emitm_jz, 2); \
- emitm_fchs(pc); \
- jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \
- }
-#endif
-
-# define jit_emit_sin_r_n(pc, r) \
- if (r) { \
- emitm_fld((pc), (r)); \
- } \
- emitm_fsin(pc); \
- if (r) { \
- emitm_fstp((pc), ((r)+1)); \
- }
-
-# define jit_emit_cos_r_n(pc, r) \
- if (r) { \
- emitm_fld((pc), (r)); \
- } \
- emitm_fcos(pc); \
- if (r) { \
- emitm_fstp((pc), ((r)+1)); \
- }
-
-# define jit_emit_sqrt_r_n(pc, r) \
- if (r) { \
- emitm_fld((pc), (r)); \
- } \
- emitm_fsqrt(pc); \
- if (r) { \
- emitm_fstp((pc), ((r)+1)); \
- }
-
-# define jit_emit_abs_r_n(pc, r) { \
- if (r) { \
- emitm_fld((pc), (r)); \
- } \
- emitm_fabs(pc); \
- if (r) { \
- emitm_fstp((pc), ((r)+1)); \
- } \
- }
-
-# define jit_emit_abs_r_i(pc, r) { \
- jit_emit_test_r_i((pc), (r)); \
- emitm_jxs((pc), emitm_jns, 3); \
- jit_emit_not_r_i((pc), (r)); \
- jit_emit_inc_r_i((pc), (r)); \
- }
-
-# define jit_emit_abs_m_n(interp, pc, mem) { \
- jit_emit_fload_m_n((interp), (pc), (mem)); \
- emitm_fabs(pc); \
- jit_emit_fstore_m_n((pc), (mem)); \
- }
-
-/* Integer comparisons */
-# define jit_emit_cmp_rr(pc, reg1, reg2) \
- emitm_alul_r_r((pc), 0x39, (reg2), (reg1))
-# define jit_emit_cmp_rr_i(pc, r1, r2) jit_emit_cmp_rr((pc), (r1), (r2))
-
-# define emitm_cmpl_r_m(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x3b, (reg), (b), (i), (s), (d))
-
-# define emitm_cmpl_m_r(pc, reg, b, i, s, d) \
- emitm_alul_r_m((pc), 0x39, (reg), (b), (i), (s), (d))
-
-# define jit_emit_cmp_ri_i(interp, pc, reg, imm) \
- emitm_alul_i_r((pc), 0x81, emit_b111, (imm), (reg))
-
-/* Unconditional Jump/Call */
-
-# define emitm_call_cfunc(pc, func) emitm_calll((pc), (char *)(func) - (pc) - 4)
-
-# define emitm_calll(pc, disp) { \
- *((pc)++) = (char) 0xe8; \
- *(long *)(pc) = (disp); (pc) += 4; }
-
-# define emitm_callr(pc, reg) { \
- *((pc)++) = (char) 0xff; \
- *((pc)++) = (char) 0xd0 | ((reg) - 1); }
-
-#if EXEC_CAPABLE
-# define emitm_callm(pc, b, i, s, d) { \
- *((pc)++) = (char) 0xff; \
- (pc) = emit_r_X((interp), (pc), emit_reg(emit_b010), (b), (i), (s), (d));\
- }
-#else /* EXEC_CAPABLE */
-# define emitm_callm(pc, b, i, s, d) { \
- *((pc)++) = (char) 0xff; \
- (pc) = emit_r_X((interp), (pc), emit_reg(emit_b010), (b), (i), (s), (d)); }
-#endif /* EXEC_CAPABLE */
-
-# define emitm_jumps(pc, disp) { \
- *((pc)++) = (char) 0xeb; \
- *((pc)++) = (disp); }
-
-# define emitm_jumpl(pc, disp) { \
- *((pc)++) = (char) 0xe9; \
- *(long *)(pc) = (disp); (pc) += 4; }
-
-# define emitm_jumpr(pc, reg) { \
- *((pc)++) = (char) 0xff; \
- *((pc)++) = (char)(0xe0 | ((reg) - 1)); }
-
-#if EXEC_CAPABLE
-# define emitm_jumpm(pc, b, i, s, d) { \
- *((pc)++) = (char) 0xff; \
- (pc) = emit_r_X((interp), (pc), emit_reg(emit_b100), (b), (i), (s), (d)); \
- }
-#else /* EXEC_CAPABLE */
-# define emitm_jumpm(pc, b, i, s, d) { \
- *((pc)++) = (char) 0xff; \
- (pc) = emit_r_X((interp), (pc), emit_reg(emit_b100), (b), (i), (s), (d)); }
-#endif /* EXEC_CAPABLE */
-
-/* Conditional jumps */
-
-/* Short jump - 8 bit disp */
-# define emitm_jxs(pc, code, disp) { \
- *((pc)++) = (char)(0x70 | (code)); \
- *((pc)++) = (char)(disp); }
-
-/* Long jump - 32 bit disp */
-# define emitm_jxl(pc, code, disp) { \
- *((pc)++) = (char) 0x0f; \
- *((pc)++) = (char)(0x80 | (code)); \
- *(long *)(pc) = (disp); (pc) += 4; }
-
-# define emitm_jo 0
-# define emitm_jno 1
-# define emitm_jb 2
-# define emitm_jnb 3
-# define emitm_jz 4
-# define emitm_je emitm_jz
-# define emitm_jnz 5
-# define emitm_jne emitm_jnz
-# define emitm_jbe 6
-# define emitm_ja 7
-# define emitm_js 8
-# define emitm_jns 9
-# define emitm_jp 10
-# define emitm_jnp 11
-# define emitm_jl 12
-# define emitm_jnl 13
-# define emitm_jle 14
-# define emitm_jg 15
-
-/* set byte conditional */
-# define jit_emit_setcc_r(pc, cc, r) \
- *(pc)++ = 0x0f; \
- *(pc)++ = 0x90 + (cc); \
- *(pc)++ = (char) emit_alu_X_r(0, (r))
-
-/*
- * core.jit interface
- *
- * The new offset based versions have uppercase RM or MR inside
- * That's probably only during transition time
- */
-
-# define jit_emit_mov_mi_i(pc, dest, immediate) \
- emitm_movl_i_m((pc), (immediate), emit_None, emit_None, emit_None, (dest))
-
-# define jit_emit_mov_MI_i(interp, pc, offs, immediate) \
- emitm_movl_i_m((pc), (immediate), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_mov_rm_i(interp, pc, reg, address) \
- emitm_movl_m_r((interp), (pc), (reg), emit_None, emit_None, emit_None, (address))
-
-# define jit_emit_mov_RM_i(interp, pc, reg, offs) \
- emitm_movl_m_r((interp), (pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_mov_mr_i(interp, pc, address, reg) \
- emitm_movl_r_m((interp), (pc), (reg), emit_None, emit_None, emit_None, (address))
-
-# define jit_emit_mov_MR_i(interp, pc, offs, reg) \
- emitm_movl_r_m((interp), (pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_mul_RM_i(interp, pc, reg, offs) \
- emitm_smull_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_sub_RM_i(interp, pc, reg, offs) \
- emitm_subl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_sub_MR_i(interp, pc, offs, reg) \
- emitm_subl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_sub_MI_i(pc, offs, imm) \
- emitm_subl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_add_RM_i(interp, pc, reg, offs) \
- emitm_addl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_add_MR_i(interp, pc, offs, reg) \
- emitm_addl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_add_MI_i(pc, offs, imm) \
- emitm_addl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_cmp_rm_i(pc, reg, address) \
- emitm_cmpl_r_m((pc), (reg), emit_None, emit_None, emit_None, (address))
-
-# define jit_emit_cmp_RM_i(interp, pc, reg, offs) \
- emitm_cmpl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_cmp_MR_i(interp, pc, offs, reg) \
- emitm_cmpl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-/* high level routines, behave like real 2 register FP */
-
-/* mapped float registers numbers are ST(1)-ST(4).
- * scratch register is ST(0)
- */
-
-/* ST(i) <- numvar */
-# define jit_emit_mov_RM_n(interp, pc, r, d) { \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (d)); \
- emitm_fstp((pc), ((r)+1)); \
-}
-
-/* ST(i) <= NUM_CONST */
-# define jit_emit_mov_ri_n(interp, pc, r, i) { \
- jit_emit_fload_m_n((interp), (pc), (i)); \
- emitm_fstp((pc), ((r)+1)); \
-}
-
-/* ST(i) <= &INT_CONST */
-# define jit_emit_mov_ri_ni(interp, pc, r, i) { \
- jit_emit_fload_m_i((interp), (pc), (i)); \
- emitm_fstp((pc), ((r)+1)); \
-}
-
-/* ST(i) <= INT_REG */
-# define jit_emit_mov_RM_ni(interp, pc, r, i) { \
- jit_emit_fload_mb_i((interp), (pc), (i)); \
- emitm_fstp((pc), ((r)+1)); \
-}
-
-/* NUM_REG(i) <= &INT_CONST
- * the int const i is loaded from the code memory
- */
-# define jit_emit_mov_MI_ni(interp, pc, offs, i) { \
- jit_emit_fload_m_i((interp), (pc), (i)); \
- jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \
-}
-
-/* INT_REG <= ST(i) */
-# define jit_emit_mov_mr_in(pc, mem, r) { \
- emitm_fld((pc), (r)); \
- jit_emit_fstore_m_i((pc), (mem)); \
-}
-
-/* numvar <- ST(i) */
-# define jit_emit_mov_mr_n(pc, d, r) { \
- emitm_fld((pc), (r)); \
- jit_emit_fstore_m_n((pc), (d)); \
-}
-
-# define jit_emit_mov_MR_n(interp, pc, d, r) { \
- if (r) { \
- emitm_fld((pc), (r)); \
- jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (d)); \
- } \
- else { \
- jit_emit_fst_mb_n((interp), (pc), emit_EBX, (d)); \
- } \
-}
-
-/* ST(r1) <= ST(r2) */
-# define jit_emit_mov_rr_n(pc, r1, r2) { \
- if ((r1) != (r2)) { \
- if (r2) { \
- emitm_fld((pc), (r2)); \
- emitm_fstp((pc), ((r1)+1)); \
- } \
- else { \
- emitm_fst((pc), (r1)); \
- } \
- } \
-}
-
-/* ST(r1) xchg ST(r2) */
-# define jit_emit_xchg_rr_n(interp, pc, r1, r2) { \
- if ((r1) != (r2)) { \
- emitm_fld((pc), (r1)); \
- emitm_fld((pc), ((r2)+1)); \
- emitm_fstp((pc), ((r1)+2)); \
- emitm_fstp((pc), ((r2)+1)); \
- } \
-}
-
-# define jit_emit_xchg_RM_n(interp, pc, r, offs) { \
- emitm_fld((pc), (r)); \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
- emitm_fstp((pc), ((r)+2)); \
- jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \
-}
-
-# define jit_emit_xchg_MR_n(interp, pc, offs, r) { \
- emitm_fld((pc), (r)); \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
- emitm_fstp((pc), ((r)+2)); \
- jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \
-}
-
-# define jit_emit_finit(pc) { *((pc)++) = (char) 0xdb; *((pc)++) = (char) 0xe3; }
-
-/* ST(i) op= MEM */
-
-# define jit_emit_xxx_rm_n(interp, op, pc, r, m) { \
- jit_emit_fload_m_n((interp), (pc), (m)); \
- emitm_f ## op ## p((pc), ((r)+1)); \
-}
-
-# define jit_emit_xxx_RM_n(interp, op, pc, r, offs) { \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
- emitm_f ## op ## p((pc), ((r)+1)); \
-}
-
-/*
- * float ops in two flavors: abs memory for constants, offsets for regs
- */
-
-# define jit_emit_add_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), add, (pc), (r), (m))
-# define jit_emit_sub_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), sub, (pc), (r), (m))
-# define jit_emit_mul_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), mul, (pc), (r), (m))
-
-# define jit_emit_add_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), add, (pc), (r), (o))
-# define jit_emit_sub_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), sub, (pc), (r), (o))
-# define jit_emit_mul_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), mul, (pc), (r), (o))
-
-/* ST(r1) += ST(r2) */
-/* r1 == 0: ST(0) <- ST(0) + ST(i)
- * r2 == 0: ST(i) <- ST(0) + ST(i)
- */
-# define jit_emit_add_rr_n(interp, pc, r1, r2) do { \
- if (!(r1)) { \
- emitm_fadd((pc), (r2)); \
- } \
- else if (!(r2)) { \
- emitm_faddr((pc), (r1)); \
- } \
- else { \
- emitm_fld((pc), (r2)); \
- emitm_faddp((pc), ((r1)+1)); \
- } \
- } \
- while (0)
-/*
- * ST(r) += INT_REG
- */
-# define jit_emit_add_RM_ni(pc, r, offs) { \
- emitm_fld((pc), (r)); \
- emitm_fiadd_m((pc), emit_EBX, 0, 1, (offs)); \
- emitm_fstp((pc), ((r)+1)); \
-}
-
-/* ST(r1) -= ST(r2) */
-/* r1 == 0: ST(0) <- ST(0) - ST(i)
- * r2 == 0: ST(i) <- ST(i) - ST(0)
- */
-# define jit_emit_sub_rr_n(interp, pc, r1, r2) do { \
- if (!(r1)) { \
- emitm_fsub((pc), (r2)); \
- } \
- else if (!(r2)) { \
- emitm_fsubr((pc), (r1)); \
- } \
- else { \
- emitm_fld((pc), (r2)); \
- emitm_fsubp((pc), ((r1)+1)); \
- } \
- } \
- while (0)
-
-/*
- * ST(r) -= INT_REG
- */
-# define jit_emit_sub_RM_ni(pc, r, offs) { \
- emitm_fld((pc), (r)); \
- emitm_fisub_m((pc), emit_EBX, 0, 1, (offs)); \
- emitm_fstp((pc), ((r)+1)); \
-}
-
-# define jit_emit_inc_r_n(pc, r) { \
- emitm_fld1(pc); \
- emitm_faddp((pc), ((r)+1)); \
-}
-
-# define jit_emit_dec_r_n(pc, r) { \
- emitm_fld1(pc); \
- emitm_fsubp((pc), ((r)+1)); \
-}
-
-/* ST(r1) *= ST(r2) */
-/* r1 == 0: ST(0) <- ST(0) * ST(i)
- * r2 == 0: ST(i) <- ST(0) * ST(i)
- */
-# define jit_emit_mul_rr_n(interp, pc, r1, r2) do { \
- if (!(r1)) { \
- emitm_fmul((pc), (r2)); \
- } \
- else if (!(r2)) { \
- emitm_fmulr((pc), (r1)); \
- } \
- else { \
- emitm_fld((pc), (r2)); \
- emitm_fmulp((pc), ((r1)+1)); \
- } \
- } \
- while (0)
-
-/*
- * ST(r) *= INT_REG
- */
-# define jit_emit_mul_RM_ni(pc, r, offs) { \
- emitm_fld((pc), (r)); \
- emitm_fimul_m((pc), emit_EBX, 0, 1, (offs)); \
- emitm_fstp((pc), ((r)+1)); \
-}
-
-/*
- * ST(r) /= INT_REG
- */
-# define jit_emit_div_RM_ni(pc, r, offs) { \
- emitm_fld((pc), (r)); \
- emitm_fidiv_m((pc), emit_EBX, 0, 1, (offs)); \
- emitm_fstp((pc), ((r)+1)); \
-}
-
-/* test r for zero */
-# define jit_emit_test_r_n(pc, r) { \
- if (r) { \
- emitm_fxch((pc), (r)); \
- } \
- emitm_fxam(pc); \
- emitm_fstw(pc); \
- emitm_sahf(pc); \
- if (r) { \
- emitm_fxch((pc), (r)); \
- } \
-}
-
-/* ST(r1) /= ST(r2) */
-char * div_rr_n(PARROT_INTERP, Parrot_jit_info_t *jit_info, int r1);
-
-# define jit_emit_div_rr_n(interp, pc, r1, r2) \
- emitm_fld((pc), (r2)); \
- jit_info->native_ptr = (pc); \
- (pc) = div_rr_n((interp), jit_info, (r1))
-
-# define jit_emit_div_ri_n(interp, pc, r, m) \
- jit_emit_fload_m_n((interp), (pc), (m)); \
- jit_info->native_ptr = (pc); \
- (pc) = div_rr_n((interp), jit_info, (r))
-
-# define jit_emit_div_RM_n(interp, pc, r, o) \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (o)); \
- jit_info->native_ptr = (pc); \
- (pc) = div_rr_n((interp), jit_info, (r))
-
-char * mod_rr_n(PARROT_INTERP, Parrot_jit_info_t *jit_info, int r);
-
-/* ST(i) %= MEM
- * please note the hardcoded jumps */
-# define jit_emit_cmod_RM_n(interp, pc, r, offs) \
- if (r) \
- emitm_fxch((pc), (r)); \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
- (pc) = mod_rr_n((interp), jit_info, (r))
-
-# define jit_emit_cmod_ri_n(interp, pc, r, mem) \
- if (r) \
- emitm_fxch((pc), (r)); \
- jit_emit_fload_m_n((interp), (pc), (mem)); \
- (pc) = mod_rr_n((interp), jit_info, (r))
-
-/* ST(r1) %= ST(r2) */
-# define jit_emit_cmod_rr_n(interp, pc, r1, r2) \
- if (r1) \
- emitm_fxch((pc), (r1)); \
- emitm_fld((pc), (r2)); \
- (pc) = mod_rr_n((interp), jit_info, (r1))
-
-/* compare ST(r) <-> mem i.e. constant */
-# define jit_emit_cmp_ri_n(interp, pc, r, mem) { \
- jit_emit_fload_m_n((interp), (pc), (mem)); \
- emitm_fld((pc), ((r)+1)); \
- emitm_fcompp(pc); \
- emitm_fstw(pc); \
- emitm_sahf(pc); \
-}
-
-# define jit_emit_cmp_RM_n(interp, pc, r, offs) { \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
- emitm_fld((pc), ((r)+1)); \
- emitm_fcompp(pc); \
- emitm_fstw(pc); \
- emitm_sahf(pc); \
-}
-
-/* compare mem <-> ST(r) */
-# define jit_emit_cmp_mi_n(interp, pc, mem, r) { \
- jit_emit_fload_m_n((interp), (pc), (mem)); \
- emitm_fcomip((pc), ((r)+1)); \
-}
-
-# define jit_emit_cmp_MR_n(interp, pc, offs, r) { \
- jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \
- emitm_fcomip((pc), ((r)+1)); \
-}
-
-/* compare ST(r1) <-> ST(r2) test FCOMI (=fcom, fstw, sahf) */
-# define jit_emit_cmp_rr_n(pc, r1, r2) { \
- if (!(r2) || ((r1)==(r2))) { \
- emitm_fld((pc), (r1)); \
- emitm_fcomip((pc), ((r2)+1)); \
- } \
- else { \
- if (r1) { \
- emitm_fxch((pc), (r1)); \
- emitm_fcomi((pc), (r2)); \
- emitm_fxch((pc), (r1)); \
- } \
- else { \
- emitm_fcomi((pc), (r2)); \
- } \
- } \
-}
-
-# define jit_emit_neg_M_i(interp, pc, offs) \
- emitm_negl_m((pc), emit_EBX, emit_None, 1, (long)(offs))
-
-# define jit_emit_band_MR_i(interp, pc, offs, reg) \
- emitm_andl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_band_RM_i(interp, pc, reg, offs) \
- emitm_andl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_band_MI_i(pc, offs, imm) \
- emitm_andl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_bor_MR_i(interp, pc, offs, reg) \
- emitm_orl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_bor_RM_i(interp, pc, reg, offs) \
- emitm_orl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_bor_MI_i(pc, offs, imm) \
- emitm_orl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_bxor_MR_i(interp, pc, offs, reg) \
- emitm_xorl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_bxor_RM_i(interp, pc, reg, offs) \
- emitm_xorl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs))
-
-# define jit_emit_bxor_MI_i(pc, offs, imm) \
- emitm_xorl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs))
-
-/* dest /= src
- * edx:eax /= src, quotient => eax, rem => edx
- */
-char * opt_div_rr(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest,
- int src, int is_div);
-
-# define jit_emit_div_rr_i(interp, pc, r1, r2) (pc) = opt_div_rr((interp), jit_info, (r1), (r2), 1)
-# define jit_emit_cmod_rr_i(interp, pc, r1, r2) (pc) = opt_div_rr((interp), jit_info, (r1), (r2), 0)
-
-char * opt_div_ri(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest,
- INTVAL imm, int is_div);
-
-# define jit_emit_div_ri_i(pc, r1, imm) (pc) = opt_div_ri(interp, jit_info, (r1), (imm), 1)
-# define jit_emit_cmod_ri_i(pc, r1, imm) (pc) = opt_div_ri(interp, jit_info, (r1), (imm), 0)
-
-char * opt_div_RM(PARROT_INTERP, Parrot_jit_info_t *jit_info, int dest,
- int offs, int is_div);
-
-# define jit_emit_div_RM_i(interp, pc, r, m) (pc) = opt_div_RM((interp), jit_info, (r), (m), 1)
-# define jit_emit_cmod_RM_i(interp, pc, r, m) (pc) = opt_div_RM((interp), jit_info, (r), (m), 0)
-
-enum { JIT_X86BRANCH, JIT_X86JUMP, JIT_X86CALL };
-
-void jit_emit_jcc(Parrot_jit_info_t *jit_info, int code, opcode_t disp);
-
-void emit_jump(Parrot_jit_info_t *jit_info, opcode_t disp);
-
-void Parrot_emit_jump_to_eax(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-# define jit_emit_stack_frame_enter(pc) do { \
- emitm_pushl_r((pc), emit_EBP); \
- jit_emit_mov_rr_i((pc), emit_EBP, emit_ESP); \
-} while (0)
-
-# define jit_emit_stack_frame_leave(pc) do { \
- jit_emit_mov_rr_i((pc), emit_ESP, emit_EBP); \
- emitm_popl_r((pc), emit_EBP); \
-} while (0)
-
-#if JIT_VTABLE_OPS
-
-# undef Parrot_jit_vtable1_op
-# undef Parrot_jit_vtable1r_op
-
-# undef Parrot_jit_vtable_111_op
-# undef Parrot_jit_vtable_112_op
-# undef Parrot_jit_vtable_221_op
-# undef Parrot_jit_vtable_1121_op
-# undef Parrot_jit_vtable_1123_op
-# undef Parrot_jit_vtable_2231_op
-
-# undef Parrot_jit_vtable_1r223_op
-# undef Parrot_jit_vtable_1r332_op
-
-# undef Parrot_jit_vtable_ifp_op
-# undef Parrot_jit_vtable_unlessp_op
-# undef Parrot_jit_vtable_newp_ic_op
-
-/* emit a call to a vtable func
- * $X->vtable(interp, $X [, $Y...])
- */
-# define MAP(i) jit_info->optimizer->map_branch[jit_info->op_i + (i)]
-
-# include "parrot/oplib/ops.h"
-
-INTVAL Parrot_FixedIntegerArray_get_integer_keyed_int(Interp*, PMC*, INTVAL);
-void Parrot_FixedIntegerArray_set_integer_keyed_int(Interp*, PMC*, INTVAL, INTVAL);
-
-char * jit_set_i_p_ki(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- size_t offset);
-
-char * jit_set_p_ki_i(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- size_t offset);
-
-/*
- * for vtable calls registers are already saved back
- */
-void Parrot_jit_vtable_n_op(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int n, int *args);
-
-void Parrot_jit_store_retval(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1)
- */
-void Parrot_jit_vtable1_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1 = $2->vtable(interp, $2)
- */
-void Parrot_jit_vtable1r_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1 = $2->vtable(interp, $2, $3)
- */
-void Parrot_jit_vtable_1r223_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1 = $3->vtable(interp, $3, $2)
- */
-void Parrot_jit_vtable_1r332_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2)
- */
-void Parrot_jit_vtable_112_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $1)
- */
-void Parrot_jit_vtable_111_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $2->vtable(interp, $2, $1)
- */
-void Parrot_jit_vtable_221_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $2->vtable(interp, $2, $3, $1)
- */
-void Parrot_jit_vtable_2231_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2, $3)
- */
-void Parrot_jit_vtable_1123_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2, $1)
- */
-void Parrot_jit_vtable_1121_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* if_p_ic, unless_p_ic */
-void Parrot_jit_vtable_if_unless_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int unless);
-
-/* unless_p_ic */
-void Parrot_jit_vtable_unlessp_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* if_p_ic */
-void Parrot_jit_vtable_ifp_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-#endif /* JIT_VTABLE_OPS */
-
-#if EXEC_CAPABLE
-# ifdef JIT_CGP
-# ifdef EXEC_SHARED
-# define exec_emit_end(interp, pc) { \
- jit_emit_mov_rm_i((pc), c, 2); \
- Parrot_exec_add_text_rellocation(jit_info->objfile, \
- jit_info->native_ptr, RTYPE_COM, "cgp_core", 0); \
- emitm_movl_m_r((interp), jit_info->native_ptr, emit_ESI, emit_ESI, \
- emit_None, 1, 0); \
- emitm_addb_i_r(jit_info->native_ptr, \
- (int)((ptrcast_t)((op_func_t*) \
- (interp)->op_lib->op_func_table)[0]) - (int)cgp_core, \
- emit_ESI); \
- emitm_jumpr((pc), emit_ESI); \
- }
-# else /* EXEC_SHARED */
-# define exec_emit_end(interp, pc) { \
- jit_emit_mov_ri_i((interp), (pc), emit_ESI, \
- (int)((ptrcast_t)((op_func_t*) \
- (interp)->op_lib->op_func_table)[0]) - (int)cgp_core); \
- Parrot_exec_add_text_rellocation(jit_info->objfile, \
- jit_info->native_ptr, RTYPE_COM, "cgp_core", -4); \
- emitm_jumpr((pc), emit_ESI); \
- }
-# endif /* EXEC_SHARED */
-
-# else /* JIT_CGP */
-
-# define exec_emit_end(pc) jit_emit_end(pc)
-
-# endif /* JIT_CGP */
-#endif /* EXEC_CAPABLE */
-
-#ifdef JIT_CGP
-# define jit_emit_end(interp, pc) { \
- jit_emit_mov_ri_i((interp), (pc), emit_ESI, \
- (ptrcast_t)((op_func_t*)(interp)->op_lib->op_func_table) [0]); \
- emitm_jumpr((pc), emit_ESI); \
- }
-#else /* JIT_CGP */
-# define jit_emit_end(pc) { \
- jit_emit_add_ri_i((interp), (pc), emit_ESP, 4); \
- emitm_popl_r((pc), emit_EDI); \
- emitm_popl_r((pc), emit_ESI); \
- emitm_popl_r((pc), emit_EBX); \
- emitm_popl_r((pc), emit_EBP); \
- emitm_ret(pc); \
- }
-
-#endif /* JIT_CGP */
-
-void jit_get_params_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/*
- * preserve registers
- * a) all callee saved on function entry
- */
-
-void jit_save_regs(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/* restore saved regs, see above */
-
-void jit_restore_regs(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/*
- * preserve registers around a functioncall
- *
- * all used register around a call (skip >= 0 := return result
- *
- * TODO factor out common code
- * use jit_emit_mov_RM_{in} functions (load/store base indexed)
- * and a macro to retrieve sp
- */
-
-int jit_save_regs_call(Parrot_jit_info_t *jit_info, PARROT_INTERP, int skip);
-
-void jit_restore_regs_call(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int skip);
-
-void jit_set_returns_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int recursive);
-
-void jit_set_args_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int recursive);
-
-/*
- * if jit_emit_noop is defined, it does align a jump target
- * to 1 << JUMP_ALIGN
- * It may emit exactly one byte, or some desired padding.
- * The instructions must perform like a noop.
- *
- * Alignment effects seem to be rather processor specific and
- * it's not quite clear if the branch src or target should be
- * aligned. Turned off for now.
- *
- * s. also info gcc /align-jump
- *
- * noop; mov %esi, %esi; lea 0(%esi), %esi
- * TODO
- * 7 bytes: 8d b4 26 00 00 00 00 lea 0x0(%esi),%esi
- * 6 bytes: 8d b6 00 00 00 00 lea 0x0(%esi),%esi
- * 5 bytes: 90 8d 74 26 00 nop, lea 0x0(%esi),%esi
- * 4 bytes: 8d 74 26 00 lea 0x0(%esi),%esi
- *
- */
-
-# define jit_emit_noop(pc) do { \
- switch (((unsigned long) (pc)) & 3) { \
- case 1: *(pc)++ = (char) 0x8d; *(pc)++ = (char) 0x76; *(pc)++ = (char) 0x00; break; \
- case 2: *(pc)++ = (char) 0x89; *(pc)++ = (char) 0xf6; break; \
- case 3: *(pc)++ = (char) 0x90; break; \
- } \
- } while (0)
-
-# define JUMP_ALIGN 0
-# define SUB_ALIGN 0
-
-#ifdef JIT_EMIT
-# if JIT_EMIT == 0
-
-extern int control_word;
-
-# ifdef JIT_CGP
-# include <parrot/oplib/core_ops_cgp.h>
-# endif
-
-# define REQUIRES_CONSTANT_POOL 0
-/*
- * examples/pir/mandel.pir and t/op/jitn_14 show rounding problems
- * due to keeping intermediate results in FP registers
- * When intermediates are written back to parrot regs, rounding to
- * 64 bit is performed, which changes results slightly
- *
- * One method is to just turn off mapped floats. The other one is
- * setting a different control word (with precision control = double)
- * see emitm_fldcw above
- */
-# define FLOAT_REGISTERS_TO_MAP 4
-
-/* registers are either allocate per section or per basic block
- * set this to 1 or 0 to change allocation scheme
- */
-# define ALLOCATE_REGISTERS_PER_SECTION 1
-
-/*
- * new style move function using offsets relative to the base_reg
- */
-# ifdef JIT_CGP
-# define INTERP_BP_OFFS todo
-# else
-# define INTERP_BP_OFFS -16
-# endif
-
-# endif /* JIT_EMIT = 0 */
-#endif /* JIT_EMIT */
-
-void Parrot_jit_dofixup(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void Parrot_jit_begin(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-/*
- * create a JITted version of a PIR sub, where everything
- * resided in registers
- *
- * The sub is called as
- *
- * opcode_t * func(Interp *i, INTVAL *sig_bits, void **args);
- *
- * args[0] ... NULL / return value address
- * args[1..n] ... addresses of n arguments
- * args[n + 1] .. opcode_t* next - usually just returned
- */
-
-void Parrot_jit_begin_sub_regs(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void Parrot_jit_begin_sub(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void jit_mov_mr_n_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg);
-
-void jit_mov_mr_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int base_reg, INTVAL offs, int src_reg);
-
-void jit_mov_rm_n_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs);
-
-void jit_mov_rm_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info,
- int dst_reg, int base_reg, INTVAL offs);
-
-void Parrot_jit_emit_finit(Parrot_jit_info_t *jit_info);
-
-void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-#ifdef JIT_EMIT
-# if JIT_EMIT == 2
-/* generate code just once */
-
-/* autogened inside core.ops */
-static void Parrot_end_jit(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-# undef Parrot_jit_restart_op
-# endif /* JIT_EMIT == 2 */
-#endif /* JIT_EMIT */
-
-void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP);
-
-int count_regs(PARROT_INTERP, char *sig, char *sig_start);
-
-size_t calc_signature_needs(const char *sig, int *strings);
-
-void * Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci,
- STRING *signature, int *sizeptr);
-
-/*
- * register usage
- * %edi, %esi ... mapped, preserved
- * %edx, %ecx ... mapped, not preserved
- * %ebx ... base pointer for register access, preserved
- * %eax ... scratch, return value register
- */
-
-extern const char i_map[];
-
-extern const char floatval_map[];
-
-extern const char i_map_sub[];
-
-extern const jit_arch_info arch_info;
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info * Parrot_jit_init(PARROT_INTERP);
-
-#undef INT_REGISTERS_TO_MAP
-#endif /* PARROT_I386_JIT_EMIT_H_GUARD */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/ia64/core.jit
==============================================================================
--- trunk/src/jit/ia64/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,305 +0,0 @@
-;
-; ia64/core.jit
-;
-;
-; $Id$
-;
-
-Parrot_end {
- jit_emit_end(NATIVECODE);
-}
-
-Parrot_set_i_ic {
- if (MAP[1]) {
- jit_emit_mov_ri_i(NATIVECODE, MAP[1], *INT_CONST[2]);
- }
- else {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- NATIVECODE = close_template(NATIVECODE);
-}
-
-Parrot_set_i_i {
- if (MAP[1] && MAP[2]) {
- jit_emit_mov_rr(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, MAP[1], &INT_REG[2]);
- }
- else if (MAP[2]) {
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], MAP[2]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- NATIVECODE = close_template(NATIVECODE);
-}
-
-TEMPLATE Parrot_binop_i_ic {
- if (MAP[1]) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[1], ISR1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
- jit_emit_mov_ri_i(NATIVECODE, ISR2, *INT_CONST[2]);
- jit_emit_<op>_rrr(NATIVECODE, ISR1, ISR2, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- NATIVECODE = close_template(NATIVECODE);
-}
-
-TEMPLATE Parrot_binop_x_x {
- if (MAP[1] && MAP[2]) {
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[2]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[1], <s1>);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[1]);
- jit_emit_<op>_rrr(NATIVECODE, <s1>, <s1>, MAP[2]);
- jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[1]);
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, &<T>_REG[2]);
- jit_emit_<op>_rrr(NATIVECODE, <s1>, <s2>, <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
- }
- NATIVECODE = close_template(NATIVECODE);
-}
-
-TEMPLATE Parrot_binop_x_x_x {
- if (MAP[1] && MAP[2] && MAP[3]) {
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[2], MAP[3]);
- }
- else if (MAP[1] && MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[3]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[2], <s1>);
- }
- else if (MAP[1] && MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[2]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], <s1>, MAP[3]);
- }
- else if (MAP[2] && MAP[3]) {
- jit_emit_<op>_rrr(NATIVECODE, <s1>, MAP[2], MAP[3]);
- jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[3]);
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, &<T>_REG[2]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], <s2>, <s1>);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[3]);
- jit_emit_<op>_rrr(NATIVECODE, <s1>, MAP[2], <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
- }
- else if (MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[2]);
- jit_emit_<op>_rrr(NATIVECODE, <s1>, <s1>, MAP[3]);
- jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, &<T>_REG[3]);
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, &<T>_REG[2]);
- jit_emit_<op>_rrr(NATIVECODE, <s1>, <s2>, <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, &<T>_REG[1], <s1>);
- }
- NATIVECODE = close_template(NATIVECODE);
-}
-
-TEMPLATE Parrot_binop_i_ic_i {
- if (MAP[1] && MAP[3]) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], ISR1, MAP[3]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_mov_ri_i(NATIVECODE, ISR2, *INT_CONST[2]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], ISR2, ISR1);
- }
- else if (MAP[3]) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- jit_emit_<op>_rrr(NATIVECODE, ISR1, ISR1, MAP[3]);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[3]);
- jit_emit_mov_ri_i(NATIVECODE, ISR2, *INT_CONST[2]);
- jit_emit_<op>_rrr(NATIVECODE, ISR1, ISR2, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- NATIVECODE = close_template(NATIVECODE);
-}
-
-TEMPLATE Parrot_binop_i_i_ic {
- if (MAP[1] && MAP[2]) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[3]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], MAP[2], ISR1);
- }
- else if (MAP[1]) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[3]);
- jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
- jit_emit_<op>_rrr(NATIVECODE, MAP[1], ISR2, ISR1);
- }
- else if (MAP[2]) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[3]);
- jit_emit_<op>_rrr(NATIVECODE, ISR1, MAP[2], ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[3]);
- jit_emit_mov_rm_i(NATIVECODE, ISR2, &INT_REG[2]);
- jit_emit_<op>_rrr(NATIVECODE, ISR1, ISR2, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- NATIVECODE = close_template(NATIVECODE);
-}
-
-Parrot_band_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bor_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bxor_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_add_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_sub_i_i {
- Parrot_binop_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_band_i_ic {
- Parrot_binop_i_ic s/<op>/and/
-}
-
-Parrot_bor_i_ic {
- Parrot_binop_i_ic s/<op>/or/
-}
-
-Parrot_bxor_i_ic {
- Parrot_binop_i_ic s/<op>/xor/
-}
-
-Parrot_add_i_ic {
- Parrot_binop_i_ic s/<op>/add/
-}
-
-Parrot_sub_i_ic {
- Parrot_binop_i_ic s/<op>/sub/
-}
-
-Parrot_band_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bor_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bxor_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_add_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_sub_i_i_i {
- Parrot_binop_x_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_band_i_i_ic {
- Parrot_binop_i_i_ic s/<op>/and/
-}
-
-Parrot_bor_i_i_ic {
- Parrot_binop_i_i_ic s/<op>/or/
-}
-
-Parrot_bxor_i_i_ic {
- Parrot_binop_i_i_ic s/<op>/xor/
-}
-
-Parrot_add_i_i_ic {
- Parrot_binop_i_i_ic s/<op>/add/
-}
-
-Parrot_sub_i_i_ic {
- Parrot_binop_i_i_ic s/<op>/sub/
-}
-
-Parrot_band_i_ic_i {
- Parrot_binop_i_ic_i s/<op>/and/
-}
-
-Parrot_bor_i_ic_i {
- Parrot_binop_i_ic_i s/<op>/or/
-}
-
-Parrot_bxor_i_ic_i {
- Parrot_binop_i_ic_i s/<op>/xor/
-}
-
-Parrot_add_i_ic_i {
- Parrot_binop_i_ic_i s/<op>/add/
-}
-
-Parrot_sub_i_ic_i {
- Parrot_binop_i_ic_i s/<op>/sub/
-}
-
-Parrot_neg_i {
- if (MAP[1]) {
- jit_emit_neg_rr(NATIVECODE, MAP[1], MAP[1]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
- jit_emit_neg_rr(NATIVECODE, ISR1, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
-}
-
-Parrot_neg_i_i {
- if (MAP[1] && MAP[2]) {
- jit_emit_neg_rr(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
- jit_emit_neg_rr(NATIVECODE, MAP[1], ISR1);
- }
- else if (MAP[2]) {
- jit_emit_neg_rr(NATIVECODE, ISR1, MAP[1]);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[2]);
- jit_emit_neg_rr(NATIVECODE, ISR1, ISR1);
- jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
- }
-}
-
-Parrot_if_i_ic {
- if (MAP[1]) {
- jit_emit_cmp_r0(NATIVECODE, MAP[1]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
- jit_emit_cmp_r0(NATIVECODE, ISR1);
- }
- jit_emit_bc(jit_info, *INT_CONST[2]);
- NATIVECODE = close_template(NATIVECODE);
-}
-
Deleted: trunk/src/jit/ia64/jit_defs.c
==============================================================================
--- trunk/src/jit/ia64/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,13 +0,0 @@
-/* Stub file for RT#38929 fixes */
-/*
-Copyright (C) 2008, Parrot Foundation.
-$Id$
-*/
-/* HEADERIZER HFILE: none */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/ia64/jit_emit.h
==============================================================================
--- trunk/src/jit/ia64/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,779 +0,0 @@
-/*
- * Copyright (C) 2004-2007, Parrot Foundation.
- */
-
-#ifndef PARROT_JIT_IA64_JIT_EMIT_H_GUARD
-#define PARROT_JIT_IA64_JIT_EMIT_H_GUARD
-
-/*
- * jit_emit.h
- *
- * IA64
- *
- * $Id$
- */
-
-#if JIT_EMIT
-
-# define NATIVE_PTR ((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr
-
-/* r0 Zero
- * r1 Special
- * r2-r3 Scratch
- * r4-r7 Preserved
- * r8-r11 Scratch
- * r12-r13 Special
- * r14-r31 Scratch
- */
-
-long it = 0;
-int inst_size = 0;
-int inst_tmpl = 0;
-
-typedef struct inst_tmp_t {
- char tmplt;
- char used;
- unsigned long inst1;
- int it1;
- unsigned long inst2;
- int it2;
- unsigned long inst3;
- int it3;
-} inst_tmp_t;
-
-inst_tmp_t sit;
-
-/* Instruction types */
-
-enum {
- IT_A = 1, /* Integer ALU = I | M */
- IT_As, /* Integer ALU stop */
- IT_I, /* Non-ALU integer */
- IT_Is, /* Non-ALU integer stop */
- IT_M, /* Memory */
- IT_Ms, /* Memory stop */
- IT_F, /* Floating-Point */
- IT_Fs, /* Floating-Point */
- IT_B, /* Branch */
- IT_Bs, /* Branch */
- IT_L, /* Extended */
- IT_X, /* Extended */
- IT_Xs, /* Extended */
-};
-
-/* Templates */
-
-enum {
- MII,
- MIIs,
- MIsI,
- MIsIs,
- MLX,
- MLXs,
- MMI = 8,
- MMIs,
- MsMI,
- MsMIs,
- MFI,
- MFIs,
- MMF,
- MMFs,
- MIB,
- MIBs,
- MBB,
- MBBs,
- BBB = 0x16,
- BBBs,
- MMB,
- MMBs,
- MFB = 0x1C,
- MFBs
-};
-
-/* Reserved registers */
-
-# define ISR1 2
-# define ISR2 3
-# define RSF 34
-# define R_INTREP 4
-# define R_BYTECODE 5
-# define R_OPMAP 6
-# define R_RETURN_ADR 7
-# define R_RETURN 8
-# define R_ARG1 32
-# define R_ARG2 33
-
-# define FSR1 2
-# define FSR2 3
-
-/* Application Registers */
-# define PFS 64
-
-# define RSRV_REG 26
-
-# define emit_x2(pc, r1, imm64) \
- pc = close_template(pc); \
- pc = loadinst(pc, ((long)((imm64 >> 22) & (long)0x1fffffffffff)), IT_L); \
- it = ((long)6 << 37) | \
- ((long)((imm64 >> 63) & 0x1) << 36) | \
- ((long)((imm64 >> 7) & 0x1ff) << 27) | \
- ((long)((imm64 >> 21) & 0x1) << 21) | \
- ((long)((imm64 >> 16) & 0x1f) << 22) | \
- ((long)((imm64 & 0x7f)) << 13) | \
- ((((long)r1 & 0x3f)) << 6); \
- pc = loadinst(pc, it, IT_X); \
-
-# define emit_x4(pc, d, wh, imm64, p, b1) \
- pc = close_template(pc); \
- pc = loadinst(pc, (long)((imm64 >> 20) & 0x7fffffffff) << 2, IT_L); \
- it = ((long)0xD << 37) | ((long)(((long)(imm64) >> 63) & 0x1) << 36) | \
- ((long)d << 35) | ((long)wh << 33) | \
- (((long)imm64 & 0xfffff) << 13) | (p << 12) | (b1 << 6); \
- pc = loadinst(pc, it, IT_X);
-
-# define emit_a1(pc, x2a, ve, x4, x2b, r3, r2, r1) \
- it = ((long)8 << 37) | ((long)x2a << 34) | ((long)ve << 33) | \
- ((long)x4 << 29) | ((long)x2b << 27) | (r3 << 20) | (r2 << 13) | \
- (r1 << 6); \
- pc = loadinst(pc, it, IT_A);
-
-# define emit_a4(pc, r3, imm14, r1) \
- it = ((long)8 << 37) | ((long)((imm14 >> 13) & 0x1) << 36) | \
- ((long)2 << 34) | (((imm14 >> 7) & 0x3f) << 27) | (r3 << 20) | \
- ((imm14 & 0x7f) << 13) | (r1 << 6); \
- pc = loadinst(pc, it, IT_A);
-
-# define emit_a5(pc, r3, imm22, r1) \
- it = ((long)9 << 37) | ((long)((imm22 >> 7) & 0x1ff) << 27) | \
- (((imm22 >> 16) & 0x1f) << 22) | ((imm22 & 0x7f) << 13) | \
- ((r3 & 0x3) << 20) | (r1 << 6); \
- pc = loadinst(pc, it, IT_A);
-
-# define emit_a6(pc, op, tb, x2, ta, c, p2, r3, r2, p1) \
- it = ((long)op << 37) | ((long)tb << 36) | ((long)x2 << 34) | \
- ((long)ta << 33) | ((long)p2 << 27) | ((long)r3 << 20) | \
- ((long)r2 << 13) | ((long)c << 12) | (p1 << 6); \
- pc = loadinst(pc, it, IT_M); /**/ \
- pc = loadinst(pc, emit_fill_nop_m, IT_F);
-
-# define emit_m1(pc, x6, r3, r1) \
- it = ((long)4 << 37) | ((long)x6 << 30) | (r3 << 20) | (r1 << 6); \
- pc = loadinst(pc, it, IT_M);
-
-# define emit_m2(pc, x6, r3, r2, r1) \
- it = ((long)4 << 37) | ((long)1 << 36) | ((long)x6 << 30) | \
- (r3 << 20) | (r2 << 13) | (r1 << 6); \
- pc = loadinst(pc, it, IT_M);
-
-# define emit_m4(pc, x6, r3, r2) \
- it = ((long)4 << 37) | ((long)x6 << 30) | (r3 << 20) | (r2 << 13); \
- pc = loadinst(pc, it, IT_M);
-
-# define fd_sig 0x1C
-# define fd_exp 0x1D
-# define fd_s 0x1E
-# define fd_d 0x1F
-
-# define emit_m18(pc, x6, r2, f1) \
- it = ((long)6 << 37) | ((long)x6 << 30) | ((long)1 << 27) | \
- (r2 << 13) | (f1 << 6); \
- pc = loadinst(pc, it, IT_M);
-
-# define emit_m19(pc, x6, f2, r1) \
- it = ((long)4 << 37) | ((long)x6 << 30) | ((long)1 << 27) | \
- (f2 << 13) | (r1 << 6); \
- pc = loadinst(pc, it, IT_M);
-
-# define emit_m34(pc, il, o, r, r1) \
- it = ((long)1 << 37) | (long)0x6 << 33 | ((long)(r >> 3) << 27) | \
- ((long)il << 20) | ((long)(il + o) << 13) | ((long)r1 << 6); \
- pc = loadinst(pc, it, IT_M);
-
-# define ph_few 0
-# define ph_many 1
-
-# define bwh_sptk 0
-# define bwh_spnt 1
-# define bwh_dptk 2
-# define bwh_dpnt 3
-
-# define dh_none 0
-# define dh_clr 1
-
-# define emit_b1(pc, d, wh, imm21, p, b1, qp) \
- it = ((long)4 << 37) | ((long)((imm21 >> 20) & 0x1) << 36) | \
- ((long)d << 35) | ((long)wh << 33) | \
- ((long)(imm21 & 0xfffff) << 13) | (p << 12) | (b1 << 6) | qp; \
- pc = loadinst(pc, it, IT_B);
-
-# define emit_b3(pc, d, wh, imm20b, p, b1) \
- it = ((long)5 << 37) | ((long)((imm20b >> 20) & 0x1) << 36) | \
- ((long)d << 35) | ((long)wh << 33) | \
- ((long)(imm20b & 0xfffff) << 13) | (p << 12) | (b1 << 6); \
- pc = loadinst(pc, it, IT_B);
-
-# define emit_b4(pc, d, wh, x6, b2, p, btype) \
- it = ((long)1 << 36) | ((long)d << 35) | ((long)wh << 33) | \
- ((long)x6 << 27) | (b2 << 13) | (p << 12) | (btype << 6); \
- pc = loadinst(pc, it, IT_B);
-
-# define emit_i21(pc, b1, r2) \
- it = ((long)0 << 37) | (long)0x7 << 33 | \
- ((long)r2 << 13) | ((long)b1 << 6);\
- pc = loadinst(pc, it, IT_I);
-
-# define emit_i22(pc, r1, b2) \
- it = ((long)0 << 37) | (long)0x31 << 27 | \
- ((long)b2 << 13) | ((long)r1 << 6);\
- pc = loadinst(pc, it, IT_I);
-
-# define emit_i26(pc, ar3, r2) \
- it = ((long)0x2A << 27) | (long)ar3 << 20 | ((long)r2 << 13);\
- pc = loadinst(pc, it, IT_I);
-
-/* Pseudo instructions. */
-# define jit_emit_mov_ri_i(pc, dest, imm) \
- emit_x2((pc), (dest), ((long)(imm)));
-
-/* Store a CPU register back to a Parrot register. */
-
-# define jit_emit_mov_mr_i(pc, addr, reg) \
- emit_a4((pc), R_INTREP, (((char *)(addr)) - ((char *)(interp))), ISR2); \
- emit_m4((pc), 0x33, ISR2, (reg));
-
-# define jit_emit_mov_rm_i(pc, reg, addr) \
- emit_a4((pc), R_INTREP, (((char *)(addr)) - ((char *)(interp))), ISR2); \
- emit_m1((pc), 0x3, ISR2, (reg));
-
-# define jit_emit_mov_rr(pc, dst, src) \
- emit_a4((pc), (src), 0, (dst));
-
-# define jit_emit_add_rrr(pc, D, A, B) \
- emit_a1((pc), 0, 0, 0, 0, (A), (B), (D));
-
-# define jit_emit_sub_rrr(pc, D, A, B) \
- emit_a1((pc), 0, 0, 1, 1, (B), (A), (D));
-
-# define jit_emit_neg_rr(pc, D, A) \
- emit_a1((pc), 0, 0, 1, 1, (A), 0, (D));
-
-# define jit_emit_and_rrr(pc, D, A, B) \
- emit_a1((pc), 0, 0, 3, 0, (A), (B), (D));
-
-# define jit_emit_or_rrr(pc, D, A, B) \
- emit_a1((pc), 0, 0, 3, 2, (A), (B), (D));
-
-# define jit_emit_xor_rrr(pc, D, A, B) \
- emit_a1((pc), 0, 0, 3, 3, (A), (B), (D));
-
-# define jit_emit_mov_nr(pc, dst, src) \
- emit_m18((pc), (fr_sig), (dst), (src));
-
-# define jit_emit_mov_rn(pc, dst, src) \
- emit_m19((pc), (fr_sig), (dst), (src));
-
-# define jit_emit_cmp_r0(pc, src) \
- emit_a6(pc, 0xE, 0, 2, 0, 0, 7, src, 0, 6);
-
-# define jit_emit_nop(pc) \
- (it) = emit_fill_nop_m; \
- (pc) = loadinst((pc), it, IT_M);
-
-# define jit_emit_end(pc) \
- emit_i26((pc), PFS, RSF); \
- emit_i21((pc), 0, R_RETURN_ADR); \
- jit_emit_mov_rr(NATIVE_PTR, 12, 35); \
- emit_b4((pc), dh_none, bwh_sptk, 0x21, 0, ph_many, 4); \
- (pc) = close_template((pc));
-
-# define emit_fill_nop 0x4000000
-# define emit_fill_nop_m 0x8000000
-# define emit_fill_nop_b 0x4000000000
-
-# define JIT_IA64_CALL 1
-# define JIT_IA64_BRANCH 2
-
-static int
-invalid_template(void)
-{
- if (sit.it2 == 0)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == 0)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_Is && sit.it3 == 0)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_L && sit.it3 == 0)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == 0)
- return 0;
- if (sit.it1 == IT_Ms && sit.it2 == IT_M && sit.it3 == 0)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == 0)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_B && sit.it3 == 0)
- return 0;
- if (sit.it1 == IT_B && sit.it2 == IT_B && sit.it3 == 0)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == IT_I)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == IT_Is)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_Is && sit.it3 == IT_I)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_Is && sit.it3 == IT_Is)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_L && sit.it3 == IT_X)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_L && sit.it3 == IT_Xs)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_I)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_Is)
- return 0;
- if (sit.it1 == IT_Ms && sit.it2 == IT_M && sit.it3 == IT_I)
- return 0;
- if (sit.it1 == IT_Ms && sit.it2 == IT_M && sit.it3 == IT_Is)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == IT_I)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == IT_Is)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_F)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_Fs)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == IT_B)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == IT_Bs)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_B && sit.it3 == IT_B)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_B && sit.it3 == IT_Bs)
- return 0;
- if (sit.it1 == IT_B && sit.it2 == IT_B && sit.it3 == IT_B)
- return 0;
- if (sit.it1 == IT_B && sit.it2 == IT_B && sit.it3 == IT_Bs)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_B)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_Bs)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == IT_B)
- return 0;
- if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == IT_Bs)
- return 0;
- return 1;
-}
-
-static char *
-close_template(char *pc)
-{
- char *pit;
- int i;
-
- if (sit.used == 0)
- return pc;
- else if (sit.used == 1 && sit.it1 == IT_M) {
- sit.tmplt = MIsIs; /**/
- sit.inst2 = emit_fill_nop_m >> 2;
- sit.inst3 = emit_fill_nop_m >> 1;
- }
- else if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == IT_I)
- sit.tmplt = MIsIs; /**/
- else if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == IT_Is)
- sit.tmplt = MIsIs; /**/
- else if (sit.it1 == IT_M && sit.it2 == IT_Is && sit.it3 == IT_I)
- sit.tmplt = MIsIs; /**/
- else if (sit.it1 == IT_M && sit.it2 == IT_Is && sit.it3 == IT_Is)
- sit.tmplt = MIsIs;
- else if (sit.it1 == IT_M && sit.it2 == IT_L && sit.it3 == IT_X)
- sit.tmplt = MLXs; /* Force stop */
- else if (sit.it1 == IT_M && sit.it2 == IT_L && sit.it3 == IT_Xs)
- sit.tmplt = MLXs;
- else if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_I)
- sit.tmplt = MMIs; /**/
- else if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_Is)
- sit.tmplt = MMIs;
- else if (sit.it1 == IT_Ms && sit.it2 == IT_M && sit.it3 == IT_I)
- sit.tmplt = MsMIs; /**/
- else if (sit.it1 == IT_Ms && sit.it2 == IT_M && sit.it3 == IT_Is)
- sit.tmplt = MsMIs;
- else if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == IT_I)
- sit.tmplt = MFIs; /**/
- else if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == IT_Is)
- sit.tmplt = MFIs;
- else if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_F)
- sit.tmplt = MMF;
- else if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_Fs)
- sit.tmplt = MMFs;
- else if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == IT_B)
- sit.tmplt = MIBs; /**/
- else if (sit.it1 == IT_M && sit.it2 == IT_I && sit.it3 == IT_Bs)
- sit.tmplt = MIBs;
- else if (sit.it1 == IT_M && sit.it2 == IT_B && sit.it3 == IT_B)
- sit.tmplt = MBB;
- else if (sit.it1 == IT_M && sit.it2 == IT_B && sit.it3 == IT_Bs)
- sit.tmplt = MBBs;
- else if (sit.it1 == IT_B && sit.it2 == IT_B && sit.it3 == IT_B)
- sit.tmplt = BBBs; /**/
- else if (sit.it1 == IT_B && sit.it2 == IT_B && sit.it3 == IT_Bs)
- sit.tmplt = BBBs;
- else if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_B)
- sit.tmplt = MMBs; /**/
- else if (sit.it1 == IT_M && sit.it2 == IT_M && sit.it3 == IT_Bs)
- sit.tmplt = MMBs;
- else if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == IT_B)
- sit.tmplt = MFB;
- else if (sit.it1 == IT_M && sit.it2 == IT_F && sit.it3 == IT_Bs)
- sit.tmplt = MFBs;
- else if (sit.it1 == IT_M && sit.it2 == IT_I) {
- sit.tmplt = MIsIs; /**/
- sit.inst3 = emit_fill_nop;
- }
- else if (sit.it1 == IT_M && sit.it2 == IT_Is) {
- sit.tmplt = MIsIs; /**/
- sit.inst3 = emit_fill_nop;
- }
- else if (sit.it1 == IT_M && sit.it2 == IT_L) {
- sit.tmplt = MLXs; /**/
- sit.inst3 = emit_fill_nop;
- }
- else if (sit.it1 == IT_M && sit.it2 == IT_M) {
- sit.tmplt = MMI;
- sit.inst3 = emit_fill_nop;
- }
- else if (sit.it1 == IT_Ms && sit.it2 == IT_M) {
- sit.tmplt = MsMI;
- sit.inst3 = emit_fill_nop;
- }
- else if (sit.it1 == IT_M && sit.it2 == IT_F) {
- sit.tmplt = MFI;
- sit.inst3 = emit_fill_nop;
- }
- else if (sit.it1 == IT_M && sit.it2 == IT_B) {
- sit.tmplt = MBB;
- sit.inst3 = emit_fill_nop_b;
- }
- else if (sit.it1 == IT_B && sit.it2 == IT_B) {
- sit.tmplt = BBBs; /**/
- sit.inst3 = emit_fill_nop_b;
- }
-
- pit = (char *)&sit.inst1;
- *(pc++) = (char)sit.tmplt | *(pit++);
- for (i = 0; i < 5; i++)
- *(pc++) = *(pit++);
- pit = (char *)&sit.inst2;
- for (i = 0; i < 5; i++)
- *(pc++) = *(pit++);
- pit = (char *)&sit.inst3;
- for (i = 0; i < 5; i++)
- *(pc++) = *(pit++);
-
- sit.used = 0;
- sit.inst1 = 0;
- sit.it1 = 0;
- sit.inst2 = 0;
- sit.it2 = 0;
- sit.inst3 = 0;
- sit.it3 = 0;
- return pc;
-}
-
-static char *
-loadinst(char *pc, long inst, int itype)
-{
- char *pit = (char *)&inst;
- int i;
-
-RELOAD:
- switch (sit.used++) {
- case 0:
- sit.inst1 = inst << 5;
- if (itype == IT_B) {
- sit.inst1 = emit_fill_nop_b << 5;
- sit.it1 = IT_B;
- sit.inst2 = emit_fill_nop_b >> 2;
- sit.it2 = IT_B;
- sit.inst3 = inst >> 1;
- sit.inst2 |= (long)((inst & 0x1) << 39);
- sit.it3 = itype;
- sit.used = 3;
- return close_template(pc);
- }
- else if (itype == IT_M)
- sit.it1 = IT_M;
- else if ((itype == IT_I) || (itype == IT_A)) {
- sit.inst1 = ((long)emit_fill_nop_m << 5);
- sit.it1 = IT_M;
- sit.inst2 = (inst >> 2) & 0x7fffffffff;
- sit.inst1 |= (long)((inst & 0x3) << 46);
- sit.it2 = IT_I;
- sit.used++;
- }
- else if (itype == IT_L) {
- sit.it1 = IT_M;
- sit.inst1 = ((long)emit_fill_nop_m << 5);
- sit.inst2 = (inst >> 2) & 0x7fffffffff;
- sit.inst1 |= (long)((inst & 0x3) << 46);
- sit.it2 = itype;
- sit.used++;
- }
- break;
- case 1:
- if (itype == IT_A)
- sit.it2 = IT_I;
- else
- sit.it2 = itype;
- sit.inst2 = (inst >> 2) & 0x7fffffffff;
- sit.inst1 |= (long)((inst & 0x3) << 46);
- break;
- case 2:
- if (itype == IT_A)
- sit.it3 = IT_I;
- else
- sit.it3 = itype;
- if (invalid_template()) {
- pc = close_template(pc);
- goto RELOAD;
- }
- sit.inst3 = inst >> 1;
- sit.inst2 |= (long)((inst & 0x1) << 39);
- pc = close_template(pc);
- return pc;
- }
-
- if (invalid_template())
- pc = close_template(pc);
-
- return pc;
-}
-
-static void
-jit_emit_bc(Parrot_jit_info_t *jit_info, opcode_t disp)
-{
- opcode_t opcode = jit_info->op_i + disp;
- int offset;
- if (opcode <= jit_info->op_i) {
- offset = jit_info->arena.op_map[opcode].offset -
- (jit_info->native_ptr - jit_info->arena.start);
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- offset +=
- jit_info->optimizer->cur_section->branch_target->load_size;
- }
- else {
- offset = 0;
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_IA64_BRANCH;
- jit_info->arena.fixups->param.opcode = opcode;
-
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- }
- emit_b1(jit_info->native_ptr, dh_none, bwh_dptk, offset >> 4, ph_few, 0, 7);
-}
-
-static void
-Parrot_jit_jump_to_ret(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- jit_emit_sub_rrr(NATIVE_PTR, ISR1, R_RETURN, R_BYTECODE);
- jit_emit_add_rrr(NATIVE_PTR, ISR1, ISR1, R_OPMAP);
- emit_m1(NATIVE_PTR, 3, ISR1, ISR1);
- NATIVE_PTR = close_template(NATIVE_PTR);
- emit_i21(NATIVE_PTR, 0, ISR1);
- emit_b4(NATIVE_PTR, dh_none, bwh_sptk, 0x20, 0, ph_many, 0);
-}
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- emit_m34(NATIVE_PTR, RSRV_REG, 2, 0, RSF);
- jit_emit_mov_rr(NATIVE_PTR, 1, 4);
- jit_emit_mov_rr(NATIVE_PTR, R_INTREP, R_ARG1);
- jit_emit_mov_rr(NATIVE_PTR, R_BYTECODE, R_ARG2);
- jit_emit_mov_ri_i(NATIVE_PTR, R_OPMAP, jit_info->arena.op_map);
- jit_emit_mov_rr(NATIVE_PTR, 35, 12);
- emit_i22(NATIVE_PTR, R_RETURN_ADR, 0);
- jit_emit_mov_rr(NATIVE_PTR, 8, R_ARG2);
- Parrot_jit_jump_to_ret(jit_info, interp);
-}
-
-static void
-fixup_jump_addr(char *fixup_ptr, long d)
-{
- char *pit;
- long tmp, i;
-
- tmp = (long)(((long)((d >> 21) & 0xfffff) << 35) |
- ((long)((d & 0xfffff) << 12)));
- for (i = 0; i < 11; i++)
- fixup_ptr++;
- pit = (char *)&tmp;
- for (i = 0; i < 5; i++)
- *(fixup_ptr++) |= *(pit++);
-}
-
-void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_jit_fixup_t *fixup;
- char *fixup_ptr, *pit, *disp;
- long d, tmp, i;
-
- fixup = jit_info->arena.fixups;
-
- while (fixup){
- switch (fixup->type){
- case JIT_IA64_CALL:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = (((long)fixup->param.fptr - (long)fixup_ptr)) >> 4;
- emit_x4(fixup_ptr, dh_none, bwh_sptk, d, ph_many, 0);
- break;
- case JIT_IA64_BRANCH:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = (jit_info->arena.op_map[fixup->param.opcode].offset
- - fixup->native_offset + fixup->skip) >> 4;
- fixup_jump_addr(fixup_ptr, d);
- break;
-
- default:
- exit_fatal(EXCEPTION_JIT_ERROR, "Unknown fixup type:%d\n",
- fixup->type);
- break;
- }
- fixup = fixup->next;
- }
-}
-
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- emit_a4(NATIVE_PTR, R_BYTECODE,
- ((long)jit_info->cur_op - (long)interp->code->base.data),
- (R_ARG1 + RSRV_REG));
- jit_emit_mov_rr(NATIVE_PTR, (R_ARG2 + RSRV_REG), R_INTREP);
- jit_emit_mov_rr(NATIVE_PTR, 32, 1);
-
- NATIVE_PTR = close_template(NATIVE_PTR);
- Parrot_jit_newfixup(jit_info);
-
- jit_info->arena.fixups->type = JIT_IA64_CALL;
- jit_info->arena.fixups->param.fptr =
- (void (*)(void))(*(long *)(
- interp->op_func_table[*(jit_info->cur_op)]));
-
- emit_x4(NATIVE_PTR, dh_none, bwh_sptk, 0, ph_many, 0);
- jit_emit_mov_rr(NATIVE_PTR, 1, 32);
- NATIVE_PTR = close_template(NATIVE_PTR);
-}
-
-void
-Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
- Parrot_jit_jump_to_ret(jit_info, interp);
-}
-
-# undef Parrot_jit_restart_op
-void
-Parrot_jit_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- char *jmp_ptr, *sav_ptr;
-
- Parrot_jit_normal_op(jit_info, interp);
- /* test r8, if zero (e.g after trace), return from JIT */
- jit_emit_cmp_r0(jit_info->native_ptr, R_RETURN);
- /* remember PC */
- jmp_ptr = jit_info->native_ptr;
- emit_b1(jit_info->native_ptr, dh_none, bwh_dptk, 0, ph_few, 0, 7);
- jit_emit_end(jit_info->native_ptr);
- /* fixup above jump */
- sav_ptr = jit_info->native_ptr;
- jit_info->native_ptr = jmp_ptr;
- fixup_jump_addr(jit_info->native_ptr, (long)((sav_ptr - jmp_ptr) >> 4));
- /* restore PC */
- jit_info->native_ptr = sav_ptr;
- Parrot_jit_jump_to_ret(jit_info, interp);
-}
-
-/* move reg to mem (i.e. intreg) */
-void
-Parrot_jit_emit_mov_mr(PARROT_INTERP, char *mem, int reg)
-{
- jit_emit_mov_mr_i(
- ((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr, mem, reg);
- NATIVE_PTR = close_template(NATIVE_PTR);
-}
-
-/* move mem (i.e. intreg) to reg */
-void
-Parrot_jit_emit_mov_rm(PARROT_INTERP, int reg, char *mem)
-{
- jit_emit_mov_rm_i(
- ((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr, reg, mem);
- NATIVE_PTR = close_template(NATIVE_PTR);
-}
-
-/* move reg to mem (i.e. numreg) */
-void
-Parrot_jit_emit_mov_mr_n(PARROT_INTERP, char *mem, int reg)
-{
-}
-
-/* move mem (i.e. numreg) to reg */
-void
-Parrot_jit_emit_mov_rm_n(PARROT_INTERP, int reg, char *mem)
-{
-}
-
-
-
-#endif /* JIT_EMIT */
-#if JIT_EMIT == 0
-
-# define REQUIRES_CONSTANT_POOL 0
-# define INT_REGISTERS_TO_MAP 22
-
-# ifndef JIT_IMCC
-# define CACHELINESIZE 32
-
-char intval_map[INT_REGISTERS_TO_MAP] =
- { 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 };
-
-static void
-ia64_sync_cache(void *_start, void *_end)
-{
- char *start = (char*)(((long)_start) &~(CACHELINESIZE - 1));
- char *end = (char *)((((long)_end)+CACHELINESIZE-1) &~(CACHELINESIZE - 1));
- char *_sync;
-
- for (_sync = start; _sync < end; _sync += CACHELINESIZE) {
- __asm__ __volatile__(
- "fc %0\n"
- ";;\n"
- "sync.i\n"
- ";;\n"
- "srlz.i\n"
- ";;\n"
- :
- : "r" ((long)_sync));
- }
-}
-
-# endif
-
-#endif /* !JIT_EMIT */
-
-#endif /* PARROT_JIT_IA64_JIT_EMIT_H_GUARD */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/mips/core.jit
==============================================================================
--- trunk/src/jit/mips/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,58 +0,0 @@
-;
-; mips/core.jit
-;
-;
-; $Id$
-;
-
-Parrot_end {
- emit_lw(NATIVECODE, ra, 32, sp);
- emit_lw(NATIVECODE, fp, 28, sp);
- emit_addiu(jit_info->native_ptr, sp, sp, 40);
- emit_jr(NATIVECODE, ra);
-}
-
-Parrot_set_i_ic {
- if (MAP[1]) {
- emit_imm32(NATIVECODE, MAP[1], *INT_CONST[2]);
- }
- else {
- emit_imm32(NATIVECODE, at, *INT_CONST[2]);
- emit_sw_r(NATIVECODE, at, ROFFS_INT(1));
- }
-}
-
-Parrot_set_i_i {
- if (MAP[1] && MAP[2]) {
- emit_mov(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- emit_lw_r(NATIVECODE, MAP[1], ROFFS_INT(2));
- }
- else if (MAP[2]) {
- emit_sw_r(NATIVECODE, MAP[2], ROFFS_INT(1));
- }
- else {
- emit_lw_r(NATIVECODE, at, ROFFS_INT(2));
- emit_sw_r(NATIVECODE, at, ROFFS_INT(1));
- }
-}
-
-Parrot_neg_i_i {
- if (MAP[1] && MAP[2]) {
- emit_neg(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- emit_lw_r(NATIVECODE, at, ROFFS_INT(2));
- emit_neg(NATIVECODE, MAP[1], at);
- }
- else if (MAP[2]) {
- emit_neg(NATIVECODE, at, MAP[1]);
- emit_sw_r(NATIVECODE, at, ROFFS_INT(1));
- }
- else {
- emit_lw_r(NATIVECODE, at, ROFFS_INT(2));
- emit_neg(NATIVECODE, at, at);
- emit_sw_r(NATIVECODE, at, ROFFS_INT(1));
- }
-}
Deleted: trunk/src/jit/mips/jit_defs.c
==============================================================================
--- trunk/src/jit/mips/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,13 +0,0 @@
-/* Stub file for RT#38929 fixes */
-/*
-Copyright (C) 2008, Parrot Foundation.
-$Id$
-*/
-/* HEADERIZER HFILE: none */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/mips/jit_emit.h
==============================================================================
--- trunk/src/jit/mips/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,497 +0,0 @@
-/*
- * Copyright (C) 2003-2008, Parrot Foundation.
- */
-
-/*
- * jit_emit.h
- *
- * SVN Info
- * $Id$
- * Overview:
- * MIPS JIT
- * History:
- * Initial version by Daniel Grunblatt on 2002.8.20
- * Notes:
- * References:
- */
-
-#ifndef PARROT_MIPS_JIT_EMIT_H_GUARD
-#define PARROT_MIPS_JIT_EMIT_H_GUARD
-
-# define BASE_REG s0
-# define Parrot_jit_emit_get_base_reg_no(pc) BASE_REG
-
-typedef enum {
- zero,
- at,
- v0,
- v1,
- a0,
- a1,
- a2,
- a3,
- t0,
- t1,
- t2,
- t3,
- t4,
- t5,
- t6,
- t7,
- s0,
- s1,
- s2,
- s3,
- s4,
- s5,
- s6,
- s7,
- t8,
- t9,
- k0,
- k1,
- gp,
- sp,
- fp,
- ra
-} mips_register_t;
-
-#if JIT_EMIT
-
-enum { JIT_MIPS_CALL, JIT_MIPS_BRANCH };
-
-/*
- * R type
- *
- * +--------------------------------------------------------------------+
- * | Opcode | rs | rt | rd | re | funct |
- * +--------------------------------------------------------------------+
- * 31 26 25 21 20 16 15 11 10 6 5 0
- *
- */
-
-# define emit_r(pc, opcode, rs, rt, rd, re, funct) \
- *(int *)(((pc) += 4) - 4) = \
- (opcode) << 26 | (rs) << 21 | (rt) << 16 | (rd) << 11 | (re) << 6 | (funct);
-
-/*
- * I type
- *
- * +--------------------------------------------------------------------+
- * | Opcode | rs | rt | offset |
- * +--------------------------------------------------------------------+
- * 31 26 25 21 20 16 15 0
- *
- */
-
-# define emit_i(pc, opcode, rs, rt, offset) \
- *(int *)(((pc) += 4) - 4) = \
- (opcode) << 26 | (rs) << 21 | (rt) << 16 | ((long)(offset) & 0xffff);
-
-/*
- * J type
- *
- * +--------------------------------------------------------------------+
- * | Opcode | target |
- * +--------------------------------------------------------------------+
- * 31 26 25 0
- *
- */
-
-# define emit_j(pc, opcode, target) \
- *(int *)(((pc) += 4) - 4) = (opcode) << 26 | (target);
-
-# define emit_nop(pc) emit_j((pc), 0, 0)
-
-/* LW
- *
- * To load a word from memory as a signed value.
- * rt = (rs + offset)
- */
-
-# define emit_lw(pc, rt, offset, rs) \
- emit_i((pc), 0x23, (rs), (rt), (offset))
-
-# define emit_sw(pc, rt, offset, rs) \
- emit_i((pc), 0x2b, (rs), (rt), (offset))
-
-# define emit_sw_r(pc, reg, addr) \
- emit_sw((pc), (reg), (addr), BASE_REG)
-
-# define emit_lw_r(pc, reg, addr) \
- emit_lw((pc), (reg), (addr), BASE_REG)
-
-/* LUI
- *
- * To load a constant into the upper half of a word.
- * rt = imm << 16
- */
-
-# define emit_lui(pc, rt, imm) \
- emit_i((pc), 0xf, 0, (rt), (imm))
-
-/* AND
- *
- * To do a bitwise logical AND.
- * rd = rs ^ rt
- */
-
-# define emit_and(pc, rd, rs, rt) \
- emit_r((pc), 0, (rs), (rt), (rd), 0, 0x24)
-
-/* OR
- *
- * To do a bitwise logical OR.
- * rd = rs | rt
- */
-
-# define emit_or(pc, rd, rs, rt) \
- emit_r((pc), 0, (rs), (rt), (rd), 0, 0x25)
-
-/* XOR
- *
- * To do a bitwise logical EXCLUSIVE OR.
- * rd = rs ^ rt
- */
-
-# define emit_xor(pc, rd, rs, rt) \
- emit_r((pc), 0, (rs), (rt), (rd), 0, 0x26)
-
-
-/* ORI
- *
- * To do a bitwise logical OR with a constant.
- * rt = rs | imm
- */
-
-# define emit_ori(pc, rs, rt, imm) \
- emit_i((pc), 0xd, (rs), (rt), (imm))
-
-/* ADD
- *
- * To add 32 bit integers.
- * rd = rs + rt
- */
-
-# define emit_add(pc, rd, rs, rt) \
- emit_r((pc), 0, (rs), (rt), (rd), 0, 0x20)
-
-/* ADDIU
- *
- * To add a constant to a 32 bit integer.
- * rt = rs + imm
- */
-
-# define emit_addiu(pc, rs, rt, imm) \
- emit_i((pc), 9, (rs), (rt), (imm))
-
-/* SUB
- *
- * To substract 32 bit integers.
- * rd = rs - rt
- */
-
-# define emit_sub(pc, rd, rs, rt) \
- emit_r((pc), 0, (rs), (rt), (rd), 0, 0x22)
-
-/* MULT
- *
- * To multiply 32 bit integers.
- * (LO , HI) = rs * rt
- */
-
-# define emit_mult(pc, rs, rt) \
- emit_r((pc), 0, (rs), (rt), 0, 0, 0x18)
-
-/* MFLO
- *
- * To copy the special purpose register LO to a GPR.
- */
-
-# define emit_mflo(pc, rd) \
- emit_r((pc), 0, 0, 0, (rd), 0, 0x12)
-
-/* MUL (Pseudo instruction)
- *
- * To multiply 32 bit integers.
- * rd = rs * rt
- */
-
-# define emit_mul(pc, rd, rs, rt) \
- emit_mult((pc), (rs), (rt)); \
- emit_mflo((pc), (rd))
-
-/* DIV
- *
- * To divide 32 bit integers.
- * (LO , HI) = rs / rt
- * The quotient is placed in LO and the reminder in HI.
- */
-
-# define emit_divi(pc, rs, rt) \
- emit_r((pc), 0, (rs), (rt), 0, 0, 0x1a)
-
-/* DIV (Pseudo instruction)
- *
- * To divide 32 bit integers.
- * rd = rs / rt
- */
-
-# define emit_div(pc, rd, rs, rt) \
- emit_divi((pc), (rs), (rt)); \
- emit_mflo((pc), (rd))
-
-/* JR
- *
- * To branch to an instruction address in a register.
- * PC = rs
- */
-
-# define emit_jr(pc, rs) \
- emit_r((pc), 0, (rs), 0, 0, 0, 8)
-
-/* JAL
- *
- * To procedure call within the current 256 MB aligned region.
- */
-
-# define emit_jal(pc) \
- emit_j((pc), 3, 0)
-
-/* JALR
- *
- * To procedure call to an instruction address in a register.
- */
-
-# define emit_jalr(pc, rs, rd) \
- emit_r((pc), 0, (rs), 0, (rd), 0, 9)
-
-/* MOVE
- *
- * To move a GPR.
- * rd = rs
- */
-
-# define emit_move(pc, rs, rd) \
- emit_r((pc), 0, (rs), 0, (rd), 0, 0x21)
-
-# define emit_mov(pc, rd, rs) \
- emit_move((pc), (rs), (rd))
-
-/* NEG
- * rd = -rt
- */
-
-# define emit_negu(pc, rd, rt) \
- emit_r((pc), 0, 0, (rt), (rd), 0, 0x23)
-
-# define emit_neg(pc, rd, rt) \
- emit_r((pc), 0, 0, (rt), (rd), 0, 0x22)
-
-/* Load a constant */
-
-# define emit_imm32(pc, rd, imm) \
- emit_lui((pc), (rd), ((long)(imm) >> 16)); \
- emit_ori((pc), (rd), (rd), (imm))
-
-
-static void
-emit_if(Parrot_jit_info_t *jit_info, char opcode, mips_register_t rs,
- mips_register_t rt, opcode_t disp)
-{
- opcode_t opcode = jit_info->op_i + disp;
- int offset;
-
- if (opcode <= jit_info->op_i) {
- offset = jit_info->arena.op_map[opcode].offset -
- (jit_info->native_ptr - jit_info->arena.start);
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- offset +=
- jit_info->optimizer->cur_section->branch_target->load_size;
- }
- else {
- offset = 0;
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_MIPS_BRANCH;
- jit_info->arena.fixups->param.opcode = opcode;
-
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- }
- emit_i(jit_info->native_ptr, opcode, rs, rt, offset);
-}
-
-/* BEQ
- *
- * To compare GPRs then do a PC-relative conditional branch.
- * if (rs == rt) branch
- */
-
-# define emit_beq(pc, rs, rt, imm) \
- emit_if((pc), 4, (rs), (rt), (imm))
-
-/* BNE
- *
- * To compare GPRs then do a PC-relative conditional branch.
- * if (rs != rt) branch
- */
-
-# define emit_bne(pc, rs, rt, imm) \
- emit_if((pc), 5, (rs), (rt), (imm))
-
-/* BNEZ
- *
- * To compare GPRs then do a PC-relative conditional branch.
- * if (rs != 0) branch
- */
-
-# define emit_bnez(pc, rs, imm) \
- emit_if((pc), 1, (rs), 2, (imm))
-
-
-/* BEGZ
- *
- * To compare GPRs then do a PC-relative conditional branch.
- * if (rs >= 0) branch
- */
-
-# define emit_begz(pc, rs, imm) \
- emit_if((pc), 1, (rs), 1, (imm))
-
-/* SLT
- *
- * To record the result of a less than comparison.
- * rd <- (rs < rt)
- */
-
-# define emit_slt(pc, rs, rt, rd) \
- emit_r((pc), 0, (rs), (rt), (rd), 0, 0x2a)
-
-/* GE (Pseudo-op)
- */
-# define emit_ge(pc, rs, rt, imm) \
- emit_slt((pc), (rs), (rt), (at)); \
- emit_beqz((pc), (at), (imm))
-
-#endif /* JIT_EMIT */
-
-#if JIT_EMIT == 2
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- emit_addiu(jit_info->native_ptr, sp, sp, -40);
- emit_sw(jit_info->native_ptr, ra, 32, sp);
- emit_sw(jit_info->native_ptr, fp, 28, sp);
- emit_mov(jit_info->native_ptr, s0, a0);
- emit_imm32(jit_info->native_ptr, s1, jit_info->arena.op_map);
- emit_imm32(jit_info->native_ptr, s2, interp->code->base.data);
-}
-
-void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
- Interp * interp)
-{
- Parrot_jit_fixup_t *fixup;
- char *fixup_ptr;
- char *disp;
- long d, high, low;
-
- fixup = jit_info->arena.fixups;
-
- while (fixup) {
- switch (fixup->type) {
- case JIT_MIPS_CALL:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = (((long)fixup->param.fptr - (long)0x10000000) / 4);
- *(fixup_ptr++) |= (char)(d >> 29) & 3;
- *(fixup_ptr++) = (char)(d >> 16);
- *(fixup_ptr++) = (char)(d >> 8);
- *(fixup_ptr++) |= (char)d & ~3;
- break;
- default:
- exit_fatal(EXCEPTION_JIT_ERROR, "Unknown fixup type:%d\n",
- fixup->type);
- break;
- }
- fixup = fixup->next;
- }
-}
-
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
-}
-
-void
-Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
-}
-
-/*void
-Parrot_jit_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
-}*/
-
-/* move reg to mem (i.e. intreg) */
-void
-Parrot_jit_emit_mov_mr_offs(PARROT_INTERP, int base, size_t offs, int reg)
-{
-}
-
-/* move mem (i.e. intreg) to reg */
-void
-Parrot_jit_emit_mov_rm_offs(PARROT_INTERP, int reg, int base, size_t offs)
-{
-}
-
-void
-Parrot_jit_emit_mov_mr_n_offs(PARROT_INTERP, int base, size_t offs, int reg)
-{
-}
-
-void
-Parrot_jit_emit_mov_rm_n_offs(PARROT_INTERP, int reg, int base, size_t offs)
-{
-}
-
-
-#endif /* JIT_EMIT == 2 */
-
-#if JIT_EMIT == 0
-
-# define REQUIRES_CONSTANT_POOL 0
-# define INT_REGISTERS_TO_MAP 24
-
-# ifndef JIT_IMCC
-static char intval_map[INT_REGISTERS_TO_MAP] =
- { v0, v1, a0, a1, a2, a3, t0, t1, t2, t3, t4, t5, t6, t7, s0, s1, s2, s3,
- s4, s5, s6, s7, t8, t9 };
-
-# include <asm/cachectl.h>
-
-extern int cacheflush(char* addr, int nbytes, int cache);
-static void sync_cache(void *_start, void *_end);
-
-static void
-sync_cache(void *_start, void *_end)
-{
- cacheflush((char*)_start, (int)((char *)_end - (char *)_start), BCACHE);
-}
-
-# endif /* JIT_IMCC */
-#endif /* JIT_EMIT == 0 */
-#endif /* PARROT_MIPS_JIT_EMIT_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/ppc/asm.s
==============================================================================
--- trunk/src/jit/ppc/asm.s Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,51 +0,0 @@
-.text
- .align 12
-#if !defined(__NetBSD__) && !defined(__OpenBSD__)
- .globl _Parrot_ppc_jit_restore_nonvolatile_registers
-_Parrot_ppc_jit_restore_nonvolatile_registers:
-#else
- .globl Parrot_ppc_jit_restore_nonvolatile_registers
-Parrot_ppc_jit_restore_nonvolatile_registers:
-#endif
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- lfd %f14,-84(%r1)
- lfd %f15,-92(%r1)
- lfd %f16,-100(%r1)
- lfd %f17,-108(%r1)
- lfd %f18,-116(%r1)
- lfd %f19,-124(%r1)
- lfd %f20,-132(%r1)
- lfd %f21,-140(%r1)
- lfd %f22,-148(%r1)
- lfd %f23,-156(%r1)
- lfd %f24,-164(%r1)
- lfd %f25,-172(%r1)
- lfd %f26,-180(%r1)
- lfd %f27,-188(%r1)
- lfd %f28,-196(%r1)
- lfd %f29,-204(%r1)
- lfd %f30,-212(%r1)
- lfd %f31,-220(%r1)
-#else /* !__NetBSD__ && !__OpenBSD__ */
- lfd f14,-84(r1)
- lfd f15,-92(r1)
- lfd f16,-100(r1)
- lfd f17,-108(r1)
- lfd f18,-116(r1)
- lfd f19,-124(r1)
- lfd f20,-132(r1)
- lfd f21,-140(r1)
- lfd f22,-148(r1)
- lfd f23,-156(r1)
- lfd f24,-164(r1)
- lfd f25,-172(r1)
- lfd f26,-180(r1)
- lfd f27,-188(r1)
- lfd f28,-196(r1)
- lfd f29,-204(r1)
- lfd f30,-212(r1)
- lfd f31,-220(r1)
-#endif /* __NetBSD__ || __OpenBSD__ */
-
- blr
Deleted: trunk/src/jit/ppc/core.jit
==============================================================================
--- trunk/src/jit/ppc/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,1313 +0,0 @@
-;
-; ppc/core.jit
-;
-;
-; $Id$
-;
-
-# TODO complete this
-#define P_ARITH ((PREV_OP == dec_i) || (PREV_OP == inc_i) || (PREV_OP == sub_i_i_i))
-Parrot_end {
- jit_emit_lwz(NATIVECODE, r1, 0, r1);
- jit_emit_lwz(NATIVECODE, r0, 8, r1);
-
- jit_emit_call_func(NATIVECODE, (void *)Parrot_ppc_jit_restore_nonvolatile_registers);
-
- jit_emit_mtlr(NATIVECODE, r0);
- jit_emit_lmw(NATIVECODE, r13, -PPC_JIT_GP_REGISTER_SAVE_SPACE, r1);
-
- jit_emit_blr(NATIVECODE);
-}
-
-Parrot_noop {
-; preferred no-op on ppc
- jit_emit_ori(NATIVECODE, r0, r0, 0);
-}
-
-Parrot_set_i_ic {
- if (MAP[1]) {
- jit_emit_mov_ri_i(NATIVECODE, MAP[1], *INT_CONST[2]);
- }
- else {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_set_i_n {
- if (MAP[2]) {
- jit_emit_fctiwz (NATIVECODE, FSR2, MAP[2]);
- }
- else {
- jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(2));
- jit_emit_fctiwz (NATIVECODE, FSR2, FSR1);
- }
- if (MAP[1]) {
- jit_emit_add_rri_i(NATIVECODE, ISR1, 0, -4);
- jit_emit_stfiwx (NATIVECODE, FSR2, ISR1, r1); /* -> -4(sp) */
- jit_emit_lwz (NATIVECODE, MAP[1], -4, r1);
- }
- else {
- jit_emit_add_rri_i(NATIVECODE, ISR1, 0, ROFFS_INT(1));
- jit_emit_stfiwx (NATIVECODE, FSR2, ISR1, r13); /* -> offs(base) */
- }
-}
-
-Parrot_set_n_ic {
- static double xx = 4503601774854144.0; /* 0x4330000080000000L; */
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
- jit_emit_xoris( NATIVECODE, ISR1, ISR1, 0x8000);
- /* use redzone for intermediate */
- jit_emit_stw( NATIVECODE, ISR1, -4, r1);
- jit_emit_addis( NATIVECODE, ISR1, r31, 0x4330);
- jit_emit_stw( NATIVECODE, ISR1, -8, r1);
- jit_emit_lfd( NATIVECODE, FSR1, -8, r1);
- /* we should keep this magic const in a preserved eg eg. f31 */
- jit_emit_mov_ri_i(NATIVECODE, ISR2, &xx);
- jit_emit_lfd( NATIVECODE, FSR2, 0, ISR2);
- if (MAP[1]) {
- jit_emit_fsub_rrr(NATIVECODE, MAP[1], FSR1, FSR2);
- }
- else {
- jit_emit_fsub_rrr(NATIVECODE, FSR1, FSR1, FSR2);
- jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR1);
- }
-}
-
-Parrot_set_n_i {
- static double xx = 4503601774854144.0; /* 0x4330000080000000L; */
- if (MAP[2]) {
- jit_emit_xoris( NATIVECODE, ISR1, MAP[2], 0x8000);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_xoris( NATIVECODE, ISR1, ISR1, 0x8000);
- }
- /* use redzone for intermediate */
- jit_emit_stw( NATIVECODE, ISR1, -4, r1);
- jit_emit_addis( NATIVECODE, ISR1, r31, 0x4330);
- jit_emit_stw( NATIVECODE, ISR1, -8, r1);
- jit_emit_lfd( NATIVECODE, FSR1, -8, r1);
- /* we should keep this magic const in a preserved eg f31 */
- jit_emit_mov_ri_i(NATIVECODE, ISR2, &xx);
- jit_emit_lfd( NATIVECODE, FSR2, 0, ISR2);
- if (MAP[1]) {
- jit_emit_fsub_rrr(NATIVECODE, MAP[1], FSR1, FSR2);
- }
- else {
- jit_emit_fsub_rrr(NATIVECODE, FSR1, FSR1, FSR2);
- jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR1);
- }
-}
-
-Parrot_null_i {
- if (MAP[1]) {
- jit_emit_mov_rr(NATIVECODE, MAP[1], r31);
- }
- else {
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), r31);
- }
-}
-
-TEMPLATE Parrot_set_x_x {
- if (MAP[1] && MAP[2]) {
- jit_emit_mov_rr(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, MAP[1], ROFFS_INT(2));
- }
- else if (MAP[2]) {
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), MAP[2]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_set_i_i {
- Parrot_set_x_x
-}
-
-Parrot_set_s_s {
- Parrot_set_x_x s/INT/STR/`
-}
-
-Parrot_set_p_p {
- Parrot_set_x_x s/INT/PMC/
-}
-
-Parrot_set_n_n {
- if (MAP[1] && MAP[2]) {
- jit_emit_mov_rr_n(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_n(NATIVECODE, MAP[1], ROFFS_NUM(2));
- }
- else if (MAP[2]) {
- jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), MAP[2]);
- }
- else {
- jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(2));
- jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR1);
- }
-}
-
-Parrot_set_n_nc {
- if (MAP[1]) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[2]);
- jit_emit_lfd(NATIVECODE, MAP[1], 0, ISR1);
- }
- else {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[2]);
- jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
- jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR1);
- }
-}
-
-TEMPLATE unary_x_x {
- if (MAP[1] && MAP[2]) {
- jit_emit_<op>_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
- jit_emit_<op>_rr<_N>(NATIVECODE, MAP[1], <s1>);
- }
- else if (MAP[2]) {
- jit_emit_<op>_rr<_N>(NATIVECODE, <s1>, MAP[1]);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
- jit_emit_<op>_rr<_N>(NATIVECODE, <s1>, <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
- }
-}
-
-TEMPLATE unary_i_i {
- unary_x_x s/<_N>/_i/ s/<t>/INT/ s/<s1>/ISR1/
-}
-
-TEMPLATE unary_n_n {
- unary_x_x s/<_N>/_n/ s/<t>/NUM/ s/<s1>/FSR1/
-}
-
-Parrot_neg_i_i {
- unary_i_i s/<op>/neg/
-}
-
-Parrot_neg_n_n {
- unary_n_n s/<op>/neg/
-}
-
-Parrot_abs_n_n {
- unary_n_n s/<op>/abs/
-}
-
-TEMPLATE binop_x_xc {
- int im;
- if (MAP[1]) {
-#ifdef jit_emit_<op>_rri<_N>
- im = *INT_CONST[2];
- /* *if* immediate constant is small and there is a dedicated
- * opcode, just use it
- * _n variants don't have immediates, only _i
- *
- * This could be further improved, if there exists also
- * a shifted opcode variant like 'oris'. But then this code
- * should be factored out into jit_emit.h. This OTOH needs some
- * convention about scratch register usage.
- */
- if (!(im >> 16)) {
- jit_emit_<op>_rri_i(NATIVECODE, MAP[1], MAP[1], im);
- }
- else
-#endif
- {
- jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[2]);
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[1], <s1>);
- }
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(1));
-#ifdef jit_emit_<op>_rri<_N>
- im = *INT_CONST[2];
- if (!(im >> 16)) {
- jit_emit_<op>_rri_i(NATIVECODE, <s1>, <s1>, im);
- }
- else
-#endif
- {
- jit_emit_mov_ri<_N>(NATIVECODE, <s2>, <c>_CONST[2]);
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, <s2>);
- }
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
- }
-}
-
-TEMPLATE binop_n_nc {
- binop_x_xc s/<_N>/_n/ s/<t>/NUM/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<c>/&NUM/
-}
-
-TEMPLATE binop_i_ic {
- binop_x_xc s/<_N>/_i/ s/<t>/INT/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<c>/*INT/
-}
-
-TEMPLATE binop_x_x {
- if (MAP[1] && MAP[2]) {
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[1], <s1>);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(1));
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, MAP[2]);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(1));
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, <s2>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
-}
-
-TEMPLATE binop_x_x_x {
- if (MAP[1] && MAP[2] && MAP[3]) {
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[2], MAP[3]);
- }
- else if (MAP[1] && MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[2], <s1>);
- }
- else if (MAP[1] && MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s1>, MAP[3]);
- }
- else if (MAP[2] && MAP[3]) {
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, MAP[2], MAP[3]);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s2>, <s1>);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, MAP[2], <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
- else if (MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(2));
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, MAP[3]);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<T>(3));
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<T>(2));
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s2>, <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<T>(1), <s1>);
- }
-}
-
-TEMPLATE binop_x_xc_x {
- if (MAP[1] && MAP[3]) {
- jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[2]);
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s1>, MAP[3]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
- jit_emit_mov_ri<_N>(NATIVECODE, <s2>, <c>_CONST[2]);
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s2>, <s1>);
- }
- else if (MAP[3]) {
- jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[2]);
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s1>, MAP[3]);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
- jit_emit_mov_ri<_N>(NATIVECODE, <s2>, <c>_CONST[2]);
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s2>, <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
- }
-}
-
-TEMPLATE binop_i_ic_i {
- binop_x_xc_x s/<_N>/_i/ s/<t>/INT/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<c>/*INT/
-}
-TEMPLATE binop_n_nc_n {
- binop_x_xc_x s/<_N>/_n/ s/<t>/NUM/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<c>/&NUM/
-}
-
-TEMPLATE binop_x_x_xc {
- if (MAP[1] && MAP[2]) {
-#ifdef jit_emit_<op>_rri<_N>
- /* common case - operands are MAPped */
- int im = *INT_CONST[3];
- if (!(im >> 16)) {
- jit_emit_<op>_rri_i(NATIVECODE, MAP[1], MAP[2], im);
- }
- else
-#endif
- {
- jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[3]);
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], MAP[2], <s1>);
- }
- }
- else if (MAP[1]) {
- jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[3]);
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
- jit_emit_<op>_rrr<_N>(NATIVECODE, MAP[1], <s2>, <s1>);
- }
- else if (MAP[2]) {
- jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[3]);
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, MAP[2], <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
- }
- else {
- jit_emit_mov_ri<_N>(NATIVECODE, <s1>, <c>_CONST[3]);
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
- jit_emit_<op>_rrr<_N>(NATIVECODE, <s1>, <s2>, <s1>);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_<t>(1), <s1>);
- }
-}
-
-TEMPLATE binop_i_i_ic {
- binop_x_x_xc s/<_N>/_i/ s/<t>/INT/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<c>/*INT/
-}
-
-TEMPLATE binop_n_n_nc {
- binop_x_x_xc s/<_N>/_n/ s/<t>/NUM/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<c>/&NUM/
-}
-
-Parrot_band_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bor_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bxor_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_shr_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/shr/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_shl_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/shl/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_lsr_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/lsr/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_add_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_sub_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_mul_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/mul/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_div_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/div/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_cmod_i_i {
- binop_x_x s/<_N>/_i/ s/<op>/cmod/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_band_i_ic {
- binop_i_ic s/<op>/and/
-}
-
-Parrot_bor_i_ic {
- binop_i_ic s/<op>/or/
-}
-
-Parrot_bxor_i_ic {
- binop_i_ic s/<op>/xor/
-}
-
-Parrot_shr_i_ic {
- binop_i_ic s/<op>/shr/
-}
-
-Parrot_shl_i_ic {
- binop_i_ic s/<op>/shl/
-}
-
-Parrot_lsr_i_ic {
- binop_i_ic s/<op>/lsr/
-}
-
-Parrot_add_i_ic {
- binop_i_ic s/<op>/add/
-}
-
-Parrot_sub_i_ic {
- binop_i_ic s/<op>/sub/
-}
-
-Parrot_mul_i_ic {
- binop_i_ic s/<op>/mul/
-}
-
-Parrot_div_i_ic {
- binop_i_ic s/<op>/div/
-}
-
-Parrot_cmod_i_ic {
- binop_i_ic s/<op>/cmod/
-}
-
-Parrot_add_n_nc {
- binop_n_nc s/<op>/add/
-}
-
-Parrot_sub_n_nc {
- binop_n_nc s/<op>/sub/
-}
-
-Parrot_mul_n_nc {
- binop_n_nc s/<op>/mul/
-}
-
-Parrot_div_n_nc {
- binop_n_nc s/<op>/div/
-}
-
-Parrot_add_n_n {
- binop_x_x s/<_N>/_n/ s/<op>/add/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
-}
-
-Parrot_div_n_n {
- binop_x_x s/<_N>/_n/ s/<op>/div/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
-}
-
-Parrot_mul_n_n {
- binop_x_x s/<_N>/_n/ s/<op>/mul/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
-}
-
-Parrot_sub_n_n {
- binop_x_x s/<_N>/_n/ s/<op>/sub/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
-}
-
-Parrot_band_i_i_i {
- binop_x_x_x s/<_N>/_i/ s/<op>/and/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bor_i_i_i {
- binop_x_x_x s/<_N>/_i/ s/<op>/or/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_bxor_i_i_i {
- binop_x_x_x s/<_N>/_i/ s/<op>/xor/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_add_i_i_i {
- binop_x_x_x s/<_N>/_i/ s/<op>/add/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_sub_i_i_i {
- binop_x_x_x s/<_N>/_i/ s/<op>/sub/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_mul_i_i_i {
- binop_x_x_x s/<_N>/_i/ s/<op>/mul/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_div_i_i_i {
- binop_x_x_x s/<_N>/_i/ s/<op>/div/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_cmod_i_i_i {
- binop_x_x_x s/<_N>/_i/ s/<op>/cmod/ s/<s1>/ISR1/ s/<s2>/ISR2/ s/<T>/INT/
-}
-
-Parrot_band_i_i_ic {
- binop_i_i_ic s/<op>/and/
-}
-
-Parrot_bor_i_i_ic {
- binop_i_i_ic s/<op>/or/
-}
-
-Parrot_bxor_i_i_ic {
- binop_i_i_ic s/<op>/xor/
-}
-
-Parrot_shr_i_i_ic {
- binop_i_i_ic s/<op>/shr/
-}
-
-Parrot_shl_i_i_ic {
- binop_i_i_ic s/<op>/shl/
-}
-
-Parrot_lsr_i_i_ic {
- binop_i_i_ic s/<op>/lsr/
-}
-
-Parrot_add_i_i_ic {
- binop_i_i_ic s/<op>/add/
-}
-
-Parrot_sub_i_i_ic {
- binop_i_i_ic s/<op>/sub/
-}
-
-Parrot_mul_i_i_ic {
- binop_i_i_ic s/<op>/mul/
-}
-
-Parrot_div_i_i_ic {
- binop_i_i_ic s/<op>/div/
-}
-
-Parrot_cmod_i_i_ic {
- binop_i_i_ic s/<op>/cmod/
-}
-
-Parrot_add_n_n_nc {
- binop_n_n_nc s/<op>/add/
-}
-
-Parrot_sub_n_n_nc {
- binop_n_n_nc s/<op>/sub/
-}
-
-Parrot_mul_n_n_ic {
- binop_n_n_nc s/<op>/mul/
-}
-
-Parrot_div_n_n_nc {
- binop_n_n_nc s/<op>/div/
-}
-
-Parrot_band_i_ic_i {
- binop_i_ic_i s/<op>/and/
-}
-
-Parrot_bor_i_ic_i {
- binop_i_ic_i s/<op>/or/
-}
-
-Parrot_bxor_i_ic_i {
- binop_i_ic_i s/<op>/xor/
-}
-
-Parrot_shr_i_ic_i {
- binop_i_ic_i s/<op>/shr/
-}
-
-Parrot_lsr_i_ic_i {
- binop_i_ic_i s/<op>/lsr/
-}
-
-Parrot_shl_i_ic_i {
- binop_i_ic_i s/<op>/shl/
-}
-
-Parrot_add_i_ic_i {
- binop_i_ic_i s/<op>/add/
-}
-
-Parrot_sub_i_ic_i {
- binop_i_ic_i s/<op>/sub/
-}
-
-Parrot_mul_i_ic_i {
- binop_i_ic_i s/<op>/mul/
-}
-
-Parrot_div_i_ic_i {
- binop_i_ic_i s/<op>/div/
-}
-
-Parrot_cmod_i_ic_i {
- binop_i_ic_i s/<op>/cmod/
-}
-
-Parrot_add_n_nc_n {
- binop_n_nc_n s/<op>/add/
-}
-
-Parrot_sub_n_nc_n {
- binop_n_nc_n s/<op>/sub/
-}
-
-Parrot_mul_n_nc_n {
- binop_n_nc_n s/<op>/mul/
-}
-
-Parrot_div_n_nc_n {
- binop_n_nc_n s/<op>/div/
-}
-
-Parrot_add_n_n_n {
- binop_x_x_x s/<_N>/_n/ s/<op>/add/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
-}
-
-Parrot_sub_n_n_n {
- binop_x_x_x s/<_N>/_n/ s/<op>/sub/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
-}
-
-Parrot_mul_n_n_n {
- binop_x_x_x s/<_N>/_n/ s/<op>/mul/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
-}
-
-Parrot_div_n_n_n {
- binop_x_x_x s/<_N>/_n/ s/<op>/div/ s/<s1>/FSR1/ s/<s2>/FSR2/ s/<T>/NUM/
-}
-
-Parrot_rot_i_i_ic_ic {
- int rc = *INT_CONST[3];
- int bw = *INT_CONST[4];
- if (rc < 0)
- rc = bw + rc;
- if (MAP[1] && MAP[2]) {
- jit_emit_rot_rri(NATIVECODE, MAP[1], MAP[2], rc);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(2));
- jit_emit_rot_rri(NATIVECODE, MAP[1], ISR2, rc);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_rot_rri(NATIVECODE, ISR1, MAP[2], rc);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(2));
- jit_emit_rot_rri(NATIVECODE, ISR1, ISR2, rc);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-
-}
-
-; actually this covers islt too, by passing the bit
-TEMPLATE iseq_i_x_x {
- if (MAP[2] && MAP[3]) {
- jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], MAP[3]);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
- jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], <s1>);
- }
- else if (MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
- jit_emit_cmp_rr<_N>(NATIVECODE, <s1>, MAP[3]);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
- jit_emit_cmp_rr<_N>(NATIVECODE, <s2>, <s1>);
- }
- jit_emit_mfcr(NATIVECODE, ISR1);
- /* bits 0 LT, 1 GT, 2 EQ */
- /* see also extrwi */
- if (MAP[1]) {
- jit_emit_rlwinm(NATIVECODE, MAP[1], ISR1, <b>, 31, 31);
- }
- else {
- jit_emit_rlwinm(NATIVECODE, ISR1, ISR1, <b>, 31, 31);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-TEMPLATE isle_i_x_x {
- if (MAP[2] && MAP[3]) {
- jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], MAP[3]);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
- jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], <s1>);
- }
- else if (MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
- jit_emit_cmp_rr<_N>(NATIVECODE, <s1>, MAP[3]);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
- jit_emit_cmp_rr<_N>(NATIVECODE, <s2>, <s1>);
- }
- jit_emit_mfcr(NATIVECODE, ISR1);
- /* bits 0 LT, 1 GT, 2 EQ */
- /* this is LT or LE - get LT */
- jit_emit_rlwinm(NATIVECODE, ISR2, ISR1, 1, 31, 31);
- /* get EQ and or the bits into destination */
- jit_emit_rlwinm(NATIVECODE, ISR1, ISR1, 3, 31, 31);
- if (MAP[1]) {
- jit_emit_or_rrr(NATIVECODE, MAP[1], ISR1, ISR2);
- }
- else {
- jit_emit_or_rrr(NATIVECODE, ISR1, ISR1, ISR2);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-TEMPLATE cmp_i_x_x {
- if (MAP[2] && MAP[3]) {
- jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], MAP[3]);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
- jit_emit_cmp_rr<_N>(NATIVECODE, MAP[2], <s1>);
- }
- else if (MAP[3]) {
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(2));
- jit_emit_cmp_rr<_N>(NATIVECODE, <s1>, MAP[3]);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, <s2>, ROFFS_<t>(2));
- jit_emit_mov_rm<_N>(NATIVECODE, <s1>, ROFFS_<t>(3));
- jit_emit_cmp_rr<_N>(NATIVECODE, <s2>, <s1>);
- }
- jit_emit_mfcr(NATIVECODE, ISR1);
- /* bits 0 LT, 1 GT, 2 EQ */
- /* get LT -> 0/1 */
- jit_emit_rlwinm(NATIVECODE, ISR2, ISR1, 1, 31, 31);
- /* reverse bit */
- jit_emit_xori (NATIVECODE, ISR2, ISR2, 1);
- /* sub 1 -> -1 / 0 */
- jit_emit_subi (NATIVECODE, ISR2, ISR2, 1);
- /* get GT or the bits into destination */
- jit_emit_rlwinm(NATIVECODE, ISR1, ISR1, 2, 31, 31);
- if (MAP[1]) {
- jit_emit_or_rrr(NATIVECODE, MAP[1], ISR1, ISR2);
- }
- else {
- jit_emit_or_rrr(NATIVECODE, ISR1, ISR1, ISR2);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-Parrot_iseq_i_i_i {
- iseq_i_x_x s/<s1>/ISR1/ s/<s2>/ISR2/ s/<t>/INT/ s/<_N>/_i/ s/<b>/3/
-}
-
-Parrot_iseq_i_n_n {
- iseq_i_x_x s/<s1>/FSR1/ s/<s2>/FSR2/ s/<t>/NUM/ s/<_N>/_n/ s/<b>/3/
-}
-
-Parrot_islt_i_i_i {
- iseq_i_x_x s/<s1>/ISR1/ s/<s2>/ISR2/ s/<t>/INT/ s/<_N>/_i/ s/<b>/1/
-}
-
-Parrot_islt_i_n_n {
- iseq_i_x_x s/<s1>/FSR1/ s/<s2>/FSR2/ s/<t>/NUM/ s/<_N>/_n/ s/<b>/1/
-}
-
-Parrot_isle_i_i_i {
- isle_i_x_x s/<s1>/ISR1/ s/<s2>/ISR2/ s/<t>/INT/ s/<_N>/_i/
-}
-
-Parrot_isle_i_n_n {
- isle_i_x_x s/<s1>/FSR1/ s/<s2>/FSR2/ s/<t>/NUM/ s/<_N>/_n/
-}
-
-Parrot_cmp_i_i_i {
- cmp_i_x_x s/<s1>/ISR1/ s/<s2>/ISR2/ s/<t>/INT/ s/<_N>/_i/
-}
-
-Parrot_cmp_i_n_n {
- cmp_i_x_x s/<s1>/FSR1/ s/<s2>/FSR2/ s/<t>/NUM/ s/<_N>/_n/
-}
-
-Parrot_inc_i {
- if (MAP[1]) {
- jit_emit_add_rri_i (NATIVECODE, MAP[1], MAP[1], 1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_add_rri_i (NATIVECODE, ISR1, ISR1, 1);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_dec_i {
- if (MAP[1]) {
- jit_emit_add_rri_i (NATIVECODE, MAP[1], MAP[1], -1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_add_rri_i (NATIVECODE, ISR1, ISR1, -1);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-Parrot_inc_n {
- static const double one = 1.0;
- jit_emit_mov_ri_i(NATIVECODE, ISR1, &one);
- jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
- if (MAP[1]) {
- jit_emit_fadd_rrr(NATIVECODE, MAP[1], MAP[1], FSR1);
- }
- else {
- jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
- jit_emit_fadd_rrr(NATIVECODE, FSR2, FSR2, FSR1);
- jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR2);
- }
-}
-
-Parrot_dec_n {
- static const double one = 1.0;
- jit_emit_mov_ri_i(NATIVECODE, ISR1, &one);
- jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
- if (MAP[1]) {
- jit_emit_fsub_rrr(NATIVECODE, MAP[1], MAP[1], FSR1);
- }
- else {
- jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
- jit_emit_fsub_rrr(NATIVECODE, FSR2, FSR2, FSR1);
- jit_emit_mov_mr_n(NATIVECODE, ROFFS_NUM(1), FSR2);
- }
-}
-
-
-TEMPLATE Parrot_unaryop_x {
- if (MAP[1]) {
- jit_emit_<op>_rr<_N>(NATIVECODE, MAP[1], MAP[1]);
- }
- else {
- jit_emit_mov_rm<_N>(NATIVECODE, SCRATCH1, ROFFS_INT(1));
- jit_emit_<op>_rr<_N>(NATIVECODE, SCRATCH1, SCRATCH1);
- jit_emit_mov_mr<_N>(NATIVECODE, ROFFS_INT(1), SCRATCH1);
- }
-}
-
-; a recursive template
-TEMPLATE Parrot_unaryop_i {
- Parrot_unaryop_x s/<_N>/_i/ s/SCRATCH1/ISR1/
-}
-
-TEMPLATE Parrot_unaryop_n {
- Parrot_unaryop_x s/<_N>/_n/ s/INT/NUM/ s/SCRATCH1/FSR1/
-}
-
-Parrot_neg_i {
- Parrot_unaryop_i s/<op>/neg/
-}
-
-Parrot_neg_n {
- Parrot_unaryop_n s/<op>/neg/
-}
-
-Parrot_abs_n {
- Parrot_unaryop_n s/<op>/abs/
-}
-
-Parrot_abs_i {
- if (MAP[1]) {
- jit_emit_srawi(NATIVECODE, ISR1, MAP[1], 31);
- jit_emit_add_rrr(NATIVECODE, ISR2, ISR1, MAP[1]);
- jit_emit_xor_rrr(NATIVECODE, MAP[1], ISR2, ISR1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_srawi(NATIVECODE, ISR2, ISR1, 31);
- jit_emit_add_rrr(NATIVECODE, ISR1, ISR2, ISR1);
- jit_emit_xor_rrr(NATIVECODE, ISR1, ISR1, ISR2);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_INT(1), ISR1);
- }
-}
-
-
-TEMPLATE Parrot_ifunless_i_ic {
- if (P_ARITH && MAP[1]) {
- /* set the Rc bit of prev for the sake of +50% more MOPS */
- NATIVECODE[-1] |= 1;
- }
- else if (MAP[1]) {
- jit_emit_cmp_ri(NATIVECODE, MAP[1], 0);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_cmp_ri(NATIVECODE, ISR1, 0);
- }
- jit_emit_bc(jit_info, <COND>, *INT_CONST[2]);
-}
-
-Parrot_if_i_ic {
- Parrot_ifunless_i_ic s/<COND>/BNE/
-}
-
-Parrot_unless_i_ic {
- Parrot_ifunless_i_ic s/<COND>/BEQ/
-}
-
-TEMPLATE Parrot_ifunless_n_ic {
- static const double zero = 0.0;
- jit_emit_mov_ri_i(NATIVECODE, ISR1, &zero);
- jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
- if (MAP[1]) {
- jit_emit_cmp_rr_n(NATIVECODE, MAP[1], FSR1);
- }
- else {
- jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
- jit_emit_cmp_rr_n(NATIVECODE, FSR2, FSR1);
- }
- jit_emit_bc(jit_info, <COND>, *INT_CONST[2]);
-}
-
-Parrot_if_n_ic {
- Parrot_ifunless_n_ic s/<COND>/BNE/
-}
-
-Parrot_unless_n_ic {
- Parrot_ifunless_n_ic s/<COND>/BEQ/
-}
-
-TEMPLATE Parrot_branch_i_i_ic {
-; First, emit the compare op:
- if (MAP[1] && MAP[2]) {
- jit_emit_cmp_rr_i(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_cmp_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_cmp_rr_i(NATIVECODE, ISR1, MAP[2]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(1));
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(2));
- jit_emit_cmp_rr_i(NATIVECODE, ISR2, ISR1);
- }
-; Now the branch. XXX: need to handle large displacements.
- jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
-}
-
-TEMPLATE Parrot_branch_i_ic_ic {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
-
- if (MAP[1]) {
- jit_emit_cmp_rr_i(NATIVECODE, MAP[1], ISR1);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(1));
- jit_emit_cmp_rr_i(NATIVECODE, ISR2, ISR1);
- }
-; Now the branch. XXX: need to handle large displacements.
- jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
-
-}
-
-TEMPLATE Parrot_branch_ic_i_ic {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, *INT_CONST[1]);
-
- if (MAP[2]) {
- jit_emit_cmp_rr_i(NATIVECODE, ISR1, MAP[2]);
- }
- else {
- jit_emit_mov_rm_i(NATIVECODE, ISR2, ROFFS_INT(2));
- jit_emit_cmp_rr_i(NATIVECODE, ISR1, ISR2);
- }
-; Now the branch. XXX: need to handle large displacements.
- jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
-}
-
-Parrot_eq_i_i_ic {
- Parrot_branch_i_i_ic s/<CON>/BEQ/
-}
-
-Parrot_eq_i_ic_ic {
- Parrot_branch_i_ic_ic s/<CON>/BEQ/
-}
-
-Parrot_eq_ic_i_ic {
- Parrot_branch_ic_i_ic s/<CON>/BEQ/
-}
-
-
-Parrot_lt_i_i_ic {
- Parrot_branch_i_i_ic s/<CON>/BLT/
-}
-
-Parrot_lt_i_ic_ic {
- Parrot_branch_i_ic_ic s/<CON>/BLT/
-}
-
-Parrot_lt_ic_i_ic {
- Parrot_branch_ic_i_ic s/<CON>/BLT/
-}
-
-Parrot_le_i_i_ic {
- Parrot_branch_i_i_ic s/<CON>/BLE/
-}
-
-Parrot_le_i_ic_ic {
- Parrot_branch_i_ic_ic s/<CON>/BLE/
-}
-
-Parrot_le_ic_i_ic {
- Parrot_branch_ic_i_ic s/<CON>/BLE/
-}
-
-
-Parrot_ne_i_i_ic {
- Parrot_branch_i_i_ic s/<CON>/BNE/
-}
-
-Parrot_ne_i_ic_ic {
- Parrot_branch_i_ic_ic s/<CON>/BNE/
-}
-
-Parrot_ne_ic_i_ic {
- Parrot_branch_ic_i_ic s/<CON>/BNE/
-}
-
-
-TEMPLATE Parrot_branch_n_n_ic {
- if (MAP[1] && MAP[2]) {
- jit_emit_cmp_rr_n(NATIVECODE, MAP[1], MAP[2]);
- }
- else if (MAP[1]) {
- jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(2));
- jit_emit_cmp_rr_n(NATIVECODE, MAP[1], FSR1);
- }
- else if (MAP[2]) {
- jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(1));
- jit_emit_cmp_rr_n(NATIVECODE, FSR1, MAP[2]);
- }
- else {
- jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
- jit_emit_mov_rm_n(NATIVECODE, FSR1, ROFFS_NUM(2));
- jit_emit_cmp_rr_n(NATIVECODE, FSR2, FSR1);
- }
- jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
-}
-
-TEMPLATE Parrot_branch_n_nc_ic {
- jit_emit_mov_ri_n(NATIVECODE, FSR1, &NUM_CONST[2]);
- if (MAP[1]) {
- jit_emit_cmp_rr_n(NATIVECODE, MAP[1], FSR1);
- }
- else {
- jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(1));
- jit_emit_cmp_rr_n(NATIVECODE, FSR2, FSR1);
- }
- jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
-}
-
-TEMPLATE Parrot_branch_nc_n_ic {
- if (MAP[2]) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[1]);
- jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
- jit_emit_cmp_rr_n(NATIVECODE, FSR1, MAP[2]);
- }
- else {
- jit_emit_mov_rm_n(NATIVECODE, FSR2, ROFFS_NUM(2));
- jit_emit_mov_ri_i(NATIVECODE, ISR1, &NUM_CONST[1]);
- jit_emit_lfd(NATIVECODE, FSR1, 0, ISR1);
- jit_emit_cmp_rr_n(NATIVECODE, FSR1, FSR2);
- }
- jit_emit_bc(jit_info, <CON>, *INT_CONST[3]);
-}
-
-Parrot_eq_n_n_ic {
- Parrot_branch_n_n_ic s/<CON>/BEQ/
-}
-
-Parrot_eq_n_nc_ic {
- Parrot_branch_n_nc_ic s/<CON>/BEQ/
-}
-
-Parrot_eq_nc_n_ic {
- Parrot_branch_nc_n_ic s/<CON>/BEQ/
-}
-
-
-Parrot_lt_n_n_ic {
- Parrot_branch_n_n_ic s/<CON>/BLT/
-}
-
-Parrot_lt_n_nc_ic {
- Parrot_branch_n_nc_ic s/<CON>/BLT/
-}
-
-Parrot_lt_nc_n_ic {
- Parrot_branch_nc_n_ic s/<CON>/BLT/
-}
-
-
-Parrot_le_n_n_ic {
- Parrot_branch_n_n_ic s/<CON>/BLE/
-}
-
-Parrot_le_n_nc_ic {
- Parrot_branch_n_nc_ic s/<CON>/BLE/
-}
-
-Parrot_le_nc_n_ic {
- Parrot_branch_nc_n_ic s/<CON>/BLE/
-}
-
-Parrot_ne_n_n_ic {
- Parrot_branch_n_n_ic s/<CON>/BNE/
-}
-
-Parrot_ne_n_nc_ic {
- Parrot_branch_n_nc_ic s/<CON>/BNE/
-}
-
-Parrot_ne_nc_n_ic {
- Parrot_branch_nc_n_ic s/<CON>/BLE/
-}
-
-
-Parrot_branch_ic {
- jit_emit_bx(jit_info, 0, *INT_CONST[1]);
-}
-
-Parrot_branch_i {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_INT(1));
- jit_emit_mtlr(NATIVECODE, ISR1);
- jit_emit_blr(NATIVECODE);
-}
-
-TEMPLATE Parrot_set_or_clone_s_sc {
-; Parrot_str_copy(Interp *interp, STRING *s)
- jit_emit_mov_rr(NATIVECODE, r3, r16);
- jit_emit_mov_ri_i(NATIVECODE, r4, CONST(2)->u.string);
-
- jit_emit_call_func(NATIVECODE, (void*) Parrot_str_copy);
-
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_STR(1), r3);
-}
-
-Parrot_set_s_sc {
- Parrot_set_or_clone_s_sc
-}
-
-Parrot_clone_s_sc {
- Parrot_set_or_clone_s_sc
-}
-
-Parrot_set_s_s {
- jit_emit_mov_rm_i(NATIVECODE, ISR1, ROFFS_STR(2));
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_STR(1), ISR1);
-}
-
-Parrot_clone_s_s {
- jit_emit_mov_rr(NATIVECODE, r3, r16);
- jit_emit_mov_rm_i(NATIVECODE, r4, ROFFS_STR(2));
-
- jit_emit_call_func(NATIVECODE, (void*) Parrot_str_copy);
-
- jit_emit_mov_mr_i(NATIVECODE,ROFFS_STR(1), r3);
-}
-
-Parrot_set_p_pc {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, CONST(2)->u.key);
- jit_emit_mov_mr_i(NATIVECODE, ROFFS_PMC(1), ISR1);
-}
-
-; the following 4 ops don't branch but are translated as cpfp
-; which adds unneeded overhead - convert to normal ops
-; or just JIT (TODO) the 2 easy ones
-Parrot_set_args_pc {
- if (jit_info->code_type == JIT_CODE_FILE) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
- jit_emit_stw(NATIVECODE, ISR1, offsetof(Interp, current_args), r16);
- }
- else {
- jit_set_args_pc(jit_info, interp,
- jit_info->flags & JIT_CODE_RECURSIVE);
- }
-}
-
-extern Parrot_set_returns_pc {
- if (jit_info->code_type == JIT_CODE_FILE)
- Parrot_jit_normal_op(jit_info, interp);
- else {
- jit_set_returns_pc(jit_info, interp,
- jit_info->flags & JIT_CODE_RECURSIVE);
- }
-}
-
-extern Parrot_returncc {
- if (jit_info->code_type == JIT_CODE_FILE)
- Parrot_jit_restart_op(jit_info, interp);
- else {
- /* fetch args[n+1] -> retval */
- if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
- jit_emit_lwz(jit_info->native_ptr, r1, 0, r1);
- jit_emit_lwz(jit_info->native_ptr, r3, 4 + jit_info->n_args * 4, r5);
- jit_emit_lwz(jit_info->native_ptr, r31, -4, r1);
- jit_emit_lwz(jit_info->native_ptr, r0, 8, r1); /* get link reg */
- jit_emit_mtlr(jit_info->native_ptr, r0); /* move to link reg */
- }
- jit_emit_blr(jit_info->native_ptr);
- }
-}
-
-Parrot_pic_callr___pc {
- PackFile_Constant **constants = CONTEXT(interp)->constants;
- PMC *sig_result = constants[CUR_OPCODE[1]]->u.key;
- opcode_t *params = jit_info->optimizer->sections->begin;
- PMC *sig_params = constants[params[1]]->u.key;
- int op_i = VTABLE_elements(interp, sig_params) + 2;
- int offset = jit_info->arena.op_map[op_i].offset;
- int here = NATIVECODE - jit_info->arena.start;
- int skip;
-
- /* TODO preserve necessary regs */
- assert(*CUR_OPCODE == PARROT_OP_get_results_pc);
-
- if (!VTABLE_elements(interp, sig_result))
- skip = -1;
- /* skip result - save rest */
- else
- skip = MAP(2);
-
- offset -= here;
-
- /* bl */
- _emit_bx(NATIVECODE, 1, offset);
-
- jit_restore_regs_call(jit_info, interp, skip);
-}
-
-extern Parrot_get_params_pc {
- if (jit_info->code_type == JIT_CODE_FILE)
- Parrot_jit_normal_op(jit_info, interp);
- else if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
- jit_get_params_pc(jit_info, interp);
- }
-}
-
-Parrot_get_results_pc {
- if (jit_info->code_type == JIT_CODE_FILE) {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
- jit_emit_lwz(NATIVECODE, ISR2, offsetof(Interp, ctx), r16);
- jit_emit_lwz(NATIVECODE, ISR2, offsetof(PMC, data), ISR2);
- jit_emit_stw(NATIVECODE, ISR1,
- offsetof(Parrot_Context, current_results), ISR2);
- }
- else {
- PackFile_Constant **constants = CONTEXT(interp)->constants;
- PMC *sig_result = constants[CUR_OPCODE[1]]->u.key;
-
- if (!VTABLE_elements(interp, sig_result))
- return;
-
- /* result is r3 TODO Nums */
- jit_emit_mov_rr(NATIVECODE, MAP(2), r3);
- }
-}
Deleted: trunk/src/jit/ppc/exec_dep.c
==============================================================================
--- trunk/src/jit/ppc/exec_dep.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,85 +0,0 @@
-/*
- Copyright (C) 2003-2008, Parrot Foundation.
- $Id$
-*/
-
-/*
- * exec_dep.c
- *
- * Overview:
- * PPC dependent functions to emit an executable.
- * History:
- * Initial version by Daniel Grunblatt on 2003.6.9
- * Notes:
- * References:
- */
-
-#include "parrot/parrot.h"
-#include "jit.h"
-#define JIT_EMIT 1
-#include "jit_emit.h"
-#include "exec_dep.h"
-
-/* HEADERIZER HFILE: src/jit/ppc/exec_dep.h */
-
-#ifdef JIT_CGP
-
-void
-Parrot_exec_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
-}
-
-#else /* JIT_CGP */
-
-void
-Parrot_exec_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- add_disp(jit_info->native_ptr, r3,
- ((long)jit_info->cur_op - (long)interp->code->base.data));
- jit_emit_mov_rr(jit_info->native_ptr, r4, r13);
-
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_FUNC,
- interp->op_info_table[*jit_info->cur_op].func_name, 0);
- _emit_bx(jit_info->native_ptr, 1, 0);
-}
-
-#endif /* JIT_CGP */
-
-void
-Parrot_exec_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- Parrot_exec_normal_op(jit_info, interp);
- jit_emit_sub_rrr(jit_info->native_ptr, r3, r3, r15);
- jit_emit_add_rrr(jit_info->native_ptr, r3, r14, r3);
- jit_emit_lwz(jit_info->native_ptr, r3, 0, r3);
- jit_emit_mtlr(jit_info->native_ptr, r3);
- jit_emit_blr(jit_info->native_ptr);
-}
-
-void
-Parrot_exec_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
-}
-
-/* Assign the offset of the program_code */
-void
-offset_fixup(Parrot_exec_objfile_t *obj)
-{
- int i, j;
-
- for (i = 0; i < obj->data_count; i++) {
-#ifdef EXEC_MACH_O
- obj->symbol_table[i].value = obj->text.size;
-#endif
- for (j = 0; j < i; j++)
- obj->symbol_table[i].value += obj->data_size[j];
- }
-}
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/ppc/exec_dep.h
==============================================================================
--- trunk/src/jit/ppc/exec_dep.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,58 +0,0 @@
-/*
- Copyright (C) 2003-2008, Parrot Foundation.
- $Id$
-*/
-
-/*
- * exec_dep.h
- *
- * Overview:
- * PPC dependent functions to emit an executable.
- * History:
- * Initial version by Daniel Grunblatt on 2003.6.9
- * Notes:
- * References:
- */
-
-#include "jit.h"
-#include "jit_emit.h"
-
-#ifndef PARROT_PPC_EXEC_DEP_H_GUARD
-#define PARROT_PPC_EXEC_DEP_H_GUARD
-
-/* HEADERIZER BEGIN: src/exec_dep.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-
-void offset_fixup(Parrot_exec_objfile_t *obj);
-void Parrot_exec_cpcf_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
- __attribute__nonnull__(2);
-
-void Parrot_exec_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
- __attribute__nonnull__(2);
-
-void Parrot_exec_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
- __attribute__nonnull__(2);
-
-void Parrot_exec_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
- __attribute__nonnull__(2);
-
-#define ASSERT_ARGS_offset_fixup __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
-#define ASSERT_ARGS_Parrot_exec_cpcf_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_exec_normal_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_exec_normal_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_exec_restart_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-/* HEADERIZER END: src/exec_dep.c */
-
-#endif /* PARROT_PPC_EXEC_DEP_H_GUARD */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/ppc/jit_defs.c
==============================================================================
--- trunk/src/jit/ppc/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,13 +0,0 @@
-/* Stub file for RT#38929 fixes */
-/*
-Copyright (C) 2008, Parrot Foundation.
-$Id$
-*/
-/* HEADERIZER HFILE: none */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/ppc/jit_emit.h
==============================================================================
--- trunk/src/jit/ppc/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,1408 +0,0 @@
-/*
- * Copyright (C) 2002-2009, Parrot Foundation.
- */
-
-/*
- * jit_emit.h
- *
- * PPC
- *
- * $Id$
- */
-
-#ifndef PARROT_PPC_JIT_EMIT_H_GUARD
-#define PARROT_PPC_JIT_EMIT_H_GUARD
-
-# include <unistd.h>
-# include <sys/mman.h>
-# include <limits.h>
-# include "parrot/oplib/ops.h"
-# include "pmc/pmc_fixedintegerarray.h"
-
-#ifndef CACHELINESIZE
- /* TODO this should be determined by configure */
-# ifdef PARROT_EXEC_OS_AIX
- /* for POWER3 */
-# define CACHELINESIZE 0x80
-# else
- /* for PowerPC */
-# define CACHELINESIZE 0x10
-# endif
-#endif
-
-typedef enum {
- r0,
- r1,
- r2,
- r3,
- r4,
- r5,
- r6,
- r7,
- r8,
- r9,
- r10,
- r11,
- ISR1 = r11,
- r12,
- ISR2 = r12,
- r13,
- r14,
- r15,
- r16,
- r17,
- r18,
- r19,
- r20,
- r21,
- r22,
- r23,
- r24,
- r25,
- r26,
- r27,
- r28,
- r29,
- r30,
- r31
-} ppc_iregister_t;
-
-# define Parrot_jit_emit_get_base_reg_no(pc) r13
-
-typedef enum {
- f0,
- FSR1 = f0,
- f1,
- f2,
- f3,
- f4,
- f5,
- f6,
- f7,
- f8,
- f9,
- f10,
- f11,
- f12,
- f13,
- FSR2 = f13,
- f14,
- f15,
- f16,
- f17,
- f18,
- f19,
- f20,
- f21,
- f22,
- f23,
- f24,
- f25,
- f26,
- f27,
- f28,
- f29,
- f30,
- f31
-} ppc_fregister_t;
-
-/* Scratch registers. */
-
-
-enum { JIT_PPC_CALL, JIT_PPC_BRANCH, JIT_PPC_UBRANCH };
-
-# define emit_op(op) ((op) << 2)
-
-# define emit_r3(reg) ((reg) >> 3)
-
-# define emit_l5(reg) ((reg) << 5)
-
-/* Move (mr).
- *
- * mr rD,rA
- *
- * +-----------------------------------+
- * | 31 |
- * +-----------------------------------+
- * 0 5 6 29 30 31
- * */
-# define jit_emit_mov_rr(pc, dst, src) \
- do { \
- if ((dst) != (src)) { \
- *((pc)++) = emit_op(31) | emit_r3(src); \
- *((pc)++) = (char)(emit_l5(src) | (dst)); \
- *((pc)++) = (char)(0x3 | (src) * 8); \
- *((pc)++) = 0x78; \
- } \
- } \
- while (0)
-
-/* Move from/to special purpose register.
- *
- * mtspr SPR,rS
- *
- * +--------------------------------------------------------------------+
- * | 31 | D-S | spr | type | 0 |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 20 21 30 31
- *
- * spr = 8 == LR
- * spr = 9 == CTR
- *
- * mfspr type == 339
- * mtspr type == 467
- *
- * mtlr rS == mtspr 8,rS
- * mtctr rS == mtspr 9,rS
- *
- */
-# define jit_emit_mxspr(pc, S, spr, type) \
- *((pc)++) = 31 << 2 | (S) >> 3; \
- *((pc)++) = (char)((S) << 5 | (spr)); \
- *((pc)++) = (type) >> 7; \
- *((pc)++) = (char)((type) << 1)
-
-# define jit_emit_mtlr(pc, S) \
- jit_emit_mxspr((pc), (S), 8, 467)
-
-# define jit_emit_mtctr(pc, S) \
- jit_emit_mxspr((pc), (S), 9, 467)
-
-# define jit_emit_mflr(pc, D) \
- jit_emit_mxspr((pc), (D), 8, 339)
-
-/* Branches (b/bl/ba/bla) with 24 bits literal.
- *
- * b (AA = 0, LK = 0)
- * bl (AA = 0, LK = 1)
- * ba (AA = 1, LK = 0)
- * bla (AA = 1, LK = 1)
- *
- * +--------------------------------------------------------------------+
- * | 18 | LI | AA | LK |
- * +--------------------------------------------------------------------+
- * 0 5 6 29 30 31
- *
- * If AA = 0, the branch target address is the sum of LI and the address of
- * this instruction.
- * If AA = 1, the branch target address is the value of LI.
- * If LK = 1, the effective address of the instruction following the branch
- * instruction is placed into the link register.
- *
- */
-
-
-# define _emit_bx(pc, type, disp) \
- *((pc)++) = (char)((18 << 2) | (((disp) >> 24) & 3)); \
- *((pc)++) = (char)((disp) >> 16); \
- *((pc)++) = (char)((disp) >> 8); \
- *((pc)++) = (char)((disp) | (type))
-
-# define jit_emit_b(pc, disp) \
- jit_emit_bx((pc), 0, (disp))
-
-# define jit_emit_bl(pc, disp) \
- jit_emit_bx((pc), 1, (disp))
-
-# define jit_emit_ba(pc, disp) \
- jit_emit_bx((pc), 2, (disp))
-
-# define jit_emit_bla(pc, disp) \
- jit_emit_bx((pc), 3, (disp))
-
-/* Branch conditional to count register or link register.
- *
- * +--------------------------------------------------------------------+
- * | 19 | BO | BI | 0 | type | LK |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 20 21 30 31
- *
- * cr [type = 528]
- * lr [type = 16]
- */
-
-# define jit_emit_bcctrx(pc, bo, bi, type, lk) \
- *((pc)++) = 19 << 2 | (bo) >> 3; \
- *((pc)++) = (char)((bo) << 5 | (bi)); \
- *((pc)++) = (type) >> 7; \
- *((pc)++) = (char)((type) << 1| (lk))
-
-# define jit_emit_bcctr(pc, bo, bi) \
- jit_emit_bcctrx((pc), (bo), (bi), 528, 0)
-
-# define jit_emit_bcctrl(pc, bo, bi) \
- jit_emit_bcctrx((pc), (bo), (bi), 528, 1)
-
-# define jit_emit_bctrl(pc) \
- jit_emit_bcctrl((pc), 20, 0)
-
-# define jit_emit_blr(pc) \
- jit_emit_bcctrx((pc), 20, 0, 16, 0)
-
-# define jit_emit_bclr(pc, bo, bi) \
- jit_emit_bcctrx((pc), (bo), (bi), 16, 0)
-
-# define jit_emit_bclrl(pc, bo, bi) \
- jit_emit_bcctrx((pc), (bo), (bi), 16, 1)
-
-/* 3 register operation.
- *
- * +--------------------------------------------------------------------+
- * | Opcode | D | A | B |OE| type |Rc|
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 20 21 22 30 31
- *
- */
-
-# define jit_emit_3reg(pc, opcode, D, A, B, OE, type, Rc) \
- *((pc)++) = opcode << 2 | D >> 3; \
- *((pc)++) = (char)(D << 5 | A); \
- *((pc)++) = B << 3 | OE | type >> 7; \
- *((pc)++) = (char)(type << 1 | Rc);
-
-/* 3 register operation (without OE bit)
- *
- * +--------------------------------------------------------------------+
- * | Opcode | D | A | B | type |Rc|
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 20 21 22 30 31
- *
- */
-
-# define jit_emit_3reg_x(pc, opcode, D, A, B, type, Rc) \
- *(pc++) = opcode << 2 | D >> 3; \
- *(pc++) = (char)(D << 5 | A); \
- *(pc++) = B << 3 | type >> 7; \
- *(pc++) = (char)(type << 1 | Rc);
-
-/* Add [type = 266, OE = 0, Rc = 0]
- *
- * adds rA and rB and place the result in rD.
- */
-
-# define jit_emit_add_rrr(pc, D, A, B) \
- jit_emit_3reg((pc), 31, (D), (A), (B), 0, 266, 0);
-
-# define jit_emit_subf(pc, D, A, B) \
- jit_emit_3reg((pc), 31, (D), (B), (A), 0, 40, 0);
-
-# define jit_emit_sub_rrr jit_emit_subf
-
-# define jit_emit_neg_rr_i(pc, D, A) \
- jit_emit_3reg((pc), 31, (D), (A), 0, 0, 104, 0);
-
-# define jit_emit_mul_rrr(pc, D, A, B) \
- jit_emit_3reg((pc), 31, (D), (A), (B), 0, 235, 0);
-
-# define jit_emit_div_rrr_no_check(pc, D, A, B) \
- jit_emit_3reg((pc), 31, (D), (A), (B), 0, 491, 0);
-
-# define jit_emit_cmp_ri(pc, ra, simm) \
- _emit_cmpi((pc), 11, 0, (ra), (simm));
-
-
-# define jit_emit_and_rrr(pc, D, A, B) \
- jit_emit_3reg_x((pc), 31, (A), (D), (B), 28, 0)
-
-# define jit_emit_or_rrr(pc, D, A, B) \
- jit_emit_3reg_x((pc), 31, (A), (D), (B), 444, 0)
-
-# define jit_emit_xor_rrr(pc, D, A, B) \
- jit_emit_3reg_x((pc), 31, (A), (D), (B), 316, 0)
-
-# define jit_emit_srawi(pc, D, A, immediate) \
- jit_emit_3reg_x((pc), 31, (A), (D), (immediate), 824, 0)
-
-/* canonical names */
-
-# define jit_emit_and_rrr_i jit_emit_and_rrr
-# define jit_emit_add_rrr_i jit_emit_add_rrr
-# define jit_emit_cmod_rrr_i jit_emit_cmod_rrr
-# define jit_emit_div_rrr_i jit_emit_div_rrr
-# define jit_emit_mul_rrr_i jit_emit_mul_rrr
-# define jit_emit_or_rrr_i jit_emit_or_rrr
-# define jit_emit_sub_rrr_i jit_emit_sub_rrr
-# define jit_emit_xor_rrr_i jit_emit_xor_rrr
-
-/* shift ops */
-/* slw */
-# define jit_emit_shl_rrr_i(pc, D, A, B) \
- jit_emit_3reg_x((pc), 31, (A), (D), (B), 24, 0)
-
-/* sraw */
-# define jit_emit_shr_rrr_i(pc, D, A, B) \
- jit_emit_3reg_x((pc), 31, (A), (D), (B), 792, 0)
-
-/* srw */
-# define jit_emit_lsr_rrr_i(pc, D, A, B) \
- jit_emit_3reg_x((pc), 31, (A), (D), (B), 536, 0)
-
-# define jit_emit_shr_rri jit_emit_srawi
-# define jit_emit_shl_rri(pc, D, A, n) \
- jit_emit_rlwinm((pc), (D), (A), (n), 0, 31-(n))
-# define jit_emit_lsr_rri(pc, D, A, n) \
- jit_emit_rlwinm((pc), (D), (A), 32-(n), (n), 31)
-
-/* 2 register and immediate operation.
- *
- * +--------------------------------------------------------------------+
- * | Opcode | D-S | A | Immediate-Disp |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 31
- *
- * addi [opcode = 14] Adds rA to Immediate and place the result in rD.
- *
- * addis [opcode = 15] Adds rA to Immediate shifted 16 bits and place the
- * result in rD.
- *
- * andil [opcode = 28] Ands rD and the (unsigned)Immediate and place the
- * result in rA.
- *
- * lwz rD,d(rA) [op = 32]
- * lwzu rD,d(rA) [op = 33]
- * lbz rD,d(rA) [op = 34]
- * lbzu rD,d(rA) [op = 35]
- * stw rS,d(rA) [op = 36]
- * stwu rS,d(rA) [op = 37]
- * stb rS,d(rA) [op = 38]
- * stbu rS,d(rA) [op = 39]
- * lhz rD,d(rA) [op = 40]
- * lhzu rD,d(rA) [op = 41]
- * lha rD,d(rA) [op = 42]
- * lhau rD,d(rA) [op = 43]
- * sth rS,d(rA) [op = 44]
- * sthu rS,d(rA) [op = 45]
- * lmw rD,d(rA) [op = 46]
- * stmw rS,d(rA) [op = 47]
- * lfu frD,d(rA) [op = 48]
- * lfsu frD,d(rA) [op = 49]
- * lfd frD,d(rA) [op = 50]
- * lfdu frD,d(rA) [op = 51]
- * stfs frS,d(rA) [op = 52]
- * stfsu frS,d(rA) [op = 53]
- * stfd frS,d(rA) [op = 54]
- * stfdu frS,d(rA) [op = 55]
- */
-
-# define jit_emit_2reg(pc, opcode, D, A, immediate) \
- *((pc)++) = (opcode) << 2 | (D) >> 3; \
- *((pc)++) = (char)((D) << 5 | (A)); \
- *((pc)++) = ((immediate) >> 8); \
- *((pc)++) = (char)(immediate)
-
-# define jit_emit_add_rri_i(pc, D, A, immediate) \
- jit_emit_2reg((pc), 14, (D), (A), (immediate))
-
-# define jit_emit_addis(pc, D, A, immediate) \
- jit_emit_2reg((pc), 15, (D), (A), (immediate))
-
-# define jit_emit_ori(pc, D, S, immediate) \
- jit_emit_2reg((pc), 24, (S), (D), (immediate))
-
-# define jit_emit_oris(pc, D, S, immediate) \
- jit_emit_2reg((pc), 25, (S), (D), (immediate))
-
-# define jit_emit_xori(pc, D, S, immediate) \
- jit_emit_2reg((pc), 26, (S), (D), (immediate))
-
-# define jit_emit_xoris(pc, D, S, immediate) \
- jit_emit_2reg((pc), 27, (S), (D), (immediate))
-
-# define jit_emit_andil(pc, S, A, uimm) \
- jit_emit_2reg((pc), 28, (S), (A), (uimm))
-
-# define jit_emit_subfic(pc, D, A, immediate) \
- jit_emit_2reg((pc), 8, (D), (A), (immediate))
-
-# define jit_emit_subi(pc, D, A, im) jit_emit_add_rri_i((pc), (D), (A), -(im))
-
-# define jit_emit_lwz(pc, D, disp, A) \
- jit_emit_2reg((pc), 32, (D), (A), (disp))
-
-# define jit_emit_lwzu(pc, D, disp, A) \
- jit_emit_2reg((pc), 33, (D), (A), (disp))
-
-# define jit_emit_lwzx(pc, D, A, B) \
- jit_emit_3reg_x((pc), 31, (D), (A), (B), 23, 0)
-
-# define jit_emit_stw(pc, S, disp, A) \
- jit_emit_2reg((pc), 36, (S), (A), (disp))
-
-# define jit_emit_stwu(pc, S, disp, A) \
- jit_emit_2reg((pc), 37, (S), (A), (disp))
-
-# define jit_emit_stmw(pc, S, disp, A) \
- jit_emit_2reg((pc), 47, (S), (A), (disp))
-
-# define jit_emit_lmw(pc, D, disp, A) \
- jit_emit_2reg((pc), 46, (D), (A), (disp))
-
-# define jit_emit_lfd(pc, D, disp, A) \
- jit_emit_2reg((pc), 50, (D), (A), (disp))
-
-# define jit_emit_stfd(pc, S, disp, A) \
- jit_emit_2reg((pc), 54, (S), (A), (disp))
-
-/* A-format operation.
- *
- * +--------------------------------------------------------------------+
- * | Opcode | D | A | B | C | XOP |Rc|
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 20 21 25 26 30 31
- *
- */
-
-# define jit_emit_3a(pc, opcode, D, A, B, C, type, Rc) \
- *((pc)++) = (opcode)<< 2 | (D) >> 3; \
- *((pc)++) = (char)((D) << 5 | (A)); \
- *((pc)++) = (char)((B) << 3 | (C) >> 2); \
- *((pc)++) = (char)((C) << 6 | (type) << 1 | (Rc))
-
-/* rotate instructions */
-
-# define jit_emit_rlwimi(pc, A, S, SH, MB, ME) \
- jit_emit_3a((pc), 20, (S), (A), (SH), (MB), (ME), 0)
-
-# define jit_emit_rlwinm(pc, A, S, SH, MB, ME) \
- jit_emit_3a((pc), 21, (S), (A), (SH), (MB), (ME), 0)
-
-# define jit_emit_rot_rri(pc, A, S, im) \
- jit_emit_rlwinm((pc), (A), (S), (im), 0, 31)
-
-# define jit_emit_rlwnm(pc, A, S, B, MB, ME) \
- jit_emit_3a((pc), 23, (S), (A), (B), (M), (ME), 0)
-
-/* mfcr (CR -> D) */
-# define jit_emit_mfcr(pc, D) jit_emit_3reg_x((pc), 31, (D), 0, 0, 19, 0)
-
-# define jit_emit_fadd_rrr(pc, D, A, B) jit_emit_3a((pc), 63, (D), (A), (B), 0, 21, 0)
-# define jit_emit_fsub_rrr(pc, D, A, B) jit_emit_3a((pc), 63, (D), (A), (B), 0, 20, 0)
-# define jit_emit_fmul_rrr(pc, D, A, B) jit_emit_3a((pc), 63, (D), (A), 0, (B), 25, 0)
-# define jit_emit_fdiv_rrr_no_check(pc, D, A, B) jit_emit_3a((pc), 63, (D), (A), (B), 0, 18, 0)
-
-/* canonical names */
-# define jit_emit_add_rrr_n jit_emit_fadd_rrr
-# define jit_emit_div_rrr_n jit_emit_fdiv_rrr
-# define jit_emit_mul_rrr_n jit_emit_fmul_rrr
-# define jit_emit_sub_rrr_n jit_emit_fsub_rrr
-
-# define jit_emit_fsel(pc, D, A, B, C) jit_emit_3a((pc), 63, (D), (A), (B), (C), 23, 0)
-
-# define jit_emit_abs_rr_n(pc, D, A) jit_emit_3reg_x((pc), 63, (D), 0, (A), 264, 0)
-# define jit_emit_neg_rr_n(pc, D, A) jit_emit_3reg_x((pc), 63, (D), 0, (A), 40, 0)
-
-# define jit_emit_fmr(pc, D, A) jit_emit_3reg_x((pc), 63, (D), 0, (A), 72, 0)
-# define jit_emit_mov_rr_n(pc, D, A) jit_emit_fmr((pc), (D), (A))
-
-/* float cvt to int (round towards zero) */
-# define jit_emit_fctiwz(pc, D, A) jit_emit_3reg_x((pc), 63, (D), 0, (A), 15, 0)
-/* Store Floating-Point as Integer Word Indexed */
-# define jit_emit_stfiwx(pc, S, A, B) jit_emit_3reg_x((pc), 31, (S), (A), (B), 983, 0)
-
-/* not in core.ops, but probably should be: */
-# define jit_emit_fsqrt(pc, D, A) jit_emit_3reg((pc), 63, (D), 0, (A), 0, 18, 0)
-
-/* Load a CPU register from a Parrot register. */
-
-# define jit_emit_mov_rm_i(pc, reg, offs) \
- jit_emit_lwz((pc), (reg), (offs), r13)
-
-# define jit_emit_mov_rm_n(pc, reg, offs) \
- jit_emit_lfd((pc), (reg), (offs), r13)
-
-/* compare operation.
- *
- * +--------------------------------------------------------------------+
- * | Opcode | BF | |L | A | B | |
- * +--------------------------------------------------------------------+
- * 0 5 6 8 9 10 11 15 16 20 21 31
- *
- * opcode = 31 for integer, 63 for floating point
- * bf is the comparison result field to use (we just always use 0)
- */
-
-# define _emit_cmp(pc, t, bf, ra, rb) \
- *((pc)++) = (t) << 2 | ((int)(bf)) >> 1; \
- *((pc)++) = (char)((bf) << 7 | (ra)); \
- *((pc)++) = (char)((rb) << 3); \
- *((pc)++) = 0
-
-# define jit_emit_cmp_rr_i(pc, ra, rb) _emit_cmp((pc), 31, 0, (ra), (rb))
-# define jit_emit_cmp_rr_n(pc, ra, rb) _emit_cmp((pc), 63, 0, (ra), (rb))
-
-/* compare immediate operation.
- *
- * +--------------------------------------------------------------------+
- * | Opcode | BF | |L | A | SIMM |
- * +--------------------------------------------------------------------+
- * 0 5 6 8 9 10 11 15 16 31
- *
- */
-
-# define _emit_cmpi(pc, t, bf, ra, simm) \
- *((pc)++) = (t) << 2 | ((int)(bf)) >> 1; \
- *((pc)++) = (char)((bf) << 7 | (ra)); \
- *((pc)++) = (simm) >> 8; \
- *((pc)++) = (char)(simm)
-
-/* Branch conditional to immediate
- *
- * +--------------------------------------------------------------------+
- * | 16 | BO | BI | BD | AA | LK |
- * +--------------------------------------------------------------------+
- * 0 5 6 10 11 15 16 30 31
- *
- * Branch flags. A 10-bit quantity representing BO and BI. BO is 12
- * for true and 4 for false. BI indicates the comparison type (lt=0,
- * gt = 1, eq = 2). BD is the relative or absolute displacement,
- * divided by four, or AA, LK are set to zero, giving a 16-bit displacement.
- */
-
-# define _BLT 0
-# define _BGT 1
-# define _BEQ 2
-# define _BYES (12 << 5)
-# define _BNO (4 << 5)
-
-typedef enum {
- BLT = _BYES | _BLT,
- BGE = _BNO | _BLT,
- BGT = _BYES | _BGT,
- BLE = _BNO | _BGT,
- BEQ = _BYES | _BEQ,
- BNE = _BNO | _BEQ
-} branch_t;
-
-# define _emit_bc(pc, opt, bd, aa, lk) \
- *((pc)++) = 16 << 2 | ((int)(opt)) >> 8; \
- *((pc)++) = (char)((opt)&0xff); \
- *((pc)++) = (char)((bd) >> 8); \
- *((pc)++) = (char)((bd) | (aa) << 1 | (lk))
-
-static void
-jit_emit_bc(Parrot_jit_info_t *jit_info, branch_t cond, opcode_t disp) {
- opcode_t opcode = jit_info->op_i + disp;
- int offset;
- if (opcode <= jit_info->op_i) {
- offset = jit_info->arena.op_map[opcode].offset -
- (jit_info->native_ptr - jit_info->arena.start);
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- offset +=
- jit_info->optimizer->cur_section->branch_target->load_size;
- }
- else {
- offset = 0;
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_PPC_BRANCH;
- jit_info->arena.fixups->param.opcode = opcode;
-
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- }
- /* TODO check offset - 16 bits only allowed */
- _emit_bc(jit_info->native_ptr, cond, offset, 0, 0);
-}
-
-static void
-jit_emit_bx(Parrot_jit_info_t *jit_info, char type, opcode_t disp)
-{
- opcode_t opcode = jit_info->op_i + disp;
- int offset;
-
- if (opcode <= jit_info->op_i) {
- offset = jit_info->arena.op_map[opcode].offset -
- (jit_info->native_ptr - jit_info->arena.start);
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- offset +=
- jit_info->optimizer->cur_section->branch_target->load_size;
- }
- else {
- offset = 0;
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_PPC_UBRANCH;
- jit_info->arena.fixups->param.opcode = opcode;
-
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- }
- _emit_bx(jit_info->native_ptr, type, offset);
-}
-
-
-/* Store a CPU register back to a Parrot register. */
-
-# define jit_emit_mov_mr_i(pc, offs, reg) \
- jit_emit_stw((pc), (reg), (offs), r13)
-
-# define jit_emit_mov_mr_n(pc, offs, reg) \
- jit_emit_stfd((pc), (reg), (offs), r13)
-
-/*
- * Load a 32-bit immediate value.
- */
-
-# define jit_emit_mov_ri_i(pc, D, imm) \
- jit_emit_ori((pc), (D), r31, (long)(imm) & 0xffff); \
- if ((long)(imm) >> 16 != 0) { \
- jit_emit_oris((pc), (D), (D), (long)(imm) >> 16); }
-
-/* load a float constant (needs a gpr temp: ISR2) */
-
-# define jit_emit_mov_ri_n(pc, D, offs) \
- jit_emit_mov_ri_i((pc), ISR1, (offs)); \
- jit_emit_lfd((pc), (D), 0, ISR1);
-
-# define add_disp(pc, D, disp) \
- jit_emit_mov_ri_i((pc), ISR1, (disp)); \
- jit_emit_add_rrr((pc), (D), r15, ISR1)
-
-# define jit_emit_load_op_map(pc) \
- jit_emit_lwz((pc), ISR1, offsetof(Interp, code), r16); \
- jit_emit_lwz((pc), ISR1, offsetof(PackFile_ByteCode, jit_info), ISR1); \
- jit_emit_lwz((pc), r14, (offsetof(Parrot_jit_arena_t, op_map) + \
- offsetof(Parrot_jit_info_t, arena)), ISR1)
-
-# define jit_emit_load_code_start(pc) \
- jit_emit_lwz((pc), ISR1, offsetof(Interp, code), r16); \
- jit_emit_lwz((pc), r15, offsetof(PackFile_Segment, data), ISR1)
-
-# define jit_emit_branch_to_opcode(pc, D) \
- jit_emit_lwz((pc), r13, offsetof(Interp, ctx), r16); \
- jit_emit_lwz((pc), r13, offsetof(PMC, data), r13); \
- jit_emit_lwz((pc), r13, offsetof(Parrot_Context, bp), r13); \
- jit_emit_sub_rrr(jit_info->native_ptr, ISR1, (D), r15); \
- jit_emit_lwzx(jit_info->native_ptr, ISR1, ISR1, r14); \
- jit_emit_mtctr(jit_info->native_ptr, ISR1); \
- jit_emit_bctrl(jit_info->native_ptr)
-
-#ifdef PARROT_EXEC_OS_AIX /* support AIX calling convention using compiler intermediary _ptrgl */
-# define jit_emit_call_func(pc, addr) \
- jit_emit_mov_ri_i(jit_info->native_ptr, ISR1, (long)*((long*)(addr))); \
- jit_emit_mtctr(jit_info->native_ptr, ISR1); \
- jit_emit_bctrl(jit_info->native_ptr);
-#else
-# define jit_emit_call_func(pc, addr) \
- jit_emit_mov_ri_i(jit_info->native_ptr, ISR1, (long)(addr)); \
- jit_emit_mtctr(jit_info->native_ptr, ISR1); \
- jit_emit_bctrl(jit_info->native_ptr);
-#endif
-
-#if EXEC_CAPABLE
-# define load_nc(pc, D, disp) \
- jit_emit_oris((pc), (D), r31, (long)(disp) >> 16); \
- Parrot_exec_add_text_rellocation(jit_info->objfile, \
- (pc), RTYPE_DATA, "const_table", -2); \
- jit_emit_ori(jit_info->native_ptr, (D), (D), (long)(disp) & 0xffff); \
- Parrot_exec_add_text_rellocation(jit_info->objfile, \
- (pc), RTYPE_DATA1, "const_table", -2);
-#endif /* EXEC_CAPABLE */
-
-static char *
-div_rrr(Parrot_jit_info_t *jit_info, char D, char A, char B)
-{
- char *jmp_ptr, *sav_ptr;
- static const char div_by_zero[] = "Divide by zero";
- char *pc = jit_info->native_ptr;
-
- jit_emit_cmp_ri(pc, B, 0);
- /* remember PC */
- jmp_ptr = pc;
- /* emit jump past exception code, dummy offset */
- _emit_bc(pc, BNE, 0, 0, 0);
- jit_emit_mov_rr(pc, r3, r16); /* interp */
- jit_emit_mov_ri_i(pc, r4, 0); /* NULL */
- jit_emit_mov_ri_i(pc, r5, EXCEPTION_DIV_BY_ZERO); /* type */
- jit_emit_mov_ri_i(pc, r6, div_by_zero);
- jit_info->native_ptr = pc;
- jit_emit_call_func(pc, Parrot_ex_throw_from_c_args);
- pc = jit_info->native_ptr;
- /* fixup above jump */
- sav_ptr = pc;
- pc = jmp_ptr;
- _emit_bc(pc, BNE, ((long)(sav_ptr - jmp_ptr)), 0, 0);
- /* restore PC */
- pc = sav_ptr;
- jit_emit_div_rrr_no_check(pc, D, A, B);
- return pc;
-}
-
-static char *
-fdiv_rrr(Parrot_jit_info_t *jit_info, char D, char A, char B)
-{
- char *jmp_ptr, *sav_ptr;
- static const char div_by_zero[] = "Divide by zero";
- char *pc = jit_info->native_ptr;
- static const double zero = 0.0;
-
- jit_emit_mov_ri_i(pc, ISR1, &zero);
- jit_emit_lfd(pc, f1, 0, ISR1);
-
- jit_emit_cmp_rr_n(pc, B, f1); /* XXX be sure it's unmapped */
- /* remember PC */
- jmp_ptr = pc;
- /* emit jump past exception code, dummy offset */
- _emit_bc(pc, BNE, 0, 0, 0);
- jit_emit_mov_rr(pc, r3, r16); /* interp */
- jit_emit_mov_ri_i(pc, r4, 0); /* NULL */
- jit_emit_mov_ri_i(pc, r5, EXCEPTION_DIV_BY_ZERO); /* type */
- jit_emit_mov_ri_i(pc, r6, div_by_zero);
- jit_info->native_ptr = pc;
- jit_emit_call_func(pc, Parrot_ex_throw_from_c_args);
- pc = jit_info->native_ptr;
- /* fixup above jump */
- sav_ptr = pc;
- pc = jmp_ptr;
- _emit_bc(pc, BNE, ((long)(sav_ptr - jmp_ptr)), 0, 0);
- /* restore PC */
- pc = sav_ptr;
- jit_emit_fdiv_rrr_no_check(pc, D, A, B);
- return pc;
-}
-
-# define jit_emit_div_rrr(pc, D, A, B) (pc) = div_rrr(jit_info, (D), (A), (B))
-# define jit_emit_fdiv_rrr(pc, D, A, B) (pc) = fdiv_rrr(jit_info, (D), (A), (B))
-
-/* XXX except A = -2^31 and B = -1 */
-
-static char *
-cmod_rrr(Parrot_jit_info_t *jit_info, char D, char A, char B)
-{
- char *pc;
- pc = div_rrr(jit_info, D, A, B);
- jit_emit_mul_rrr(pc, D, D, B);
- jit_emit_sub_rrr(pc, D, A, D);
- return pc;
-}
-
-# define jit_emit_cmod_rrr(pc, D, A, B) (pc) = cmod_rrr(jit_info, (D), (A), (B))
-
-
-void Parrot_ppc_jit_restore_nonvolatile_registers(void);
-
-/*
- * r13 - r31 are preserved i.e. 19 GPRs
- * f14 - f31 are preserved
- * (these are all of the nonvolatile registers)
- */
-# define PPC_JIT_GP_REGISTER_SAVE_SPACE (4*19)
-# define PPC_JIT_FP_REGISTER_SAVE_SPACE (8*18)
-/*
- * 24 linkage area
- * 32 param area i.e.enough for 8 args
- * 12 round up so that sum is divisible by 16
- */
-# define PPC_JIT_FRAME_SIZE (PPC_JIT_GP_REGISTER_SAVE_SPACE + PPC_JIT_FP_REGISTER_SAVE_SPACE + 68)
-
-#if JIT_EMIT == 2
-
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- add_disp(jit_info->native_ptr, r3,
- ((long)jit_info->cur_op - (long)interp->code->base.data));
- jit_emit_mov_rr(jit_info->native_ptr, r4, r16); /* interp */
-
- /*
- Parrot_jit_newfixup(jit_info);
-
- jit_info->arena.fixups->type = JIT_PPC_CALL;
- jit_info->arena.fixups->param.fptr =
- (void (*)(void))interp->op_func_table[*(jit_info->cur_op)];
-
- _emit_bx(jit_info->native_ptr, 1, 0);
- */
-
- jit_emit_call_func(jit_info->native_ptr,
- interp->op_func_table[*(jit_info->cur_op)]);
-}
-
-void
-Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
-
- /* fix our reserved registers, in case we are branching to a new segment */
- jit_emit_load_op_map(jit_info->native_ptr);
- jit_emit_load_code_start(jit_info->native_ptr);
-
- /* branch to the opcode just returned from the normal_op call, in r3 */
- jit_emit_branch_to_opcode(jit_info->native_ptr, r3);
-}
-
-static void Parrot_end_jit(Parrot_jit_info_t *, PARROT_INTERP);
-
-# undef Parrot_jit_restart_op
-/* Parrot_jit_restart_op is based on the i386 version */
-void
-Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- char *jmp_ptr, *sav_ptr;
-
- Parrot_jit_normal_op(jit_info, interp);
- /* test return value; if zero (e.g after trace), return from JIT */
- jit_emit_cmp_ri(jit_info->native_ptr, r3, 0);
- /* remember PC */
- jmp_ptr = jit_info->native_ptr;
- /* emit jump past exit code, dummy offset */
- _emit_bc(jit_info->native_ptr, BNE, 0, 0, 0);
- Parrot_end_jit(jit_info, interp);
- /* fixup above jump */
- sav_ptr = jit_info->native_ptr;
- jit_info->native_ptr = jmp_ptr;
- _emit_bc(jit_info->native_ptr, BNE, ((long)(sav_ptr - jmp_ptr)), 0, 0);
- /* restore PC */
- jit_info->native_ptr = sav_ptr;
-
- /* fix our reserved registers, in case we are branching to a new segment */
- jit_emit_load_op_map(jit_info->native_ptr);
- jit_emit_load_code_start(jit_info->native_ptr);
-
- /* branch to the opcode just returned from the normal_op call, in r3 */
- jit_emit_branch_to_opcode(jit_info->native_ptr, r3);
-}
-
-#endif /* JIT_EMIT == 2 */
-
-# define NATIVECODE jit_info->native_ptr
-# define CUR_OPCODE jit_info->cur_op
-# define MAP(i) jit_info->optimizer->map_branch[jit_info->op_i + (i)]
-static void
-jit_get_params_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP)
-{
- PMC *sig_pmc = CONTEXT(interp)->constants[CUR_OPCODE[1]]->u.key;
- INTVAL *sig_bits = PMC_data_typed(sig_pmc, INTVAL *);
- INTVAL n = VTABLE_get_integer(interp, sig_pmc);
- INTVAL i;
-
- jit_info->n_args = n;
-
- for (i = 0; i < n; ++i) {
- switch (sig_bits[i] & PARROT_ARG_TYPE_MASK) {
- case PARROT_ARG_INTVAL:
- jit_emit_lwz(NATIVECODE, MAP(2+i), 4 + i*4, r5);
- break;
- case PARROT_ARG_FLOATVAL:
- jit_emit_lwz(NATIVECODE, ISR1, 4 + i*4, r5);
- jit_emit_lfd(jit_info->native_ptr, MAP(2+i), 0, ISR1);
- break;
- default:
- break;
- }
- }
-}
-
-# define CONST(i) interp->code->const_table->constants[jit_info->cur_op[(i)]]
-static void
-jit_set_returns_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int recursive)
-{
- PMC *sig_pmc;
- INTVAL *sig_bits, sig;
-
- sig_pmc = CONTEXT(interp)->constants[CUR_OPCODE[1]]->u.key;
- if (!VTABLE_elements(interp, sig_pmc))
- return;
- GETATTR_FixedIntegerArray_int_array(interp, sig_pmc, sig_bits);
- sig = sig_bits[0];
- if (!recursive) {
- /* ISR2 <- args[0] */
- jit_emit_lwz(jit_info->native_ptr, ISR2, 0, r5);
- }
- switch (sig & (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT)) {
- case PARROT_ARG_INTVAL:
- if (recursive) {
- jit_emit_mov_rr(NATIVECODE, r3, MAP(2));
- }
- else {
- jit_emit_stw(jit_info->native_ptr, MAP(2), 0, ISR2);
- }
- break;
- case PARROT_ARG_INTVAL|PARROT_ARG_CONSTANT:
- if (recursive) {
- jit_emit_mov_ri_i(NATIVECODE, r3, CUR_OPCODE[2]);
- }
- else {
- jit_emit_mov_ri_i(NATIVECODE, ISR1, CUR_OPCODE[2]);
- jit_emit_stw(jit_info->native_ptr, ISR1, 0, ISR2);
- }
- break;
- case PARROT_ARG_FLOATVAL:
- if (recursive) {
- /* floats are returned in f1 according to ABI */
- jit_emit_mov_rr_n(NATIVECODE, f1, MAP(2));
- }
- else {
- jit_emit_stfd(jit_info->native_ptr, MAP(2), 0, ISR2);
- }
- break;
- case PARROT_ARG_FLOATVAL|PARROT_ARG_CONSTANT:
- jit_emit_mov_ri_i(NATIVECODE, ISR1, &CONST(2)->u.number);
- if (recursive) {
- jit_emit_lfd(jit_info->native_ptr, f1, 0, ISR1);
- }
- else {
- jit_emit_lfd(jit_info->native_ptr, FSR1, 0, ISR1);
- jit_emit_stfd(jit_info->native_ptr, FSR1, 0, ISR2);
- }
- break;
- default:
- exit_fatal(1, "set_returns_jit - unknown type");
- break;
- }
-}
-
-static int jit_save_regs_call(Parrot_jit_info_t *, PARROT_INTERP, int skip);
-
-static void
-jit_set_args_pc(Parrot_jit_info_t *jit_info, PARROT_INTERP, int recursive)
-{
- PMC *sig_args, *sig_params, *sig_result;
- INTVAL *sig_bits, sig, i, n;
- PackFile_Constant ** constants;
- opcode_t *params, *result;
- char params_map;
- int skip, used_n;
- const jit_arch_regs *reg_info;
-
- if (!recursive) {
- /* create args array */
- exit_fatal(1, "set_args_jit - can't do that yet ");
- }
-
- constants = CONTEXT(interp)->constants;
- sig_args = constants[CUR_OPCODE[1]]->u.key;
- if (!VTABLE_elements(interp, sig_args))
- return;
- params = jit_info->optimizer->sections->begin;
- sig_params = constants[params[1]]->u.key;
- ASSERT_SIG_PMC(sig_params);
- GETATTR_FixedIntegerArray_int_array(interp, sig_args, sig_bits);
- n = VTABLE_elements(interp, sig_args);
- /*
- * preserve registers - need get_results, because we skip the
- * return value
- */
- result = CUR_OPCODE + 2 + n + 3; /* set_args, set_p_pc */
- PARROT_ASSERT(*result == PARROT_OP_get_results_pc);
- sig_result = constants[result[1]]->u.key;
- ASSERT_SIG_PMC(sig_result);
-
- if (!VTABLE_elements(interp, sig_result))
- skip = -1;
- else
- skip = MAP(2 + n + 3 + 2);
- used_n = jit_save_regs_call(jit_info, interp, skip);
- for (i = 0; i < n; ++i) {
- sig = sig_bits[i];
- /* move args to params regs */
- params_map = jit_info->optimizer->map_branch[2 + i];
- /* TODO check for overlaps/collision */
- switch (sig & (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT)) {
- case PARROT_ARG_INTVAL:
- jit_emit_mov_rr(NATIVECODE, params_map, MAP(2 + i));
- break;
- case PARROT_ARG_INTVAL|PARROT_ARG_CONSTANT:
- jit_emit_mov_ri_i(NATIVECODE, params_map, CUR_OPCODE[2 + i]);
- break;
- default:
- exit_fatal(1, "set_args_jit - unknown type");
- break;
- }
- }
-}
-
-/*
- * preserve registers around a functioncall
- *
- * b) all used register around a call (skip >= 0 := return result
- * TODO save N regs for b) too
- */
-static int
-jit_save_regs_call(Parrot_jit_info_t *jit_info, PARROT_INTERP, int skip)
-{
- int i, used_i, save_i;
- const jit_arch_regs *reg_info;
-
- /* create stack frame 24 link + 32 params -> 64 */
- jit_emit_mflr(jit_info->native_ptr, r0); /* store link reg */
- jit_emit_stw(jit_info->native_ptr, r0, 8, r1); /* stw r0,8(r1) */
- jit_emit_stwu(jit_info->native_ptr, r1, -64, r1);
- used_i = CONTEXT(interp)->n_regs_used[REGNO_INT];
- reg_info = &jit_info->arch_info->regs[jit_info->code_type];
- for (i = 0; i < used_i; ++i) {
- if (reg_info->map_I[i] == skip)
- continue;
- /* we use param area sp+24 := r3, sp+52 := r10 */
- jit_emit_stw(jit_info->native_ptr, reg_info->map_I[i], 24 + i*4, r1);
- }
- /* preserve link register */
- return 0; /* TODO N regs */
-}
-
-static void
-jit_restore_regs_call(Parrot_jit_info_t *jit_info, PARROT_INTERP,
- int skip)
-{
-
- int i, used_i, save_i;
- const jit_arch_regs *reg_info;
-
- used_i = CONTEXT(interp)->n_regs_used[REGNO_INT];
- reg_info = &jit_info->arch_info->regs[jit_info->code_type];
- /* note - reversed order of jit_save_regs */
- for (i = used_i - 1; i >= 0; --i) {
- if (reg_info->map_I[i] == skip)
- continue;
- /* we use param area sp+24 := r3, sp+52 := r10 */
- jit_emit_lwz(jit_info->native_ptr, reg_info->map_I[i], 24 + i*4, r1);
- }
- /* pop stack frame */
- jit_emit_add_rri_i(jit_info->native_ptr, r1, r1, 64);
- /* restore link reg */
- jit_emit_lwz(jit_info->native_ptr, r0, 8, r1);
- jit_emit_mtlr(jit_info->native_ptr, r0);
- /* TODO other types */
-}
-
-#if JIT_EMIT == 0
-
-/*
- * emit stack frame according to ABI
- * see also jit/ppc/core.jit for Parrot_end
- */
-static void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int i;
- jit_emit_mflr(jit_info->native_ptr, r0);
- jit_emit_stmw(jit_info->native_ptr, r13, -PPC_JIT_GP_REGISTER_SAVE_SPACE, r1);
-
- for (i = 1; i <= 18; ++i)
- {
- jit_emit_stfd(jit_info->native_ptr, (i + 13), (-PPC_JIT_GP_REGISTER_SAVE_SPACE - i*8), r1);
- }
- jit_emit_stw(jit_info->native_ptr, r0, 8, r1);
- jit_emit_stwu(jit_info->native_ptr, r1, -PPC_JIT_FRAME_SIZE, r1);
- jit_emit_xor_rrr(jit_info->native_ptr, r31, r31, r31);
- jit_emit_mov_rr(jit_info->native_ptr, r16, r3); /* interp */
- if (!jit_info->objfile) {
- jit_emit_load_op_map(jit_info->native_ptr);
- }
-# if EXEC_CAPABLE
- else {
- jit_emit_oris(jit_info->native_ptr, r14, r31, 0);
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_DATA, "opcode_map", -2);
- jit_emit_ori(jit_info->native_ptr, r14, r14, 0);
- Parrot_exec_add_text_rellocation(jit_info->objfile,
- jit_info->native_ptr, RTYPE_DATA1, "opcode_map", -2);
- }
-# endif
-
- jit_emit_load_code_start(jit_info->native_ptr);
-
- /* jit_emit restart code: branch to the program counter passed into
- the JIT invocation as the second parameter, which is r4 */
- jit_emit_branch_to_opcode(jit_info->native_ptr, r4);
-}
-
-static void
-Parrot_jit_begin_sub(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
-}
-
-static void
-Parrot_jit_begin_sub_regs(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- jit_emit_mflr(jit_info->native_ptr, r0); /* optional */
- jit_emit_stw(jit_info->native_ptr, r0, 8, r1); /* stw r0,8(r1) */
- /* preserve r31 */
- jit_emit_stw(jit_info->native_ptr, r31, -4, r1);
- /* 24 linkage area, 32 params , 1 word local, roundup => 32 */
- jit_emit_stwu(jit_info->native_ptr, r1, -64, r1);
- /* r31 = 0 - needed for load immediate */
- jit_emit_xor_rrr(jit_info->native_ptr, r31, r31, r31);
-
- if (jit_info->flags & JIT_CODE_RECURSIVE) {
- char * L1;
- int offs;
- jit_get_params_pc(jit_info, interp);
- /* remember fixup position - call sub */
- L1 = NATIVECODE;
- _emit_bx(NATIVECODE, 1, 0xbeef); /* bl */
- /* fetch args */
- jit_emit_lwz(jit_info->native_ptr, ISR2, 0, r5);
- /* store INTVAL result */
- jit_emit_stw(jit_info->native_ptr, r3, 0, ISR2);
- /* fetch pc -> return it */
- jit_emit_lwz(jit_info->native_ptr, r3, 4 + jit_info->n_args * 4, r5);
- /* return sequence */
- jit_emit_lwz(jit_info->native_ptr, r1, 0, r1);
- jit_emit_lwz(jit_info->native_ptr, r31, -4, r1);
- jit_emit_lwz(jit_info->native_ptr, r0, 8, r1); /* opt */
- jit_emit_mtlr(jit_info->native_ptr, r0); /* opt */
- jit_emit_blr(jit_info->native_ptr);
- /* re-emit call */
- offs = NATIVECODE - L1;
- _emit_bx(L1, 1, offs); /* bl */
- }
-}
-
-static void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_fixup_t *fixup;
- char *fixup_ptr;
- char *disp;
- long d, high, low;
-
- fixup = jit_info->arena.fixups;
-
- while (fixup){
- switch (fixup->type){
- case JIT_PPC_CALL:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = ((long)fixup->param.fptr - (long)fixup_ptr);
- *(fixup_ptr++) |= (char)(d >> 29) & 3;
- *(fixup_ptr++) = (char)(d >> 16);
- *(fixup_ptr++) = (char)(d >> 8);
- *(fixup_ptr++) |= (char)d & ~3;
- break;
-
- case JIT_PPC_UBRANCH:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = jit_info->arena.op_map[fixup->param.opcode].offset
- - fixup->native_offset + fixup->skip;
- *(fixup_ptr++) |= (char)(d >> 24) & 3;
- *(fixup_ptr++) = (char)(d >> 16);
- *(fixup_ptr++) = (char)(d >> 8);
- *(fixup_ptr++) |= (char)d & ~3;
- break;
-
- case JIT_PPC_BRANCH:
- /* TODO check offset - 16 bits only allowed */
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- d = jit_info->arena.op_map[fixup->param.opcode].offset
- - fixup->native_offset + fixup->skip;
- fixup_ptr += 2;
- *(fixup_ptr++) = (char)(d >> 8);
- *(fixup_ptr++) |= (char)d & ~3;
- break;
-
- default:
- exit_fatal(EXCEPTION_JIT_ERROR, "Unknown fixup type:%d\n",
- fixup->type);
- break;
- }
- fixup = fixup->next;
- }
-}
-
-
-/* move reg to mem (i.e. intreg) */
-static void
-jit_mov_mr_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info, int base,
- INTVAL offs, int reg)
-{
- jit_emit_mov_mr_i(jit_info->native_ptr, offs, reg);
- /*
- * if we save registers, the last instruction isn't the ins that
- * sets condition codes, so the speed hack in Parrot_ifunless_i_ic
- * doesn't work.
- */
- jit_info->prev_op = 0;
-}
-
-/* move mem (i.e. intreg) to reg */
-static void
-jit_mov_rm_offs(PARROT_INTERP, Parrot_jit_info_t *jit_info, int reg, int base,
- INTVAL offs)
-{
- jit_emit_mov_rm_i(jit_info->native_ptr, reg, offs);
-}
-
-/* move reg to mem (i.e. numreg) */
-static void
-jit_mov_mr_n_offs(PARROT_INTERP, Parrot_jit_info_t * jit_info, int base,
- INTVAL offs, int reg)
-{
- jit_emit_mov_mr_n(jit_info->native_ptr, offs, reg);
- jit_info->prev_op = 0;
-}
-
-/* move mem (i.e. numreg) to reg */
-static void
-jit_mov_rm_n_offs(PARROT_INTERP, Parrot_jit_info_t * jit_info, int reg,
- int base, INTVAL offs)
-{
- jit_emit_mov_rm_n(jit_info->native_ptr, reg, offs);
-}
-# define REQUIRES_CONSTANT_POOL 0
-# ifdef PARROT_EXEC_OS_AIX
-# define INT_REGISTERS_TO_MAP 14
-# else
-# define INT_REGISTERS_TO_MAP 14
-# endif
-# define FLOAT_REGISTERS_TO_MAP 18
-
-/*
- * Register usage
- * r0 special rA/0 not allocatable, not usable as ISR1
- * r1 SP
- * r2 TOC (AIX only) / allocated
- * r3 - r10 allocated
- * r11 ISR1
- * r12 ISR2
- * r13 Parrot register frame pointer
- * r14 op_map
- * r15 code_start
- * r16 interpreter
- * r17 - r30 allocated
- * r31 zero
- *
- * f0 FSR1
- * f1 - f12 allocated
- * f13 FSR2
- * f14 - f31 - unused, need preserving if allocated
- */
-
-
-static const char intval_map[INT_REGISTERS_TO_MAP] =
- { r17, r18, r19, r20, r21, r22, r23,
- r24, r25, r26, r27, r28, r29, r30
-# ifndef PARROT_EXEC_OS_AIX
- /* AIX calling convention reserves r2 */
- /* r2, */
-# endif
- };
-
-static const char intval_map_sub[] =
- { r4, r6, r7, r8, r9, r10 };
-/*
- * f0, f13 are used as scratch registers
- * f1 - f12 are (additional) volatile registers
- * f14 - f31 are not nonvolatile, and preserved in begin/end
- */
-static const char floatval_map[FLOAT_REGISTERS_TO_MAP] =
- {
- f14, f15, f16, f17, f18, f19, f20, f21,
- f22, f23, f24, f25, f26, f27, f28, f29, f30, f31
- };
-
-static const char floatval_map_sub[] =
-{ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12 };
-
-void ppc_flush_line(char *_sync);
-void ppc_sync(void);
-
-# ifndef __IBMC__
-
-void
-ppc_flush_line(char *_sync)
-{
- __asm__ __volatile__(
- "dcbf 0,%0"
- :
- : "r" ((long)_sync));
-}
-
-void
-ppc_sync(void)
-{
- __asm__ __volatile__("sync");
-}
-
-# endif
-
-static void
-ppc_sync_cache(void *_start, void *_end)
-{
- char *start = (char*)(((int)_start) &~(CACHELINESIZE - 1));
- char *end = (char *)((((int)_end)+CACHELINESIZE-1) &~(CACHELINESIZE - 1));
- char *_sync;
-
- for (_sync = start; _sync < end; _sync += CACHELINESIZE) {
- ppc_flush_line(_sync);
- }
- ppc_sync();
-}
-
-static void
-ppc_flush_cache(Parrot_jit_info_t * jit_info, PARROT_INTERP)
-{
- ppc_sync_cache(jit_info->arena.start, jit_info->native_ptr);
-}
-
-
-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,
- ppc_flush_cache,
- {
- {
- Parrot_jit_begin, /* emit code prologue */
- INT_REGISTERS_TO_MAP, /* mapped ints */
- INT_REGISTERS_TO_MAP, /* all are preserved */
- intval_map,
- FLOAT_REGISTERS_TO_MAP, /* mapped float regs */
- FLOAT_REGISTERS_TO_MAP, /* all preserved */
- floatval_map
- },
- {
- Parrot_jit_begin_sub, /* emit code prologue */
- 6, /* 6 mapped ints */
- 6, /* all volatile */
- intval_map_sub,
- 12, /* mapped float regs */
- 12, /* all volatile */
- floatval_map_sub
- },
- {
- Parrot_jit_begin_sub_regs, /* emit code prologue */
- 6, /* 6 mapped ints */
- 6, /* all volatile */
- intval_map_sub,
- 12, /* TODO 12 mapped float regs */
- 12, /* all volatile */
- floatval_map_sub
- }
- }
-};
-
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info *
-Parrot_jit_init(PARROT_INTERP)
-{
- return &arch_info;
-}
-
-#endif /* JIT_EMIT == 0 */
-#endif /* PARROT_PPC_JIT_EMIT_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/ppc/ppc-linux.s
==============================================================================
--- trunk/src/jit/ppc/ppc-linux.s Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,25 +0,0 @@
-.text
- .align 12
- .globl Parrot_ppc_jit_restore_nonvolatile_registers
-Parrot_ppc_jit_restore_nonvolatile_registers:
-
- lfd 14,-84(1)
- lfd 15,-92(1)
- lfd 16,-100(1)
- lfd 17,-108(1)
- lfd 18,-116(1)
- lfd 19,-124(1)
- lfd 20,-132(1)
- lfd 21,-140(1)
- lfd 22,-148(1)
- lfd 23,-156(1)
- lfd 24,-164(1)
- lfd 25,-172(1)
- lfd 26,-180(1)
- lfd 27,-188(1)
- lfd 28,-196(1)
- lfd 29,-204(1)
- lfd 30,-212(1)
- lfd 31,-220(1)
-
- blr
Deleted: trunk/src/jit/skeleton/jit_defs.c
==============================================================================
--- trunk/src/jit/skeleton/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,13 +0,0 @@
-/* Stub file for RT#38929 fixes */
-/*
-Copyright (C) 2008, Parrot Foundation.
-$Id$
-*/
-/* HEADERIZER HFILE: none */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/skeleton/jit_emit.h
==============================================================================
--- trunk/src/jit/skeleton/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2005-2007, Parrot Foundation.
- */
-
-/*
- * jit_emit.h
- *
- * skeleton example - a stripped down jit/ppc/jit_emit.h
- *
- * $Id$
- */
-
-#ifndef PARROT_JIT_SKELETON_JIT_EMIT_H_GUARD
-#define PARROT_JIT_SKELETON_JIT_EMIT_H_GUARD
-
-# include <unistd.h>
-# include <limits.h>
-
-/*
- * define all the available cpu registers
- * reserve some for special purposes
- */
-typedef enum {
- r0, /* r0 (reg #0) can't be mapped - use it as temp if possible */
- r1,
- r2,
- ARG1 = r3, /* return value, first arg of function call */
- r4,
- r5,
- r6,
- r7,
- r8,
- r9,
- r10,
- r11,
- ISR1 = r11, /* temp aka intermediate scratch reg 1 */
- r12,
- ISR2 = r12, /* temp reg 2 */
- BP = r13, /* register base pointer (persistent) */
- OP_MAP = r14, /* cached op_map (persistent) */
- CODE_START = r15, /* cached code begint (persistent) */
- INTERP = r16, /* cached interpreter register (persistent) */
- r17,
- ...
- r31
-} arch_iregister_t;
-
-/*
- * If your arch doesn't have that much register available, you
- * don't cache OP_MAP, CODE_START, and INTERP in a cpu register.
- * Only BP (the register base pointer is needed and 1 or 2 temp regs
- */
-
-
-/*
- * define, which register is the register base pointer
- */
-
-# define Parrot_jit_emit_get_base_reg_no(pc) BP
-
-/*
- * define floating point register too, if there are some
- */
-typedef enum {
- f0, /* f0 (reg #0) can't be mapped - use it as temp if possible */
- FSR1 = f0,
- f1,
- ...
- f13,
- FSR2 = f13,
- ...
- f31
-} arch_fregister_t;
-
-/*
- * now define macros for all possible (and implemented) operations
- *
- * Parrot defines JIT_EMIT to 1 or 2, when this file is included in
- * exec_cpu.c or jit_cpu.c
- */
-
-#if JIT_EMIT
-
-/*
- * the arch might have different branch types:
- * long offset, short offset, absolute, ...
- */
-enum { JIT_ARCH_CALL, JIT_ARCH_BRANCH, JIT_ARCH_UBRANCH };
-
-/*
- * emit code for a register move, pc is the location to emit the
- * asm code
- */
-# define jit_emit_mov_rr(pc, dst, src) ...
-
-# define jit_emit_add_rrr(pc, D, A, B) ...
-
-/*
- * load register from memory offset, relative to the register base pointer
- * this is used to load hardware cpu registers from parrot registers
- */
-# define jit_emit_mov_rm_i(pc, reg, offs) \
- jit_emit_lwz((pc), (reg), (offs), BP) /* e.g. PPC */
-
-/* load floating point register from Parrot register */
-# define jit_emit_mov_rm_n(pc, reg, offs) \
- jit_emit_lfd((pc), (reg), (offs), BP) /* e.g. PPC */
-
-/* Store a CPU register back to a Parrot register. */
-
-# define jit_emit_mov_mr_i(pc, offs, reg) \
- jit_emit_stw((pc), (reg), (offs), BP)
-
-# define jit_emit_mov_mr_n(pc, offs, reg) \
- jit_emit_stfd((pc), (reg), (offs), BP)
-
-/*
- * emit a branch and remember the branch target for code fixup,
- * which id done, when all code is emitted
- */
-static void
-jit_emit_bc(Parrot_jit_info_t *jit_info, branch_t cond, opcode_t disp)
-{
- /* see other architectures */
-}
-
-
-/*
- * Load a 32-bit immediate value.
- */
-
-# define jit_emit_mov_ri_i(pc, D, imm) ...
-
-/*
- * define some helper macros for code generation
- * Parrot_jit_normal_op() is: create code that does the equivalent of:
- *
- * PC = ((INTERP->op_func_table)[*PC])(PC,INTERP)
- *
- * First we need to calculate the PC at runtime by adding disp to
- * to the cached CODE_START register 'add_disp' in jit/ppc
- */
-
-# define add_disp(pc, D, disp) \
- jit_emit_mov_ri_i((pc), ISR1, (disp)); \
- jit_emit_add_rrr((pc), (D), CODE_START, ISR1)
-
-/*
- * emit code that gets interp->code->jit_info->arena->op_map
- * and sets the OP_MAP register
- */
-# define jit_emit_load_op_map(pc) ...
-
-/*
- * emit code that gets interp->code->base.data
- * and sets the CODE_START register
- */
-# define jit_emit_load_code_start(pc) ...
-
-/*
- * emit code that branches to the next code piece
- */
-# define jit_emit_branch_to_opcode(pc, D) ...
-
-/*
- * emit code that calls a Parrot opcode function
- */
-# define jit_emit_call_func(pc, addr) ...
-
-#endif /* JIT_EMIT */
-
-#if JIT_EMIT == 2
-
-/*
- * emit code that calls a core.ops function from src/core_ops.c,
- * the generated code is the translation of this:
- *
- * PC = ((INTERP->op_func_table)[*PC])(PC,INTERP)
- */
-void
-Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
-}
-
-/*
- * emit code for a branching parrot opcode. All cached registers
- * need recalculation, as a branch can go into different code segments
- * with different code start and different jit_info
- */
-void
-Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
-
- /* fix our reserved registers,
- * in case we are branching to a new segment
- */
- jit_emit_load_op_map(jit_info->native_ptr);
- jit_emit_load_code_start(jit_info->native_ptr);
-
- /* branch to the opcode just returned from the normal_op call ARG1 */
- jit_emit_branch_to_opcode(jit_info->native_ptr, ARG1);
-}
-
-/*
- * release stack frame end exit see core.jit
- */
-static void Parrot_end_jit(Parrot_jit_info_t *, Interp *);
-
-# undef Parrot_jit_restart_op
-/*
- * emit code that might leave the JIT runcore
- * see ppc or i386
- */
-void
-Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
-}
-
-#endif /* JIT_EMIT == 2 */
-
-#if JIT_EMIT == 0
-
-/*
- * emit stack frame according to ABI
- * preserve mapped registers according to ABI
- * load INTERP, OP_MAP, CODE_START, BP registers
- * then run the code at pc
- *
- * the function is called as
- * runops(interp, pc)
- *
- * at runtime
- */
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- ...
-}
-/*
- * fix up all emitted branches
- * see ppc or i386
- */
-static void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
-}
-
-/*
- * define interface functions for register -> parrot register moves
- * and v.v.
- *
- * see ppc or x86
- */
-
-static void
-jit_mov_mr_offs(...) {}
-static void
-jit_mov_rm_offs(...) {}
-
-static void
-jit_mov_mr_n_offs(...) {}
-static void
-jit_mov_rm_n_offs(...) {}
-
-/*
- * define how many int and float registers can be used by the
- * jit core
- */
-
-# define INT_REGISTERS_TO_MAP 14
-# define FLOAT_REGISTERS_TO_MAP 2
-
-/*
- * enumerate these mapped registers
- * please note that you have to preserve registers in
- * Parrot_jit_begin according to the ABI of the architecture
- */
-
-static const char intval_map[INT_REGISTERS_TO_MAP] =
-
- { r17, r18, r19, r20, r21, r22, r23,
- r24, r25, r26, r27, r28, r29, r30
- };
-
-static const char floatval_map[FLOAT_REGISTERS_TO_MAP] =
- {
-
- f4, f5
- };
-
-/*
- * you might need a function that flushes hardware caches after
- * JIT compilation is done
- */
-static void
-ppc_flush_cache(Parrot_jit_info_t * jit_info, Interp *i)
-{
- ...
-}
-
-/*
- * define arch specific details in jit_arch_info
- */
-
-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,
- ppc_flush_cache,
- {
- /* JIT_CODE_FILE */
- {
- Parrot_jit_begin, /* emit code prologue */
- INT_REGISTERS_TO_MAP, /* mapped ints */
- INT_REGISTERS_TO_MAP, /* all are preserved */
- intval_map,
- FLOAT_REGISTERS_TO_MAP, /* mapped float regs */
- FLOAT_REGISTERS_TO_MAP, /* all preserved */
- floatval_map
- },
- /* JIT_CODE_SUB */
- {
- Parrot_jit_begin_sub, /* emit code prologue */
- 7, /* 7 mapped ints */
- 7, /* all volatile */
- intval_map_sub,
- 12, /* mapped float regs */
- 12, /* all volatile */
- floatval_map_sub
- },
- /* JIT_CODE_SUB_REGS_ONLY */
- {
- Parrot_jit_begin_sub_regs, /* emit code prologue */
- 7, /* 7 mapped ints */
- 7, /* all volatile */
- intval_map_sub,
- 12, /* 12 mapped float regs */
- 12, /* all volatile */
- floatval_map_sub
- }
- }
-};
-
-/*
- * and finally you need an interface function to return above structure
- */
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-const jit_arch_info *
-Parrot_jit_init(PARROT_INTERP)
-{
- return &arch_info;
-}
-
-
-#endif /* JIT_EMIT == 0 */
-#endif /* PARROT_JIT_SKELETON_JIT_EMIT_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/sun4/core.jit
==============================================================================
--- trunk/src/jit/sun4/core.jit Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,956 +0,0 @@
-;
-; sun4/core.jit
-;
-; $Id$
-;
-
-Parrot_end {
- emitm_ret(NATIVECODE);
- emitm_restore_i(NATIVECODE, emitm_g(0), emitm_g(0), emitm_g(0));
-}
-
-Parrot_noop {
- emitm_nop(NATIVECODE);
-}
-
-TEMPLATE Parrot_set_x_x {
- if(MAP[1] && MAP[2]){
- jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], MAP[2]);
- }
- else if(MAP[1]){
- jit_emit_load<_N>(jit_info, interp, 2, MAP[1]);
- }
- else if(MAP[2]){
- jit_emit_store<_N>(jit_info, interp, 1, MAP[2]);
- }
- else {
- jit_emit_load<_N>(jit_info, interp, 2, ISR1);
- jit_emit_store<_N>(jit_info, interp, 1, ISR1);
- }
-}
-
-Parrot_set_i_i {
- Parrot_set_x_x s/<_N>/_i/
-}
-
-Parrot_set_p_p {
- Parrot_set_x_x s/<_N>/_i/
-}
-
-Parrot_set_s_s {
- Parrot_set_x_x s/<_N>/_i/
-}
-
-Parrot_set_n_n {
- Parrot_set_x_x s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_set_i_ic {
- Parrot_set_x_x s/<_N>/_i/
-}
-
-Parrot_set_n_ic {
- if(MAP[1]){
- jit_emit_load_n(jit_info, interp, 2, MAP[1]);
- emitm_fitod(NATIVECODE, MAP[1], MAP[1]);
- }
- else {
- jit_emit_load_n(jit_info, interp, 2, FSR1);
- emitm_fitod(NATIVECODE, FSR1, FSR1);
- jit_emit_store_n(jit_info, interp, 1, FSR1);
- }
-}
-
-Parrot_set_n_nc {
- Parrot_set_x_x s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_set_n_i {
- /* There's no way to move a value directly between integer and floating
- * point registers so the mapped integer register must be written to memory
- */
- if(MAP[2]){
- jit_emit_store_i(jit_info, interp, 2, MAP[2]);
- }
-
- jit_emit_load_n(jit_info, interp, 2, FSR1);
-
- /* If result register is mapped convert directly into the register */
- if(MAP[1]){
- emitm_fitod(NATIVECODE, FSR1, MAP[1]);
- }
- else {
- emitm_fitod(NATIVECODE, FSR1, FSR2);
- jit_emit_store_n(jit_info, interp, 1, FSR2);
- }
-}
-
-Parrot_set_i_n {
- if(MAP[2]){
- emitm_fdtoi(NATIVECODE, MAP[2], FSR2);
- }
- else {
- jit_emit_load_n(jit_info, interp, 2, FSR1);
- emitm_fdtoi(NATIVECODE, FSR1, FSR2);
- }
-
- jit_emit_store_n(jit_info, interp, 1, FSR2);
-
- /* No float reg to integer reg move instruction available */
- if(MAP[1]){
- jit_emit_load_i(jit_info, interp, 1, MAP[1]);
- }
-}
-
-Parrot_set_i_nc {
- if(MAP[2]){
- emitm_fdtoi(NATIVECODE, MAP[2], FSR1);
- }
- else {
- jit_emit_load_n(jit_info, interp, 2, FSR2);
- emitm_fdtoi(NATIVECODE, FSR2, FSR1);
- }
-
- jit_emit_store_n(jit_info, interp, 1, FSR1);
-
- if(MAP[1]){
- jit_emit_load_i(jit_info, interp, 1, MAP[1]);
- }
-}
-
-TEMPLATE Parrot_binop_x_x {
- int arg1, arg2;
-
- if (MAP[1]) {
- arg1 = MAP[1];
- }
- else {
- arg1 = ISR1;
- jit_emit_load<_N>(jit_info, interp, 1, ISR1);
- }
-
- if (MAP[2]) {
- arg2 = MAP[2];
- }
- else {
- arg2 = ISR2;
- jit_emit_load<_N>(jit_info, interp, 2, arg2);
- }
-
- emitm_<op>(NATIVECODE, arg1, arg2, arg1);
-
- if(!MAP[1]){
- jit_emit_store<_N>(jit_info, interp, 1, arg1);
- }
-}
-
-Parrot_add_i_i {
- Parrot_binop_x_x s/<op>/add_r/ s/<_N>/_i/
-}
-
-Parrot_sub_i_i {
- Parrot_binop_x_x s/<op>/sub_r/ s/<_N>/_i/
-}
-
-Parrot_bor_i_i {
- Parrot_binop_x_x s/<op>/or_r/ s/<_N>/_i/
-}
-
-Parrot_bxor_i_i {
- Parrot_binop_x_x s/<op>/xor_r/ s/<_N>/_i/
-}
-
-Parrot_band_i_i {
- Parrot_binop_x_x s/<op>/and_r/ s/<_N>/_i/
-}
-
-Parrot_add_n_n {
- Parrot_binop_x_x s/<op>/faddd/ s/<_N>/_n/
-}
-
-Parrot_sub_n_n {
- Parrot_binop_x_x s/<op>/fsubd/ s/<_N>/_n/
-}
-
-Parrot_mul_n_n {
- Parrot_binop_x_x s/<op>/fmuld/ s/<_N>/_n/
-}
-
-Parrot_div_n_n {
- Parrot_binop_x_x s/<op>/fdivd/ s/<_N>/_n/
-}
-
-TEMPLATE Parrot_incdec_i {
- int arg1;
-
- if(MAP[1]){
- arg1 = MAP[1];
- }
- else {
- arg1 = ISR1;
- jit_emit_load_i(jit_info, interp, 1, arg1);
- }
-
- emitm_<op>_i(NATIVECODE, arg1, 1, arg1);
-
- if(!MAP[1]){
- jit_emit_store_i(jit_info, interp, 1, arg1);
- }
-}
-
-Parrot_inc_i {
- Parrot_incdec_i s/<op>/add/
-}
-
-Parrot_dec_i {
- Parrot_incdec_i s/<op>/sub/
-}
-
-TEMPLATE Parrot_binop_i_xc {
- int arg1;
-
- if(MAP[1]){
- arg1 = MAP[1];
- }
- else {
- arg1 = ISR1;
- jit_emit_load_i(jit_info, interp, 1, arg1);
- }
-
- if(emitm_simm13_const(*INT_CONST[2])){
- emitm_<op>_i(NATIVECODE, arg1, *INT_CONST[2], arg1);
- }
- else {
- jit_emit_load_i(jit_info, interp, 2, ISR1);
- emitm_<op>_r(NATIVECODE, arg1, ISR1, arg1);
- }
-
- if(!MAP[1]){
- jit_emit_store_i(jit_info, interp, 1, arg1);
- }
-}
-
-Parrot_add_i_ic {
- Parrot_binop_i_xc s/<op>/add/
-}
-
-Parrot_sub_i_ic {
- Parrot_binop_i_xc s/<op>/sub/
-}
-
-Parrot_bor_i_ic {
- Parrot_binop_i_xc s/<op>/or/
-}
-
-Parrot_band_i_ic {
- Parrot_binop_i_xc s/<op>/and/
-}
-
-Parrot_bxor_i_ic {
- Parrot_binop_i_xc s/<op>/xor/
-}
-
-Parrot_add_n_nc {
- Parrot_binop_x_x s/<op>/faddd/ s/ISR/FSR/ s/<_N>/_n/
-}
-
-Parrot_sub_n_nc {
- Parrot_binop_x_x s/<op>/fsubd/ s/ISR/FSR/ s/<_N>/_n/
-}
-
-Parrot_mul_n_nc {
- Parrot_binop_x_x s/<op>/fmuld/ s/ISR/FSR/ s/<_N>/_n/
-}
-
-Parrot_div_n_nc {
- Parrot_binop_x_x s/<op>/fdivd/ s/ISR/FSR/ s/<_N>/_n/
-}
-
-TEMPLATE Parrot_binop_x_x_x {
- int arg2, arg3;
-
- /* Generate load if needed */
- if(MAP[2]){
- arg2 = MAP[2];
- }
- else {
- arg2 = ISR1;
- jit_emit_load<_N>(jit_info, interp, 2, arg2);
- }
-
- /* Generate load if needed */
- if (MAP[3]) {
- arg3 = MAP[3];
- }
- else {
- arg3 = ISR2;
- jit_emit_load<_N>(jit_info, interp, 3, arg3);
- }
-
- /* Destination is a register */
- if (MAP[1]) {
- emitm_<op>(NATIVECODE, arg2, arg3, MAP[1]);
- }
- /* Destination is memory */
- else {
- emitm_<op>(NATIVECODE, arg2, arg3, ISR1);
- jit_emit_store<_N>(jit_info, interp, 1, ISR1);
- }
-}
-
-Parrot_add_i_ic_ic {
- Parrot_binop_x_x_x s/<op>/add_r/ s/<_N>/_i/
-}
-
-Parrot_sub_i_ic_ic {
- Parrot_binop_x_x_x s/<op>/sub_r/ s/<_N>/_i/
-}
-
-Parrot_band_i_ic_ic {
- Parrot_binop_x_x_x s/<op>/and_r/ s/<_N>/_i/
-}
-
-Parrot_bor_i_ic_ic {
- Parrot_binop_x_x_x s/<op>/or_r/ s/<_N>/_i/
-}
-
-Parrot_bxor_i_ic_ic {
- Parrot_binop_x_x_x s/<op>/xor_r/ s/<_N>/_i/
-}
-
-Parrot_shl_i_ic_ic {
- Parrot_binop_x_x_x s/<op>/sll_r/ s/<_N>/_i/
-}
-
-Parrot_shr_i_ic_ic {
- Parrot_binop_x_x_x s/<op>/sra_r/ s/<_N>/_i/
-}
-
-Parrot_lsr_i_ic_ic {
- Parrot_binop_x_x_x s/<op>/srl_r/ s/<_N>/_i/
-}
-
-Parrot_add_n_nc_nc {
- Parrot_binop_x_x_x s/<op>/faddd/ s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_sub_n_nc_nc {
- Parrot_binop_x_x_x s/<op>/fsubd/ s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_mul_n_nc_nc {
- Parrot_binop_x_x_x s/<op>/fmuld/ s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_div_n_nc_nc {
- Parrot_binop_x_x_x s/<op>/fdivd/ s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_add_i_i_ic {
- Parrot_binop_x_x_x s/<op>/add_r/ s/<_N>/_i/
-}
-
-Parrot_sub_i_i_ic {
- Parrot_binop_x_x_x s/<op>/sub_r/ s/<_N>/_i/
-}
-
-Parrot_bor_i_i_ic {
- Parrot_binop_x_x_x s/<op>/or_r/ s/<_N>/_i/
-}
-
-Parrot_bxor_i_i_ic {
- Parrot_binop_x_x_x s/<op>/xor_r/ s/<_N>/_i/
-}
-
-Parrot_band_i_i_ic {
- Parrot_binop_x_x_x s/<op>/and_r/ s/<_N>/_i/
-}
-
-Parrot_add_n_n_nc {
- Parrot_binop_x_x_x s/<op>/faddd/ s/<_N>/_n/
-}
-
-Parrot_sub_n_n_nc {
- Parrot_binop_x_x_x s/<op>/fsubd/ s/<_N>/_n/
-}
-
-Parrot_mul_n_n_nc {
- Parrot_binop_x_x_x s/<op>/fmuld/ s/<_N>/_n/
-}
-
-Parrot_div_n_n_nc {
- Parrot_binop_x_x_x s/<op>/fdivd/ s/<_N>/_n/
-}
-
-Parrot_add_i_ic_i {
- Parrot_binop_x_x_x s/<op>/add_r/ s/<_N>/_i/
-}
-
-Parrot_sub_i_ic_i {
- Parrot_binop_x_x_x s/<op>/sub_r/ s/<_N>/_i/
-}
-
-Parrot_bor_i_ic_i {
- Parrot_binop_x_x_x s/<op>/or_r/ s/<_N>/_i/
-}
-
-Parrot_bxor_i_ic_i {
- Parrot_binop_x_x_x s/<op>/xor_r/ s/<_N>/_i/
-}
-
-Parrot_band_i_ic_i {
- Parrot_binop_x_x_x s/<op>/and_r/ s/<_N>/_i/
-}
-
-Parrot_shl_i_ic_i {
- Parrot_binop_x_x_x s/<op>/sll_r/ s/<_N>/_i/
-}
-
-Parrot_shr_i_ic_i {
- Parrot_binop_x_x_x s/<op>/sra_r/ s/<_N>/_i/
-}
-
-Parrot_lsr_i_ic_i {
- Parrot_binop_x_x_x s/<op>/srl_r/ s/<_N>/_i/
-}
-
-Parrot_add_n_nc_n {
- Parrot_binop_x_x_x s/<op>/faddd/ s/<_N>/_n/
-}
-
-Parrot_sub_n_nc_n {
- Parrot_binop_x_x_x s/<op>/fsubd/ s/<_N>/_n/
-}
-
-Parrot_mul_n_nc_n {
- Parrot_binop_x_x_x s/<op>/fmuld/ s/<_N>/_n/
-}
-
-Parrot_div_n_nc_n {
- Parrot_binop_x_x_x s/<op>/fdivd/ s/<_N>/_n/
-}
-
-Parrot_add_i_i_i {
- Parrot_binop_x_x_x s/<op>/add_r/ s/<_N>/_i/
-}
-
-Parrot_sub_i_i_i {
- Parrot_binop_x_x_x s/<op>/sub_r/ s/<_N>/_i/
-}
-
-Parrot_bor_i_i_i {
- Parrot_binop_x_x_x s/<op>/or_r/ s/<_N>/_i/
-}
-
-Parrot_bxor_i_i_i {
- Parrot_binop_x_x_x s/<op>/xor_r/ s/<_N>/_i/
-}
-
-Parrot_band_i_i_i {
- Parrot_binop_x_x_x s/<op>/and_r/ s/<_N>/_i/
-}
-
-Parrot_shl_i_i_i {
- Parrot_binop_x_x_x s/<op>/sll_r/ s/<_N>/_i/
-}
-
-Parrot_shr_i_i_i {
- Parrot_binop_x_x_x s/<op>/sra_r/ s/<_N>/_i/
-}
-
-Parrot_lsr_i_i_i {
- Parrot_binop_x_x_x s/<op>/srl_r/ s/<_N>/_i/
-}
-
-Parrot_sub_n_n_n {
- Parrot_binop_x_x_x s/<op>/fsubd/ s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_add_n_n_n {
- Parrot_binop_x_x_x s/<op>/faddd/ s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_mul_n_n_n {
- Parrot_binop_x_x_x s/<op>/fmuld/ s/<_N>/_n/ s/ISR/FSR/
-}
-
-Parrot_div_n_n_n {
- Parrot_binop_x_x_x s/<op>/fdivd/ s/<_N>/_n/ s/ISR/FSR/
-}
-
-;
-;Parrot_neg_n {
-; if(MAP[1]){
-; emitm_fnegs(NATIVECODE, MAP[1], MAP[1]);
-; }
-; else {
-; jit_emit_load_n(jit_info, interp, 1, FSR1);
-; emitm_fnegs(NATIVECODE, FSR1, FSR1);
-; jit_emit_store_n(jit_info, interp, 1, FSR1);
-; }
-;}
-
-TEMPLATE Parrot_unop_x_x {
- if(MAP[1] && MAP[2]){
- emitm_<op>(NATIVECODE, MAP[2], MAP[1]);
- }
- else if(MAP[1]){
- jit_emit_load<_N>(jit_info, interp, 2, MAP[1]);
- emitm_<op>(NATIVECODE, MAP[1], MAP[1]);
- }
- else {
- jit_emit_load<_N>(jit_info, interp, 2, ISR1);
- emitm_<op>(NATIVECODE, ISR1, ISR1);
- jit_emit_store<_N>(jit_info, interp, 1, ISR1);
- }
-}
-
-TEMPLATE Parrot_unop_x_nc {
- if(MAP[1] && MAP[2]){
- emitm_<op>(NATIVECODE, MAP[2], MAP[1]);
- }
- else if(MAP[1]){
- jit_emit_load<_N>(jit_info, interp, 2, MAP[1]);
- emitm_<op>(NATIVECODE, MAP[1], MAP[1]);
- }
- else {
- jit_emit_load<_N>(jit_info, interp, 2, ISR1);
- emitm_<op>(NATIVECODE, ISR1, ISR1);
- jit_emit_store<_N>(jit_info, interp, 1, ISR1);
- }
-}
-
-;Parrot_neg_n_nc {
-; Parrot_unop_x_x s/<op>/fnegs/ s/<_N>/_n/ s/ISR/FSR/
-;}
-
-;Parrot_neg_n_n {
-; Parrot_unop_x_x s/<op>/fnegs/ s/<_N>/_n/ s/ISR/FSR/
-;}
-
-TEMPLATE Parrot_abs_nx_nx {
- if(MAP[1] && MAP[2]){
- emitm_fabss(NATIVECODE, MAP[2], MAP[1]);
- emitm_fmovs(NATIVECODE, MAP[2] + 1, MAP[1] + 1);
- }
- else if(MAP[1]){
- jit_emit_load_n(jit_info, interp, 2, MAP[1]);
- emitm_fabss(NATIVECODE, MAP[1], MAP[1]);
- }
- else {
- jit_emit_load_n(jit_info, interp, 2, FSR1);
- emitm_fabss(NATIVECODE, FSR1, FSR1);
- jit_emit_store_n(jit_info, interp, 1, FSR1);
- }
-}
-
-Parrot_abs_n_n {
- Parrot_abs_nx_nx
-}
-
-Parrot_abs_n_nc {
- Parrot_abs_nx_nx
-}
-
-TEMPLATE Parrot_sqrt_nx_nx {
- if(MAP[1] && MAP[2]){
- emitm_fsqrtd(NATIVECODE, MAP[2], MAP[1]);
- }
- else if(MAP[1]){
- jit_emit_load_n(jit_info, interp, 2, MAP[1]);
- emitm_fsqrtd(NATIVECODE, MAP[1], MAP[1]);
- }
- else {
- jit_emit_load_n(jit_info, interp, 2, FSR1);
- emitm_fsqrtd(NATIVECODE, FSR1, FSR1);
- jit_emit_store_n(jit_info, interp, 1, FSR1);
- }
-}
-
-Parrot_sqrt_n_n {
- Parrot_sqrt_nx_nx
-}
-
-Parrot_sqrt_n_nc {
- Parrot_sqrt_nx_nx
-}
-
-
-TEMPLATE Parrot_if_ix_x {
- if(MAP[1]){
- emitm_subcc_r(NATIVECODE, MAP[1], emitm_g(0), emitm_g(0));
- }
- else {
- jit_emit_load_i(jit_info, interp, 1, ISR1);
- emitm_subcc_r(NATIVECODE, ISR1, emitm_g(0), emitm_g(0));
- }
-
- Parrot_jit_bicc(jit_info, emitm_<a>, 0, *INT_CONST[2]);
- emitm_nop(NATIVECODE);
-}
-
-Parrot_if_ic_ic {
- Parrot_if_ix_x s/<a>/bne/
-}
-
-Parrot_if_i_ic {
- Parrot_if_ix_x s/<a>/bne/
-}
-
-Parrot_unless_i_ic {
- Parrot_if_ix_x s/<a>/be/
-}
-
-Parrot_branch_ic {
- Parrot_jit_bicc(jit_info, emitm_ba, 0, *INT_CONST[1]);
- emitm_nop(NATIVECODE);
-}
-
-TEMPLATE Parrot_cmp_x_x_ic {
- if(MAP[1] && MAP[2]){
- emitm_<op>(NATIVECODE, MAP[1], MAP[2] <nill>);
- }
- else if (MAP[1]) {
- jit_emit_load<_N>(jit_info, interp, 2, ISR2);
- emitm_<op>(NATIVECODE, MAP[1], ISR2 <nill>);
- }
- else if (MAP[2]) {
- jit_emit_load<_N>(jit_info, interp, 1, ISR1);
- emitm_<op>(NATIVECODE, ISR1, MAP[2] <nill>);
- }
- else {
- jit_emit_load<_N>(jit_info, interp, 1, ISR1);
- jit_emit_load<_N>(jit_info, interp, 2, ISR2);
- emitm_<op>(NATIVECODE, ISR1, ISR2 <nill>);
- }
-
- Parrot_jit_<branch>(jit_info, emitm_<a>, 0, *INT_CONST[3]);
- emitm_nop(NATIVECODE);
-}
-
-Parrot_eq_ic_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/be/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_eq_i_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/be/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_eq_ic_i_ic {
- Parrot_cmp_x_x_ic s/<a>/be/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_eq_i_i_ic {
- Parrot_cmp_x_x_ic s/<a>/be/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_ne_ic_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/bne/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_ne_i_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/bne/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_ne_ic_i_ic {
- Parrot_cmp_x_x_ic s/<a>/bne/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_ne_i_i_ic {
- Parrot_cmp_x_x_ic s/<a>/bne/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_lt_ic_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/bl/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_lt_i_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/bl/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_lt_ic_i_ic {
- Parrot_cmp_x_x_ic s/<a>/bl/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_lt_i_i_ic {
- Parrot_cmp_x_x_ic s/<a>/bl/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_le_ic_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/ble/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_le_i_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/ble/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_le_ic_i_ic {
- Parrot_cmp_x_x_ic s/<a>/ble/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_le_i_i_ic {
- Parrot_cmp_x_x_ic s/<a>/ble/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_gt_ic_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/bg/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_gt_i_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/bg/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_gt_ic_i_ic {
- Parrot_cmp_x_x_ic s/<a>/bg/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_gt_i_i_ic {
- Parrot_cmp_x_x_ic s/<a>/bg/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_ge_ic_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/bge/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_ge_i_ic_ic {
- Parrot_cmp_x_x_ic s/<a>/bge/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_ge_ic_i_ic {
- Parrot_cmp_x_x_ic s/<a>/bge/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_ge_i_i_ic {
- Parrot_cmp_x_x_ic s/<a>/bge/ s/<op>/subcc_r/ s/<branch>/bicc/ s/<_N>/_i/ s/<nill>/, emitm_g(0)/
-}
-
-Parrot_eq_n_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbe/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_eq_nc_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbe/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_eq_n_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbe/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_eq_nc_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbe/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_ne_n_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbne/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_ne_nc_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbne/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_ne_n_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbne/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_ne_nc_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbne/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_lt_n_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbl/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_lt_nc_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbl/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_lt_n_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbl/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_lt_nc_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbl/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_le_n_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fble/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_le_nc_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fble/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_le_n_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fble/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_le_nc_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fble/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_gt_n_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbg/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_gt_nc_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbg/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_gt_n_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbg/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_gt_nc_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbg/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_ge_n_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbge/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_ge_nc_n_ic {
- Parrot_cmp_x_x_ic s/<a>/fbge/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_ge_n_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbge/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-Parrot_ge_nc_nc_ic {
- Parrot_cmp_x_x_ic s/<a>/fbge/ s/<op>/fcmpd/ s/<branch>/fbfcc/ s/<_N>/_n/ s/ISR/FSR/ s/<nill>//
-}
-
-TEMPLATE Parrot_iscmp_ix_ix_ix {
- if(MAP[2] && MAP[3]){
- emitm_subcc_r(NATIVECODE, MAP[2], MAP[3], emitm_g(0));
- }
- else if (MAP[2]) {
- jit_emit_load_i(jit_info, interp, 3, ISR2);
- emitm_subcc_r(NATIVECODE, MAP[2], ISR2, emitm_g(0));
- }
- else if (MAP[3]) {
- jit_emit_load_i(jit_info, interp, 2, ISR1);
- emitm_subcc_r(NATIVECODE, ISR1, MAP[3], emitm_g(0));
- }
- else {
- jit_emit_load_i(jit_info, interp, 2, ISR1);
- jit_emit_load_i(jit_info, interp, 3, ISR2);
- emitm_subcc_r(NATIVECODE, ISR1, ISR2, emitm_g(0));
- }
-
- emitm_bicc(NATIVECODE, 1, emitm_<a>, 3);
-
- if(MAP[1]){
- emitm_mov_i(NATIVECODE, 1, MAP[1]);
- emitm_or_r(NATIVECODE, emitm_g(0), emitm_g(0), MAP[1]);
- } else {
- jit_emit_store_i(jit_info, interp, 1, 1);
- jit_emit_store_i(jit_info, interp, 1, 0);
- }
-}
-
-Parrot_isgt_i_i_i {
- Parrot_iscmp_ix_ix_ix s/<a>/bg/
-}
-
-Parrot_isgt_i_ic_i {
- Parrot_iscmp_ix_ix_ix s/<a>/bg/
-}
-
-Parrot_isgt_i_i_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/bg/
-}
-
-Parrot_isgt_i_ic_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/bg/
-}
-
-Parrot_isge_i_i_i {
- Parrot_iscmp_ix_ix_ix s/<a>/bge/
-}
-
-Parrot_isge_i_ic_i {
- Parrot_iscmp_ix_ix_ix s/<a>/bge/
-}
-
-Parrot_isge_i_i_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/bge/
-}
-
-Parrot_isge_i_ic_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/bge/
-}
-
-Parrot_isle_i_i_i {
- Parrot_iscmp_ix_ix_ix s/<a>/ble/
-}
-
-Parrot_isle_i_ic_i {
- Parrot_iscmp_ix_ix_ix s/<a>/ble/
-}
-
-Parrot_isle_i_i_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/ble/
-}
-
-Parrot_isle_i_ic_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/ble/
-}
-
-Parrot_islt_i_i_i {
- Parrot_iscmp_ix_ix_ix s/<a>/bl/
-}
-
-Parrot_islt_i_ic_i {
- Parrot_iscmp_ix_ix_ix s/<a>/bl/
-}
-
-Parrot_islt_i_i_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/bl/
-}
-
-Parrot_islt_i_ic_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/bl/
-}
-
-Parrot_iseq_i_i_i {
- Parrot_iscmp_ix_ix_ix s/<a>/be/
-}
-
-Parrot_iseq_i_ic_i {
- Parrot_iscmp_ix_ix_ix s/<a>/be/
-}
-
-Parrot_iseq_i_i_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/be/
-}
-
-Parrot_iseq_i_ic_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/be/
-}
-
-Parrot_isne_i_i_i {
- Parrot_iscmp_ix_ix_ix s/<a>/bne/
-}
-
-Parrot_isne_i_ic_i {
- Parrot_iscmp_ix_ix_ix s/<a>/bne/
-}
-
-Parrot_isne_i_i_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/bne/
-}
-
-Parrot_isne_i_ic_ic {
- Parrot_iscmp_ix_ix_ix s/<a>/bne/
-}
-
-/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/sun4/jit_defs.c
==============================================================================
--- trunk/src/jit/sun4/jit_defs.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,13 +0,0 @@
-/* Stub file for RT#38929 fixes */
-/*
-Copyright (C) 2008, Parrot Foundation.
-$Id$
-*/
-/* HEADERIZER HFILE: none */
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit/sun4/jit_emit.h
==============================================================================
--- trunk/src/jit/sun4/jit_emit.h Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,1200 +0,0 @@
-/*
- * Copyright (C) 2002-2009, Parrot Foundation.
- */
-
-/*
-** jit_emit.h
-**
-** SPARC
-**
-** $Id$
-**/
-
-#ifndef PARROT_SUN4_JIT_EMIT_H_GUARD
-#define PARROT_SUN4_JIT_EMIT_H_GUARD
-
-/* XXX As of rev 11423, sun4 jit no longer compiles due to the missing
- Parrot_jit_init() function and the corresponding arch_info structure.
- Prior to that, it compiled, but probably didn't work. See notes labeled
- XXX Hack [perl #37819] below.
-*/
-
-/*
- * SPARC JIT overview:
- *
- * The interpreter pointer is kept in i0.
- * The address of register I0 is stored in i1, with all parrot register access
- * performed relative to this register.
- * The address of the opcode - native code mapping array is kept in i3.
- *
- * See IMPORTANT SHORTCUTS below.
- */
-
-/* Sparc register numbers */
-#define emitm_g(n) (n)
-#define emitm_o(n) ((n) + 8)
-#define emitm_l(n) ((n) + 16)
-#define emitm_i(n) ((n) + 24)
-#define emitm_f(n) (n)
-
-#if JIT_EMIT
-
-# define emitm_FP emitm_i(6)
-# define emitm_SP emitm_o(6)
-
-# define emitm_mask(n, val) ((unsigned)(val) & ((1U << (n)) - 1))
-
-# define emitm_hi30(val) ((unsigned)(val) >> 2)
-# define emitm_hi22(val) ((unsigned)(val) >> 10)
-# define emitm_lo10(val) emitm_mask(10, (val))
-# define emitm_simm13(val) emitm_mask(13, (val))
-
-# define emitm_opval(val) ((unsigned)(val) << 30)
-# define emitm_op2val(val) ((unsigned)(val) << 22)
-# define emitm_op3val(val) ((unsigned)(val) << 19)
-# define emitm_rd(val) ((unsigned)(val) << 25)
-# define emitm_rs1(val) ((unsigned)(val) << 14)
-
-# define emitm_simm13_max 4095
-# define emitm_simm13_min -4096
-
-# define emitm_simm13_const(val) (((val) >= emitm_simm13_min) && ((val) < emitm_simm13_max))
-
-# define emitm_branch_max 8388607
-# define emitm_branch_min -8388608
-
-/* format 1 - only instruction */
-# define emitm_call_30(pc, disp30) { \
- *(unsigned *)(pc) = emitm_opval(1) | (disp30); \
- pc += 4; }
-
-/* format 2a - sethi primarily */
-# define emitm_2a(pc, op, rd, op2, imm22) { \
- *(unsigned *)(pc) = emitm_opval(op) | emitm_rd(rd) | emitm_op2val(op2) | \
- (imm22); \
- pc += 4; }
-
-/* format 2b - branches */
-# define emitm_2b(pc, a, cond, op2, disp22) { \
- *(unsigned *)(pc) = emitm_opval(0) | ((unsigned)(a) << 29) | \
- ((unsigned)(cond) << 25) | emitm_op2val(op2) | \
- emitm_mask(22, disp22); \
- pc += 4; }
-
-/* Generic fields of format 3 */
-# define emitm_fmt3(pc, op, rd, op3, rs1, low14) { \
- *(unsigned *)pc = emitm_opval(op) |emitm_rd(rd) | emitm_op3val(op3) | \
- emitm_rs1(rs1) | (low14); \
- pc +=4 ; }
-
-/* format 3a */
-# define emitm_3a(pc, op, rd, op3, rs1, asi, rs2) \
- emitm_fmt3(pc, op, rd, op3, rs1, ((asi) << 5) | (rs2))
-
-/* format 3b */
-# define emitm_3b(pc, op, rd, op3, rs1, simm13) \
- emitm_fmt3(pc, op, rd, op3, rs1, (1L << 13) | emitm_mask(13, (simm13)))
-
-/* format 3c */
-# define emitm_3c(pc, op, rd, op3, rs1, opf, rs2) \
- emitm_fmt3(pc, op, rd, op3, rs1, (opf << 5) | (rs2))
-
-/* Miscellaneous instructions */
-
-/* sethi imm22, r[rd] */
-# define emitm_sethi(pc, imm22, rd) emitm_2a((pc), 0, (rd), 04, (imm22))
-
-/* NOP */
-# define emitm_nop(pc) emitm_sethi((pc), 0, 0)
-
-/* SAVE */
-
-# define emitm_save_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 074, (rs1), 0, (rs2))
-# define emitm_save_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 074, (rs1), (i))
-
-/* RESTORE */
-# define emitm_restore_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 075, (rs1), 0, (rd))
-# define emitm_restore_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 075, (rs1), (i))
-
-/* MOV */
-# define emitm_mov_r(pc, rs, rd) emitm_or_r((pc), emitm_g(0), (rs), (rd))
-# define emitm_mov_i(pc, i, rd) emitm_or_i((pc), emitm_g(0), (i), (rd))
-
-/* Integer Register Loads */
-
-/* ldX[rs1 + simm13], rd */
-# define emitm_ldsb_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 011, (rs1), (i))
-# define emitm_ldub_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 001, (rs1), (i))
-# define emitm_ldsh_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 012, (rs1), (i))
-# define emitm_lduh_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 002, (rs1), (i))
-# define emitm_ld_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 000, (rs1), (i))
-# define emitm_ldd_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 003, (rs1), (i))
-
-/* ldX[rs1 + rs2], rd */
-# define emitm_ldsb_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 011, (rs1), 0, (rs2))
-# define emitm_ldub_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 001, (rs1), 0, (rs2))
-# define emitm_ldsh_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 012, (rs1), 0, (rs2))
-# define emitm_lduh_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 002, (rs1), 0, (rs2))
-# define emitm_ld_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 000, (rs1), 0, (rs2))
-# define emitm_ldd_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 003, (rs1), 0, (rs2))
-
-/* Integer Register Stores */
-
-/* stX rd, [rs1 + simm13] */
-# define emitm_stb_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 005, (rs1), (i))
-# define emitm_sth_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 006, (rs1), (i))
-# define emitm_st_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 004, (rs1), (i))
-# define emitm_std_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 007, (rs1), (i))
-
-/* stX rd, [rs1 + rs2] */
-# define emitm_stb_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 005, (rs1), 0, (rs2))
-# define emitm_sth_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 006, (rs1), 0, (rs2))
-# define emitm_st_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 004, (rs1), 0, (rs2))
-# define emitm_std_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 007, (rs1), 0, (rs2))
-
-/* Floating Point Register Loads */
-
-/* ldX[rs1 + simm13], freg[rd] */
-# define emitm_ldf_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 040, (rs1), (i))
-# define emitm_lddf_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 043, (rs1), (i))
-
-# define emitm_ldfsr_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 041, (rs1), (i))
-
-/* ldX[rs1 + rs2], freg[rd] */
-# define emitm_ldf_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 040, (rs1), 0, (rs2))
-# define emitm_lddf_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 043, (rs1), 0, (rs2))
-
-# define emitm_ldfsr_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 041, (rs1), 0, (rs2))
-
-/* Floating Point Register Stores */
-
-/* stX freg[rd], [rs1 + simm13] */
-# define emitm_stf_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 044, (rs1), (i))
-# define emitm_stdf_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 047, (rs1), (i))
-
-# define emitm_stfsr_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 045, (rs1), (i))
-
-/* stX freg[rd], [rs1 + rs2] */
-# define emitm_stf_r_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 044, (rs1), 0, (rs2))
-# define emitm_stdf_r_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 047, (rs1), 0, (rs2))
-# define emitm_stfsr_r_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 045, (rs1), 0, (rs2))
-
-/* Logical instructions */
-
-/* op r[rs1], r[rs2], r[rd] */
-# define emitm_logic_r(pc, op3, rs1, rs2, rd) \
- emitm_3a((pc), 2, (rd), (op3), (rs1), 0, (rs2))
-
-/* op r[rs1], simm13, r[rd] */
-# define emitm_logic_i(pc, op3, rs1, simm13, rd) \
- emitm_3b((pc), 2, (rd), (op3), (rs1), (simm13))
-
-# define emitm_and_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 001, (rs1), (rs2), (rd))
-# define emitm_andcc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 021, (rs1), (rs2), (rd))
-# define emitm_andn_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 005, (rs1), (rs2), (rd))
-# define emitm_andncc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 025, (rs1), (rs2), (rd))
-# define emitm_and_i(pc, rs1, i, rd) emitm_logic_i((pc), 001, (rs1), (i), (rd))
-# define emitm_andcc_i(pc, rs1, i, rd) emitm_logic_i((pc), 021, (rs1), (i), (rd))
-# define emitm_andn_i(pc, rs1, i, rd) emitm_logic_i((pc), 005, (rs1), (i), (rd))
-# define emitm_andncc_i(pc, rs1, i, rd) emitm_logic_i((pc), 025, (rs1), (i), (rd))
-# define emitm_or_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 002, (rs1), (rs2), (rd))
-# define emitm_orcc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 022, (rs1), (rs2), (rd))
-# define emitm_orn_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 006, (rs1), (rs2), (rd))
-# define emitm_orncc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 026, (rs1), (rs2), (rd))
-# define emitm_or_i(pc, rs1, i, rd) emitm_logic_i((pc), 002, (rs1), (i), (rd))
-# define emitm_orcc_i(pc, rs1, i, rd) emitm_logic_i((pc), 022, (rs1), (i), (rd))
-# define emitm_orn_i(pc, rs1, i, rd) emitm_logic_i((pc), 006, (rs1), (i), (rd))
-# define emitm_orncc_i(pc, rs1, i, rd) emitm_logic_i((pc), 026, (rs1), (i), (rd))
-# define emitm_xor_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 003, (rs1), (rs2), (rd))
-# define emitm_xorcc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 023, (rs1), (rs2), (rd))
-# define emitm_xorn_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 007, (rs1), (rs2), (rd))
-# define emitm_xorncc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 027, (rs1), (rs2), (rd))
-# define emitm_xor_i(pc, rs1, i, rd) emitm_logic_i((pc), 003, (rs1), (i), (rd))
-# define emitm_xorcc_i(pc, rs1, i, rd) emitm_logic_i((pc), 023, (rs1), (i), (rd))
-# define emitm_xorn_i(pc, rs1, i, rd) emitm_logic_i((pc), 007, (rs1), (i), (rd))
-# define emitm_xorncc_i(pc, rs1, i, rd) emitm_logic_i((pc), 027, (rs1), (i), (rd))
-
-/* Shift Left Logical */
-# define emitm_sll_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 045, (rs1), 0, (rs2))
-# define emitm_sll_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 045, (rs1), (i))
-
-/* Shift Right Logical */
-# define emitm_srl_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 046, (rs1), 0, (rs2))
-# define emitm_srl_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 046, (rs1), (i))
-
-/* Shift Right Arithmetic */
-# define emitm_sra_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 047, (rs1), 0, (rs2))
-# define emitm_sra_i(pc, rs1, i, rd) emitm_3a((pc), 2, (rd), 047, (rs1), (i))
-
-/* Arithmetic ops */
-# define emitm_add_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 0, (rs1), 0, (rs2))
-# define emitm_addcc_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 020, (rs1), 0, (rs2))
-# define emitm_addX_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 010, (rs1), 0, (rs2))
-# define emitm_addXcc_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 030, (rs1), 0, (rs2))
-# define emitm_add_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 0, (rs1), (i))
-# define emitm_addcc_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 020, (rs1), (i))
-# define emitm_addX_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 010, (rs1), (i))
-# define emitm_addXcc_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 030, (rs1), (i))
-
-/* Arithmetic ops */
-# define emitm_sub_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 004, (rs1), 0, (rs2))
-# define emitm_subcc_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 024, (rs1), 0, (rs2))
-# define emitm_subX_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 014, (rs1), 0, (rs2))
-# define emitm_subXcc_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 034, (rs1), 0, (rs2))
-# define emitm_sub_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 004, (rs1), (i))
-# define emitm_subcc_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 024, (rs1), (i))
-# define emitm_subX_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 014, (rs1), (i))
-# define emitm_subXcc_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 034, (rs1), (i))
-
-/* Floating point operations */
-
-/* MOV */
-# define emitm_fmovs(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0001, (rs))
-
-/* Arithmetic operations */
-# define emitm_faddd(pc, rs1, rs2, rd) emitm_3c((pc), 2, (rd), 064, (rs1), 0102, (rs2))
-# define emitm_fsubd(pc, rs1, rs2, rd) emitm_3c((pc), 2, (rd), 064, (rs1), 0106, (rs2))
-# define emitm_fmuld(pc, rs1, rs2, rd) emitm_3c((pc), 2, (rd), 064, (rs1), 0112, (rs2))
-# define emitm_fdivd(pc, rs1, rs2, rd) emitm_3c((pc), 2, (rd), 064, (rs1), 0116, (rs2))
-# define emitm_fabss(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0011, (rs))
-# define emitm_fnegs(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0005, (rs))
-
-# define emitm_fsqrtd(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0052, (rs))
-
-/* Floating <-> Integer Conversion */
-# define emitm_fitod(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0310, (rs))
-# define emitm_fdtoi(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0322, (rs))
-
-/* Floating point tests */
-# define emitm_fcmpd(pc, rs1, rs2) emitm_3c((pc), 2, 0, 065, (rs1), 0122, (rs2))
-
-/* Jump and Link */
-
-# define emitm_jumpl_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 070, (rs1), 0, (rs2))
-# define emitm_jumpl_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 070, (rs1), (i))
-
-/* RET */
-# define emitm_ret(pc) emitm_jumpl_i((pc), emitm_i(7), 8, emitm_g(0))
-
-/* integer conditions */
-# define emitm_ba 010
-# define emitm_bn 000
-# define emitm_bne 011
-# define emitm_be 001
-# define emitm_bg 012
-# define emitm_ble 002
-# define emitm_bge 013
-# define emitm_bl 003
-# define emitm_bgu 014
-# define emitm_bleu 004
-# define emitm_bcc 015
-# define emitm_bcs 005
-# define emitm_bpos 016
-# define emitm_bneg 006
-# define emitm_bvc 017
-# define emitm_bvs 007
-
-/* floating-point conditions */
-# define emitm_fba 010
-# define emitm_fbn 000
-# define emitm_fbu 007
-# define emitm_fbg 006
-# define emitm_fbug 005
-# define emitm_fbl 004
-# define emitm_fbul 003
-# define emitm_fblg 002
-# define emitm_fbne 001
-# define emitm_fbe 011
-# define emitm_fbue 012
-# define emitm_fbge 013
-# define emitm_fbuge 014
-# define emitm_fble 015
-# define emitm_fbule 016
-# define emitm_fbo 017
-
-# define emitm_icc 02
-# define emitm_fcc 06
-
-/* Branch on integer condition codes */
-# define emitm_bicc(pc, a, cond, disp22) emitm_2b((pc), (a), (cond), 02, (disp22))
-
-/* Branch on floating-point condition codes */
-# define emitm_fbfcc(pc, a, cond, disp22) emitm_2b((pc), (a), (cond), 06, (disp22))
-
-# define jit_emit_mov_rr_i(pc, dst, src) emitm_mov_r((pc), (src), (dst))
-# define jit_emit_mov_rr_n(pc, dst, src) { \
- emitm_fmovs((pc), (src), (dst)); \
- emitm_fmovs((pc), (src)+1, (dst)+1); }
-
-/*
-void main(){
- char ar[1024];
- char *ar2;
-
- ar2 = &ar[0];
- emitm_ld_r(ar2, emitm_g(0), emitm_i(1), emitm_o(7));
- emitm_ldub_r(ar2, emitm_g(0), emitm_i(1), emitm_o(7));
- emitm_ldsh_r(ar2, emitm_g(0), emitm_i(1), emitm_o(7));
-}
-*/
-
-/* Fixup types */
-enum {JIT_BRANCH, JIT_CALL30 };
-
-/*
- *
- * IMPORTANT SHORTCUTS
- *
- * */
-
-/* The register holding the interpreter pointer */
-# define Parrot_jit_intrp emitm_i(0)
-
-/* The register holding the address of I0 */
-# define Parrot_jit_regbase emitm_i(2)
-
-/* The register containing the address of the opmap */
-# define Parrot_jit_opmap emitm_i(3)
-
-/* These registers should be used only in .jit ops and not helper routines
- * in jit_emit.h
- */
-# define ISR1 emitm_i(4)
-# define ISR2 emitm_i(5)
-# define FSR1 emitm_f(0)
-# define FSR2 emitm_f(2)
-
-/* This register can be used only in jit_emit.h calculations */
-# define XSR1 emitm_l(0)
-# define XSR2 emitm_g(1)
-
-# define Parrot_jit_regbase_ptr(interp) ®_INT((interp), 0)
-
-/* The offset of a Parrot register from the base register */
-# define Parrot_jit_regoff(a, i) (unsigned)(a) - (unsigned)(Parrot_jit_regbase_ptr(i))
-
-/* interp->code */
-# define jit_emit_load_coderef(pc, reg) \
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp, offsetof(Interp, code), (reg)); \
-
-/* Load op_map address */
-# define jit_emit_load_op_map(pc, code) \
- emitm_ld_i(jit_info->native_ptr, (code), \
- offsetof(PackFile_ByteCode, jit_info), XSR1); \
- emitm_ld_i(jit_info->native_ptr, XSR1, \
- (offsetof(Parrot_jit_arena_t, op_map) + offsetof(Parrot_jit_info_t, arena)), \
- Parrot_jit_opmap);
-
-/* Construct the starting address of the byte code (code start) */
-# define jit_emit_load_code_start(pc, code) \
- emitm_ld_i(jit_info->native_ptr, (code), offsetof(PackFile_Segment, data), \
- XSR1);
-
-/* Generate a jump to a bytecode address in reg_num
- * - uses the temporary register
- */
-static void
-Parrot_jit_bytejump(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int reg_num)
-{
- jit_emit_load_coderef(jit_info->native_ptr, XSR2);
-
- jit_emit_load_op_map(jit_info->native_ptr, XSR2);
- jit_emit_load_code_start(jit_info->native_ptr, XSR2);
-
- /* Calculates the offset into op_map shadow array
- * assuming sizeof (opcode_t) == sizeof (opmap array entry) */
- emitm_sub_r(jit_info->native_ptr, reg_num, XSR1, XSR1);
-
- /* Load the address of the native code from op_map */
- emitm_ld_r(jit_info->native_ptr, Parrot_jit_opmap, XSR1, XSR1);
-
- /* This jumps to the address from op_map */
- emitm_jumpl_i(jit_info->native_ptr, XSR1, 0, XSR1);
-
- /* fixup where we have the Parrot registers - context switches */
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp, offsetof(Interp, ctx),
- Parrot_jit_intrp);
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp, offsetof(PMC, data),
- Parrot_jit_intrp);
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp,
- offsetof(Parrot_Context, bp), Parrot_jit_intrp);
-}
-
-/* Generate conditional branch to offset from current parrot op */
-static void Parrot_jit_branch(Parrot_jit_info_t *jit_info, int branch, int cond,
- int annul, opcode_t disp)
-{
- int offset;
- opcode_t opcode;
-
- opcode = jit_info->op_i + disp;
- if (opcode <= jit_info->op_i){
- offset = jit_info->arena.op_map[opcode].offset -
- (jit_info->native_ptr - jit_info->arena.start);
-
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- offset +=
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- if ((offset > emitm_branch_max) || (offset < emitm_branch_min))
- exit_fatal(EXCEPTION_JIT_ERROR,
- "Branches beyond 8 Megabytes not yet supported\n");
- offset /= 4;
- emitm_2b(jit_info->native_ptr, annul, cond, branch, offset);
- return;
- }
-
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_BRANCH;
- jit_info->arena.fixups->param.opcode = opcode;
-
- /* If the branch is to the current section, skip the load instructions. */
- if (jit_info->optimizer->cur_section->branch_target ==
- jit_info->optimizer->cur_section)
- jit_info->arena.fixups->skip =
- jit_info->optimizer->cur_section->branch_target->load_size;
-
- emitm_2b(jit_info->native_ptr, annul, cond, branch, 0);
-}
-
-/* Generate branch on integer condition codes */
-# define Parrot_jit_bicc(jit_info, cond, annul, disp) \
- Parrot_jit_branch((jit_info), emitm_icc, (cond), (annul), (disp))
-
-/* Generate branch on floating-point condition codes */
-# define Parrot_jit_fbfcc(jit_info, cond, annul, disp) \
- Parrot_jit_branch((jit_info), emitm_fcc, (cond), (annul), (disp))
-
-/* This function loads a value */
-static void jit_emit_load_i(Parrot_jit_info_t *jit_info,
- PARROT_INTERP,
- int param,
- int hwreg)
-{
- opcode_t op_type;
- int val;
-
- op_type = interp->op_info_table[*jit_info->cur_op].types[param - 1];
- val = jit_info->cur_op[param];
-
- switch (op_type){
- case PARROT_ARG_IC:
- if ((val < emitm_simm13_min) || (val > emitm_simm13_max)){
- emitm_sethi(jit_info->native_ptr, emitm_hi22(val), hwreg);
- emitm_or_i(jit_info->native_ptr, hwreg, emitm_lo10(val),
- hwreg);
- }
- else {
- emitm_or_i(jit_info->native_ptr, emitm_g(0), val, hwreg);
- }
-
- break;
- case PARROT_ARG_NC:
- val = (int)&interp->code->const_table->
- constants[val]->u.number;
-
- /* Load double into integer registers */
- emitm_sethi(jit_info->native_ptr, emitm_hi22(val), XSR1);
- emitm_ldd_i(jit_info->native_ptr, XSR1, emitm_lo10(val),
- hwreg);
- break;
-
- case PARROT_ARG_I:
- val = (int)®_INT(interp, val);
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp), hwreg);
- break;
-
- case PARROT_ARG_P:
- val = (int)®_PMC(interp, val);
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp), hwreg);
- break;
-
- case PARROT_ARG_S:
- val = (int)®_STR(interp, val);
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp), hwreg);
- break;
-
- case PARROT_ARG_N:
- val = (int)®_NUM(interp, val);
- emitm_ldd_i(jit_info->native_ptr, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp), hwreg);
- break;
-
- default:
- exit_fatal(EXCEPTION_JIT_ERROR,
- "Unsupported op parameter type %d\n",
- op_type);
- }
-}
-
-static void jit_emit_store_i(Parrot_jit_info_t *jit_info,
- PARROT_INTERP,
- int param,
- int hwreg)
-{
- opcode_t op_type;
- int val;
-
- op_type = interp->op_info_table[*jit_info->cur_op].types[param - 1];
- val = jit_info->cur_op[param];
-
- switch (op_type){
- case PARROT_ARG_I:
- val = (int)®_INT(interp, val);
- emitm_st_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp));
- break;
-
- case PARROT_ARG_P:
- val = (int)®_PMC(interp, val);
- emitm_st_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp));
- break;
-
- case PARROT_ARG_S:
- val = (int)®_STR(interp, val);
- emitm_st_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp));
- break;
-
- case PARROT_ARG_N:
- val = (int)®_NUM(interp, val);
- emitm_std_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp));
- break;
-
- default:
- exit_fatal(EXCEPTION_JIT_ERROR,
- "Unsupported op parameter type %d\n", op_type);
- }
-}
-
-static void jit_emit_load_n(Parrot_jit_info_t *jit_info,
- PARROT_INTERP,
- int param,
- int hwreg)
-{
- opcode_t op_type;
- long val;
-
- op_type = interp->op_info_table[*jit_info->cur_op].types[param - 1];
- val = jit_info->cur_op[param];
-
- switch (op_type){
- case PARROT_ARG_IC:
- /* Load integer into floating point registers - should use
- constant pool */
- val = &jit_info->cur_op[param];
- emitm_sethi(jit_info->native_ptr, emitm_hi22(val), XSR1);
- emitm_ldf_i(jit_info->native_ptr, XSR1, emitm_lo10(val), hwreg);
- break;
-
- case PARROT_ARG_NC:
- val = (int)&interp->code->const_table->
- constants[val]->u.number;
-
- /* Load double into floating point registers */
- emitm_sethi(jit_info->native_ptr, emitm_hi22(val), XSR1);
- emitm_lddf_i(jit_info->native_ptr, XSR1, emitm_lo10(val),
- hwreg);
- break;
-
- case PARROT_ARG_I:
- val = (int)®_INT(interp, val);
- emitm_ldf_i(jit_info->native_ptr, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp), hwreg);
- break;
-
- case PARROT_ARG_N:
- val = (int)®_NUM(interp, val);
- emitm_lddf_i(jit_info->native_ptr, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp), hwreg);
- break;
-
- default:
- exit_fatal(EXCEPTION_JIT_ERROR,
- "Unsupported op parameter type %d\n", op_type);
- }
-}
-
-static void jit_emit_store_n(Parrot_jit_info_t *jit_info,
- PARROT_INTERP,
- int param,
- int hwreg)
-{
- opcode_t op_type;
- int val;
-
- op_type = interp->op_info_table[*jit_info->cur_op].types[param - 1];
- val = jit_info->cur_op[param];
-
- switch (op_type){
- case PARROT_ARG_I:
- val = (int)®_INT(interp, val);
- emitm_stf_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp));
- break;
-
- case PARROT_ARG_N:
- val = (int)®_NUM(interp, val);
- emitm_stdf_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
- Parrot_jit_regoff(val, interp));
- break;
-
- default:
- exit_fatal(EXCEPTION_JIT_ERROR,
- "Unsupported op parameter type %d\n", op_type);
- }
-}
-
-
-void Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_fixup_t *fixup;
- Parrot_jit_fixup_t *last_fixup;
- char *fixup_ptr;
- int fixup_val;
-
- fixup = jit_info->arena.fixups;
-
- while (fixup){
- switch (fixup->type){
- /* This fixes-up a branch to a known opcode offset */
- case JIT_BRANCH:
- fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
- fixup_val = (jit_info->arena.op_map[fixup->param.opcode].offset
- - fixup->native_offset + fixup->skip) / 4;
- *(int *)(fixup_ptr) |= emitm_mask(22, fixup_val);
- break;
-
- case JIT_CALL30:
- fixup_ptr = jit_info->arena.start + fixup->native_offset;
- fixup_val = (int)fixup->param.fptr - (int)fixup_ptr;
- emitm_call_30(fixup_ptr, emitm_hi30(fixup_val));
- break;
-
- default:
- exit_fatal(EXCEPTION_JIT_ERROR, "Unknown fixup type:%d\n",
- fixup->type);
- break;
- }
- fixup = fixup->next;
- }
-}
-
-void
-Parrot_jit_begin(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- /* generated code is called as jit_code(interp, pc)
- * so interpreter is in i0 and pc in i1.
- * i1 is reusable once past the jump. interpreter is preserved in i0
- */
- int ireg0_offset;
- int ireg0_address;
-
- /* Standard Prolog */
- emitm_save_i(jit_info->native_ptr, emitm_SP, -104, emitm_SP);
-
- /* Calculate the offset of I0 in the interpreter struct */
- ireg0_address = (int)Parrot_jit_regbase_ptr(interp);
- ireg0_offset = ireg0_address - (int)interp;
-
- /* All parrot registers will be addressed relative to I0 */
- if ((ireg0_offset < emitm_simm13_min) || (ireg0_offset > emitm_simm13_max)){
- /* Store the address of I0 if its offset doesnt fit in the immediate */
- emitm_sethi(jit_info->native_ptr, emitm_hi22(ireg0_address), Parrot_jit_regbase);
- emitm_or_i(jit_info->native_ptr, Parrot_jit_regbase, emitm_lo10(ireg0_address),
- Parrot_jit_regbase);
- }
- else {
- /* Calculate the address of I0 */
- emitm_add_i(jit_info->native_ptr, Parrot_jit_intrp, ireg0_offset,
- Parrot_jit_regbase);
- }
-
- /* Jump to the current pc */
- Parrot_jit_bytejump(jit_info, interp, emitm_i(1));
-}
-
-void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- emitm_sethi(jit_info->native_ptr, emitm_hi22(jit_info->cur_op), emitm_o(0));
- emitm_or_i(jit_info->native_ptr,
- emitm_o(0), emitm_lo10(jit_info->cur_op), emitm_o(0));
-
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_CALL30;
- jit_info->arena.fixups->param.fptr =
- (void (*)(void))interp->op_func_table[*(jit_info->cur_op)];
-
- emitm_call_30(jit_info->native_ptr, 0);
- emitm_mov_r(jit_info->native_ptr, Parrot_jit_intrp, emitm_o(1));
-}
-
-void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
- Parrot_jit_bytejump(jit_info, interp, emitm_o(0));
-}
-
-# undef Parrot_jit_restart_op
-void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_normal_op(jit_info, interp);
-
- /* Test whether the return value is 0 */
- emitm_subcc_r(jit_info->native_ptr, emitm_o(0), emitm_g(0), emitm_g(0));
-
- /* If the return pc is not zero skip the next 3 instructions */
- emitm_bicc(jit_info->native_ptr, 0, emitm_bne, 4);
- emitm_nop(jit_info->native_ptr);
-
- /* Return if the return pc is 0 */
- emitm_ret(jit_info->native_ptr);
- emitm_restore_i(jit_info->native_ptr, emitm_g(0), emitm_g(0), emitm_g(0));
-
- Parrot_jit_bytejump(jit_info, interp, emitm_o(0));
-}
-
-/* move reg to mem (i.e. intreg) */
-void
-Parrot_jit_emit_mov_mr(PARROT_INTERP, char *mem, int reg)
-{
- emitm_st_i(((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr,
- reg, Parrot_jit_regbase, Parrot_jit_regoff(mem, interp));
-}
-
-/* move mem (i.e. intreg) to reg */
-void
-Parrot_jit_emit_mov_rm(PARROT_INTERP, int reg, char *mem)
-{
- emitm_ld_i(((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr,
- Parrot_jit_regbase, Parrot_jit_regoff(mem, interp), reg);
-}
-
-/* move reg to mem (i.e. numreg) */
-void
-Parrot_jit_emit_mov_mr_n(PARROT_INTERP, char *mem, int reg)
-{
- emitm_stdf_i(((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr,
- reg, Parrot_jit_regbase, Parrot_jit_regoff(mem, interp));
-}
-
-/* move mem (i.e. numreg) to reg */
-void
-Parrot_jit_emit_mov_rm_n(PARROT_INTERP, int reg, char *mem)
-{
- emitm_lddf_i(((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr,
- Parrot_jit_regbase, Parrot_jit_regoff(mem, interp), reg);
-}
-
-/* XXX Hack to fix the following bug as of 05 Dec 2005:
- Hack [perl #37819] Sun4 builds fail linking against jit.o
- These dummy definitions blindly copied from jit/mips/jit_emit.h.
- Apparently, they need to be inside a JIT_EMIT section of this
- file.
- See also the "Hack [perl #37819]" section near the bottom of this
- file.
-*/
-void
-Parrot_jit_emit_mov_mr_offs(PARROT_INTERP, int base, size_t offs, int reg)
-{
-}
-
-void
-Parrot_jit_emit_mov_rm_offs(PARROT_INTERP, int reg, int base, size_t offs)
-{
-}
-
-void
-Parrot_jit_emit_mov_mr_n_offs(PARROT_INTERP, int base, size_t offs, int reg)
-{
-}
-
-void
-Parrot_jit_emit_mov_rm_n_offs(PARROT_INTERP, int reg, int base, size_t offs)
-{
-}
-/* XXX end blind hack for [perl #37819] --but see
- additional hack section at bottom.
-*/
-# ifndef NO_JIT_VTABLE_OPS
-
-# undef Parrot_jit_vtable1_op
-# undef Parrot_jit_vtable1r_op
-
-# undef Parrot_jit_vtable_111_op
-# undef Parrot_jit_vtable_112_op
-# undef Parrot_jit_vtable_221_op
-# undef Parrot_jit_vtable_1121_op
-# undef Parrot_jit_vtable_1123_op
-# undef Parrot_jit_vtable_2231_op
-
-# undef Parrot_jit_vtable_1r223_op
-# undef Parrot_jit_vtable_1r332_op
-
-# undef Parrot_jit_vtable_ifp_op
-# undef Parrot_jit_vtable_unlessp_op
-# undef Parrot_jit_vtable_newp_ic_op
-
-/* emit a call to a vtable func
- * $X->vtable(interp, $X [, $Y...] )
- */
-static void
-Parrot_jit_vtable_n_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int n, int *args)
-{
- int nvtable = op_jit[*jit_info->cur_op].extcall;
- op_info_t *op_info = &interp->op_info_table[*jit_info->cur_op];
-
- int pmc = 0; /* pmc saves the left most Pi */
- int rdx = 1; /* native (outgoing) register index */
-
- int idx, pi, i;
- size_t offset;
-
- offset = offsetof(VTABLE, absolute);
- offset += nvtable * sizeof (void *);
-
- for (idx = 1; idx <= n; idx++) {
- i = args[idx - 1];
- pi = *(jit_info->cur_op + i);
-
- switch (op_info->types[i - 1]) {
- case PARROT_ARG_S:
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
- REG_OFFS_STR(pi), emitm_o(rdx));
- break;
- case PARROT_ARG_K:
- case PARROT_ARG_P:
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
- REG_OFFS_PMC(pi), emitm_o(rdx));
- if (! pmc) { pmc = rdx; }
- break;
- case PARROT_ARG_KI:
- case PARROT_ARG_I:
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
- REG_OFFS_INT(pi), emitm_o(rdx));
- break;
- case PARROT_ARG_KIC:
- case PARROT_ARG_IC:
- if (emitm_simm13_const(pi)) {
- emitm_mov_i(jit_info->native_ptr, pi, emitm_o(rdx));
- }
- else {
- emitm_sethi(jit_info->native_ptr, emitm_hi22(pi), emitm_o(rdx));
- emitm_or_i(jit_info->native_ptr, emitm_o(rdx), emitm_lo10(pi), emitm_o(rdx));
- }
- break;
- case PARROT_ARG_N:
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
- REG_OFFS_NUM(pi), emitm_o(rdx));
- emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
- REG_OFFS_NUM(pi) + 4, emitm_o(++rdx));
- break;
- case PARROT_ARG_NC:
-# define NC_addr &interp->code->const_table->constants[pi]->u.number
- emitm_sethi(jit_info->native_ptr, emitm_hi22(NC_addr), XSR1);
- emitm_or_i(jit_info->native_ptr, XSR1, emitm_lo10(NC_addr), XSR1);
-
- emitm_ld_i(jit_info->native_ptr, XSR1, 0, emitm_o(rdx));
- emitm_ld_i(jit_info->native_ptr, XSR1, 4, emitm_o(++rdx));
- break;
- case PARROT_ARG_SC:
-# define SC_addr &interp->code->const_table->constants[pi]->u.string
- emitm_sethi(jit_info->native_ptr, emitm_hi22(SC_addr), XSR1);
- emitm_or_i(jit_info->native_ptr, XSR1, emitm_lo10(SC_addr), XSR1);
-
- emitm_ld_i(jit_info->native_ptr, XSR1, 0, emitm_o(rdx));
- break;
- case PARROT_ARG_KC:
- case PARROT_ARG_PC:
-# define KC_addr &interp->code->const_table->constants[pi]->u.key
- emitm_sethi(jit_info->native_ptr, emitm_hi22(KC_addr), XSR1);
- emitm_or_i(jit_info->native_ptr, XSR1, emitm_lo10(KC_addr), XSR1);
-
- emitm_ld_i(jit_info->native_ptr, XSR1, 0, emitm_o(rdx));
- break;
- default:
- exit_fatal(1,
- "jit_vtable_n_op: unimp type %d, arg %d vtable %d",
- op_info->types[i - 1], i, nvtable);
- break;
- }
-
- rdx++;
- }
-
- emitm_ld_i(jit_info->native_ptr, emitm_o(pmc), offsetof(struct PMC, vtable), XSR1);
- emitm_ld_i(jit_info->native_ptr, XSR1, offset, XSR1);
-
- emitm_jumpl_i(jit_info->native_ptr, XSR1, 0, emitm_o(7));
- emitm_mov_r(jit_info->native_ptr, Parrot_jit_intrp, emitm_o(0));
-}
-
-static void
-Parrot_jit_store_retval(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- opcode_t op_type = interp->op_info_table[*jit_info->cur_op].types[0];
- long val = jit_info->cur_op[1];
-
- switch (op_type){
- case PARROT_ARG_I:
- emitm_st_i(jit_info->native_ptr, emitm_o(0), Parrot_jit_regbase,
- Parrot_jit_regoff((int)®_INT(interp, val), interp));
- break;
- case PARROT_ARG_P:
- emitm_st_i(jit_info->native_ptr, emitm_o(0), Parrot_jit_regbase,
- Parrot_jit_regoff((int)®_PMC(interp, val), interp));
- break;
- case PARROT_ARG_S:
- emitm_st_i(jit_info->native_ptr, emitm_o(0), Parrot_jit_regbase,
- Parrot_jit_regoff((int)®_STR(interp, val), interp));
- break;
- case PARROT_ARG_N:
- emitm_stdf_i(jit_info->native_ptr, emitm_f(0), Parrot_jit_regbase,
- Parrot_jit_regoff((int)®_NUM(interp, val), interp));
- break;
- default:
- exit_fatal(EXCEPTION_JIT_ERROR, "jit_vtable1r: ill LHS");
- }
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1)
- */
-static void
-Parrot_jit_vtable1_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 1, a);
-}
-
-/* emit a call to a vtable func
- * $1 = $2->vtable(interp, $2)
- */
-static void
-Parrot_jit_vtable1r_op(Parrot_jit_info_t *jit_info,
- Interp * interp)
-{
- int a[] = { 2 };
- Parrot_jit_vtable_n_op(jit_info, interp, 1, a);
- Parrot_jit_store_retval(jit_info, interp);
-}
-
-/* emit a call to a vtable func
- * $1 = $2->vtable(interp, $2, $3)
- */
-static void
-Parrot_jit_vtable_1r223_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 2, 3 };
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
- Parrot_jit_store_retval(jit_info, interp);
-}
-
-/* emit a call to a vtable func
- * $1 = $3->vtable(interp, $3, $2)
- */
-static void
-Parrot_jit_vtable_1r332_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 3, 2 };
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
- Parrot_jit_store_retval(jit_info, interp);
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2)
- */
-static void
-Parrot_jit_vtable_112_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1, 2 };
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $1)
- */
-static void
-Parrot_jit_vtable_111_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1, 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
-}
-
-/* emit a call to a vtable func
- * $2->vtable(interp, $2, $1)
- */
-static void
-Parrot_jit_vtable_221_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 2, 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
-}
-
-/* emit a call to a vtable func
- * $2->vtable(interp, $2, $3, $1)
- */
-static void
-Parrot_jit_vtable_2231_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 2, 3, 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2, $3)
- */
-static void
-Parrot_jit_vtable_1123_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1, 2, 3 };
- Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
-}
-
-/* emit a call to a vtable func
- * $1->vtable(interp, $1, $2, $1)
- */
-static void
-Parrot_jit_vtable_1121_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- int a[] = { 1, 2, 1 };
- Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
-}
-
-/* if_p_ic, unless_p_ic */
-static void
-Parrot_jit_vtable_if_unless_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP, int unless)
-{
- int ic = *(jit_info->cur_op + 2); /* branch offset */
-
- /* emit call to vtable function i.e. get_bool, result in o0 */
- Parrot_jit_vtable1_op(jit_info, interp);
-
- /* test the result - and branch (or not) accordingly */
- emitm_subcc_r(jit_info->native_ptr, emitm_o(0), emitm_g(0), emitm_g(0));
- Parrot_jit_bicc(jit_info, unless ? emitm_be : emitm_bne, 0, ic);
-
- emitm_nop(jit_info->native_ptr);
-}
-
-static void
-Parrot_jit_vtable_ifp_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_vtable_if_unless_op(jit_info, interp, 0);
-}
-
-static void
-Parrot_jit_vtable_unlessp_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- Parrot_jit_vtable_if_unless_op(jit_info, interp, 1);
-}
-
-/* new_p_ic */
-static void
-Parrot_jit_vtable_newp_ic_op(Parrot_jit_info_t *jit_info,
- PARROT_INTERP)
-{
- void *igniter = (void (*)(void))pmc_new_noinit;
- size_t offset = offsetof(VTABLE, init);
-
- int p1 = *(jit_info->cur_op + 1);
- int i2 = *(jit_info->cur_op + 2);
-
- if (i2 <= 0 || i2 >= interp->n_vtable_max)
- exit_fatal(1, "Illegal PMC enum (%d) in new", i2);
-
- /* get "a" pmc first - calling function: pmc_new_noinit(...) */
- /* PMC* pmc_new_noinit(PARROT_INTERP, INTVAL base_type) */
- if (emitm_simm13_const(i2)) {
- emitm_mov_i(jit_info->native_ptr, i2, emitm_o(1));
- }
- else {
- emitm_sethi(jit_info->native_ptr, emitm_hi22(i2), emitm_o(1));
- emitm_or_i(jit_info->native_ptr, emitm_o(1), emitm_lo10(i2), emitm_o(1));
- }
-
- Parrot_jit_newfixup(jit_info);
- jit_info->arena.fixups->type = JIT_CALL30;
- jit_info->arena.fixups->param.fptr = D2FPTR(igniter);
-
- emitm_call_30(jit_info->native_ptr, 0);
- emitm_mov_r(jit_info->native_ptr, Parrot_jit_intrp, emitm_o(0));
-
- /* got a new pmc, sync mem and prepare vtable call (regs) */
- emitm_mov_r(jit_info->native_ptr, emitm_o(0), emitm_o(1));
- emitm_st_i(jit_info->native_ptr, emitm_o(0), Parrot_jit_regbase,
- Parrot_jit_regoff((int)®_PMC(interp, p1), interp));
-
- emitm_ld_i(jit_info->native_ptr, emitm_o(0), offsetof(struct PMC, vtable), XSR1);
- emitm_ld_i(jit_info->native_ptr, XSR1, offset, XSR1);
-
- emitm_jumpl_i(jit_info->native_ptr, XSR1, 0, emitm_o(7));
- emitm_mov_r(jit_info->native_ptr, Parrot_jit_intrp, emitm_o(0));
-}
-
-# endif /* NO_JIT_VTABLE_OPS */
-
-#else /* JIT_EMIT */
-
-# define REQUIRES_CONSTANT_POOL 0
-# define INT_REGISTERS_TO_MAP 6
-# define FLOAT_REGISTERS_TO_MAP 6
-
-# ifndef JIT_IMCC
-char intval_map[INT_REGISTERS_TO_MAP] =
- { emitm_l(1), emitm_l(2), emitm_l(3), emitm_l(4), emitm_l(5), emitm_l(6)
- };
-
-char floatval_map[] =
- { emitm_f(4), emitm_f(6), emitm_f(8), emitm_f(10), emitm_f(12), emitm_f(14)
- };
-# endif
-
-# define PRESERVED_INT_REGS 6
-# define PRESERVED_FLOAT_REGS 0
-
-#endif /* JIT_EMIT */
-
-/* XXX Hack [perl #37819] Unlike the functions above, this one apparently
- sometimes needs to be defined both in and out of the JIT_EMIT section.
- However, at this point, the Parrot_jit_regbase symbol is not
- defined, so we replace it with the integer 26 (which is what it
- expands to anyway.
-*/
-# define Parrot_jit_emit_get_base_reg_no(pc) 26 /*Parrot_jit_regbase */
-
-#endif /* PARROT_SUN4_JIT_EMIT_H_GUARD */
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit_debug.c
==============================================================================
--- trunk/src/jit_debug.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,409 +0,0 @@
-/*
-Copyright (C) 2001-2008, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/jit_debug.c - Write stabs file for JIT code
-
-=head1 SYNOPSIS
-
-When debugging JIT code with C<gdb>, do:
-
- add-symbol-file <file.o> 0
-
-=head1 DESCRIPTION
-
-Stabs is a file format for information that describes a program to a
-debugger.
-
-For more information see the stabs documentation at
-http://sources.redhat.com/gdb/current/onlinedocs/stabs_toc.html.
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include <parrot/parrot.h>
-#include "parrot/exec.h"
-#include "jit.h"
-
-#define N_GSYM "32" /* global variable */
-#define N_FNAME "34"
-#define N_FUN "36"
-#define N_STSYM "38" /* variable in data section */
-#define N_LCSYM "40" /* bss section */
-#define N_MAIN "42"
-#define N_ROSYM "44"
-#define N_PC "48"
-#define N_NSYMS "50"
-#define N_NOMAP "52"
-#define N_OBJ "56"
-#define N_OPT "60"
-#define N_RSYM "64" /* register variable */
-#define N_M2C "66"
-#define N_SLINE "68"
-#define N_DSLINE "70"
-#define N_BSLINE "72"
-#define N_BROWS "72"
-#define N_DEFD "74"
-#define N_FLINE "76"
-#define N_EHDECL "80"
-#define N_MOD2 "80"
-#define N_CATCH "84"
-#define N_SSYM "96"
-#define N_ENDM "98"
-#define N_SO "100" /* filename */
-#define N_LSYM "128" /* stack variable */
-#define N_BINCL "130"
-#define N_SOL "132"
-#define N_PSYM "160" /* parameter */
-#define N_EINCL "162"
-#define N_ENTRY "164"
-#define N_LBRAC "192"
-#define N_EXCL "194"
-#define N_SCOPE "196"
-#define N_RBRAC "224"
-#define N_BCOMM "226"
-#define N_ECOMM "228"
-#define N_ECOML "232"
-#define N_WITH "234"
-#define N_NBTEXT "240"
-#define N_NBDATA "242"
-#define N_NBBSS "244"
-#define N_NBSTS "246"
-#define N_NBLCS "248"
-
-#ifdef __GNUC__
-void Parrot_jit_debug(PARROT_INTERP);
-
-# define BIT_SIZE(t) ((int)(sizeof (t)*8))
-# define BYTE_SIZE(t) ((int)sizeof (t))
-# define BIT_OFFSET(str, field) ((int)(offsetof(str, field) * 8))
-
-typedef struct BaseTypes {
- const char *name;
- const char *spec;
-} BaseTypes;
-
-/*
-
-=item C<static void write_types(FILE *stabs, PARROT_INTERP)>
-
-Writes the types to C<stabs>.
-
-=cut
-
-*/
-
-static void
-write_types(FILE *stabs, PARROT_INTERP)
-{
- /* It would be create if this function would be auto generated */
- int i, j;
- /* borrowed from mono */
- static BaseTypes base_types[] = {
- {"Void", "(0,1)"},
- {"Char", ";-128;127;"},
- {"Byte", ";0;255;"},
- {"Int16", ";-32768;32767;"},
- {"UInt16", ";0;65535;"},
- {"Int32", ";0020000000000;0017777777777;"}, /* 5 */
- {"UInt32", ";0000000000000;0037777777777;"},
- {"Int64", ";01000000000000000000000;0777777777777777777777;"},
- {"UInt64", ";0000000000000;01777777777777777777777;"},
- {"Single", "r(0,8);4;0;"},
- {"Double", "r(0,8);8;0;"}, /* 10 */
- {"LongDouble", "r(0,8);12;0;"},
-# if INTVAL_SIZE == 4
- {"INTVAL", "(0,5);"}, /* 12 */
-# else
- {"INTVAL", "(0,7);"},
-# endif
-# if NUMVAL_SIZE == 8
- {"FLOATVAL", "(0,10);"}, /* 13 */
-# else
- {"FLOATVAL", "(0,11);"},
-# endif
- {"Ptr", "*(0,0);"},
- {"CharPtr", "*(0,1);"}, /* 15 */
- {0, 0}
- };
- for (i = 0; base_types[i].name; ++i) {
- if (! base_types[i].spec)
- continue;
- fprintf(stabs, ".stabs \"%s:t(0,%d)=", base_types[i].name, i);
- if (base_types[i].spec [0] == ';') {
- fprintf(stabs, "r(0,%d)%s\"", i, base_types[i].spec);
- }
- else {
- fprintf(stabs, "%s\"", base_types[i].spec);
- }
- fprintf(stabs, "," N_LSYM ",0,0,0\n");
- }
- fprintf(stabs, ".stabs \"STRING:t(0,%d)=*(0,%d)\""
- "," N_LSYM ",0,0,0\n", i, i+1);
- ++i;
- fprintf(stabs, ".stabs \"Parrot_String:T(0,%d)=s%d"
- "bufstart:(0,14),%d,%d;"
- "buflen:(0,6),%d,%d;"
- "flags:(0,12),%d,%d;"
- "bufused:(0,12),%d,%d;"
- "strstart:(0,15),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i++, BYTE_SIZE(STRING),
- BIT_OFFSET(STRING, _bufstart), BIT_SIZE(void*),
- BIT_OFFSET(STRING, _buflen), BIT_SIZE(size_t),
- BIT_OFFSET(STRING, flags), BIT_SIZE(UINTVAL),
- BIT_OFFSET(STRING, bufused), BIT_SIZE(UINTVAL),
- BIT_OFFSET(STRING, strstart), BIT_SIZE(void*));
-
- fprintf(stabs, ".stabs \"PMCType:T(0,%d)=e", i++);
- for (j = 0; j < interp->n_vtable_max; ++j) {
- if (interp->vtables[j] && interp->vtables[j]->whoami) {
- STRING *name = interp->vtables[j]->whoami;
- size_t items = fwrite(name->strstart, name->strlen, 1, stabs);
- if (!items)
- fprintf(stderr, "Error writing stabs!\n");
- fprintf(stabs, ":%d,", j);
- }
- }
-
- fprintf(stabs, ";\"," N_LSYM ",0,0,0\n");
-
- fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d"
- "flags:(0,12),%d,%d;"
- "vtable:*(0,%d),%d,%d;"
- "data:(0,14),%d,%d;"
- "_metadata:*(0,%d),%d,%d;"
- "_next_for_GC:*(0,%d),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(PMC),
- BIT_OFFSET(PMC, flags), BIT_SIZE(UINTVAL),
- i + 1, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*),
- BIT_OFFSET(PMC, data), BIT_SIZE(void*),
- i, BIT_OFFSET(PMC, _metadata), BIT_SIZE(void*),
- i, BIT_OFFSET(PMC, _next_for_GC), BIT_SIZE(void*));
-
- i++;
-
- /* someone can add some field to this one */
- fprintf(stabs, ".stabs \"VTABLE:T(0,%d)=s%d"
- "base_type:(0,12),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(_vtable),
- BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL));
-
- i++;
-}
-
-/*
-
-=item C<static void
-write_vars(FILE *stabs, PARROT_INTERP)>
-
-Writes the contents of the registers to C<stabs>.
-
-=cut
-
-*/
-
-static void
-write_vars(FILE *stabs, PARROT_INTERP)
-{
- int i;
- /* fake static var stabs */
- for (i = 0; i < NUM_REGISTERS; i++) {
- fprintf(stabs, ".stabs \"I%d:S(0,12)\"," N_STSYM ",0,0,%p\n", i,
- (char*)®_INT(interp, i));
- fprintf(stabs, ".stabs \"N%d:S(0,13)\"," N_STSYM ",0,0,%p\n", i,
- (char*)®_NUM(interp, i));
- fprintf(stabs, ".stabs \"S%d:S(0,16)\"," N_STSYM ",0,0,%p\n", i,
- (char*)®_STR(interp, i));
- fprintf(stabs, ".stabs \"P%d:S*(0,19)\"," N_STSYM ",0,0,%p\n", i,
- (char*)®_PMC(interp, i));
- }
-}
-
-/*
-
-=item C<static STRING *
-debug_file(PARROT_INTERP, STRING *file, const char *ext)>
-
-Returns C<file> with C<ext> appended.
-
-=cut
-
-*/
-
-static STRING *
-debug_file(PARROT_INTERP, STRING *file, const char *ext)
-{
- STRING *ret;
- ret = Parrot_str_copy(interp, file);
- ret = Parrot_str_append(interp, ret,
- string_make(interp, ext, strlen(ext), NULL,
- PObj_external_FLAG));
- return ret;
-}
-
-/*
-
-=item C<static void
-Parrot_jit_debug_stabs(PARROT_INTERP)>
-
-Writes the JIT debugging stabs.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_debug_stabs(PARROT_INTERP)
-{
- Parrot_jit_info_t *jit_info = interp->code->jit_info;
- STRING *file = NULL;
- STRING *pasmfile, *stabsfile, *ofile, *cmd;
- FILE *stabs;
- size_t i;
- int line;
- opcode_t lc;
- PackFile_Debug *debug;
-
- if (interp->code->debugs) {
- char *ext;
- char * const src = Parrot_str_to_cstring(interp,
- Parrot_debug_pc_to_filename(interp,
- interp->code->debugs, 0));
- pasmfile = string_make(interp, src, strlen(src), NULL,
- PObj_external_FLAG);
- file = Parrot_str_copy(interp, pasmfile);
- /* chop pasm/pir */
-
- ext = strrchr(src, '.');
- if (ext && STREQ(ext, ".pasm"))
- Parrot_str_chopn_inplace(interp, file, 4);
- else if (ext && STREQ(ext, ".pir"))
- Parrot_str_chopn_inplace(interp, file, 3);
- else if (!ext) /* EVAL_n */
- file = Parrot_str_append(interp, file,
- string_make(interp, ".", 1, NULL, PObj_external_FLAG));
-
- Parrot_str_free_cstring(src);
- }
- else {
- /* chop pbc */
- Parrot_str_chopn_inplace(interp, file, 3);
- pasmfile = debug_file(interp, file, "pasm");
- }
- stabsfile = debug_file(interp, file, "stabs.s");
- ofile = debug_file(interp, file, "o");
- {
- char *const temp = Parrot_str_to_cstring(interp, stabsfile);
- stabs = fopen(temp, "w");
- Parrot_str_free_cstring(temp);
- }
- if (stabs == NULL)
- return;
-
- {
- char * const temp = Parrot_str_to_cstring(interp, pasmfile);
- /* filename info */
- fprintf(stabs, ".data\n.text\n"); /* darwin wants it */
- fprintf(stabs, ".stabs \"%s\"," N_SO ",0,0,0\n", temp);
- Parrot_str_free_cstring(temp);
- }
- /* jit_func start addr */
- fprintf(stabs, ".stabs \"jit_func:F(0,1)\"," N_FUN ",0,1,%p\n",
- jit_info->arena.start);
-
- write_types(stabs, interp);
- write_vars(stabs, interp);
- /* if we don't have line numbers, emit dummys, assuming there are
- * no comments and spaces in source for testing
- */
-
- /* jit_begin */
- fprintf(stabs, ".stabn " N_SLINE ",0,1,0\n");
- line = 1;
- lc = 0;
- debug = interp->code->debugs;
- for (i = 0; i < interp->code->base.size; i++) {
- if (jit_info->arena.op_map[i].ptr) {
- op_info_t* op = &interp->op_info_table[
- interp->code->base.data[i]];
- if (interp->code->debugs) {
- if (lc >= (int)(debug->base.size))
- break;
- line = (int)debug->base.data[lc++];
- }
- fprintf(stabs, ".stabn " N_SLINE ",0,%d,%d /* %s */\n", line,
- (int)((char *)jit_info->arena.op_map[i].ptr -
- (char *)jit_info->arena.start),
- op->full_name);
- line++;
- }
- }
- /* eof */
- fprintf(stabs, ".stabs \"\"," N_FUN ",0,1,%p\n",
- (char *) jit_info->arena.size);
- fclose(stabs);
-
- /* run the stabs file through C<as> generating file.o */
- cmd = Parrot_sprintf_c(interp, "as %Ss -o %Ss", stabsfile, ofile);
-
- {
- char * const temp = Parrot_str_to_cstring(interp, cmd);
- int status = system(temp);
- if (status)
- fprintf(stderr, "Assembly failed: %d\n%s\n", status, temp);
- Parrot_str_free_cstring(temp);
- }
-}
-
-/*
-
-=item C<void
-Parrot_jit_debug(PARROT_INTERP)>
-
-Writes the JIT debugging stabs. Just calls C<Parrot_jit_debug_stabs()>.
-
-=cut
-
-*/
-
-void
-Parrot_jit_debug(PARROT_INTERP)
-{
- Parrot_jit_debug_stabs(interp);
-}
-
-
-#endif
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<src/jit.c>, F<include/parrot/jit.h>, F<docs/jit.pod>.
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Deleted: trunk/src/jit_debug_xcoff.c
==============================================================================
--- trunk/src/jit_debug_xcoff.c Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,375 +0,0 @@
-/*
-Copyright (C) 2001-2008, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/jit_debug_xcoff.c - XCOFF stabs for JIT
-
-=head1 DESCRIPTION
-
-Write an XCOFF stabs file for JIT code. This file is based on
-F<src/jit_debug.c>.
-
-Stabs is a file format for information that describes a program to a
-debugger.
-
-For more information see the stabs documentation at
-http://sources.redhat.com/gdb/current/onlinedocs/stabs_toc.html.
-
-=head2 Functions
-
-=over 4
-
-=cut
-
-*/
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include <parrot/parrot.h>
-#include "parrot/exec.h"
-#include "jit.h"
-
-#ifdef __IBMC__
-
-/* following from /usr/include/dbxstclass.h */
-# define C_GSYM "0x80" /* global variable */
-# define C_LSYM "0x81" /* stack variable */
-# define C_PSYM "0x82" /* parameter */
-# define C_RSYM "0x83" /* register variable */
-# define C_RPSYM "0x84"
-# define C_STSYM "0x85" /* variable in data section */
-# define C_TCSYM "0x86"
-# define C_BCOMM "0x87"
-# define C_ECOML "0x88"
-# define C_ECOMM "0x89"
-# define C_DECL "0x8c" /* type declaration */
-# define C_ENTRY "0x8d"
-# define C_FUN "0x8e"
-# define C_BSTAT "0x8f"
-# define C_ESTAT "0x90"
-
-void Parrot_jit_debug(PARROT_INTERP);
-
-# define BIT_SIZE(t) ((int)(sizeof (t)*8))
-# define BYTE_SIZE(t) ((int)sizeof (t))
-# define BIT_OFFSET(str, field) ((int)(offsetof((str), (field)) * 8))
-
-typedef struct BaseTypes {
- const char *name;
- const char *spec;
-} BaseTypes;
-
-/*
-
-=item C<static void write_types(FILE *stabs, PARROT_INTERP)>
-
-Writes the types to C<stabs>.
-
-=cut
-
-*/
-
-static void
-write_types(FILE *stabs, PARROT_INTERP)
-{
- int i, j;
- /* borrowed from mono */
- static BaseTypes base_types[] = {
- {"Char", "-6"},
- {"Byte", "-5"},
- {"Int16", "-3"},
- {"UInt16", "-7"},
- {"Int32", "-1"}, /* 5 */
- {"UInt32", "-8"},
- {"Int64", ";01000000000000000000000;0777777777777777777777;"},
- {"UInt64", ";0000000000000;01777777777777777777777;"},
- {"Single", "-12"},
- {"Double", "-13"}, /* 10 */
- {"LongDouble", "-14"},
-# if INTVAL_SIZE == 4
- {"INTVAL", "5;"}, /* 12 */
-# else
- {"INTVAL", "7;"},
-# endif
-# if NUMVAL_SIZE == 8
- {"FLOATVAL", "10;"}, /* 13 */
-# else
- {"FLOATVAL", "11;"},
-# endif
- {"Ptr", "*0;"},
- {"CharPtr", "*1;"}, /* 15 */
- {0, 0}
- };
- for (i = 0; base_types[i].name; ++i) {
- if (! base_types[i].spec)
- continue;
- fprintf(stabs, ".stabx \"%s:t%d=", base_types[i].name, i);
- if (base_types[i].spec [0] == ';') {
- fprintf(stabs, "r%d%s\"", i, base_types[i].spec);
- }
- else {
- fprintf(stabs, "%s\"", base_types[i].spec);
- }
- fprintf(stabs, ",0," C_DECL ",0\n");
- }
- fprintf(stabs, ".stabx \"STRING:t%d=*%d\""
- ",0," C_DECL ",0\n", i, i+1);
- ++i;
- fprintf(stabs, ".stabs \"Parrot_String:T(0,%d)=s%d"
- "bufstart:(0,14),%d,%d;"
- "buflen:(0,6),%d,%d;"
- "flags:(0,12),%d,%d;"
- "bufused:(0,12),%d,%d;"
- "strstart:(0,15),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i++, BYTE_SIZE(STRING),
- BIT_OFFSET(STRING, _bufstart), BIT_SIZE(void*),
- BIT_OFFSET(STRING, _buflen), BIT_SIZE(size_t),
- BIT_OFFSET(STRING, flags), BIT_SIZE(UINTVAL),
- BIT_OFFSET(STRING, bufused), BIT_SIZE(UINTVAL),
- BIT_OFFSET(STRING, strstart), BIT_SIZE(void*));
-
- fprintf(stabs, ".stabs \"PMCType:T(0,%d)=e", i++);
- for (j = 0; j < interp->n_vtable_max; ++j) {
- if (interp->vtables[j] && interp->vtables[j]->whoami) {
- STRING *name = interp->vtables[j]->whoami;
- size_t items = fwrite(name->strstart, name->strlen, 1, stabs);
- if (!items)
- fprintf(stderr, "Error writing stabs!\n");
- fprintf(stabs, ":%d,", j);
- }
- }
-
- fprintf(stabs, ";\"," N_LSYM ",0,0,0\n");
-
- fprintf(stabs, ".stabs \"PMC:T(0,%d)=s%d"
- "flags:(0,12),%d,%d;"
- "vtable:*(0,%d),%d,%d;"
- "data:(0,14),%d,%d;"
- "_metadata:*(0,%d),%d,%d;"
- "_next_for_GC:*(0,%d),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(PMC),
- BIT_OFFSET(PMC, flags), BIT_SIZE(UINTVAL),
- i + 1, BIT_OFFSET(PMC, vtable), BIT_SIZE(void*),
- BIT_OFFSET(PMC, data), BIT_SIZE(void*),
- i, BIT_OFFSET(PMC, _metadata), BIT_SIZE(void*),
- i, BIT_OFFSET(PMC, _next_for_GC), BIT_SIZE(void*));
-
- i++;
-
- /* some one can add some field to this one */
- fprintf(stabs, ".stabs \"VTABLE:T(0,%d)=s%d"
- "base_type:(0,12),%d,%d;"
- ";\""
- "," N_LSYM ",0,0,0\n", i, BYTE_SIZE(_vtable),
- BIT_OFFSET(VTABLE, base_type), BIT_SIZE(INTVAL));
-
- i++;
-
-}
-
-/*
-
-=item C<static void
-write_vars(FILE *stabs, PARROT_INTERP)>
-
-Writes the contents of the registers to C<stabs>.
-
-=cut
-
-*/
-
-static void
-write_vars(FILE *stabs, PARROT_INTERP)
-{
- int i;
- /* fake static var stabs */
- fprintf(stabs, ".bs parrot_jit_vars\n");
- for (i = 0; i < NUM_REGISTERS; i++) {
- fprintf(stabs, ".stabx \"I%d:V12\",0x%p," C_STSYM ",0\n", i,
- (char*)®_INT(interp, i));
- fprintf(stabs, ".stabx \"N%d:V13\",0x%p," C_STSYM ",0\n", i,
- (char*)®_NUM(interp, i));
- fprintf(stabs, ".stabx \"S%d:V16\",0x%p," C_STSYM ",0\n", i,
- (char*)®_STR(interp, i));
- fprintf(stabs, ".stabx \"P%d:V19\",0x%p," C_STSYM ",0\n", i,
- (char*)®_PMC(interp, i));
- }
- fprintf(stabs, ".es\n");
-}
-
-/*
-
-=item C<static STRING *
-debug_file(PARROT_INTERP, STRING *file, const char *ext)>
-
-Returns C<file> with C<ext> appended.
-
-=cut
-
-*/
-
-static STRING *
-debug_file(PARROT_INTERP, STRING *file, const char *ext)
-{
- STRING *ret;
- ret = Parrot_str_copy(interp, file);
- ret = Parrot_str_append(interp, ret,
- string_make(interp, ext, strlen(ext), NULL,
- PObj_external_FLAG));
- return ret;
-}
-
-/*
-
-=item C<static void
-Parrot_jit_debug_stabs(PARROT_INTERP)>
-
-Writes the JIT debugging stabs.
-
-=cut
-
-*/
-
-static void
-Parrot_jit_debug_stabs(PARROT_INTERP)
-{
- Parrot_jit_info_t *jit_info = interp->jit_info;
- STRING *file = NULL;
- STRING *pasmfile, *stabsfile, *ofile, *cmd;
- FILE *stabs;
- size_t i;
- int line;
- opcode_t lc;
-
- if (interp->code->debugs) {
- char *ext;
- char * const src = Parrot_str_to_cstring(interp,
- Parrot_debug_pc_to_filename(interp,
- interp->code->debugs, 0));
- pasmfile = string_make(interp, src, strlen(src), NULL,
- PObj_external_FLAG);
- file = Parrot_str_copy(interp, pasmfile);
- /* chop pasm/pir */
-
- ext = strrchr(src, '.');
- if (ext && STREQ(ext, ".pasm"))
- Parrot_str_chopn_inplace(interp, file, 4);
- else if (ext && STREQ(ext, ".pir"))
- Parrot_str_chopn_inplace(interp, file, 3);
- else if (!ext) /* EVAL_n */
- file = Parrot_str_append(interp, file,
- string_make(interp, ".", 1, NULL, PObj_external_FLAG));
- Parrot_str_free_cstring(src);
- }
- else {
- /* chop pbc */
- Parrot_str_chopn_inplace(interp, file, 3);
- pasmfile = debug_file(interp, file, "pasm");
- }
- stabsfile = debug_file(interp, file, "stabs.s");
- ofile = debug_file(interp, file, "o");
- {
- char * const temp = Parrot_str_to_cstring(interp, stabsfile);
- stabs = fopen(temp, "w");
- Parrot_str_free_cstring(temp);
- }
- if (stabs == NULL)
- return;
-
- {
- char * const temp = Parrot_str_to_cstring(interp, pasmfile);
- /* filename info */
- fprintf(stabs, ".file \"%s\"\n", temp);
- Parrot_str_free_cstring(temp);
- }
- /* declare function name */
- fprintf(stabs, ".jit_func:\n");
- /* jit_func start addr */
- fprintf(stabs, ".stabx \"jit_func:F1\",0x%p," C_FUN ",0\n",
- jit_info->arena.start);
- fprintf(stabs, ".function .jit_func,.jit_func,0,0\n");
- fprintf(stabs, ".bf 1\n");
-
- write_types(stabs, interp);
- write_vars(stabs, interp);
- /* if we don't have line numbers, emit dummys, assuming there are
- * no comments and spaces in source for testing
- */
-
- /* jit_begin */
- fprintf(stabs, ".line 1\n");
- line = 1;
- lc = 0;
- for (i = 0; i < interp->code->base.size; i++) {
- if (jit_info->arena.op_map[i].ptr) {
- op_info_t* op = &interp->op_info_table[
- interp->code->base.data[i]];
- if (interp->code->debugs) {
- line = (int)interp->code->debugs->base.data[lc++];
- }
- fprintf(stabs, ".line %d # 0x%p %s\n", line,
- (int)((char *)jit_info->arena.op_map[i].ptr -
- (char *)jit_info->arena.start),
- op->full_name);
- line++;
- }
- }
- /* eof */
- fprintf(stabs, ".stabx \"\",0x%p," C_FUN ",0\n",
- (char *) jit_info->arena.size);
- fprintf(stabs, ".ef %d\n", line);
- fclose(stabs);
- /* run the stabs file through C<as> generating file.o */
- cmd = Parrot_sprintf_c(interp, "as %Ss -o %Ss", stabsfile, ofile);
-
- {
- char * const temp = Parrot_str_to_cstring(interp, cmd);
- system(temp);
- Parrot_str_free_cstring(temp);
- }
-}
-
-/*
-
-=item C<void
-Parrot_jit_debug(PARROT_INTERP)>
-
-Writes the JIT debugging stabs. Just calls C<Parrot_jit_debug_stabs()>.
-
-=cut
-
-*/
-
-void
-Parrot_jit_debug(PARROT_INTERP)
-{
- Parrot_jit_debug_stabs(interp);
-}
-
-#endif
-
-
-/*
-
-=back
-
-=head1 SEE ALSO
-
-F<src/jit_debug.c>, F<src/jit.c>, F<src/jit.h>.
-
-=cut
-
-*/
-
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
Modified: trunk/src/packfile.c
==============================================================================
--- trunk/src/packfile.c Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/src/packfile.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -29,7 +29,6 @@
#include "parrot/extend.h"
#include "parrot/packfile.h"
#include "parrot/runcore_api.h"
-#include "jit.h"
#include "../compilers/imcc/imc.h"
#include "packfile.str"
#include "pmc/pmc_sub.h"
@@ -463,10 +462,6 @@
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
-#if EXEC_CAPABLE
- extern int Parrot_exec_run;
-#endif
-
/* offset not in ptr diff, but in byte */
#define OFFS(pf, cursor) ((pf) ? ((const char *)(cursor) - (const char *)((pf)->src)) : 0)
/**
@@ -2564,9 +2559,6 @@
ASSERT_ARGS(byte_code_destroy)
PackFile_ByteCode * const byte_code = (PackFile_ByteCode *)self;
-#ifdef HAS_JIT
- Parrot_destroy_jit(byte_code->jit_info);
-#endif
if (byte_code->prederef.code) {
Parrot_free_memalign(byte_code->prederef.code);
byte_code->prederef.code = NULL;
@@ -3698,10 +3690,6 @@
}
-#if EXEC_CAPABLE
-PackFile_Constant *exec_const_table;
-#endif
-
/*
=item C<const opcode_t * PackFile_ConstTable_unpack(PARROT_INTERP,
@@ -3753,13 +3741,7 @@
for (i = 0; i < self->const_count; i++) {
TRACE_PRINTF(("PackFile_ConstTable_unpack(): Unpacking constant %ld/%ld\n",
i, self->const_count));
-
-#if EXEC_CAPABLE
- if (Parrot_exec_run)
- self->constants[i] = &exec_const_table[i];
- else
-#endif
- self->constants[i] = PackFile_Constant_new(interp);
+ self->constants[i] = PackFile_Constant_new(interp);
cursor = PackFile_Constant_unpack(interp, self, self->constants[i],
cursor);
Modified: trunk/src/runcore/cores.c
==============================================================================
--- trunk/src/runcore/cores.c Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/src/runcore/cores.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -255,11 +255,6 @@
# include "parrot/oplib/core_ops_cgp.h"
#endif
-#if JIT_CAPABLE
-# include "parrot/exec.h"
-# include "../jit.h"
-#endif
-
#ifdef WIN32
# define getpid _getpid
#endif
@@ -1104,39 +1099,15 @@
*/
-#if EXEC_CAPABLE
- extern int Parrot_exec_run;
-#endif
-
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
static opcode_t *
runops_exec_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
{
ASSERT_ARGS(runops_exec_core)
-#if EXEC_CAPABLE
- opcode_t *code_start = interp->code->base.data;
- /* size in opcodes */
- UINTVAL code_size = interp->code->base.size;
- opcode_t *code_end = code_start + code_size;
-
-# if defined HAVE_COMPUTED_GOTO && defined USE_CGP
-# ifdef __GNUC__
-# ifdef PARROT_I386
- init_prederef(interp, PARROT_CGP_CORE);
-# endif
-# endif
-# endif
- if (Parrot_exec_run == 1)
- Parrot_exec(interp, pc, code_start, code_end);
- else
- run_native(interp, pc, code_start);
-
-#else
UNUSED(interp);
UNUSED(pc);
-#endif
return NULL;
}
Modified: trunk/src/runcore/main.c
==============================================================================
--- trunk/src/runcore/main.c Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/src/runcore/main.c Sat Sep 19 08:10:11 2009 (r41356)
@@ -40,10 +40,6 @@
#include "parrot/oplib/ops.h"
#include "main.str"
-#if JIT_CAPABLE
-# include "parrot/exec.h"
-# include "../jit.h"
-#endif
#ifdef HAVE_COMPUTED_GOTO
# include "parrot/oplib/core_ops_cg.h"
# include "parrot/oplib/core_ops_cgp.h"
@@ -496,93 +492,6 @@
}
-#if EXEC_CAPABLE
-
-/*
-
-=item C<void exec_init_prederef(PARROT_INTERP, void *prederef_arena)>
-
-C<< interp->op_lib >> = prederefed oplib
-
-The "normal" C<op_lib> has a copy in the interpreter structure - but get
-the C<op_code> lookup function from standard core prederef has no
-C<op_info_table>
-
-=cut
-
-*/
-
-void
-exec_init_prederef(PARROT_INTERP, ARGIN(void *prederef_arena))
-{
- ASSERT_ARGS(exec_init_prederef)
- Parrot_runcore_t *old_runcore = interp->run_core;
- Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "cgp"));
-
- load_prederef(interp, interp->run_core);
- interp->run_core = old_runcore;
-
- if (!interp->code->prederef.code) {
- void ** const temp = (void **)prederef_arena;
-
- interp->code->prederef.code = temp;
- /* TODO */
- }
-}
-
-#endif
-
-
-/*
-
-=item C<void * init_jit(PARROT_INTERP, opcode_t *pc)>
-
-Initializes JIT function for the specified opcode and returns it.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-void *
-init_jit(PARROT_INTERP, SHIM(opcode_t *pc))
-{
- ASSERT_ARGS(init_jit)
-#if JIT_CAPABLE
- opcode_t *code_start;
- UINTVAL code_size; /* in opcodes */
- opcode_t *code_end;
- Parrot_jit_info_t *jit_info;
-
- if (interp->code->jit_info)
- return ((Parrot_jit_info_t *)interp->code->jit_info)->arena.start;
-
- code_start = interp->code->base.data;
- code_size = interp->code->base.size;
- code_end = code_start + code_size;
-
-# if defined HAVE_COMPUTED_GOTO && PARROT_I386_JIT_CGP
-# ifdef __GNUC__
-# ifdef PARROT_I386
- init_prederef(interp, PARROT_CGP_CORE);
-# endif
-# endif
-# endif
-
- interp->code->jit_info =
- jit_info = parrot_build_asm(interp, code_start, code_end,
- NULL, JIT_CODE_FILE);
-
- return jit_info->arena.start;
-#else
- UNUSED(interp);
- return NULL;
-#endif
-
-}
-
-
/*
=item C<void prepare_for_run(PARROT_INTERP)>
Added: trunk/t/steps/auto/frames-01.t
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/steps/auto/frames-01.t Sat Sep 19 08:10:11 2009 (r41356)
@@ -0,0 +1,74 @@
+#! perl
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+# auto/frames-01.t
+
+use strict;
+use warnings;
+use Test::More tests => 9;
+use Carp;
+use Cwd;
+use File::Path qw( mkpath );
+use File::Temp qw( tempdir );
+use File::Spec;
+use lib qw( lib t/configure/testlib );
+use_ok('config::init::defaults');
+use_ok('config::auto::frames');
+use Parrot::Configure;
+use Parrot::Configure::Options qw( process_options );
+use Parrot::Configure::Test qw(
+ test_step_thru_runstep
+ rerun_defaults_for_testing
+ test_step_constructor_and_description
+);
+use IO::CaptureOutput qw( capture );
+
+
+my ($args, $step_list_ref) = process_options( {
+ argv => [ ],
+ mode => q{configure},
+} );
+
+my $conf = Parrot::Configure->new;
+
+my $serialized = $conf->pcfreeze();
+
+test_step_thru_runstep( $conf, q{init::defaults}, $args );
+
+my $pkg = q{auto::frames};
+$conf->add_steps($pkg);
+$conf->options->set( %{$args} );
+my $step = test_step_constructor_and_description($conf);
+
+################### DOCUMENTATION ###################
+
+=head1 NAME
+
+auto/frames-01.t - test auto::frames
+
+=head1 SYNOPSIS
+
+ % prove t/steps/auto/frames-01.t
+
+=head1 DESCRIPTION
+
+The files in this directory test functionality used by F<Configure.pl>.
+
+The tests in this file test auto::frames.
+
+=head1 AUTHOR
+
+Daniel Arbelo Arrocha
+
+=head1 SEE ALSO
+
+config::auto::frames, F<Configure.pl>.
+
+=cut
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
Modified: trunk/t/steps/auto/jit-01.t
==============================================================================
--- trunk/t/steps/auto/jit-01.t Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/t/steps/auto/jit-01.t Sat Sep 19 08:10:11 2009 (r41356)
@@ -5,7 +5,7 @@
use strict;
use warnings;
-use Test::More tests => 51;
+use Test::More tests => 9;
use Carp;
use Cwd;
use File::Path qw( mkpath );
@@ -16,12 +16,12 @@
use_ok('config::auto::jit');
use Parrot::Configure;
use Parrot::Configure::Options qw( process_options );
+use IO::CaptureOutput qw( capture );
use Parrot::Configure::Test qw(
test_step_thru_runstep
rerun_defaults_for_testing
test_step_constructor_and_description
);
-use IO::CaptureOutput qw( capture );
my ($args, $step_list_ref) = process_options( {
@@ -40,328 +40,6 @@
$conf->options->set( %{$args} );
my $step = test_step_constructor_and_description($conf);
-########### _check_jitcapability() ###########
-
-my $cwd = cwd();
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'bar';
- my $osname = 'baz';
- my $corejitdir = File::Spec->catdir ( $jitbase, $cpuarch );
- mkpath( $corejitdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- my $corejit = File::Spec->catfile( $jitbase, $cpuarch, q{core.jit} );
- is( $step->_check_jitcapability($corejit, $cpuarch, $osname, 8), 0,
- "Got expected value for _check_jitcapability(): no core.jit case");
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'bar';
- my $osname = 'baz';
- my $corejitdir = File::Spec->catdir ( $jitbase, $cpuarch );
- mkpath( $corejitdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- my $corejit = File::Spec->catfile( $jitbase, $cpuarch, q{core.jit} );
- open my $FH, '>', $corejit
- or croak "Unable to open handle to file for testing";
- print $FH qq{Hello, JIT\n};
- close $FH or croak "Unable to close handle to file for testing";
- is( $step->_check_jitcapability($corejit, $cpuarch, $osname, 8), 0,
- "Got expected value for _check_jitcapability(): no JIT on this architecture case");
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'bar';
- my $osname = 'baz';
- my $corejitdir = File::Spec->catdir ( $jitbase, $cpuarch );
- mkpath( $corejitdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- my $corejit = File::Spec->catfile( $jitbase, $cpuarch, q{core.jit} );
- open my $FH, '>', $corejit
- or croak "Unable to open handle to file for testing";
- print $FH qq{Hello, JIT\n};
- close $FH or croak "Unable to close handle to file for testing";
- my $orig = $step->{jit_is_working};
- $step->{jit_is_working} = { $cpuarch => 1 };
- is( $step->_check_jitcapability($corejit, $cpuarch, $osname, 8), 1,
- "Got expected value for _check_jitcapability(): mock JIT case");
- $step->{jit_is_working} = $orig;
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'i386';
- my $osname = 'darwin';
- my $corejitdir = File::Spec->catdir ( $jitbase, $cpuarch );
- mkpath( $corejitdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- my $corejit = File::Spec->catfile( $jitbase, $cpuarch, q{core.jit} );
- open my $FH, '>', $corejit
- or croak "Unable to open handle to file for testing";
- print $FH qq{Hello, JIT\n};
- close $FH or croak "Unable to close handle to file for testing";
- my $orig = $step->{jit_is_working};
- $step->{jit_is_working} = { $cpuarch => 1 };
- is( $step->_check_jitcapability($corejit, $cpuarch, $osname, 8), 0,
- "Got expected value for _check_jitcapability(): mock darwin-i386 case");
- $step->{jit_is_working} = $orig;
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'i386';
- my $osname = 'MSWin32';
- my $corejitdir = File::Spec->catdir ( $jitbase, $cpuarch );
- mkpath( $corejitdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- my $corejit = File::Spec->catfile( $jitbase, $cpuarch, q{core.jit} );
- open my $FH, '>', $corejit
- or croak "Unable to open handle to file for testing";
- print $FH qq{Hello, JIT\n};
- close $FH or croak "Unable to close handle to file for testing";
- my $orig = $step->{jit_is_working};
- $step->{jit_is_working} = { $cpuarch => 1 };
- is( $step->_check_jitcapability($corejit, $cpuarch, $osname, 4), 0,
- "Got expected value for _check_jitcapability(): mock single-float");
- $step->{jit_is_working} = $orig;
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-########### _handle_asm() ###########
-
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'bar';
- my $jitarchname = "${cpuarch}-baz";
- my $asmdir = File::Spec->catdir( $jitbase, $cpuarch );
- mkpath( $asmdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- mkpath( q{src}, { mode => 0755 } ) or croak "Unable to make testing directory";
-
- ok(auto::jit::_handle_asm( {
- conf => $conf,
- jitbase => $jitbase,
- cpuarch => $cpuarch,
- jitarchname => $jitarchname,
- } ), "_handle_asm() returned successfully");
- is( $conf->data->get( 'asmfun_o' ), q{},
- "Got expected value for asmfun_o: no asm case");
- $conf->data->set( asmfun_o => undef ); # reset for next test
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'bar';
- my $jitarchname = "${cpuarch}-baz";
- my $asmdir = File::Spec->catdir( $jitbase, $cpuarch );
- mkpath( $asmdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- mkpath( q{src}, { mode => 0755 } ) or croak "Unable to make testing directory";
-
- my $sjit =
- File::Spec->catfile( $jitbase, $cpuarch, qq{${jitarchname}.s} );
- open my $FH, '>', $sjit
- or croak "Unable to open handle to file for testing";
- print $FH qq{Hello, JIT\n};
- close $FH or croak "Unable to close handle to file for testing";
-
- ok(auto::jit::_handle_asm( {
- conf => $conf,
- jitbase => $jitbase,
- cpuarch => $cpuarch,
- jitarchname => $jitarchname,
- } ), "_handle_asm() returned successfully");
- is( $conf->data->get( 'asmfun_o' ), q{src/asmfun$(O)},
- "Got expected value for asmfun_o: sjit case");
- $conf->data->set( asmfun_o => undef ); # reset for next test
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'bar';
- my $jitarchname = "${cpuarch}-baz";
- my $asmdir = File::Spec->catdir( $jitbase, $cpuarch );
- mkpath( $asmdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- mkpath( q{src}, { mode => 0755 } ) or croak "Unable to make testing directory";
- my $asm = File::Spec->catfile( $jitbase, $cpuarch, q{asm.s} );
- open my $FH, '>', $asm
- or croak "Unable to open handle to file for testing";
- print $FH qq{Hello, JIT\n};
- close $FH or croak "Unable to close handle to file for testing";
-
- ok(auto::jit::_handle_asm( {
- conf => $conf,
- jitbase => $jitbase,
- cpuarch => $cpuarch,
- jitarchname => $jitarchname,
- } ), "_handle_asm() returned successfully");
- is( $conf->data->get( 'asmfun_o' ), q{src/asmfun$(O)},
- "Got expected value for asmfun_o: asm case");
- $conf->data->set( asmfun_o => undef ); # reset for next test
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-########### _first_probe_for_exec() ###########
-
-is( $step->_first_probe_for_exec( 'i386', 'foobar' ), 0,
- "Got expected value for _first_probe_for_exec");
-is( $step->_first_probe_for_exec( 'i386', 'openbsd' ), 1,
- "Got expected value for _first_probe_for_exec");
-is( $step->_first_probe_for_exec( 'foobar', 'openbsd' ), 0,
- "Got expected value for _first_probe_for_exec");
-
-########### _handle_execcapable() ###########
-
-if (! defined $conf->data->get('cpuarch') ) {
- $conf->data->set('cpuarch' => 1)
-}
-
-ok(auto::jit::_handle_execcapable($conf, 1),
- "_handle_execcapable() returned true value");
-is($conf->data->get('execcapable'), 1,
- "Got expected value for execcapable");
-# prepare for next test
-$conf->data->set('execcapable' => undef);
-
-ok(auto::jit::_handle_execcapable($conf, 0),
- "_handle_execcapable() returned true value");
-is($conf->data->get('execcapable'), 0,
- "Got expected value for execcapable");
-$conf->data->set('execcapable' => undef);
-
-########### _handle_exec_protect() ###########
-
-$conf->data->set( has_exec_protect => undef );
-auto::jit::_handle_exec_protect($conf, 0, 0);
-ok( ! defined $conf->data->get( 'has_exec_protect'),
- "'has_exec_protect' undefined, as expected");
-
-auto::jit::_handle_exec_protect($conf, 1, 0);
-is( $conf->data->get( 'has_exec_protect'), 1,
- "Got expected value for 'has_exec_protect'");
-$conf->data->set( has_exec_protect => undef );
-
-{
- my ($stdout, $stderr);
- capture(
- sub { auto::jit::_handle_exec_protect($conf, 0, 1); },
- \$stdout,
- \$stderr,
- );
- ok( ! defined $conf->data->get( 'has_exec_protect'),
- "'has_exec_protect' undefined, as expected");
- like($stdout, qr/no\)/, "Got expected verbose output");
- $conf->data->set( has_exec_protect => undef );
-}
-
-{
- my ($stdout, $stderr);
- capture(
- sub { auto::jit::_handle_exec_protect($conf, 1, 1); },
- \$stdout,
- \$stderr,
- );
- is( $conf->data->get( 'has_exec_protect'), 1,
- "Got expected value for 'has_exec_protect'");
- like($stdout, qr/yes\)/, "Got expected verbose output");
- $conf->data->set( has_exec_protect => undef );
-}
-
-$conf->replenish($serialized);
-
-($args, $step_list_ref) = process_options( {
- argv => [ q{--jitcapable=0}, q{--verbose} ],
- mode => q{configure},
-} );
-rerun_defaults_for_testing($conf, $args );
-$conf->add_steps($pkg);
-$conf->options->set( %{$args} );
-$step = test_step_constructor_and_description($conf);
-
-# Mock some values so that we can get to the point inside runstep() where the
-# command-line option for jitcapable is relevant.
-
-$cwd = cwd();
-{
- my $tdir = tempdir( CLEANUP => 1 );
- chdir $tdir or croak "Unable to change to temporary directory";
- my $jitbase = 'foo';
- my $cpuarch = 'i386';
- my $osname = 'darwin';
- my $corejitdir = File::Spec->catdir ( $jitbase, $cpuarch );
- mkpath( $corejitdir, { mode => 0755 } ) or croak "Unable to make testing directory";
- my $corejit = File::Spec->catfile( $jitbase, $cpuarch, q{core.jit} );
- open my $FH, '>', $corejit
- or croak "Unable to open handle to file for testing";
- print $FH qq{Hello, JIT\n};
- close $FH or croak "Unable to close handle to file for testing";
- my $orig = $step->{jit_is_working};
- $step->{jit_is_working} = { $cpuarch => 1 };
- $conf->data->set( cpuarch => $cpuarch );
- $conf->data->set( osname => $osname );
- {
- my ($stdout, $stderr, $ret);
- capture(
- sub { $ret = $step->runstep($conf); },
- \$stdout,
- \$stderr,
- );
- ok( $ret, "runstep() returned true value" );
- like($stdout, qr/yes|no/s, "Got expected verbose output");
- }
- $step->{jit_is_working} = $orig;
- $conf->data->set( cpuarch => undef );
- $conf->data->set( osname => undef );
-
- is( $conf->data->get( 'jitarchname' ), 'nojit',
- "Got expected value for jitarchname");
- is( $conf->data->get( 'jitcapable' ), 0,
- "Got expected value for jitcapable");
- is( $conf->data->get( 'execcapable' ), 0,
- "Got expected value for execcapable");
- is( $conf->data->get( 'cc_hasjit' ), '',
- "Got expected value for cc_hasjit");
- is( $conf->data->get( 'TEMP_jit_o' ), '',
- "Got expected value for TEMP_jit_o");
- is( $conf->data->get( 'TEMP_exec_h' ), '',
- "Got expected value for TEMP_exec_h");
- is( $conf->data->get( 'TEMP_exec_o' ), '',
- "Got expected value for TEMP_exec_o");
- is( $conf->data->get( 'TEMP_exec_dep' ), '',
- "Got expected value for TEMP_exec_dep");
- is( $step->result(), 'no',
- "Got expected result for no JIT");
-
- chdir $cwd or croak "Unable to change back to starting directory";
-}
-
-pass("Completed all tests in $0");
-
################### DOCUMENTATION ###################
=head1 NAME
Deleted: trunk/tools/build/jit2c.pl
==============================================================================
--- trunk/tools/build/jit2c.pl Sat Sep 19 08:10:11 2009 (r41355)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,530 +0,0 @@
-#! perl
-# Copyright (C) 2001-2006, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-tools/build/jit2c.pl - JIT to C
-
-=head1 SYNOPSIS
-
- % perl tools/build/jit2c.pl <cpu-architecture-name> src/jit_cpu.c
-
-=head1 DESCRIPTION
-
-This script creates F<src/jit_cpu.c>. It parses the JIT file for the
-specified CPU architecture type (F<src/jit/cpu-architecture-name/core.jit>).
-
-=cut
-
-use warnings;
-use strict;
-use lib 'lib';
-
-use Parrot::OpLib::core;
-use Parrot::Op;
-use Parrot::OpTrans::C;
-
-my $trans = Parrot::OpTrans::C->new;
-
-my %type_to_arg = (
- INT_CONST => 'ic',
- NUM_CONST => 'nc',
- PMC_CONST => 'pc',
- STRING_CONST => 'sc',
- STR_CONST => 'sc',
- INT_REG => 'i',
- NUM_REG => 'n',
- PMC_REG => 'p',
- STRING_REG => 's',
- STR_REG => 's',
-);
-
-my $core_numops = scalar @{$Parrot::OpLib::core::ops};
-my @core_opfunc = map { $_->func_name($trans) } @{$Parrot::OpLib::core::ops};
-my %opcodes;
-
-for ( @{$Parrot::OpLib::core::ops} ) {
- my $name = join( '_', $_->{NAME}, @{ $_->{ARGS} }[ 0 .. $#{ $_->{ARGS} } ] );
- $opcodes{$name} = $_->{CODE};
-}
-
-my $cpuarch = shift @ARGV;
-my $genfile = shift @ARGV;
-
-my ( $function, $body, $extern, $header, $asm, $precompiled );
-
-my %templates;
-
-my @jit_funcs;
-my $func_end;
-my ( $normal_op, $cpcf_op, $restart_op );
-my %argmaps;
-my $jit_cpu;
-
-if ( $genfile =~ /jit_cpu.c/ ) {
- $jit_cpu = 1;
- push @jit_funcs, "Parrot_jit_fn_info_t _op_jit[$core_numops] = {\n";
- $func_end = '_jit';
- $normal_op = 'Parrot_jit_normal_op';
- $cpcf_op = 'Parrot_jit_cpcf_op';
- $restart_op = 'Parrot_jit_restart_op';
- %argmaps = %Parrot::OpTrans::C::arg_maps;
-}
-else {
- $jit_cpu = ( $cpuarch eq 'i386' ) ? 0 : 1;
- push @jit_funcs, "Parrot_jit_fn_info_t op_exec[$core_numops] = {\n";
- $func_end = "_exec";
- $normal_op = "Parrot_exec_normal_op";
- $cpcf_op = "Parrot_exec_cpcf_op";
- $restart_op = "Parrot_exec_restart_op";
- %argmaps = (
- op => "cur_opcode[%ld]",
-
- i => "IREG(%ld)",
- n => "NREG(%ld)",
- p => "PREG(%ld)",
- s => "SREG(%ld)",
- k => "PREG(%ld)",
- ki => "IREG(%ld)",
-
- ic => "cur_opcode[%ld]",
- nc => "CONST(%ld)",
- pc => "CONST(%ld)",
- sc => "CONST(%ld)",
- kc => "CONST(%ld)",
- kic => "cur_opcode[%ld]"
- );
-}
-
-sub readjit {
- my $file = shift;
-
- my %ops;
- my $template;
-
- local $.;
-
- open my $IN, '<', $file or die "Can't open file $file: $!";
- while ( my $line = <$IN> ) {
- if ( $line =~ m/^#define/ ) {
- $line =~
-s/PREV_OP\s(..?)\s(\w+)/(jit_info->prev_op) && (*jit_info->prev_op $1 $opcodes{$2})/g;
- $header .= $line;
- next;
- }
-
- # ignore comment and empty lines
- next if $line =~ m/^;/ || $line !~ m/\S/;
-
- if ( !defined($function) && !defined($template) ) {
- if ( $line =~ m/TEMPLATE\s+(\w+)\s*{/ ) { #}
- $template = $1;
- $asm = qq{#line $. "$file"\n};
- next;
- }
- else {
- $line =~ m/(extern\s*)?(\w+)\s*{/; #}
- $extern = ( defined($1) ) ? 1 : 0;
- $function = $2;
- $asm = qq{#line $. "$file"\n};
- next;
- }
- }
- if ( $line =~ m/^}/ ) { #{
- # 1. check templates
- while ( my ( $t, $body ) = each %templates ) {
- if ( $asm =~ /$t\s+/ ) {
- my $tbody = $body;
- while ( $asm =~ s/\b(s(.).+?\2.*?\2)(?:\s+)?// ) {
- eval "\$tbody =~ ${1}g";
- die "error in template subst: $@\n" if $@;
- }
- $asm = $tbody;
-
- # reset iterator for next run
- keys %templates;
- last;
- }
- }
-
- # end of template definition?
- if ( defined($template) ) {
- $templates{$template} = $asm;
- $template = undef;
- next;
- }
-
- # no, end of function
-
- # then do other substitutions
- $asm =~ s/([\&\*])([a-zA-Z_]+)\[(\d+)\]/make_subs($1,$2,$3)/ge;
- $asm =~ s/NEW_FIXUP/Parrot_jit_newfixup(jit_info)/g;
- $asm =~ s/CUR_FIXUP/jit_info->arena.fixups/g;
- $asm =~ s/NATIVECODE/jit_info->native_ptr/g;
- $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;
-
- # 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_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/ );
- $asm =~
-s/(emitm_pushl_m[^\n]*CONST[^\n]*)/$1\\\n Parrot_exec_add_text_rellocation(jit_info->objfile, jit_info->native_ptr, RTYPE_DATA, "const_table", 0);/g;
- $asm =~ s/jit_emit_end/exec_emit_end/;
- }
- if ( ( $cpuarch eq 'ppc' ) && ( $genfile ne "src/jit_cpu.c" ) ) {
- $asm =~
-s/jit_emit_mov_ri_i\(jit_info->native_ptr, ISR([12]), &CONST\((\d)\)\);/load_nc(jit_info->native_ptr, ISR$1, ECONST($2));/g;
- }
-
- $asm =~ s/PUSH_MAPPED_REG\((\d)\)/Parrot_jit_push_registers(jit_info,$1)/g;
- $ops{$function} = [ $asm, $extern ];
- $function = undef;
- }
- unless ($jit_cpu) {
- $line =~ s/emitm_pushl_i/emitm_pushl_m/ if $line =~ /string/;
- }
- $asm .= $line;
- }
- return %ops;
-}
-
-use Parrot::Vtable;
-my $vtable;
-my $vjit = 0;
-
-sub vtable_num {
- my $meth = shift;
- unless ($vtable) {
- $vtable = parse_vtable();
- }
- my $i = 0;
- $vjit++;
- for my $entry ( @{$vtable} ) {
- next if $entry->[4] =~ /MMD_/; # RT#46915 all
- return $i if ( $entry->[1] eq $meth );
- $i++;
- }
- die("vtable not found for $meth\n");
- return;
-}
-
-my $jit_emit_n = ( $genfile =~ /jit_cpu.c/ ) ? 2 : 1;
-
-open my $JITCPU, '>', $genfile or die;
-
-print $JITCPU <<"END_C";
-/* ex: set ro:
- * !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
- *
- * This file is generated automatically from 'src/jit/$cpuarch/core.jit'
- * by $0.
- *
- * Any changes made here will be lost!
- *
- */
-
-/* HEADERIZER HFILE: none */
-/* HEADERIZER STOP */
-
-#include<parrot/parrot.h>
-#ifdef HAVE_COMPUTED_GOTO
-# include<parrot/oplib/core_ops_cgp.h>
-#endif
-#include"parrot/exec.h"
-#include"jit.h"
-#define JIT_EMIT $jit_emit_n
-
-/* Disable "truncation from 'const int' to 'char'" warning. */
-#if defined (_MSC_VER)
-#pragma warning(disable: 4305)
-#endif
-
-/*
- *define default jit_funcs, if architecture doesn't have these optimizations
- */
-#define Parrot_jit_vtable1_op Parrot_jit_normal_op
-#define Parrot_jit_vtable1r_op Parrot_jit_normal_op
-/*
- * the numbers correspond to the registers
- */
-#define Parrot_jit_vtable_111_op Parrot_jit_normal_op
-#define Parrot_jit_vtable_112_op Parrot_jit_normal_op
-#define Parrot_jit_vtable_221_op Parrot_jit_normal_op
-#define Parrot_jit_vtable_1121_op Parrot_jit_normal_op
-#define Parrot_jit_vtable_1123_op Parrot_jit_normal_op
-#define Parrot_jit_vtable_2231_op Parrot_jit_normal_op
-#define Parrot_jit_vtable_1r223_op Parrot_jit_normal_op
-#define Parrot_jit_vtable_1r332_op Parrot_jit_normal_op
-#define Parrot_jit_vtable_1r221_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
-#define Parrot_jit_vtable_newp_ic_op Parrot_jit_normal_op
-
-#define Parrot_jit_restart_op Parrot_jit_cpcf_op
-
-#include"jit_emit.h"
-
-#undef CONST
-#ifndef MAP
-# define MAP(i) jit_info->optimizer->map_branch[jit_info->op_i + (i)]
-#endif
-
-#define ROFFS_INT(x) REG_OFFS_INT(jit_info->cur_op[x])
-#define ROFFS_NUM(x) REG_OFFS_NUM(jit_info->cur_op[x])
-#define ROFFS_STR(x) REG_OFFS_STR(jit_info->cur_op[x])
-#define ROFFS_PMC(x) REG_OFFS_PMC(jit_info->cur_op[x])
-#
-END_C
-
-if ($jit_cpu) {
- print $JITCPU <<'END_C';
-#define IREG(i) REG_INT(interp, jit_info->cur_op[i])
-#define NREG(i) REG_NUM(interp, jit_info->cur_op[i])
-#define PREG(i) REG_PMC(interp, jit_info->cur_op[i])
-#define SREG(i) REG_STR(interp, jit_info->cur_op[i])
-#define CONST(i) interp->code->const_table->constants[jit_info->cur_op[i]]
-END_C
-}
-else {
- print $JITCPU <<'END_C';
-#define CONST(i) (int *)(jit_info->cur_op[i] * sizeof(PackFile_Constant) + offsetof(PackFile_Constant, u))
-#define RCONST(i) interp->code->const_table->constants[jit_info->cur_op[i]]
-#define CALL(f) Parrot_exec_add_text_rellocation_func(jit_info->objfile, jit_info->native_ptr, f); \
- emitm_calll(jit_info->native_ptr, EXEC_CALLDISP);
-
-END_C
-}
-if ( $cpuarch eq 'ppc' && $genfile ne 'src/jit_cpu.c' ) {
- print $JITCPU
- "#define ECONST(i) (int *)(jit_info->cur_op[i] * sizeof(PackFile_Constant) + 8)\n";
-}
-
-my %core_ops = readjit("src/jit/$cpuarch/core.jit");
-
-print $JITCPU $header if $header;
-
-my $njit = keys %core_ops;
-
-my $jit_fn_retn = 'void';
-my $jit_fn_params = '(Parrot_jit_info_t *jit_info, Interp *interp)';
-
-for my $i ( 0 .. $core_numops - 1) {
- $body = $core_ops{ $core_opfunc[$i] }[0];
- $extern = $core_ops{ $core_opfunc[$i] }[1];
-
- my $jit_func;
- my $op = $Parrot::OpLib::core::ops->[$i];
-
- $precompiled = 0;
- if ( !defined $body ) {
- $precompiled = 1;
- $extern = 1;
- my $opbody = $op->body;
-
- # retranslate VTABLE_macro to the expanded form
- $opbody =~ s/
- \bVTABLE_(\w+)
- \s*\(
- interp,\s*
- {{\@(\d)}}/
- {{\@$2}}->vtable->$1(interp, {{\@$2}}/x;
-
- if ( $op->full_name eq 'new_p_ic' ) {
- $jit_func = "Parrot_jit_vtable_newp_ic_op";
- $opbody =~ /vtable->(\w+)/;
- $extern = 2; # fake number
- #print "$jit_func $extern\n";
- }
-
- # jitable vtable funcs:
- # *) $1->vtable->{vtable}(interp, $1)
- elsif (
- $opbody =~ /
- ^(?:.*\.ops")\s+
- {{\@1}}->vtable->
- (\w+)
- \(interp,
- \s*
- {{\@1}}
- \);
- \s+{{\+=\d}}/xm
- )
- {
- $jit_func = 'Parrot_jit_vtable1_op';
- $extern = vtable_num($1);
-
- #print $op->full_name .": $jit_func $extern\n";
- }
-
- # *) $1 = $2->vtable->{vtable}(interp, $2)
- elsif (
- $opbody =~ /
- ^(?:.*\.ops")\s+
- {{\@1}}\s*=\s*
- {{\@2}}->vtable->
- (\w+)
- \(interp,
- \s*
- {{\@2}}
- \);
- \s+{{\+=\d}}/xm
- )
- {
- $jit_func = 'Parrot_jit_vtable1r_op';
- $extern = vtable_num($1);
-
- #print $op->full_name .": $jit_func $extern\n";
- }
-
- # *) $X->vtable->{vtable}(interp, $Y, $Z)
- elsif (
- $opbody =~ /
- ^(?:.*\.ops")\s+
- {{\@(\d)}}->vtable->
- (\w+)
- \(interp,
- \s*
- {{\@(\d)}},\s*{{\@(\d)}}
- \);
- \s+{{\+=\d}}/xm
- )
- {
- $jit_func = "Parrot_jit_vtable_$1$3$4_op";
- $extern = vtable_num($2);
-
- #print $op->full_name .": $jit_func $extern\n";
- }
-
- # *) $R = $X->vtable->{vtable}(interp, $Y, $Z)
- elsif (
- $opbody =~ /
- ^(?:.*\.ops")\s+
- {{\@(\d)}}\s*=\s*
- {{\@(\d)}}->vtable->
- (\w+)
- \(interp,
- \s*
- {{\@(\d)}},\s*{{\@(\d)}}
- \);
- \s+{{\+=\d}}/xm
- )
- {
- $jit_func = "Parrot_jit_vtable_$1r$2$4$5_op";
- $extern = vtable_num($3);
-
- #print $op->full_name .": $jit_func $extern\n";
- }
-
- # *) $X->vtable->{vtable}(interp, $Y, $Z, $A)
- elsif (
- $opbody =~ /
- ^(?:.*\.ops")\s+
- {{\@(\d)}}->vtable->
- (\w+)
- \(interp,
- \s*
- {{\@(\d)}},\s*{{\@(\d)}},\s*{{\@(\d)}}
- \);
- \s+{{\+=\d}}/xm
- )
- {
- $jit_func = "Parrot_jit_vtable_$1$3$4$5_op";
- $extern = vtable_num($2);
-
- #print $op->full_name .": $jit_func $extern\n";
- }
-
- # some specials
- 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 =~ /JUMP_RESTART/ ) {
- $jit_func = $restart_op;
- }
- elsif ( $op->jump ) {
- $jit_func = $cpcf_op;
- }
- else {
- $jit_func = $normal_op;
- }
- }
- else {
- $jit_func = "$core_opfunc[$i]$func_end";
- }
-
- unless ($precompiled) {
- print $JITCPU "\nstatic $jit_fn_retn\n"
- . $core_opfunc[$i]
- . $func_end
- . $jit_fn_params . "\n{\n"
- . $body . "}\n";
- }
- push @jit_funcs, "{ $jit_func, $extern }, " . "/* op $i: $core_opfunc[$i] */\n";
-}
-
-print $JITCPU @jit_funcs, "};\n";
-
-if ( $genfile =~ /jit_cpu.c/ ) {
- print $JITCPU <<"EOC";
- Parrot_jit_fn_info_t *op_jit = &_op_jit[0];
-
- extern int jit_op_count(void);
- int jit_op_count(void) { return $core_numops; }
-EOC
-}
-
-# append the C code coda
-print $JITCPU <<"EOC";
-
-/*
- * Local variables:
- * c-file-style: "parrot"
- * buffer-read-only: t
- * End:
- * vim: expandtab shiftwidth=4:
- */
-EOC
-
-print("jit2c: JITed $njit (+ $vjit vtable) of $core_numops ops\n");
-
-sub make_subs {
- my ( $ptr, $type, $index ) = @_;
-
- return ( ( $ptr eq '&' ? '&' : '' ) . sprintf( $argmaps{ $type_to_arg{$type} }, $index ) );
-}
-
-
-# Local Variables:
-# mode: cperl
-# cperl-indent-level: 4
-# fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:
Modified: trunk/tools/build/nativecall.pl
==============================================================================
--- trunk/tools/build/nativecall.pl Sat Sep 19 07:27:32 2009 (r41355)
+++ trunk/tools/build/nativecall.pl Sat Sep 19 08:10:11 2009 (r41356)
@@ -219,7 +219,6 @@
#include "pmc/pmc_nci.h"
#include "pmc/pmc_pointer.h"
#include "nci.str"
-#include "jit.h"
/* HEADERIZER HFILE: none */
/* HEADERIZER STOP */
@@ -231,122 +230,7 @@
* - if it returns NULL, the hardcoded version will do the job
*/
-#if defined(HAS_JIT) && defined(I386)
-# include "parrot/exec.h"
-# include "jit.h"
-# define CAN_BUILD_CALL_FRAMES
-#endif
-
-/*
- * helper funcs - get argument n
- */
-static INTVAL
-get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_int(st->val);
-}
-
-static FLOATVAL
-get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_num(st->val);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING*
-get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- /* TODO or act like below? */
- if (n >= st->src.n)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too few arguments passed to NCI function");
-
- Parrot_fetch_arg_nci(interp, st);
-
- return UVal_str(st->val);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static PMC*
-get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
- /*
- * excessive args are passed as NULL
- * used by e.g. MMD infix like __add
- */
- if (n < st->src.n)
- Parrot_fetch_arg_nci(interp, st);
- else
- UVal_pmc(st->val) = PMCNULL;
-
- return UVal_pmc(st->val);
-}
-
-#define GET_NCI_I(n) get_nci_I(interp, &st, n)
-#define GET_NCI_S(n) get_nci_S(interp, &st, n)
-#define GET_NCI_N(n) get_nci_N(interp, &st, n)
-#define GET_NCI_P(n) get_nci_P(interp, &st, n)
-
-/*
- * set return value
- */
-static void
-set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val)
-{
- Parrot_init_ret_nci(interp, st, "I");
- if (st->dest.i < st->dest.n) {
- UVal_int(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-static void
-set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val)
-{
- Parrot_init_ret_nci(interp, st, "N");
- if (st->dest.i < st->dest.n) {
- UVal_num(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-static void
-set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val)
-{
- Parrot_init_ret_nci(interp, st, "S");
- if (st->dest.i < st->dest.n) {
- UVal_str(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
-
-static void
-set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val)
-{
- Parrot_init_ret_nci(interp, st, "P");
- if (st->dest.i < st->dest.n) {
- UVal_pmc(st->val) = val;
- Parrot_convert_arg(interp, st);
- Parrot_store_arg(interp, st);
- }
-}
+#include "frame_builder.h"
#ifndef CAN_BUILD_CALL_FRAMES
/* All our static functions that call in various ways. Yes, terribly
More information about the parrot-commits
mailing list