Ticket #1105: merge.patch
File merge.patch, 139.9 KB (added by plobsing, 12 years ago) |
---|
-
MANIFEST
diff --git a/MANIFEST b/MANIFEST index 840b7f8..0f3bd1b 100644
a b 234 234 config/auto/env/test_unsetenv_c.in [] 235 235 config/auto/format.pm [] 236 236 config/auto/frames.pm [] 237 config/auto/frames/test_exec_cygwin_c.in []238 config/auto/frames/test_exec_linux_c.in []239 config/auto/frames/test_exec_openbsd_c.in []240 237 config/auto/gc.pm [] 241 238 config/auto/gc/test_c.in [] 242 239 config/auto/gcc.pm [] … … 258 255 config/auto/isreg.pm [] 259 256 config/auto/isreg/test_c.in [] 260 257 config/auto/jit.pm [] 258 config/auto/libjit.pm [] 259 config/auto/libjit/libjit_c.in [] 261 260 config/auto/memalign.pm [] 262 261 config/auto/memalign/test2_c.in [] 263 262 config/auto/memalign/test_c.in [] … … 310 309 config/gen/crypto.pm [] 311 310 config/gen/crypto/digest_pmc.in [] 312 311 config/gen/crypto/digest_t.in [] 312 config/gen/libjit.pm [] 313 config/gen/libjit/frame_builder_libjit_c.in [] 314 config/gen/libjit/frame_builder_libjit_h.in [] 313 315 config/gen/makefiles.pm [] 314 316 config/gen/makefiles/CFLAGS.in [] 315 317 config/gen/makefiles/data_json.in [] … … 1940 1942 t/steps/auto/inline-01.t [test] 1941 1943 t/steps/auto/isreg-01.t [test] 1942 1944 t/steps/auto/jit-01.t [test] 1945 t/steps/auto/libjit-01.t [test] 1943 1946 t/steps/auto/memalign-01.t [test] 1944 1947 t/steps/auto/msvc-01.t [test] 1945 1948 t/steps/auto/neg_0-01.t [test] … … 1964 1967 t/steps/gen/config_pm-01.t [test] 1965 1968 t/steps/gen/core_pmcs-01.t [test] 1966 1969 t/steps/gen/crypto-01.t [test] 1970 t/steps/gen/libjit-01.t [test] 1967 1971 t/steps/gen/makefiles-01.t [test] 1968 1972 t/steps/gen/opengl-01.t [test] 1969 1973 t/steps/gen/parrot_include-01.t [test] -
MANIFEST.SKIP
diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP index 38d117d..772755c 100644
a b 1 1 # ex: set ro: 2 2 # $Id$ 3 # generated by tools/dev/mk_manifest_and_skip.pl Sun Sep 27 09:00:392009 UT3 # generated by tools/dev/mk_manifest_and_skip.pl Sun Oct 18 15:34:28 2009 UT 4 4 # 5 5 # This file should contain a transcript of the svn:ignore properties 6 6 # of the directories in the Parrot subversion repository. (Needed for … … 653 653 ^src/extend_vtable\.c/ 654 654 ^src/fingerprint\.c$ 655 655 ^src/fingerprint\.c/ 656 ^src/frame_builder_libjit\.c$ 657 ^src/frame_builder_libjit\.c/ 658 ^src/frame_builder_libjit\.h$ 659 ^src/frame_builder_libjit\.h/ 656 660 ^src/glut_callbacks\.c$ 657 661 ^src/glut_callbacks\.c/ 658 662 ^src/install_config\.c$ -
MANIFEST.generated
diff --git a/MANIFEST.generated b/MANIFEST.generated index ff86d1e..ee0aad0 100644
a b 1 1 # $Id$ 2 # Please re-sort this file after *EVERY* modification 2 3 # See tools/dev/install_files.pl for documentation on the 3 4 # format of this file. 4 5 # Please re-sort this file after *EVERY* modification … … 7 8 blib/lib/libparrot.dylib [main]lib 8 9 blib/lib/libparrot.so.1.7.0 [main]lib 9 10 blib/lib/libparrot.so [main]lib 11 blib/lib/libparrot.so.1.6.0 [main]lib 10 12 compilers/data_json/data_json.pbc [data_json] 11 13 compilers/json/JSON.pbc [json] 12 14 compilers/json/JSON/grammar.pbc [json] … … 37 39 include/parrot/extend_vtable.h [main]include 38 40 include/parrot/feature.h [main]include 39 41 include/parrot/has_header.h [main]include 42 include/parrot/oplib/core_ops.h [main]include 40 43 include/parrot/oplib/core_ops_cg.h [main]include 41 44 include/parrot/oplib/core_ops_cgp.h [main]include 42 include/parrot/oplib/core_ops.h [main]include43 45 include/parrot/oplib/core_ops_switch.h [main]include 44 46 include/parrot/oplib/ops.h [main]include 45 47 include/parrot/pbcversion.h [devel]include … … 48 50 include/parrot/platform_limits.h [devel]include 49 51 include/parrot/vtable.h [main]include 50 52 install_config.fpmc [main]lib 51 src/install_config.o [main]lib 52 src/install_config.obj [main]lib 53 installable_parrot_config.exe [main]bin 53 installable_parrot [main]bin 54 installable_parrot.exe [main]bin 54 55 installable_parrot_config [main]bin 55 installable_parrot_ debugger.exe[main]bin56 installable_parrot_config.exe [main]bin 56 57 installable_parrot_debugger [main]bin 57 installable_parrot .exe[main]bin58 installable_parrot 59 installable_p bc_disassemble.exe[main]bin58 installable_parrot_debugger.exe [main]bin 59 installable_parrot_nqp [main]bin 60 installable_parrot_nqp.exe [main]bin 60 61 installable_pbc_disassemble [main]bin 61 installable_pbc_d ump.exe[main]bin62 installable_pbc_disassemble.exe [main]bin 62 63 installable_pbc_dump [main]bin 63 installable_pbc_ merge.exe[main]bin64 installable_pbc_dump.exe [main]bin 64 65 installable_pbc_merge [main]bin 65 installable_pbc_ to_exe.exe[main]bin66 installable_pbc_merge.exe [main]bin 66 67 installable_pbc_to_exe [main]bin 67 installable_parrot_nqp.exe [main]bin 68 installable_parrot_nqp [main]bin 68 installable_pbc_to_exe.exe [main]bin 69 69 lib/Parrot/Config/Generated.pm [devel]lib 70 libparrot.dll [main]bin71 libparrot.lib [main]bin72 70 lib/Parrot/OpLib/core.pm [devel]lib 73 lib/Parrot/Pmc2c/PCCMETHOD_BITS.pm [devel]lib74 71 lib/Parrot/PMC.pm [devel]lib 72 lib/Parrot/Pmc2c/PCCMETHOD_BITS.pm [devel]lib 73 libparrot.dll [main]bin 74 libparrot.lib [main]bin 75 75 parrot.pc [main]pkgconfig 76 76 runtime/parrot/dynext/digest_group.bundle [library] 77 77 runtime/parrot/dynext/digest_group.dll [library] … … 97 97 runtime/parrot/dynext/match_group.dll [library] 98 98 runtime/parrot/dynext/match_group.dylib [library] 99 99 runtime/parrot/dynext/match_group.so [library] 100 runtime/parrot/dynext/math_ops.so [library]101 100 runtime/parrot/dynext/math_ops.bundle [library] 102 101 runtime/parrot/dynext/math_ops.dll [library] 103 102 runtime/parrot/dynext/math_ops.dylib [library] 103 runtime/parrot/dynext/math_ops.so [library] 104 104 runtime/parrot/dynext/obscure_ops.bundle [library] 105 105 runtime/parrot/dynext/obscure_ops.dll [library] 106 106 runtime/parrot/dynext/obscure_ops.dylib [library] … … 145 145 runtime/parrot/include/warnings.pasm [main] 146 146 runtime/parrot/library/CGI/QueryHash.pbc [main] 147 147 runtime/parrot/library/Config/JSON.pbc [main] 148 runtime/parrot/library/config.pbc [main]149 runtime/parrot/library/config.pir [main]150 148 runtime/parrot/library/Crow.pbc [main] 149 runtime/parrot/library/Data/Dumper.pbc [main] 151 150 runtime/parrot/library/Data/Dumper/Base.pbc [main] 152 151 runtime/parrot/library/Data/Dumper/Default.pbc [main] 153 runtime/parrot/library/Data/Dumper.pbc [main]154 152 runtime/parrot/library/Data/Replace.pbc [main] 155 153 runtime/parrot/library/Digest/MD5.pbc [main] 156 runtime/parrot/library/dumper.pbc [main]157 154 runtime/parrot/library/Getopt/Obj.pbc [main] 158 155 runtime/parrot/library/HTTP/Daemon.pbc [main] 159 156 runtime/parrot/library/Iter.pbc [main] 160 157 runtime/parrot/library/JSON.pbc [main] 161 runtime/parrot/library/libpcre.pbc [main]162 runtime/parrot/library/Math/Random/mt19937ar.pbc [main]163 runtime/parrot/library/Math/Rand.pbc [main]164 158 runtime/parrot/library/MIME/Base64.pbc [main] 159 runtime/parrot/library/Math/Rand.pbc [main] 160 runtime/parrot/library/Math/Random/mt19937ar.pbc [main] 165 161 runtime/parrot/library/NCI/call_toolkit_init.pbc [main] 166 runtime/parrot/library/ncurses.pbc [main]167 runtime/parrot/library/OpenGL_funcs.pir [main]168 runtime/parrot/library/OpenGL_funcs.pbc [main]169 162 runtime/parrot/library/OpenGL.pbc [main] 163 runtime/parrot/library/OpenGL_funcs.pbc [main] 164 runtime/parrot/library/OpenGL_funcs.pir [main] 170 165 runtime/parrot/library/P6object.pbc [main] 171 runtime/parrot/library/Parrot/Capture_PIR.pbc [main] 172 runtime/parrot/library/Parrot/Coroutine.pbc [main] 173 runtime/parrot/library/Parrot/Exception.pbc [main] 174 runtime/parrot/library/Parrot/HLLCompiler.pbc [main] 175 runtime/parrot/library/parrotlib.pbc [main] 176 runtime/parrot/library/pcore.pbc [main] 177 runtime/parrot/library/pcre.pbc [main] 166 runtime/parrot/library/PCT.pbc [main] 178 167 runtime/parrot/library/PCT/Grammar.pbc [main] 179 168 runtime/parrot/library/PCT/HLLCompiler.pbc [main] 180 169 runtime/parrot/library/PCT/PAST.pbc [main] 181 runtime/parrot/library/P CT.pbc [main]170 runtime/parrot/library/PGE.pbc [main] 182 171 runtime/parrot/library/PGE/Dumper.pbc [main] 183 172 runtime/parrot/library/PGE/Glob.pbc [main] 184 173 runtime/parrot/library/PGE/Hs.pbc [main] 185 runtime/parrot/library/PGE.pbc [main]186 174 runtime/parrot/library/PGE/Perl6Grammar.pbc [main] 187 175 runtime/parrot/library/PGE/Text.pbc [main] 188 176 runtime/parrot/library/PGE/Util.pbc [main] 177 runtime/parrot/library/Parrot/Capture_PIR.pbc [main] 178 runtime/parrot/library/Parrot/Coroutine.pbc [main] 179 runtime/parrot/library/Parrot/Exception.pbc [main] 180 runtime/parrot/library/Parrot/HLLCompiler.pbc [main] 189 181 runtime/parrot/library/Protoobject.pbc [main] 190 182 runtime/parrot/library/Range.pbc [main] 191 183 runtime/parrot/library/Stream/Base.pbc [main] … … 197 189 runtime/parrot/library/Stream/Replay.pbc [main] 198 190 runtime/parrot/library/Stream/Sub.pbc [main] 199 191 runtime/parrot/library/Stream/Writer.pbc [main] 192 runtime/parrot/library/TGE.pbc [tge] 200 193 runtime/parrot/library/Tcl/Glob.pbc [main] 201 194 runtime/parrot/library/TclLibrary.pbc [main] 195 runtime/parrot/library/Test/Builder.pbc [main] 196 runtime/parrot/library/Test/Builder/Output.pbc [main] 202 197 runtime/parrot/library/Test/Builder/Test.pbc [main] 203 runtime/parrot/library/Test/Builder/Tester.pbc [main]204 198 runtime/parrot/library/Test/Builder/TestPlan.pbc [main] 205 runtime/parrot/library/Test/Builder/Output.pbc [main] 206 runtime/parrot/library/Test/Builder.pbc [main] 199 runtime/parrot/library/Test/Builder/Tester.pbc [main] 207 200 runtime/parrot/library/Test/Class.pbc [main] 208 201 runtime/parrot/library/Test/More.pbc [main] 209 runtime/parrot/library/TGE.pbc [tge] 210 runtime/parrot/library/uuid.pbc [main] 202 runtime/parrot/library/YAML/Dumper.pbc [main] 211 203 runtime/parrot/library/YAML/Dumper/Base.pmc [main] 212 204 runtime/parrot/library/YAML/Dumper/Default.pmc [main] 213 runtime/parrot/library/YAML/Dumper.pbc [main] 205 runtime/parrot/library/config.pbc [main] 206 runtime/parrot/library/config.pir [main] 207 runtime/parrot/library/dumper.pbc [main] 208 runtime/parrot/library/libpcre.pbc [main] 209 runtime/parrot/library/ncurses.pbc [main] 210 runtime/parrot/library/parrotlib.pbc [main] 211 runtime/parrot/library/pcore.pbc [main] 212 runtime/parrot/library/pcre.pbc [main] 213 runtime/parrot/library/uuid.pbc [main] 214 214 src/call_list.txt [devel]src 215 src/frame_builder_libjit.c [devel]src 216 src/frame_builder_libjit.h [devel]src 215 217 src/glut_callbacks.c [] 218 src/install_config.o [main]lib 219 src/install_config.obj [main]lib 216 220 src/jit_emit.h [] 217 221 src/nci.c [] 218 222 src/null_config.c [] -
config/auto/frames.pm
diff --git a/config/auto/frames.pm b/config/auto/frames.pm index f6f7d67..519b44e 100644
a b 40 40 41 41 sub _call_frames_buildable { 42 42 my $conf = shift; 43 44 my $osname = $conf->data->get('osname');45 my $cpuarch = $conf->data->get('cpuarch');46 my $nvsize = $conf->data->get('nvsize');47 43 my $can_build_call_frames; 48 44 49 45 if (defined $conf->options->get('buildframes')) { 50 46 $can_build_call_frames = $conf->options->get('buildframes'); 51 47 } 52 48 else { 53 # TT #1132 54 # Temporary disable build frames automatically. 55 #$can_build_call_frames = ($nvsize == 8 && $cpuarch eq 'i386' 56 # && $osname ne 'darwin'); 57 $can_build_call_frames = 0; 49 $can_build_call_frames = $conf->data->get('HAS_LIBJIT'); 58 50 } 59 51 return $can_build_call_frames; 60 52 } … … 63 55 my ($self, $conf, $can_build_call_frames) = @_; 64 56 if ( $can_build_call_frames ) { 65 57 $conf->data->set( 66 cc_build_call_frames => '-DCAN_BUILD_CALL_FRAMES', 58 cc_build_call_frames => '-DCAN_BUILD_CALL_FRAMES', 59 has_exec_protect => 1, 67 60 ); 68 # test for executable malloced memory69 my $osname = $conf->data->get( 'osname' );70 if ( -e "config/auto/frames/test_exec_${osname}_c.in" ) {71 $conf->cc_gen("config/auto/frames/test_exec_${osname}_c.in");72 eval { $conf->cc_build(); };73 if ($@) {74 $conf->data->set( has_exec_protect => 0 );75 }76 else {77 my $exec_protect_test = (78 $conf->cc_run(0) !~ /ok/ && $conf->cc_run(1) =~ /ok/79 );80 if ($exec_protect_test) {81 $conf->data->set( has_exec_protect => 1 );82 }83 else {84 $conf->data->set( has_exec_protect => 0 );85 }86 }87 $conf->cc_clean();88 }89 else {90 $conf->data->set( has_exec_protect => 0 );91 }92 61 $self->set_result( 'yes' ); 93 62 } 94 63 else { 95 $conf->data->set( 64 $conf->data->set(cc_build_call_frames => ''); 96 65 $self->set_result( 'no' ); 97 66 } 98 67 return 1; -
(a) a/config/auto/frames/test_exec_cygwin_c.in vs. (b) /dev/null
diff --git a/config/auto/frames/test_exec_cygwin_c.in b/config/auto/frames/test_exec_cygwin_c.in deleted file mode 100644 index 4871d23..0000000
a b 1 /*2 Copyright (C) 2008-2009, Parrot Foundation.3 $Id$4 5 test for exec privs6 */7 8 #include <stdio.h>9 #include <stdlib.h>10 #include <sys/mman.h>11 #include <limits.h>12 #include <errno.h>13 #include <malloc.h>14 #include <unistd.h>15 #include <string.h>16 #ifndef PAGE_SIZE17 # define PAGE_SIZE getpagesize()18 #endif19 #20 21 /*22 * c equiv:23 int t() {24 return 1;25 }26 */27 28 char code[] = {29 0xB8, 0x01, 0, 0, 0, /* movl $1, %eax */30 0xC3 /* ret */31 };32 33 typedef int (*pf)(void);34 35 int36 main(int argc, char *argv[])37 {38 pf t;39 char *p;40 int rc;41 int prot = PROT_READ;42 43 if (argc != 2) {44 fprintf(stderr, "usage: test 0 | 1\n");45 exit(1);46 }47 48 if (atoi(argv[1]))49 prot |= PROT_EXEC;50 51 p = memalign(PAGE_SIZE, PAGE_SIZE);52 memcpy(p, code, sizeof (code));53 54 t = (pf) p;55 rc = mprotect(p, PAGE_SIZE, prot);56 57 if (rc) {58 fprintf(stderr, "p = %p PAGE_SIZE = %d (0x%x)\n", p,59 PAGE_SIZE, PAGE_SIZE);60 perror("failure");61 }62 63 if (t() == 1)64 puts("ok");65 else66 return 1;67 68 return 0;69 }70 71 /*72 * Local variables:73 * c-file-style: "parrot"74 * End:75 * vim: expandtab shiftwidth=4:76 */ -
(a) a/config/auto/frames/test_exec_linux_c.in vs. (b) /dev/null
diff --git a/config/auto/frames/test_exec_linux_c.in b/config/auto/frames/test_exec_linux_c.in deleted file mode 100644 index 0090134..0000000
a b 1 /*2 Copyright (C) 2004-2009, Parrot Foundation.3 $Id$4 5 test for exec privs6 */7 8 #include <stdio.h>9 #include <stdlib.h>10 #include <sys/mman.h>11 #include <limits.h>12 #include <errno.h>13 #include <malloc.h>14 #include <unistd.h>15 #ifndef PAGE_SIZE16 # define PAGE_SIZE getpagesize()17 #endif18 19 /*20 * c equiv:21 int t() {22 return 1;23 }24 */25 26 char code[] = {27 0xB8, 0x01, 0, 0, 0, /* movl $1, %eax */28 0xC3 /* ret */29 };30 31 typedef int (*pf)(void);32 33 int34 main(int argc, char *argv[])35 {36 pf t;37 char *p;38 int rc;39 int prot = PROT_READ;40 41 if (argc != 2) {42 fprintf(stderr, "usage: test 0 | 1\n");43 exit(1);44 }45 if (atoi(argv[1]))46 prot |= PROT_EXEC;47 48 p = memalign(PAGE_SIZE, sizeof (code));49 memcpy(p, code, sizeof (code));50 t = (pf) p;51 rc = mprotect(p, PAGE_SIZE, prot);52 if (rc) {53 fprintf(stderr, "p = %p PAGE_SIZE = %d (0x%x)\n", p,54 PAGE_SIZE, PAGE_SIZE);55 perror("failure");56 }57 58 if (t() == 1)59 puts("ok");60 else61 return 1;62 63 return 0;64 }65 66 /*67 * Local variables:68 * c-file-style: "parrot"69 * End:70 * vim: expandtab shiftwidth=4:71 */ -
(a) a/config/auto/frames/test_exec_openbsd_c.in vs. (b) /dev/null
diff --git a/config/auto/frames/test_exec_openbsd_c.in b/config/auto/frames/test_exec_openbsd_c.in deleted file mode 100644 index 7f1826f..0000000
a b 1 /*2 Copyright (C) 2004-2009, Parrot Foundation.3 $Id$4 5 test for exec privs6 */7 8 #include <stdio.h>9 #include <stdlib.h>10 #include <sys/mman.h>11 #include <limits.h>12 #include <errno.h>13 #include <malloc.h>14 #include <unistd.h>15 #ifndef PAGE_SIZE16 # define PAGE_SIZE sysconf(_SC_PAGESIZE)17 #endif18 19 /*20 * c equiv:21 int t() {22 return 1;23 }24 */25 26 char code[] = {27 0xB8, 0x01, 0, 0, 0, /* movl $1, %eax */28 0xC3 /* ret */29 };30 31 typedef int (*pf)(void);32 33 int34 main(int argc, char *argv[])35 {36 pf t;37 char *p;38 int rc;39 int prot = PROT_READ;40 41 if (argc != 2) {42 fprintf(stderr, "usage: test 0 | 1\n");43 exit(1);44 }45 if (atoi(argv[1]))46 prot |= PROT_EXEC;47 48 p = malloc(PAGE_SIZE);49 memcpy(p, code, sizeof (code));50 t = (pf) p;51 rc = mprotect(p, PAGE_SIZE, prot);52 if (rc) {53 fprintf(stderr, "p = %p PAGE_SIZE = %d (0x%x)\n", p,54 PAGE_SIZE, PAGE_SIZE);55 perror("failure");56 }57 58 if (t() == 1)59 puts("ok");60 else61 return 1;62 63 return 0;64 }65 66 /*67 * Local variables:68 * c-file-style: "parrot"69 * End:70 * vim: expandtab shiftwidth=4:71 */ -
(a) /dev/null vs. (b) b/config/auto/libjit.pm
diff --git a/config/auto/libjit.pm b/config/auto/libjit.pm new file mode 100644 index 0000000..868cb1e
a b 1 # Copyright (C) 2009, Parrot Foundation. 2 # $Id$ 3 4 =head1 NAME 5 6 config/auto/libjit - Check whether LibJIT is installed 7 8 =head1 DESCRIPTION 9 10 Determines whether libjit is present is installed and functional on the system. 11 It is OK when it doesn't exist. 12 13 The libjit library implements just-in-time compilation functionality. Unlike 14 other JITs, this one is designed to be independent of any particular virtual 15 machine bytecode format or language. 16 17 libjit can be obtained from L<http://freshmeat.net/projects/libjit/> or through 18 your distribution's package manager. Developer documentation is available from 19 L<http://www.gnu.org/software/dotgnu/libjit-doc/libjit.html> 20 21 =cut 22 23 package auto::libjit; 24 25 use strict; 26 use warnings; 27 28 use base 'Parrot::Configure::Step'; 29 30 use Parrot::Configure::Utils ':auto'; 31 32 sub _init { 33 my $self = shift; 34 my %data = ( 35 description => 'Is LibJIT installed', 36 result => '', 37 ); 38 return \%data; 39 } 40 41 sub runstep { 42 my ($self, $conf) = @_; 43 44 my ($verbose, $without) = $conf->options->get( qw{ 45 verbose 46 without-libjit 47 }); 48 49 my ($has_libjit, $extra_libs); 50 if ($without) { 51 $has_libjit = 0; 52 } 53 else { 54 $extra_libs = $self->_select_lib( { 55 conf => $conf, 56 osname => $conf->data->get_p5('OSNAME'), 57 cc => $conf->data->get('cc'), 58 win32_nongcc => 'libjit.lib', 59 default => '-ljit', 60 } ); 61 62 $conf->cc_gen('config/auto/libjit/libjit_c.in'); 63 eval { $conf->cc_build('', $extra_libs) }; 64 if ($@) { 65 print "cc_build() failed: $@\n" if $verbose; 66 $has_libjit = 0; 67 } 68 else { 69 my $test; 70 eval { $test = $conf->cc_run(); }; 71 if ($@) { 72 print "cc_run() failed: $@\n" if $verbose; 73 $has_libjit = 0; 74 } 75 else { 76 $has_libjit = 77 $self->_evaluate_cc_run($test, $has_libjit, $verbose); 78 } 79 } 80 $conf->cc_clean(); 81 } 82 83 $conf->data->set( HAS_LIBJIT => $has_libjit ); 84 _handle_has_libjit($conf, $has_libjit, $extra_libs); 85 $self->set_result( $has_libjit ? 'yes' : 'no' ); 86 87 return 1; 88 } 89 90 sub _evaluate_cc_run { 91 my ($self, $test, $has_libjit, $verbose) = @_; 92 if ($test =~ m/^USES INTERPRETER: \d+/ ) { 93 $has_libjit = 1; 94 print " (yes) " if $verbose; 95 $self->set_result("yes"); 96 } 97 return $has_libjit; 98 } 99 100 sub _handle_has_libjit { 101 my ($conf, $has_libjit, $extra_libs) = @_; 102 if ($has_libjit) { 103 $conf->data->set( 104 libjit_has_alloca => ($conf->data->get('cpuarch') eq 'i386' ? '1' : '0'), 105 ); 106 $conf->data->add( ' ', libs => $extra_libs ); 107 } 108 else { 109 $conf->data->set( libjit_has_alloca => 0 ); 110 } 111 } 112 113 1; 114 115 # Local Variables: 116 # mode: cperl 117 # cperl-indent-level: 4 118 # fill-column: 100 119 # End: 120 # vim: expandtab shiftwidth=4: -
(a) /dev/null vs. (b) b/config/auto/libjit/libjit_c.in
diff --git a/config/auto/libjit/libjit_c.in b/config/auto/libjit/libjit_c.in new file mode 100644 index 0000000..6875b92
a b 1 /* 2 * Copyright (C) 2009, Parrot Foundation. 3 * $Id$ 4 */ 5 6 #include <stdlib.h> 7 #include <stdio.h> 8 #include <jit/jit.h> 9 10 int 11 main(int argc, char *argv[]) { 12 jit_init(); 13 printf("USES INTERPRETER: %i\n", jit_uses_interpreter()); 14 return EXIT_SUCCESS; 15 } 16 17 /* 18 * Local variables: 19 * c-file-style: "parrot" 20 * End: 21 * vim: expandtab shiftwidth=4: 22 */ -
(a) /dev/null vs. (b) b/config/gen/libjit.pm
diff --git a/config/gen/libjit.pm b/config/gen/libjit.pm new file mode 100644 index 0000000..cbe784a
a b 1 # Copyright (C) 2009, Parrot Foundation. 2 # $Id$ 3 4 =head1 NAME 5 6 config/gen/libjit.pm - LibJIT Code Generation 7 8 =head1 DESCRIPTION 9 10 Populate F<config/gen/frame_builder_libjit_h.in> and 11 F<configu/gen/frame_builder_libjit_c.in> with system appropriate 12 type information and automatically generated parrot function and 13 vtable jit wrappers. 14 15 =cut 16 17 package gen::libjit; 18 19 use strict; 20 use warnings; 21 22 use base 'Parrot::Configure::Step'; 23 24 use Parrot::Configure::Utils ':gen'; 25 26 27 sub _init { 28 my $self = shift; 29 my %data = ( 30 description => 'Generate LibJIT specific code', 31 result => '', 32 targets => { 33 frame_builder_h => 'src/frame_builder_libjit.h', 34 frame_builder_c => 'src/frame_builder_libjit.c', 35 }, 36 templates => { 37 frame_builder_h => 'config/gen/libjit/frame_builder_libjit_h.in', 38 frame_builder_c => 'config/gen/libjit/frame_builder_libjit_c.in', 39 }, 40 wrapped_vtables => { 41 get_integer => [ () => 'INTVAL' ], 42 set_integer_native => [ ('INTVAL') => 'void' ], 43 get_pointer => [ () => 'void_ptr' ], 44 set_pointer => [ ('void_ptr') => 'void' ], 45 }, 46 wrapped_funcs => { 47 get_nci_I => [ qw(void_ptr void_ptr sys_int) => 'INTVAL' ], 48 get_nci_N => [ qw(void_ptr void_ptr sys_int) => 'FLOATVAL' ], 49 get_nci_S => [ qw(void_ptr void_ptr sys_int) => 'void_ptr' ], 50 get_nci_P => [ qw(void_ptr void_ptr sys_int) => 'void_ptr' ], 51 get_nci_p => [ qw(void_ptr void_ptr sys_int) => 'void_ptr' ], 52 53 set_nci_I => [ qw(void_ptr void_ptr INTVAL) => 'void' ], 54 set_nci_N => [ qw(void_ptr void_ptr FLOATVAL) => 'void' ], 55 set_nci_S => [ qw(void_ptr void_ptr void_ptr) => 'void' ], 56 set_nci_P => [ qw(void_ptr void_ptr void_ptr) => 'void' ], 57 58 Parrot_str_new => 59 [ qw(void_ptr void_ptr UINTVAL) => 'void_ptr' ], 60 Parrot_str_to_cstring => 61 [ qw(void_ptr void_ptr) => 'void_ptr' ], 62 Parrot_str_free_cstring => 63 [ ('void_ptr') => 'void' ], 64 65 Parrot_init_arg_nci => 66 [ qw(void_ptr void_ptr void_ptr) => 'void_ptr' ], 67 pmc_new_noinit => 68 [ qw(void_ptr INTVAL) => 'void_ptr' ], 69 70 mem_sys_allocate => [ ('long') => 'void_ptr' ], 71 mem_sys_free => [ ('void_ptr') => 'void' ], 72 }, 73 ); 74 return \%data; 75 } 76 77 sub runstep { 78 my ($self, $conf) = @_; 79 80 my ($libjit_iv, $libjit_uv) = @{ 81 my $iv = $conf->data->get('iv') || ''; 82 { 83 short => [ 'jit_type_sys_short' , 'jit_type_sys_ushort' ], 84 int => [ 'jit_type_sys_int' , 'jit_type_sys_uint' ], 85 long => [ 'jit_type_sys_long' , 'jit_type_sys_ulong' ], 86 'long long' => [ 'jit_type_sys_longlong', 'jit_type_sys_ulonglong' ], 87 }->{$iv} 88 or die "Couldn't determine libjity type for intval of type '$iv'"; 89 }; 90 91 my $libjit_nv = do { 92 my $nv = $conf->data->get('nv') || ''; 93 { 94 float => 'jit_type_sys_float', 95 double => 'jit_type_sys_double', 96 'long double' => 'jit_type_sys_long_double', 97 }->{$nv} 98 or die "Couldn't determine libjity type for floatval of type '$nv'"; 99 }; 100 101 $conf->data->set( libjit_iv => $libjit_iv, 102 libjit_uv => $libjit_uv, 103 libjit_nv => $libjit_nv, ); 104 105 my @vtable_wrappers = 106 map {gen_vtable_wrapper($self, $_)} keys %{$self->{wrapped_vtables}}; 107 my @function_wrappers = 108 map {gen_function_wrapper($self, $_)} keys %{$self->{wrapped_funcs}}; 109 110 $conf->data->set( 111 TEMP_vtable_wrap_decls => 112 (join "\n", map {$_->{decl}} @vtable_wrappers), 113 TEMP_vtable_wrap_defns => 114 (join "\n", map {$_->{defn}} @vtable_wrappers), 115 TEMP_func_wrap_decls => 116 (join "\n", map {$_->{decl}} @function_wrappers), 117 TEMP_func_wrap_defns => 118 (join "\n", map {$_->{defn}} @function_wrappers) 119 ); 120 121 foreach my $t (keys %{$self->{targets}}) { 122 $conf->genfile($self->{templates}{$t}, $self->{targets}{$t}); 123 $conf->append_configure_log($t); 124 } 125 126 return 1; 127 } 128 129 sub gen_vtable_wrapper { 130 my ($self, $entry_name) = @_; 131 132 my $entry_sig = $self->{wrapped_vtables}{$entry_name}; 133 $_ = jit_prefix_type($_) for @$entry_sig; 134 135 my $ret_t = pop @$entry_sig; 136 my $arg_t = join ", ", @$entry_sig; 137 138 my $n_args = scalar @$entry_sig; 139 my $arg_decls_t = join ", ", map {'jit_value_t'} 1..$n_args; 140 my $arg_decls_v = join ", ", map {"jit_value_t v$_"} 1..$n_args; 141 my $arg_v = join ", ", map {"v$_"} 1..$n_args; 142 143 my $_arg_decls_t = $n_args ? ", $arg_decls_t" : ""; 144 my $_arg_decls_v = $n_args ? ", $arg_decls_v" : ""; 145 my $_arg_t = $n_args ? ", $arg_t" : ""; 146 my $_arg_v = $n_args ? ", $arg_v" : ""; 147 148 return { decl => <<DECL, defn => <<DEFN }; 149 jit_value_t 150 jit__vtable_$entry_name(jit_function_t, jit_value_t, jit_value_t $_arg_decls_t); 151 DECL 152 jit_value_t 153 jit__vtable_$entry_name(jit_function_t f, jit_value_t interp, jit_value_t self $_arg_decls_v) { 154 jit_type_t sig; 155 jit_value_t vtable, method; 156 jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr $_arg_t }; 157 jit_value_t arg_v[] = { interp, self $_arg_v }; 158 159 sig = jit_type_create_signature(jit_abi_cdecl, $ret_t, arg_t, $n_args + 2, 1); 160 161 vtable = jit_insn_load_relative(f, self, offsetof(PMC, vtable), jit_type_void_ptr); 162 method = jit_insn_load_relative(f, vtable, offsetof(VTABLE, $entry_name), jit_type_void_ptr); 163 164 return jit_insn_call_indirect(f, method, sig, arg_v, $n_args + 2, 0); 165 } 166 DEFN 167 } 168 169 sub gen_function_wrapper { 170 my ($self, $func_name) = @_; 171 172 my $func_sig = $self->{wrapped_funcs}{$func_name}; 173 $_ = jit_prefix_type($_) for @$func_sig; 174 175 my $ret_t = pop @$func_sig; 176 my $arg_t = join ", ", @$func_sig; 177 178 my $n_args = scalar @$func_sig; 179 my $arg_decls_t = join ", ", map {'jit_value_t'} 1..$n_args; 180 my $arg_decls_v = join ", ", map {"jit_value_t v$_"} 1..$n_args; 181 my $arg_v = join ", ", map {"v$_"} 1..$n_args; 182 183 return { decl => <<DECL, defn => <<DEFN }; 184 jit_value_t 185 jit__$func_name(jit_function_t, $arg_decls_t); 186 DECL 187 jit_value_t 188 jit__$func_name(jit_function_t f, $arg_decls_v) { 189 jit_type_t sig; 190 jit_type_t arg_t[] = { $arg_t }; 191 jit_value_t arg_v[] = { $arg_v }; 192 193 sig = jit_type_create_signature(jit_abi_cdecl, $ret_t, arg_t, $n_args, 1); 194 195 return jit_insn_call_native(f, "$func_name", (void *)&$func_name, sig, arg_v, $n_args, 0); 196 } 197 DEFN 198 } 199 200 sub jit_prefix_type { 201 my $type = shift; 202 if ($type !~ /[A-Z]/) { 203 return "jit_type_$_"; 204 } 205 else { 206 return "JIT_TYPE_$_"; 207 } 208 } 209 210 1; 211 212 # Local Variables: 213 # mode: cperl 214 # cperl-indent-level: 4 215 # fill-column: 100 216 # End: 217 # vim: expandtab shiftwidth=4: -
(a) /dev/null vs. (b) b/config/gen/libjit/frame_builder_libjit_c.in
diff --git a/config/gen/libjit/frame_builder_libjit_c.in b/config/gen/libjit/frame_builder_libjit_c.in new file mode 100644 index 0000000..e3d2e8a
a b 1 /* 2 Copyright (C) 2008-2009, Parrot Foundation. 3 $Id$ 4 */ 5 6 /* HEADERIZER HFILE: none */ 7 /* HEADERIZER STOP */ 8 9 #include "parrot/parrot.h" 10 #include "pmc/pmc_integer.h" 11 #include "pmc/pmc_unmanagedstruct.h" 12 #include "pmc/pmc_managedstruct.h" 13 #include "frame_builder.h" 14 #include "frame_builder_libjit.h" 15 16 #ifdef PARROT_HAS_LIBJIT 17 18 /* 19 20 =over 4 21 22 =item C<void *Parrot_jit_build_call_func(PARROT_INTERP, PMC *nci, STRING *sig, void **priv)> 23 24 Public interface to NCI function interface builder. 25 26 =cut 27 28 */ 29 30 void * 31 Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc, STRING *sig, void **priv) { 32 void *thunk; 33 char *sig_cstr; 34 35 sig_cstr = Parrot_str_to_cstring(interp, sig); 36 *priv = mem_sys_allocate(sizeof (struct jit_buffer_private_data)); 37 38 thunk = Parrot_jit_create_thunk(interp, sig_cstr, *priv); 39 40 Parrot_str_free_cstring(sig_cstr); 41 42 return thunk; 43 } 44 45 /* 46 47 =item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)> 48 49 This is a callback to implement the proper freeing semantics. It is called by 50 the ManagedStruct PMC as it is garbage collected. 51 52 =cut 53 54 */ 55 56 void 57 Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv) 58 { 59 struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv; 60 jit_context_destroy(jit->ctx); 61 mem_sys_free(jit->sig); 62 mem_sys_free(priv); 63 } 64 65 /* 66 67 =item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)> 68 69 This is a callback to implement the proper cloning semantics for jit buffers. 70 It is called by the ManagedStruct PMC's clone() function. 71 72 =back 73 74 =cut 75 76 */ 77 78 PMC * 79 Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv) 80 { 81 PMC * const rv = pmc_new(interp, pmc->vtable->base_type); 82 83 VTABLE_init(interp, rv); 84 /* copy the attributes */ 85 { 86 void (*tmpfreefunc)(PARROT_INTERP, void*, void*); 87 GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc); 88 SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc); 89 } 90 { 91 PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*); 92 GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc); 93 SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc); 94 } 95 96 /* compile a clone of the function */ 97 if (PARROT_MANAGEDSTRUCT(pmc)->ptr) { 98 void *rv_priv; 99 struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv; 100 STRING *sig = Parrot_str_new(interp, jit->sig, 0); 101 PARROT_MANAGEDSTRUCT(rv)->ptr = Parrot_jit_build_call_func(interp, rv, sig, &rv_priv); 102 } 103 104 return rv; 105 } 106 107 /* 108 * JIT functions 109 */ 110 111 void * 112 Parrot_jit_create_thunk(PARROT_INTERP, char *sig, void *priv) { 113 struct jit_buffer_private_data *p; 114 jit_function_t f; 115 jit_value_t jit_interp, jit_nci_pmc, jit_pcc_sig; 116 jit_value_t jit_func, jit_st; 117 118 /* populate private data */ 119 p = (struct jit_buffer_private_data*)priv; 120 p->ctx = jit_context_create(); 121 p->sig = mem_sys_strdup(sig); 122 123 /* start compiling */ 124 jit_context_build_start(p->ctx); 125 126 /* start JIT function */ 127 { 128 jit_type_t arg_types[] = { 129 jit_type_void_ptr, /* interp */ 130 jit_type_void_ptr, /* nci_pmc */ 131 jit_type_void_ptr /* pcc_sig */ 132 }; 133 jit_type_t f_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_types, 3, 1); 134 f = jit_function_create(p->ctx, f_sig); 135 } 136 137 /* get the incomming args */ 138 jit_interp = jit_value_get_param(f, 0); 139 jit_nci_pmc = jit_value_get_param(f, 1); 140 jit_pcc_sig = jit_value_get_param(f, 2); 141 142 /* get the wrapped function */ 143 jit_func = jit__vtable_get_pointer(f, jit_interp, jit_nci_pmc); 144 145 /* allocate call_state */ 146 { 147 jit_value_t sizeof_call_state 148 = jit_value_create_nint_constant(f, jit_type_sys_int, sizeof (call_state)); 149 jit_st = JIT_ALLOCA(f, sizeof_call_state); 150 } 151 152 /* init pcc */ 153 jit__Parrot_init_arg_nci(f, jit_interp, jit_st, jit_pcc_sig); 154 155 /* get the outgoing args */ 156 { 157 int nargs = strlen(sig) - 1; 158 159 jit_type_t jit_args_t[nargs]; 160 jit_value_t jit_args_v[nargs]; 161 jit_value_t jit_regs[nargs]; 162 163 Parrot_jit_parse_sig_args_pre(interp, sig, nargs, f, jit_interp, jit_st, 164 jit_args_t, jit_args_v, jit_regs); 165 166 /* get the return type */ 167 { 168 jit_type_t ret_t; 169 jit_value_t ret_v; 170 171 ret_t = Parrot_jit_parse_sig_ret_pre(interp, sig); 172 173 /* make the call */ 174 { 175 jit_type_t jit_sig 176 = jit_type_create_signature(jit_abi_cdecl, ret_t, jit_args_t, nargs, 1); 177 ret_v = jit_insn_call_indirect(f, jit_func, jit_sig, jit_args_v, nargs, 0); 178 } 179 180 /* get the incomming return */ 181 Parrot_jit_parse_sig_ret_post(interp, sig, f, jit_interp, jit_st, ret_v); 182 } 183 184 /* clean up args */ 185 Parrot_jit_parse_sig_args_post(interp, sig, nargs, f, jit_interp, jit_args_v, jit_regs); 186 } 187 188 /* deallocate call_state */ 189 JIT_ALLOCA_FREE(f, jit_st); 190 191 /* end JIT function */ 192 jit_insn_return(f, NULL); 193 194 /* compile to native callable func poitner */ 195 jit_function_compile(f); 196 jit_context_build_end(p->ctx); 197 198 return jit_function_to_closure(f); 199 } 200 201 void 202 Parrot_jit_parse_sig_args_pre(PARROT_INTERP, char *sig, int nargs, 203 jit_function_t f, jit_value_t jinterp, jit_value_t st, 204 jit_type_t *arg_types, 205 jit_value_t *arg_vals, jit_value_t *arg_regs) { 206 int i, j; 207 208 sig += 1; /* ignore return character */ 209 210 for (i = 0, j = 0; i < nargs; i++) { 211 char c; 212 jit_type_t t1; 213 jit_value_t v1, v2, v3, v4; 214 switch (c = sig[i]) { 215 case 'I': 216 t1 = JIT_TYPE_INTVAL; 217 read_int_reg: 218 arg_types[i] = t1; 219 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 220 v2 = jit__get_nci_I(f, jinterp, st, v1); 221 arg_regs[j++] = arg_vals[i] = v2; 222 break; 223 case 'c': 224 t1 = jit_type_sys_char; 225 goto read_int_reg; 226 case 's': 227 t1 = jit_type_sys_short; 228 goto read_int_reg; 229 case 'i': 230 t1 = jit_type_sys_int; 231 goto read_int_reg; 232 case 'l': 233 t1 = jit_type_sys_long; 234 goto read_int_reg; 235 236 case 'N': 237 t1 = JIT_TYPE_FLOATVAL; 238 read_float_reg: 239 arg_types[i] = t1; 240 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 241 v2 = jit__get_nci_N(f, jinterp, st, v1); 242 arg_regs[j++] = arg_vals[i] = v2; 243 break; 244 case 'f': 245 t1 = jit_type_sys_float; 246 goto read_float_reg; 247 case 'd': 248 t1 = jit_type_sys_double; 249 goto read_float_reg; 250 251 case 'S': 252 arg_types[i] = jit_type_void_ptr; 253 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 254 v2 = jit__get_nci_S(f, jinterp, st, v1); 255 arg_regs[j++] = arg_vals[i] = v2; 256 break; 257 258 case 't': 259 arg_types[i] = jit_type_void_ptr; 260 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 261 v2 = jit__get_nci_S(f, jinterp, st, v1); 262 arg_regs[j++] = v2; 263 arg_vals[i] = jit__Parrot_str_to_cstring(f, jinterp, v2); 264 break; 265 266 case 'b': 267 arg_types[i] = jit_type_void_ptr; 268 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 269 v2 = jit__get_nci_S(f, jinterp, st, v1); 270 arg_regs[j++] = v2; 271 arg_vals[i] = jit__Buffer_bufstart(f, v2); 272 break; 273 case 'B': 274 arg_types[i] = jit_type_void_ptr; 275 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 276 v2 = jit__get_nci_S(f, jinterp, st, v1); 277 arg_regs[j++] = v2; 278 v3 = jit__Parrot_str_to_cstring(f, jinterp, v2); 279 jit_value_set_addressable(v3); 280 arg_vals[i] = jit_insn_address_of(f, v3); 281 break; 282 283 case 'p': 284 arg_types[i] = jit_type_void_ptr; 285 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 286 v2 = jit__get_nci_p(f, jinterp, st, v1); 287 arg_regs[j++] = arg_vals[i] = v2; 288 break; 289 case 'P': 290 case 'O': 291 case '@': 292 arg_types[i] = jit_type_void_ptr; 293 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 294 v2 = jit__get_nci_P(f, jinterp, st, v1); 295 arg_regs[j++] = arg_vals[i] = v2; 296 break; 297 case '2': 298 t1 = jit_type_sys_short; 299 goto call_get_integer; 300 case '3': 301 t1 = jit_type_sys_int; 302 goto call_get_integer; 303 case '4': 304 t1 = jit_type_sys_long; 305 call_get_integer: 306 arg_types[i] = jit_type_void_ptr; 307 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 308 v2 = jit__get_nci_P(f, jinterp, st, v1); 309 arg_regs[j++] = v2; 310 v3 = jit__vtable_get_integer(f, jinterp, v2); 311 v4 = jit_value_create(f, t1); 312 jit_value_set_addressable(v4); 313 jit_insn_store(f, v4, v3); 314 arg_vals[i] = jit_insn_address_of(f, v4); 315 break; 316 317 case 'V': 318 arg_types[i] = jit_type_void_ptr; 319 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); 320 v2 = jit__get_nci_P(f, jinterp, st, v1); 321 arg_regs[j++] = v2; 322 v3 = jit__vtable_get_pointer(f, jinterp, v2); 323 v4 = jit_value_create(f, jit_type_void_ptr); 324 jit_value_set_addressable(v4); 325 jit_insn_store(f, v4, v3); 326 arg_vals[i] = jit_insn_address_of(f, v4); 327 break; 328 329 case '0': 330 arg_types[i] = jit_type_void_ptr; 331 arg_vals[i] = jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL); 332 break; 333 334 case 'J': 335 arg_types[i] = jit_type_void_ptr; 336 arg_vals[i] = jinterp; 337 break; 338 339 case 'U': 340 /* TODO */ 341 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 342 "arg type 'U' not yet implemented"); 343 return; 344 345 default: 346 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 347 "unkown arg type '%c'", c); 348 return; 349 } 350 } 351 } 352 353 jit_type_t 354 Parrot_jit_parse_sig_ret_pre(PARROT_INTERP, char *sig) { 355 char c; 356 switch (c = sig[0]) { 357 case 'v': 358 return jit_type_void; 359 360 case 'I': 361 return JIT_TYPE_INTVAL; 362 case 'c': 363 return jit_type_sys_char; 364 case 's': 365 return jit_type_sys_short; 366 case 'i': 367 return jit_type_sys_int; 368 case 'l': 369 return jit_type_sys_long; 370 371 case 'N': 372 return JIT_TYPE_FLOATVAL; 373 case 'f': 374 return jit_type_sys_float; 375 case 'd': 376 return jit_type_sys_double; 377 378 case 'S': 379 case 't': 380 return jit_type_void_ptr; 381 382 case 'p': 383 case 'P': 384 return jit_type_void_ptr; 385 386 case 'U': 387 /* TODO */ 388 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 389 "return type 'U' not yet implemented"); 390 return NULL; 391 default: 392 /* FAIL */ 393 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 394 "unknown return type '%c'", c); 395 return NULL; 396 } 397 } 398 399 void 400 Parrot_jit_parse_sig_ret_post(PARROT_INTERP, char *sig, 401 jit_function_t f, jit_value_t jinterp, jit_value_t st, 402 jit_value_t retval) { 403 jit_type_t t1; 404 jit_value_t v1, v2, v3; 405 switch (sig[0]) { 406 case 'v': 407 break; 408 409 case 'I': 410 case 'c': 411 case 's': 412 case 'i': 413 case 'l': 414 jit__set_nci_I(f, jinterp, st, retval); 415 break; 416 417 case 'N': 418 case 'f': 419 case 'd': 420 jit__set_nci_N(f, jinterp, st, retval); 421 break; 422 423 case 'S': 424 jit__set_nci_S(f, jinterp, st, retval); 425 break; 426 case 't': 427 v1 = jit_value_create_nint_constant(f, jit_type_sys_int, 0); 428 v2 = jit__Parrot_str_new(f, jinterp, retval, v1); 429 jit__set_nci_S(f, jinterp, st, v2); 430 break; 431 432 case 'P': 433 jit__set_nci_P(f, jinterp, st, retval); 434 break; 435 case 'p': 436 v1 = jit_value_create_intval_constant(f, enum_class_UnManagedStruct); 437 v2 = jit__pmc_new_noinit(f, jinterp, v1); 438 jit__vtable_set_pointer(f, jinterp, v2, retval); 439 jit__set_nci_P(f, jinterp, st, v2); 440 break; 441 case '2': 442 t1 = jit_type_sys_short; 443 goto create_int_pmc; 444 case '3': 445 t1 = jit_type_sys_int; 446 goto create_int_pmc; 447 case '4': 448 t1 = jit_type_sys_long; 449 create_int_pmc: 450 v1 = jit_insn_load_relative(f, retval, 0, t1); 451 v2 = jit_value_create_intval_constant(f, enum_class_Integer); 452 v3 = jit__pmc_new_noinit(f, jinterp, v2); 453 jit__vtable_set_integer_native(f, jinterp, v3, v1); 454 jit__set_nci_P(f, jinterp, st, v3); 455 break; 456 457 case 'U': 458 /* ignore (failed elsewhere) */ 459 break; 460 461 default: 462 /* ignore (failed elsewhere) */ 463 break; 464 } 465 } 466 467 void 468 Parrot_jit_parse_sig_args_post(PARROT_INTERP, char *sig, int nargs, 469 jit_function_t f, jit_value_t jinterp, 470 jit_value_t *args, jit_value_t *regs) { 471 int i, j; 472 473 sig += 1; 474 475 for (i = 0, j = 0; i < nargs; i++) { 476 jit_type_t t1; 477 jit_value_t v1; 478 switch (sig[i]) { 479 case 't': 480 jit__Parrot_str_free_cstring(f, args[i]); 481 j++; 482 break; 483 484 case 'B': 485 v1 = jit_insn_load_relative(f, args[i], 0, jit_type_void_ptr); 486 jit__Parrot_str_free_cstring(f, v1); 487 j++; 488 break; 489 490 case '2': 491 t1 = jit_type_sys_short; 492 goto set_integer; 493 case '3': 494 t1 = jit_type_sys_int; 495 goto set_integer; 496 case '4': 497 t1 = jit_type_sys_long; 498 set_integer: 499 v1 = jit_insn_load_relative(f, args[i], 0, t1); 500 jit__vtable_set_integer_native(f, jinterp, regs[j], v1); 501 j++; 502 break; 503 504 case 'V': 505 v1 = jit_insn_load_relative(f, args[i], 0, jit_type_void_ptr); 506 jit__vtable_set_pointer(f, jinterp, regs[j], v1); 507 j++; 508 break; 509 510 case 'I': 511 case 'c': 512 case 'i': 513 case 'l': 514 case 'N': 515 case 'f': 516 case 'd': 517 case 'S': 518 case 'b': 519 case 'p': 520 case 'P': 521 case 'O': 522 case '@': 523 j++; 524 break; 525 526 case 'U': 527 /* TODO */ 528 break; 529 default: 530 /* ignore */ 531 break; 532 } 533 } 534 } 535 536 jit_value_t 537 jit_value_create_intval_constant(jit_function_t f, INTVAL i) { 538 return jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, i); 539 } 540 541 /* 542 * JIT wrappers 543 */ 544 545 /* custom wrappers */ 546 jit_value_t 547 jit__Buffer_bufstart(jit_function_t f, jit_value_t buf) { 548 return jit_insn_load_relative(f, buf, offsetof(Buffer, _bufstart), jit_type_void_ptr); 549 } 550 551 /* vtable wrappers */ 552 @TEMP_vtable_wrap_defns@ 553 554 /* function wrappers */ 555 @TEMP_func_wrap_defns@ 556 557 #endif /* PARROT_HAS_LIBJIT */ 558 559 /* 560 * Local variables: 561 * c-file-style: "parrot" 562 * End: 563 * vim: expandtab shiftwidth=4: 564 */ -
(a) /dev/null vs. (b) b/config/gen/libjit/frame_builder_libjit_h.in
diff --git a/config/gen/libjit/frame_builder_libjit_h.in b/config/gen/libjit/frame_builder_libjit_h.in new file mode 100644 index 0000000..ff22e2e
a b 1 /* frame_builder_libjit.h 2 * $Id$ 3 * Copyright (C) 2009, Parrot Foundation. 4 */ 5 6 #ifndef PARROT_FRAME_BUILDER_LIBJIT_H_GUARD 7 #define PARROT_FRAME_BUILDER_LIBJIT_H_GUARD 8 9 10 #if defined(__cplusplus) 11 # define EXTERN extern "C" 12 #else 13 # define EXTERN 14 #endif 15 16 #include <assert.h> 17 #include "parrot/parrot.h" 18 #include "frame_builder.h" 19 20 #ifdef PARROT_HAS_LIBJIT 21 22 # include <jit/jit.h> 23 24 /* 25 * JITted function state data 26 */ 27 struct jit_buffer_private_data { 28 jit_context_t ctx; 29 char *sig; 30 }; 31 32 /* 33 * JIT types 34 */ 35 36 # define JIT_TYPE_UINTVAL @libjit_uv@ 37 # define JIT_TYPE_INTVAL @libjit_iv@ 38 # define JIT_TYPE_FLOATVAL @libjit_nv@ 39 40 /* 41 * JIT functions 42 */ 43 44 void * 45 Parrot_jit_create_thunk(Interp *, char *, void *); 46 47 void 48 Parrot_jit_parse_sig_args_pre(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t, 49 jit_type_t *, jit_value_t *, jit_value_t *); 50 51 jit_type_t 52 Parrot_jit_parse_sig_ret_pre(Interp *, char *); 53 54 void 55 Parrot_jit_parse_sig_ret_post(Interp *, char *, jit_function_t, jit_value_t, jit_value_t, jit_value_t); 56 57 void 58 Parrot_jit_parse_sig_args_post(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t *, jit_value_t *); 59 60 jit_value_t 61 jit_value_create_intval_constant(jit_function_t, INTVAL); 62 63 /* 64 * workaround for platforms that lack libjit alloca support 65 */ 66 # if @libjit_has_alloca@ 67 # define JIT_ALLOCA(f, n) jit_insn_alloca((f), (n)) 68 # define JIT_ALLOCA_FREE(f, p) 69 # else 70 # define JIT_ALLOCA(f, n) jit__mem_sys_allocate((f), (n)) 71 # define JIT_ALLOCA_FREE(f, p) jit__mem_sys_free((f), (p)) 72 # endif 73 74 /* 75 * JIT wrappers 76 */ 77 78 /* custom wrappers */ 79 jit_value_t 80 jit__Buffer_bufstart(jit_function_t, jit_value_t); 81 82 /* vtable wrappers */ 83 @TEMP_vtable_wrap_decls@ 84 85 /* function wrappers */ 86 @TEMP_func_wrap_decls@ 87 88 #endif /* PARROT_HAS_LIBJIT */ 89 #endif /* PARROT_FRAME_BUILDER_LIBJIT_H_GUARD */ 90 91 /* 92 * Local variables: 93 * c-file-style: "parrot" 94 * End: 95 * vim: expandtab shiftwidth=4: 96 */ -
config/gen/makefiles/root.in
diff --git a/config/gen/makefiles/root.in b/config/gen/makefiles/root.in index cad4f1a..823709c 100644
a b 217 217 myconfig \ 218 218 $(GEN_PASM_INCLUDES) \ 219 219 $(SRC_DIR)/call_list.txt \ 220 $(SRC_DIR)/frame_builder_libjit.h \ 221 $(SRC_DIR)/frame_builder_libjit.c \ 220 222 MANIFEST.configure.generated \ 221 223 .configure_trace.sto \ 222 224 .parrot_current_rev … … 442 444 $(SRC_DIR)/misc$(O) \ 443 445 $(SRC_DIR)/multidispatch$(O) \ 444 446 $(SRC_DIR)/frame_builder$(O) \ 447 $(SRC_DIR)/frame_builder_libjit$(O) \ 445 448 $(SRC_DIR)/nci$(O) \ 446 449 $(SRC_DIR)/oo$(O) \ 447 450 $(SRC_DIR)/packfile$(O) \ … … 625 628 $(SRC_DIR)/library.str \ 626 629 $(SRC_DIR)/multidispatch.str \ 627 630 $(SRC_DIR)/frame_builder.str \ 631 $(SRC_DIR)/frame_builder_libjit.str \ 628 632 $(SRC_DIR)/nci.str \ 629 633 $(SRC_DIR)/packfile.str \ 630 634 $(SRC_DIR)/pmc.str \ … … 1201 1205 1202 1206 $(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str \ 1203 1207 $(SRC_DIR)/frame_builder$(O) \ 1204 $(SRC_DIR)/ pmc/pmc_unmanagedstruct.h\1208 $(SRC_DIR)/frame_builder_libjit$(O) \ 1205 1209 $(SRC_DIR)/pmc/pmc_managedstruct.h \ 1206 1210 $(SRC_DIR)/pmc/pmc_nci.h \ 1207 1211 $(SRC_DIR)/pmc/pmc_pointer.h 1208 1212 1209 $(SRC_DIR)/frame_builder$(O) : $(SRC_DIR)/frame_builder.h $(GENERAL_H_FILES) $(SRC_DIR)/frame_builder.c $(SRC_DIR)/frame_builder.str 1213 $(SRC_DIR)/frame_builder$(O) : \ 1214 $(SRC_DIR)/frame_builder.h \ 1215 $(SRC_DIR)/frame_builder.c \ 1216 $(SRC_DIR)/frame_builder.str \ 1217 $(GENERAL_H_FILES) 1218 1219 $(SRC_DIR)/frame_builder_libjit$(O) : \ 1220 $(SRC_DIR)/frame_builder_libjit.h \ 1221 $(SRC_DIR)/frame_builder_libjit.c \ 1222 $(SRC_DIR)/frame_builder_libjit.str \ 1223 $(SRC_DIR)/frame_builder.h \ 1224 $(GENERAL_H_FILES) 1210 1225 1211 1226 $(SRC_DIR)/vtables$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/vtables.c 1212 1227 -
lib/Parrot/Configure/Options/Conf.pm
diff --git a/lib/Parrot/Configure/Options/Conf.pm b/lib/Parrot/Configure/Options/Conf.pm index 27ca853..497d3b9 100644
a b 105 105 --without-gmp Build parrot without GMP support 106 106 --without-opengl Build parrot without OpenGL support (GL/GLU/GLUT) 107 107 --without-pcre Build parrot without pcre support 108 --without-libjit Build parrot without LibJIT support 108 109 109 110 ICU Options: 110 111 -
lib/Parrot/Configure/Options/Conf/Shared.pm
diff --git a/lib/Parrot/Configure/Options/Conf/Shared.pm b/lib/Parrot/Configure/Options/Conf/Shared.pm index 729923e..f8dd3ea 100644
a b 75 75 without-gettext 76 76 without-gmp 77 77 without-icu 78 without-libjit 78 79 without-opengl 79 80 without-pcre 80 81 without-threads -
lib/Parrot/Configure/Step/List.pm
diff --git a/lib/Parrot/Configure/Step/List.pm b/lib/Parrot/Configure/Step/List.pm index 0b2190a..1989254 100644
a b 39 39 auto::format 40 40 auto::isreg 41 41 auto::arch 42 auto::libjit 42 43 auto::jit 43 44 auto::frames 44 45 auto::cpu … … 70 71 gen::parrot_include 71 72 gen::opengl 72 73 gen::call_list 74 gen::libjit 73 75 gen::makefiles 74 76 gen::platform 75 77 gen::config_pm 76 78 ); 77 79 80 =pod 81 82 =cut 83 78 84 sub get_steps_list { return @steps; } 79 85 80 86 1; -
lib/Parrot/Distribution.pm
diff --git a/lib/Parrot/Distribution.pm b/lib/Parrot/Distribution.pm index 9c668b9..7b48377 100644
a b 433 433 include/parrot/config.h 434 434 include/parrot/has_header.h 435 435 src/gc/malloc.c 436 src/frame_builder_libjit.h 437 src/frame_builder_libjit.c 436 438 } unless @exemptions; 437 439 438 440 my $path = -f $file ? $file : $file->path; -
src/frame_builder.c
diff --git a/src/frame_builder.c b/src/frame_builder.c index e123c36..1296ac9 100644
a b 7 7 /* HEADERIZER STOP */ 8 8 9 9 #include "parrot/parrot.h" 10 #include "pmc/pmc_fixedintegerarray.h"11 #include "pmc/pmc_unmanagedstruct.h"12 #include "pmc/pmc_managedstruct.h"13 10 #include "frame_builder.h" 14 11 15 /* 16 17 =over 4 18 19 =item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)> 20 21 This is a callback to implement the proper freeing semantics. It is called by 22 the ManagedStruct PMC as it is garbage collected. 23 24 =cut 25 26 */ 27 28 void 29 Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv) 12 INTVAL 13 get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n) 30 14 { 31 const struct jit_buffer_private_data * const jit = (struct jit_buffer_private_data*)priv; 32 mem_free_executable(ptr, jit->size); 33 free(priv); 34 } 15 if (n >= st->src.n) 16 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, 17 "too few arguments passed to NCI function"); 35 18 36 /* 19 Parrot_fetch_arg_nci(interp, st); 37 20 38 =item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)> 39 40 This is a callback to implement the proper cloning semantics for jit buffers. 41 It is called by the ManagedStruct PMC's clone() function. 21 return UVal_int(st->val); 22 } 42 23 43 =back 24 FLOATVAL 25 get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n) 26 { 27 if (n >= st->src.n) 28 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, 29 "too few arguments passed to NCI function"); 44 30 45 =cut 31 Parrot_fetch_arg_nci(interp, st); 46 32 47 */ 33 return UVal_num(st->val); 34 } 48 35 49 PMC * 50 Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv) 36 PARROT_WARN_UNUSED_RESULT 37 PARROT_CANNOT_RETURN_NULL 38 STRING* 39 get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n) 51 40 { 52 PMC * const rv = pmc_new(interp, pmc->vtable->base_type); 53 54 VTABLE_init(interp, rv); 55 /* copy the attributes */ 56 { 57 void (*tmpfreefunc)(PARROT_INTERP, void*, void*); 58 GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc); 59 SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc); 60 } 61 { 62 PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*); 63 GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc); 64 SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc); 65 } 66 67 { 68 void *freepriv, *clonepriv; 69 GETATTR_ManagedStruct_custom_free_priv(interp , pmc, freepriv); 70 GETATTR_ManagedStruct_custom_clone_priv(interp, pmc, clonepriv); 71 if (freepriv) { 72 void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data)); 73 memcpy(tmp, freepriv, sizeof (struct jit_buffer_private_data)); 74 SETATTR_ManagedStruct_custom_free_priv(interp, rv , tmp); 75 if (clonepriv == freepriv) { 76 /* clonepriv is a copy of freepriv, make it a copy in the clone too. */ 77 SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp); 78 clonepriv = NULL; /* disable the clonepriv copying below */ 79 } 80 } 81 if (clonepriv) { 82 void *tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data)); 83 memcpy(tmp, clonepriv, sizeof (struct jit_buffer_private_data)); 84 SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp); 85 } 86 } 41 /* TODO or act like below? */ 42 if (n >= st->src.n) 43 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, 44 "too few arguments passed to NCI function"); 87 45 88 /* copy the execmem buffer */ 89 if (PARROT_MANAGEDSTRUCT(pmc)->ptr) { 90 struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv; 91 void *ptr = PARROT_MANAGEDSTRUCT(pmc)->ptr; 92 void *newptr = mem_alloc_executable(jit->size); 93 if (!newptr) 94 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 95 "Cannot allocate executable memory"); 96 memcpy(newptr, ptr, jit->size); 97 PARROT_MANAGEDSTRUCT(rv)->ptr = newptr; 98 } 46 Parrot_fetch_arg_nci(interp, st); 99 47 100 return rv;48 return UVal_str(st->val); 101 49 } 102 50 103 104 int 105 emit_is8bit(long disp) 51 PARROT_WARN_UNUSED_RESULT 52 PARROT_CAN_RETURN_NULL 53 PMC* 54 get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n) 106 55 { 107 return disp >= -128 && disp <= 127; 56 /* 57 * excessive args are passed as NULL 58 * used by e.g. MMD infix like __add 59 */ 60 if (n < st->src.n) { 61 PMC *value; 62 Parrot_fetch_arg_nci(interp, st); 63 value = UVal_pmc(st->val); 64 return PMC_IS_NULL(value) ? (PMC *)NULL : value; 65 } 66 else 67 return NULL; 108 68 } 109 69 110 char * 111 emit_disp8_32(char *pc, int disp) 70 PARROT_WARN_UNUSED_RESULT 71 PARROT_CAN_RETURN_NULL 72 void* 73 get_nci_p(PARROT_INTERP, ARGMOD(call_state *st), int n) 112 74 { 113 if (emit_is8bit(disp)) { 114 *(pc++) = (char)disp; 115 return pc; 116 } 117 else { 118 *(long *)pc = disp; 119 return pc + 4; 120 } 75 /* 76 * excessive args are passed as NULL 77 * used by e.g. MMD infix like __add 78 */ 79 if (n < st->src.n) { 80 PMC *value; 81 Parrot_fetch_arg_nci(interp, st); 82 value = UVal_pmc(st->val); 83 return PMC_IS_NULL(value) ? (PMC *)NULL : VTABLE_get_pointer(interp, value); 84 } 85 else 86 return NULL; 121 87 } 122 88 89 /* 90 * set return value 91 */ 123 92 void 124 emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base) 125 { 126 int scale_byte; 127 128 switch (scale) { 129 case 1: 130 scale_byte = emit_Scale_1; 131 break; 132 case 2: 133 scale_byte = emit_Scale_2; 134 break; 135 case 4: 136 scale_byte = emit_Scale_4; 137 break; 138 case 8: 139 scale_byte = emit_Scale_8; 140 break; 141 default: 142 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 143 "Invalid scale factor %d\n", scale); 144 return; 145 } 146 147 *pc = (char)(scale_byte | (i == emit_None ? emit_Index_None : emit_reg_Index(i)) | 148 emit_reg_Base(base)); 149 } 150 151 char * 152 emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i, int scale, long disp) 93 set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val) 153 94 { 154 if (i && !scale) 155 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 156 "emit_r_X passed invalid scale+index combo\n"); 157 158 if (base == emit_EBP) { 159 /* modrm disp */ 160 if (i == emit_None) { 161 *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10) 162 | reg_opcode | emit_reg_rm(emit_EBP)); 163 return emit_disp8_32(pc, disp); 164 } 165 /* modrm sib disp */ 166 else { 167 *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10) 168 | reg_opcode | emit_b100); 169 emit_sib(interp, pc++, scale, i, base); 170 return emit_disp8_32(pc, disp); 171 } 172 } 173 174 /* modrm sib disp */ 175 if (base == emit_ESP) { 176 *(pc++) = (char)((emit_is8bit(disp) ? emit_Mod_b01 : emit_Mod_b10) 177 | reg_opcode | emit_rm_b100); 178 emit_sib(interp, pc++, scale, i, emit_ESP); 179 return emit_disp8_32(pc, disp); 180 } 181 182 /* modrm disp32 */ 183 if (!base && !(i && scale)) { 184 *(pc++) = (char)(emit_Mod_b00 | reg_opcode | emit_rm_b101); 185 *(long *)pc = disp; 186 return pc + 4; 95 Parrot_init_ret_nci(interp, st, "I"); 96 if (st->dest.i < st->dest.n) { 97 UVal_int(st->val) = val; 98 Parrot_convert_arg(interp, st); 99 Parrot_store_arg(interp, st); 187 100 } 188 189 /* Ok, everything should be more regular here */190 *(pc++) = (char)((disp == 0 ? emit_Mod_b00 :191 (emit_is8bit(disp) ?192 emit_Mod_b01 : emit_Mod_b10)) |193 reg_opcode |194 (!base || (scale && i) ? emit_rm_b100 : emit_reg_rm(base)));195 196 if (!base || (scale && i)) {197 emit_sib(interp, pc++, scale, i, base);198 }199 if (disp)200 pc = emit_disp8_32(pc, disp);201 202 return pc;203 101 } 204 102 205 char * 206 emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg)103 void 104 set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val) 207 105 { 208 if (opcode == emit_b000 && imm < 0) { 209 opcode = emit_b001; /* -rol => 32 + ror */ 210 imm = -imm; 211 } 212 213 if (imm == 0) { 214 /* noop */ 106 Parrot_init_ret_nci(interp, st, "N"); 107 if (st->dest.i < st->dest.n) { 108 UVal_num(st->val) = val; 109 Parrot_convert_arg(interp, st); 110 Parrot_store_arg(interp, st); 215 111 } 216 else if (imm == 1) {217 *(pc++) = (char) 0xd1;218 *(pc++) = (char) emit_alu_X_r(opcode, reg);219 }220 else if (imm > 1 && imm < 33) {221 *(pc++) = (char) 0xc1;222 *(pc++) = (char) emit_alu_X_r(opcode, reg);223 *(pc++) = (char)imm;224 }225 else {226 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,227 "emit_shift_i_r passed invalid shift\n");228 }229 230 return pc;231 }232 233 char *234 emit_popl_r(char *pc, int reg)235 {236 *(pc++) = (char)(0x58 | (reg - 1));237 return pc;238 112 } 239 113 240 unsigned char *lastpc; 241 242 size_t 243 calc_signature_needs(const char *sig, int *strings) 114 void 115 set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val) 244 116 { 245 size_t stack_size = 0; 246 while (*sig) { 247 switch (*sig) { 248 case 't': 249 (*strings)++; 250 stack_size +=4; 251 break; 252 case 'd': 253 stack_size +=8; 254 break; 255 default: 256 stack_size +=4; 257 break; 258 } 259 sig++; 117 Parrot_init_ret_nci(interp, st, "S"); 118 if (st->dest.i < st->dest.n) { 119 UVal_str(st->val) = val; 120 Parrot_convert_arg(interp, st); 121 Parrot_store_arg(interp, st); 260 122 } 261 return stack_size;262 263 123 } 264 124 265 /* 266 * The function generated here is called as func(interp, nci_info) 267 * interp ... 8(%ebp) 268 * nci_info ... 12(%ebp) 269 * 270 * The generate function for a specific signature looks quite similar to 271 * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles 272 * just compare the disassembly. 273 * 274 * If a non-NULL sizeptr is passed, the integer it points to will be written 275 * with the size of the allocated execmem buffer. 276 */ 277 278 void * 279 Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, int *sizeptr) 125 void 126 set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val) 280 127 { 281 char *pc; 282 char *execmem; 283 int i = 0; 284 int arg_count = 0; 285 int string_buffer_count = 0; 286 const int ST_SIZE_OF = 124; 287 const int JIT_ALLOC_SIZE = 1024; 288 289 char *signature_str = Parrot_str_to_cstring(interp, signature); 290 /* skip over the result */ 291 char *sig = signature_str + 1; 292 size_t stack_space_needed = calc_signature_needs(sig, 293 &string_buffer_count); 294 295 int base_offset = 0; 296 int strings_offset = base_offset - (sizeof (char *) * string_buffer_count); 297 int st_offset = strings_offset - ST_SIZE_OF; 298 int args_offset = st_offset - stack_space_needed; 299 int temp_calls_offset = args_offset - 16; 300 int total_stack_needed = -temp_calls_offset; 301 302 /* 303 * ESP 304 * 0-15, 16 bytes for utility calls 305 * stack_space_needed for actual NCI call 306 * st 307 * STRINGS -> char * holding space 308 * EBP 309 */ 310 311 /* this ought to be enough - the caller of this function 312 * should free the function pointer returned here 313 */ 314 pc = execmem = (char *)mem_alloc_executable(JIT_ALLOC_SIZE); 315 if (! pc) 316 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 317 "Cannot allocate executable memory"); 318 319 320 /* this generated jit function will be called as (INTERP (EBP 8), func_ptr 321 * (ESP 12), args signature (ESP 16)) */ 322 323 /* make stack frame, preserve %ebx */ 324 jit_emit_stack_frame_enter(pc); 325 326 emitm_subl_i_r(pc, total_stack_needed, emit_ESP); 327 328 /* Parrot_init_arg_nci(interp, &st, "S"); */ 329 /* args signature "S" */ 330 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 16); 331 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8); 332 333 /*&st*/ 334 emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset); 335 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 336 337 /*interpreter*/ 338 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8); 339 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0); 340 341 /* XXX FIXME This whole function require major rework */ 342 /* XXX FIXME if (sig && *sig) */ 343 /* XXX FIXME emitm_call_cfunc(pc, Parrot_init_arg_nci); */ 344 345 while (*sig) { 346 emitm_movl_i_m(pc, arg_count, emit_EBP, 0, 1, temp_calls_offset + 8); 347 348 switch (*sig) { 349 case '0': /* null ptr or such - doesn't consume a reg */ 350 jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX); 351 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 352 break; 353 case 'f': 354 /* FIXME emitm_call_cfunc(pc, get_nci_N); */ 355 emitm_fstps(interp, pc, emit_EBP, 0, 1, args_offset); 356 break; 357 case 'N': 358 case 'd': 359 /* FIXME emitm_call_cfunc(pc, get_nci_N); */ 360 emitm_fstpl(interp, pc, emit_EBP, 0, 1, args_offset); 361 args_offset += 4; 362 break; 363 case 'I': /* INTVAL */ 364 case 'l': /* long */ 365 case 'i': /* int */ 366 /* FIXME emitm_call_cfunc(pc, get_nci_I); */ 367 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 368 break; 369 case 't': /* string, pass a cstring */ 370 /* FIXME emitm_call_cfunc(pc, get_nci_S); */ 371 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 372 emitm_call_cfunc(pc, string_to_cstring_nullable); 373 374 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 375 /* save off temporary allocation address */ 376 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset); 377 strings_offset += 4; 378 379 /* reset ESP(4) */ 380 emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset); 381 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4); 382 break; 383 case 's': /* short: movswl intreg_o(base), %eax */ 384 /* FIXME emitm_call_cfunc(pc, get_nci_I); */ 385 emitm_movswl_r_r(pc, emit_EAX, emit_EAX); 386 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 387 break; 388 case 'c': /* char: movsbl intreg_o(base), %eax */ 389 /* emitm_call_cfunc(pc, get_nci_I); */ 390 emitm_movsbl_r_r(pc, emit_EAX, emit_EAX); 391 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 392 break; 393 case 'J': /* interpreter */ 394 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8); 395 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 396 arg_count--; 397 break; 398 case 'p': /* push pmc->data */ 399 /* FIXME emitm_call_cfunc(pc, get_nci_p); */ 400 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 401 break; 402 case 'O': /* push PMC * object in P2 */ 403 case 'P': /* push PMC * */ 404 case '@': 405 /* FIXME emitm_call_cfunc(pc, get_nci_P); */ 406 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 407 break; 408 case 'v': 409 break; 410 case 'b': /* buffer (void*) pass Buffer_bufstart(SReg) */ 411 /* FIXME emitm_call_cfunc(pc, get_nci_S); */ 412 emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 413 (size_t) &Buffer_bufstart((STRING *) NULL)); 414 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 415 break; 416 case 'B': /* buffer (void**) pass &Buffer_bufstart(SReg) */ 417 /* FIXME emitm_call_cfunc(pc, get_nci_S); */ 418 emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 419 (size_t) &Buffer_bufstart((STRING *) NULL)); 420 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 421 break; 422 case 'S': 423 /* FIXME emitm_call_cfunc(pc, get_nci_S); */ 424 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset); 425 break; 426 427 428 /* I have no idea how to handle these */ 429 case '2': 430 case '3': 431 case '4': 432 case 'V': 433 mem_free_executable(execmem, JIT_ALLOC_SIZE); 434 Parrot_str_free_cstring(signature_str); 435 return NULL; 436 break; 437 default: 438 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, 439 "Unknown arg Signature %c\n", *sig); 440 /* 441 * oops unknown signature: 442 * cleanup and try nci.c 443 */ 444 mem_free_executable(execmem, JIT_ALLOC_SIZE); 445 Parrot_str_free_cstring(signature_str); 446 return NULL; 447 } 448 args_offset +=4; 449 arg_count++; 450 sig++; 128 Parrot_init_ret_nci(interp, st, "P"); 129 if (st->dest.i < st->dest.n) { 130 UVal_pmc(st->val) = val; 131 Parrot_convert_arg(interp, st); 132 Parrot_store_arg(interp, st); 451 133 } 452 453 /* prepare to call VTABLE_get_pointer, set up args */454 /* interpreter - movl 8(%ebp), %eax */455 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);456 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);457 458 /* pmc - movl 12(%ebp), %eax */459 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 12);460 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);461 462 /* get the get_pointer() pointer from the pmc's vtable */463 emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable));464 emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer));465 466 /* call get_pointer(), result goes into eax */467 emitm_callr(pc, emit_EAX);468 emitm_addl_i_r(pc, 16, emit_ESP);469 470 /* call the resulting function pointer */471 emitm_callr(pc, emit_EAX);472 emitm_subl_i_r(pc, 16, emit_ESP);473 474 /* SAVE OFF EAX */475 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);476 477 /*&st*/478 emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);479 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);480 481 /*interpreter*/482 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);483 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);484 485 /* RESTORE BACK EAX */486 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);487 488 /* now place return value in registers */489 /* first in signature is the return value */490 sig = signature_str; /* the result */491 switch (*sig) {492 /* I have no idea how to handle these */493 case '2':494 case '3':495 case '4':496 /* get integer from pointer - untested */497 emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0);498 if (*sig == 2) /* short */499 emitm_movswl_r_r(pc, emit_EAX, emit_EAX);500 /* XXX FIXME emitm_call_cfunc(pc, set_nci_I);*/501 break;502 case 'f':503 case 'd':504 jit_emit_fstore_mb_n(interp, pc, emit_EBP, temp_calls_offset + 8);505 /* XXX FIXME emitm_call_cfunc(pc, set_nci_N); */506 /* pop num from st(0) and mov to reg */507 break;508 case 's':509 /* movswl %ax, %eax */510 emitm_movswl_r_r(pc, emit_EAX, emit_EAX);511 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);512 /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */513 break;514 case 'c':515 /* movsbl %al, %eax */516 emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);517 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);518 /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */519 break;520 case 'I': /* INTVAL */521 case 'l':522 case 'i':523 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);524 /* XXX FIXME emitm_call_cfunc(pc, set_nci_I); */525 break;526 case 'v': /* void - do nothing */527 break;528 case 'P':529 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);530 /* XXX FIXME emitm_call_cfunc(pc, set_nci_P); */531 break;532 case 'p': /* make a new unmanaged struct */533 /* save return value on stack */534 535 /* save pointer p */536 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 12);537 538 /* make new pmc */539 emitm_movl_i_m(pc, enum_class_UnManagedStruct, emit_EBP, 0, 1, temp_calls_offset + 4);540 emitm_call_cfunc(pc, pmc_new);541 542 /* restore pointer p to EDX */543 emitm_movl_m_r(interp, pc, emit_EDX, emit_EBP, 0, 1, temp_calls_offset + 12);544 545 /* copy UnManagedStruct to stack for set_nci_P call */546 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);547 548 /* eax = PMC, get return value into edx */549 /* mov data(%eax), %eax550 mov %edx, ptr(%eax) */551 emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));552 emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1,553 offsetof(struct Parrot_UnManagedStruct_attributes, ptr));554 555 /* reset EBP(4) */556 emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);557 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);558 559 /* XXX FIXME emitm_call_cfunc(pc, set_nci_P); */560 break;561 case 'S':562 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);563 /* XXX FIXME emitm_call_cfunc(pc, set_nci_S); */564 break;565 case 't': /* string */566 /* EAX is char* */567 emitm_movl_i_m(pc, 0, emit_EBP, 0, 1, temp_calls_offset + 8); /* len */568 569 /* overwrites address of st in EBP(4) */570 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);571 572 emitm_call_cfunc(pc, Parrot_str_new);573 574 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 8);575 576 /* reset EBP(4) */577 emitm_lea_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, st_offset);578 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);579 580 /* XXX FIXME emitm_call_cfunc(pc, set_nci_S); */581 break;582 default:583 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,584 "Unknown return Signature %c\n", *sig);585 /*586 * oops unknown signature:587 * cleanup and try nci.c588 */589 Parrot_str_free_cstring(signature_str);590 mem_free_executable(execmem, JIT_ALLOC_SIZE);591 return NULL;592 }593 594 /* free temporary strings */595 strings_offset = st_offset + ST_SIZE_OF;596 for (i=0; i<string_buffer_count; i++) {597 emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, strings_offset);598 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);599 emitm_call_cfunc(pc, Parrot_str_free_cstring);600 strings_offset += 4;601 }602 603 jit_emit_stack_frame_leave(pc);604 emitm_ret(pc);605 PARROT_ASSERT(pc - execmem <= JIT_ALLOC_SIZE);606 607 if (sizeptr)608 *sizeptr = JIT_ALLOC_SIZE;609 Parrot_str_free_cstring(signature_str);610 return (void *)D2FPTR(execmem);611 134 } 612 135 613 136 /* -
src/frame_builder.h
diff --git a/src/frame_builder.h b/src/frame_builder.h index 8825ff9..3d4b6cd 100644
a b 1 1 /* 2 2 * Copyright (C) 2002-2009, Parrot Foundation. 3 */4 5 /*6 * frame_builder.h7 3 * 8 * i3864 * frame_builder.h 9 5 * 10 6 * $Id$ 11 7 */ 12 8 13 #ifndef PARROT_ I386_JIT_EMIT_H_GUARD14 #define PARROT_ I386_JIT_EMIT_H_GUARD9 #ifndef PARROT_FRAME_BUILDER_H_GUARD 10 #define PARROT_FRAME_BUILDER_H_GUARD 15 11 16 12 #if defined(__cplusplus) 17 13 # define EXTERN extern "C" … … 21 17 22 18 #include <assert.h> 23 19 #include "parrot/parrot.h" 24 #include "parrot/hash.h"25 #include "parrot/oplib/ops.h"26 20 27 21 /* 28 22 * NCI interface 29 23 */ 24 30 25 void * 31 Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int*);26 Parrot_jit_build_call_func(Interp *, PMC *, STRING *, void **); 32 27 33 28 /* custom pmc callback functions */ 34 29 void … … 37 32 PMC* 38 33 Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv); 39 34 40 struct jit_buffer_private_data {41 int size;42 };43 44 /* Scale factor values */45 #define emit_Scale(scale) ((scale) << 6)46 #define emit_Scale_1 emit_Scale(0)47 #define emit_Scale_2 emit_Scale(1)48 #define emit_Scale_4 emit_Scale(2)49 #define emit_Scale_8 emit_Scale(3)50 51 /* ESIB byte */52 #define emit_reg_Index(x) (((x)-1) << 3)53 #define emit_reg_Base(x) ((x)-1)54 #define emit_Index_None ((emit_b100) << 3)55 56 35 /* 57 36 * helper funcs - get argument n 58 37 */ 59 38 60 /* 61 * if we have a delegated method like typeof_i_p, that returns an INTVAL 62 * and that is all in a sequence of JITted opcodes, and when these INTVAL 63 * is MAPped, we got a problem. So the EXT_CALL flag is disabled - mapped 64 * registers are saved/restored around vtable calls. 65 */ 66 #define JIT_VTABLE_OPS 1 67 68 /* EXEC_SHARED generates code to be used with libparrot.so 69 * It grabs the real address of cgp_core from the gcc generated code 70 * x/1i cgp_code 71 * jmp *0xXXXX 72 * x/1wx 0xXXXX 73 * real address of cpg_core 74 * s. exec_emit_end 75 * XXX This should be a command line option. 76 */ 77 #undef EXEC_SHARED 78 79 extern UINTVAL ld(UINTVAL); 80 81 #define NEG_MINUS_ZERO 82 /* #define NEG_ZERO_SUB */ 83 84 /* Register codes */ 85 #define emit_None 0 86 87 /* These are + 1 the real values */ 88 #define emit_EAX 1 89 #define emit_ECX 2 90 #define emit_EDX 3 91 #define emit_EBX 4 92 #define emit_ESP 5 93 #define emit_EBP 6 94 #define emit_ESI 7 95 #define emit_EDI 8 96 97 /* Scratch register. */ 98 99 #define ISR1 emit_EAX 100 #define FSR1 0 101 102 #define emit_b00 0 103 #define emit_b01 1 104 #define emit_b10 2 105 #define emit_b11 3 106 107 #define emit_b000 0 108 #define emit_b001 1 109 #define emit_b010 2 110 #define emit_b011 3 111 #define emit_b100 4 112 #define emit_b101 5 113 #define emit_b110 6 114 #define emit_b111 7 115 116 /* Mod R/M byte */ 117 #define emit_reg(x) ((x) << 3) 118 #define emit_Mod(Mod) ((Mod) << 6) 119 #define emit_reg_rm(x) ((x)-1) 120 121 /* Mod values for Mod R/M Byte */ 122 #define emit_Mod_b00 emit_Mod(emit_b00) 123 #define emit_Mod_b01 emit_Mod(emit_b01) 124 #define emit_Mod_b10 emit_Mod(emit_b10) 125 126 /* special R/M values */ 127 #define emit_rm_b101 emit_b101 128 #define emit_rm_b100 emit_b100 129 130 #define emit_r_m(interp, pc, reg1, b, i, s, d) \ 131 emit_r_X((interp), (pc), emit_reg((reg1)-1), (b), (i), (s), (d)) 132 133 #define emit_alu_X_r(X, reg) ((emit_b11 << 6) | ((X) << 3) | ((reg) - 1)) 134 135 #define emit_alu_r_r(reg1, reg2) emit_alu_X_r(((reg1) - 1), (reg2)) 136 137 int emit_is8bit(long disp); 138 139 char * emit_disp8_32(char *pc, int disp); 140 141 void emit_sib(PARROT_INTERP, char *pc, int scale, int i, int base); 142 143 char * emit_r_X(PARROT_INTERP, char *pc, int reg_opcode, int base, int i, 144 int scale, long disp); 145 146 char * emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg); 147 148 char * emit_shift_i_m(PARROT_INTERP, char *pc, int opcode, int imm, 149 int base, int i, int scale, long disp); 150 151 char * emit_shift_r_r(PARROT_INTERP, char *pc, int opcode, int reg1, int reg2); 152 153 char * emit_shift_r_m(PARROT_INTERP, char *pc, int opcode, int reg, 154 int base, int i, int scale, long disp); 155 156 /* CDQ - need this to do multiply */ 157 #define emitm_cdq(pc) *((pc)++) = (char) 0x99 158 159 /* RET */ 160 #define emitm_ret(pc) *((pc)++) = (char) 0xc3 161 162 /* NOP */ 163 #define emit_nop(pc) *((pc)++) = (char) 0x90 164 165 /* PUSHes */ 166 167 #define emitm_pushl_r(pc, reg) \ 168 *((pc)++) = (char) 0x50 | ((reg) - 1) 169 170 #define emitm_pushl_i(pc, imm) { \ 171 *((pc)++) = (char) 0x68; \ 172 *(long *)(pc) = (long)(imm); \ 173 (pc) += 4; } 174 175 #define emitm_pushl_m(pc, mem) { \ 176 *((pc)++) = (char) 0xff; \ 177 *((pc)++) = (char) 0x35; \ 178 *(long *)(pc) = (long)(mem); \ 179 (pc) += 4; } 180 181 char * emit_pushl_m(PARROT_INTERP, char *pc, int base, int i, int scale, 182 long disp); 183 184 /* POPs */ 185 186 char * emit_popl_r(char *pc, int reg); 187 188 # define emitm_popl_r(pc, reg) \ 189 (pc) = emit_popl_r((pc), (reg)) 190 191 char * emit_popl_m(PARROT_INTERP, char *pc, int base, int i, int scale, 192 long disp); 193 194 /* MOVes */ 195 196 char * emit_movb_r_r(char *pc, int reg1, int reg2); 197 198 # define jit_emit_mov_rr_i(pc, reg2, reg1) if ((reg1) != (reg2)) { \ 199 *((pc)++) = (char) 0x89; \ 200 *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); } 201 202 # define jit_emit_mov_ri_i(interp, pc, reg, imm) { \ 203 *((pc)++) = (char)(0xb8 | ((reg) - 1)); \ 204 *(long *)(pc) = (long)(imm); (pc) += 4; } 205 206 # define emitm_movX_Y_Z(interp, op, pc, reg1, b, i, s, d) { \ 207 *((pc)++) = (char) (op); \ 208 (pc) = emit_r_m((interp), (pc), (reg1), (b), (i), (s), (long)(d)); } 209 210 # define emitm_movb_r_m(interp, pc, reg1, b, i, s, d) \ 211 emitm_movX_Y_Z((interp), 0x88, (pc), (reg1), (b), (i), (s), (d)) 212 213 # define emitm_movl_r_m(interp, pc, reg1, b, i, s, d) \ 214 emitm_movX_Y_Z((interp), 0x89, (pc), (reg1), (b), (i), (s), (d)) 215 216 /* move byte/word with sign extension */ 217 # define emitm_movsbl_r_m(interp, pc, reg1, b, i, s, d) { \ 218 *((pc)++) = (char) 0x0f; \ 219 emitm_movX_Y_Z((interp), 0xBE, (pc), (reg1), (b), (i), (s), (d)); \ 220 } 221 222 # define emitm_movswl_r_m(interp, pc, reg1, b, i, s, d) { \ 223 *((pc)++) = (char) 0x0f; \ 224 emitm_movX_Y_Z((interp), 0xBF, (pc), (reg1), (b), (i), (s), (d)); \ 225 } 226 227 # define emitm_movsbl_r_r(pc, reg1, reg2) { \ 228 *((pc)++) = (char) 0x0f; \ 229 *((pc)++) = (char) 0xbe; \ 230 *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); \ 231 } 232 233 # define emitm_movswl_r_r(pc, reg1, reg2) { \ 234 *((pc)++) = (char) 0x0f; \ 235 *((pc)++) = (char) 0xbf; \ 236 *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); \ 237 } 238 239 # define emitm_movb_m_r(interp, pc, reg1, b, i, s, d) \ 240 emitm_movX_Y_Z((interp), 0x8a, (pc), (reg1), (b), (i), (s), (d)) 241 242 # define emitm_movl_m_r(interp, pc, reg1, b, i, s, d) \ 243 emitm_movX_Y_Z((interp), 0x8b, (pc), (reg1), (b), (i), (s), (d)) 244 245 # define emitm_lea_m_r(interp, pc, reg1, b, i, s, d) \ 246 emitm_movX_Y_Z((interp), 0x8d, (pc), (reg1), (b), (i), (s), (d)) 247 248 char * emit_movb_i_m(PARROT_INTERP, char *pc, char imm, int base, int i, 249 int scale, long disp); 250 251 # define emitm_movl_i_m(pc, imm, b, i, s, d) { \ 252 *((pc)++) = (char) 0xc7; \ 253 (pc) = emit_r_X((interp), (pc), emit_reg(emit_b000), (b), (i), (s), (long)(d)); \ 254 *(long *)(pc) = (long)(imm); (pc) += 4; } 255 256 /* Various ALU formats */ 257 258 # define emitm_alul_r_r(pc, op, reg1, reg2) { \ 259 *((pc)++) = (char) (op); *((pc)++) = (char) emit_alu_r_r((reg1), (reg2)); } 260 261 # define emitm_alub_i_r(pc, op1, op2, imm, reg) { \ 262 *((pc)++) = (char) (op1); *((pc)++) = (char) emit_alu_X_r((op2), (reg)); *((pc)++) = (char)(imm); } 263 264 # define emitm_alul_i_r(pc, op1, op2, imm, reg) { \ 265 *((pc)++) = (char) (op1); \ 266 *((pc)++) = (char) emit_alu_X_r((op2), (reg)); \ 267 *(long *)((pc)) = (long)(imm); (pc) += 4; } 268 269 # define emitm_alul_i_m(pc, op1, op2, imm, b, i, s, d) { \ 270 *((pc)++) = (char) (op1); \ 271 (pc) = emit_r_X((interp), (pc), emit_reg(op2), (b), (i), (s), (d)); \ 272 *(long *)(pc) = (long)(imm); (pc) += 4; } 273 274 # define emitm_alul_r_m(pc, op, reg, b, i, s, d) { \ 275 *((pc)++) = (char) (op); \ 276 (pc) = emit_r_X((interp), (pc), emit_reg((reg)-1), (b), (i), (s), (long)(d)); } 277 278 /* ADDs */ 279 280 # define emitm_addb_r_r(pc, reg1, reg2) \ 281 emitm_alul_r_r((pc), 0x00, (reg1), (reg2)) 282 283 # define emitm_addb_i_r(pc, imm, reg) \ 284 emitm_alub_i_r((pc), 0x83, emit_b000, (imm), (reg)) 285 286 # define jit_emit_add_rr_i(interp, pc, reg1, reg2) \ 287 emitm_alul_r_r((pc), 0x01, (reg2), (reg1)) 288 289 # define jit_emit_add_ri_i(interp, pc, reg, imm) \ 290 emitm_alul_i_r((pc), 0x81, emit_b000, (imm), (reg)) 291 292 # define emitm_addl_i_r(pc, imm, reg) \ 293 emitm_alul_i_r((pc), 0x81, emit_b000, (imm), (reg)) 294 295 # define emitm_addl_i_m(pc, imm, b, i, s, d) \ 296 emitm_alul_i_m((pc), 0x81, emit_b000, (imm), (b), (i), (s), (d)) 297 298 # define emitm_addl_r_m(pc, reg, b, i, s, d) \ 299 emitm_alul_r_m((pc), 0x01, (reg), (b), (i), (s), (d)) 300 301 # define emitm_addl_m_r(pc, reg, b, i, s, d) \ 302 emitm_alul_r_m((pc), 0x03, (reg), (b), (i), (s), (d)) 303 304 /* SUBs */ 305 306 # define jit_emit_sub_rr_i(interp, pc, reg1, reg2) \ 307 emitm_alul_r_r((pc), 0x29, (reg2), (reg1)) 308 309 # define emitm_subl_i_r(pc, imm, reg) \ 310 emitm_alul_i_r((pc), 0x81, emit_b101, (imm), (reg)) 311 312 # define jit_emit_sub_ri_i(interp, pc, r, i) emitm_subl_i_r((pc), (i), (r)) 313 314 # define emitm_subl_r_m(pc, reg, b, i, s, d) \ 315 emitm_alul_r_m((pc), 0x29, (reg), (b), (i), (s), (d)) 316 317 # define emitm_subl_m_r(pc, reg, b, i, s, d) \ 318 emitm_alul_r_m((pc), 0x2b, (reg), (b), (i), (s), (d)) 319 320 # define emitm_subl_i_m(pc, imm, b, i, s, d) \ 321 emitm_alul_i_m((pc), 0x81, emit_b101, (imm), (b), (i), (s), (d)) 322 323 /* These are used by both signed and unsigned EDIV, but only unsigned MUL */ 324 # define emitm_alu_imp_r(pc, op, reg) { \ 325 *((pc)++) = (char) 0xf7; \ 326 *((pc)++) = (char) emit_alu_X_r((op), (reg)); } 327 328 # define emitm_alu_imp_m(pc, op, b, i, s, d) { \ 329 *((pc)++) = (char) 0xf7; \ 330 (pc) = emit_r_X((interp), (pc), emit_reg(op), (b), (i), (s), (d)); } 331 332 /* Unsigned MUL and EDIV */ 333 /* EAX implicit destination in multiply and divide */ 334 335 # define emitm_umull_r(pc, reg2) emitm_alu_imp_r((pc), emit_b100, (reg2)) 336 337 # define emitm_udivl_r(pc, reg2) emitm_alu_imp_r((pc), emit_b110, (reg2)) 338 339 # define emitm_umull_m(pc, b, i, s, d) \ 340 emitm_alu_imp_m((pc), emit_b100, (b), (i), (s), (d)) 341 342 # define emitm_udivl_m(pc, b, i, s, d) \ 343 emitm_alu_imp_m((pc), emit_b110, (b), (i), (s), (d)) 344 345 /* Signed MUL and EDIV */ 346 347 # define emitm_sdivl_r(pc, reg2) emitm_alu_imp_r((pc), emit_b111, (reg2)) 348 349 # define emitm_sdivl_m(pc, b, i, s, d) \ 350 emitm_alu_imp_m((pc), emit_b111, (b), (i), (s), (d)) 351 352 # define jit_emit_cdq(pc) *(pc)++ = 0x99 353 354 /* TEST for zero */ 355 # define jit_emit_test_r_i(pc, reg1) emitm_alul_r_r((pc), 0x85, (reg1), (reg1)) 356 357 # define emitm_smull_r(pc, reg2) emitm_alu_imp_r((pc), emit_b101, (reg2)) 358 359 # define jit_emit_mul_rr_i(interp, pc, reg1, reg2) { \ 360 *(pc)++ = 0xf; \ 361 emitm_alul_r_r((pc), 0xaf, (reg1), (reg2)); } 362 363 # define emitm_smull_r_m(pc, reg1, b, i, s, d) { \ 364 *(pc)++ = 0xf; \ 365 emitm_alul_r_m((pc), 0xaf, (reg1), (b), (i), (s), (d)); } 366 367 char * opt_mul(PARROT_INTERP, char *pc, int dest, INTVAL imm, int src); 368 369 # define jit_emit_mul_rir_i(pc, dest, imm, src) \ 370 (pc) = opt_mul(interp, (pc), (dest), (imm), (src)) 371 372 373 # define jit_emit_mul_ri_i(pc, r, imm) jit_emit_mul_rir_i((pc), (r), (imm), (r)) 374 375 # define jit_emit_mul_RIM_ii(pc, reg, imm, ofs) \ 376 emitm_alul_r_m((pc), 0x69, (reg), emit_EBX, emit_None, 1, (ofs)); \ 377 *(long *)(pc) = (long)(imm); \ 378 (pc) += 4; 379 380 /* NEG */ 381 382 # define jit_emit_neg_r_i(pc, reg) emitm_alu_imp_r((pc), emit_b011, (reg)) 383 384 # define emitm_negl_m(pc, b, i, s, d) \ 385 emitm_alu_imp_m((pc), emit_b011, (b), (i), (s), (d)) 386 387 /* AND */ 388 389 # define emit_andl_r_r(pc, reg1, reg2) emitm_alul_r_r((pc), 0x21, (reg1), (reg2)) 390 # define jit_emit_band_rr_i(interp, pc, r1, r2) emit_andl_r_r((pc), (r2), (r1)) 391 392 # define jit_emit_band_ri_i(interp, pc, reg, imm) \ 393 emitm_alul_i_r((pc), 0x81, emit_b100, (imm), (reg)) 394 395 # define emitm_andl_r_m(pc, reg, b, i, s, d) \ 396 emitm_alul_r_m((pc), 0x21, (reg), (b), (i), (s), (d)) 397 398 # define emitm_andl_m_r(pc, reg, b, i, s, d) \ 399 emitm_alul_r_m((pc), 0x23, (reg), (b), (i), (s), (d)) 400 401 # define emitm_andl_i_m(pc, imm, b, i, s, d) \ 402 emitm_alul_i_m((pc), 0x81, emit_b100, (imm), (b), (i), (s), (d)) 403 404 /* TEST op */ 405 # define jit_emit_test_rr_i(pc, r1, r2) emitm_alul_r_r((pc), 0x85, (r1), (r2)) 406 407 # define jit_emit_test_ri_i(pc, r, im) \ 408 emitm_alul_i_r((pc), 0xF7, emit_b000, (im), (r)) 409 410 # define jit_emit_test_RM_i(pc, r, offs) \ 411 emitm_alul_r_m((pc), 0x85, (r), emit_EBX, 0, 1, (offs)) 412 413 /* OR */ 414 415 # define jit_emit_bor_rr_i(interp, pc, reg1, reg2) emitm_alul_r_r((pc), 0x9, (reg2), (reg1)) 416 417 # define jit_emit_bor_ri_i(interp, pc, reg, imm) \ 418 emitm_alul_i_r((pc), 0x81, emit_b001, (imm), (reg)) 419 420 # define emitm_orl_r_m(pc, reg, b, i, s, d) \ 421 emitm_alul_r_m((pc), 0x09, (reg), (b), (i), (s), (d)) 422 423 # define emitm_orl_m_r(pc, reg, b, i, s, d) \ 424 emitm_alul_r_m((pc), 0x0b, (reg), (b), (i), (s), (d)) 425 426 # define emitm_orl_i_m(pc, imm, b, i, s, d) \ 427 emitm_alul_i_m((pc), 0x81, emit_b001, (imm), (b), (i), (s), (d)) 428 429 /* XOR */ 430 431 # define jit_emit_bxor_rr_i(interp, pc, reg1, reg2) \ 432 emitm_alul_r_r((pc), 0x31, (reg2), (reg1)) 433 434 # define jit_emit_bxor_ri_i(intepr, pc, reg, imm) \ 435 emitm_alul_i_r((pc), 0x81, emit_b110, (imm), (reg)) 436 437 # define emitm_xorl_r_m(pc, reg, b, i, s, d) \ 438 emitm_alul_r_m((pc), 0x31, (reg), (b), (i), (s), (d)) 439 440 # define emitm_xorl_m_r(pc, reg, b, i, s, d) \ 441 emitm_alul_r_m((pc), 0x33, (reg), (b), (i), (s), (d)) 442 443 # define emitm_xorl_i_m(pc, imm, b, i, s, d) \ 444 emitm_alul_i_m((pc), 0x81, emit_b110, (imm), (b), (i), (s), (d)) 445 446 /* NOT */ 447 448 # define jit_emit_not_r_i(pc, reg) emitm_alu_imp_r((pc), emit_b010, (reg)) 449 # define emitm_notl_m(pc, b, i, s, d) \ 450 emitm_alu_imp_m((pc), emit_b010, (b), (i), (s), (d)) 451 452 # define jit_emit_not_M_i(interp, pc, offs) emitm_notl_m((pc), emit_EBX, 0, 1, (offs)) 453 454 /* XCHG */ 455 # define jit_emit_xchg_rr_i(interp, pc, r1, r2) { \ 456 if ((r1) != (r2)) { \ 457 *((pc)++) = (char) 0x87; \ 458 *((pc)++) = (char) emit_alu_r_r((r1), (r2)); \ 459 } \ 460 } 461 462 # define jit_emit_xchg_rm_i(pc, r, m) { \ 463 emitm_alul_r_m((pc), 0x87, (r), emit_None, emit_None, emit_None, (m)) \ 464 } 465 # define jit_emit_xchg_RM_i(interp, pc, r, offs) { \ 466 emitm_alul_r_m((pc), 0x87, (r), emit_EBX, emit_None, 1, (offs)) \ 467 } 468 # define jit_emit_xchg_MR_i(interp, pc, offs, r) jit_emit_xchg_RM_i((interp), (pc), (r), (offs)) 469 470 /* SHL */ 471 472 # define jit_emit_shl_ri_i(interp, pc, reg, imm) \ 473 { (pc) = emit_shift_i_r((interp), (pc), emit_b100, (imm), (reg)); } 474 475 # define emitm_shll_i_m(pc, imm, b, i, s, d) \ 476 { (pc) = emit_shift_i_m((pc), emit_b100, (imm), (b), (i), (s), (d)); } 477 478 # define emitm_shll_r_r(interp, pc, reg1, reg2) \ 479 { (pc) = emit_shift_r_r((interp), (pc), emit_b100, (reg1), (reg2)); } 480 481 # define emitm_shll_r_m(pc, reg, b, i, s, d) \ 482 { (pc) = emit_shift_r_m((pc), emit_b100, (reg), (b), (i), (s), (d)); } 483 484 /* SHR */ 485 486 # define jit_emit_lsr_ri_i(interp, pc, reg, imm) \ 487 { (pc) = emit_shift_i_r((interp), (pc), emit_b101, (imm), (reg)); } 488 489 # define emitm_shrl_i_m(pc, imm, b, i, s, d) \ 490 { (pc) = emit_shift_i_m((pc), emit_b101, (imm), (b), (i), (s), (d)); } 491 492 # define emitm_shrl_r_r(interp, pc, reg1, reg2) \ 493 { (pc) = emit_shift_r_r((interp), (pc), emit_b101, (reg1), (reg2)); } 494 495 # define emitm_shrl_r_m(pc, reg, b, i, s, d) \ 496 { (pc) = emit_shift_r_m((pc), emit_b101, (reg), (b), (i), (s), (d)); } 497 498 /* SAL */ 499 500 # define emitm_sall_i_r(interp, pc, imm, reg) \ 501 { (pc) = emit_shift_i_r((interp), (pc), emit_b100, (imm), (reg)); } 502 503 # define emitm_sall_i_m(pc, imm, b, i, s, d) \ 504 { (pc) = emit_shift_i_m((pc), emit_b100, (imm), (b), (i), (s), (d)); } 505 506 # define emitm_sall_r_r(interp, pc, reg1, reg2) \ 507 { (pc) = emit_shift_r_r((interp), (pc), emit_b100, (reg1), (reg2)); } 508 509 # define emitm_sall_r_m(pc, reg, b, i, s, d) \ 510 { (pc) = emit_shift_r_m((pc), emit_b100, (reg), (b), (i), (s), (d)); } 511 512 /* SAR */ 513 514 # define jit_emit_shr_ri_i(interp, pc, reg, imm) \ 515 { (pc) = emit_shift_i_r((interp), (pc), emit_b111, (imm), (reg)); } 516 517 518 # define emitm_sarl_i_m(pc, imm, b, i, s, d) \ 519 { (pc) = emit_shift_i_m((pc), emit_b111, (imm), (b), (i), (s), (d)); } 520 521 # define emitm_sarl_r_r(interp, pc, reg1, reg2) \ 522 { (pc) = emit_shift_r_r((interp), (pc), emit_b111, (reg1), (reg2)); } 523 524 # define emitm_sarl_r_m(pc, reg, b, i, s, d) \ 525 { (pc) = emit_shift_r_m((pc), emit_b111, (reg), (b), (i), (s), (d)); } 526 527 /* rotate */ 528 529 # define jit_emit_rol_ri_i(interp, pc, reg, imm) \ 530 { (pc) = emit_shift_i_r((interp), (pc), emit_b000, (imm), (reg)); } 531 532 # define jit_emit_ror_ri_i(interp, pc, reg, imm) \ 533 { (pc) = emit_shift_i_r((interp), (pc), emit_b001, (imm), (reg)); } 534 535 /* interface, shift r1 by r2 bits */ 536 537 # define jit_emit_shl_rr_i(interp, pc, r1, r2) \ 538 (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b100) 539 540 # define jit_emit_shl_RM_i(interp, pc, r1, offs) \ 541 (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b100) 542 543 /* shr seems to be the arithmetic shift */ 544 # define jit_emit_shr_rr_i(interp, pc, r1, r2) \ 545 (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b111) 546 547 # define jit_emit_shr_RM_i(interp, pc, r1, offs) \ 548 (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b111) 549 550 # define jit_emit_lsr_rr_i(interp, pc, r1, r2) \ 551 (pc) = opt_shift_rr((interp), jit_info, (r1), (r2), emit_b101) 552 553 # define jit_emit_lsr_RM_i(interp, pc, r1, offs) \ 554 (pc) = opt_shift_rm((interp), jit_info, (r1), (offs), emit_b101) 555 556 /* MOV (reg), reg */ 557 # define emit_movm_r_r(pc, src, dest) \ 558 *((pc)++) = (char) 0x8b; \ 559 *((pc)++) = (char) (src) | (dest) << 3 560 561 /* MOV X(reg), reg */ 562 # define emit_movb_i_r_r(pc, imm, src, dest) \ 563 *((pc)++) = (char)(0x8b); \ 564 *((p)c++) = (char)(0x40 | ((src) - 1) | ((dest) - 1) << 3); \ 565 *((pc)++) = (imm) 566 567 /* INC / DEC */ 568 # define jit_emit_inc_r_i(pc, reg) *((pc)++) = (char)(0x40 | ((reg) - 1)) 569 # define jit_emit_dec_r_i(pc, reg) *((pc)++) = (char)(0x48 | ((reg) - 1)) 570 571 /* Floating point ops */ 572 573 # define emitm_floatop 0xd8 /* 11011000 */ 574 # define jit_emit_dec_fsp(pc) { *((pc)++) = (char) 0xD9; *((pc)++) = (char) 0xF6; } 575 # define jit_emit_inc_fsp(pc) { *((pc)++) = (char) 0xD9; *((pc)++) = (char) 0xF7; } 576 577 # define emitm_fl_2(interp, pc, mf, opa, opb, b, i, s, d) { \ 578 *((pc)++) = (char)(emitm_floatop | ((mf) << 1) | (opa)); \ 579 (pc) = emit_r_X((interp), (pc), emit_reg(opb), (b), (i), (s), (long)(d)); } 580 581 # define emitm_fl_3(pc, d_p_opa, opb_r, sti) { \ 582 *((pc)++) = (char)(emitm_floatop | (d_p_opa)); \ 583 *((pc)++) = (char)(0xc0 | ((opb_r) << 3) | (sti)); } 584 585 # define emitm_fl_4(pc, op) { \ 586 *((pc)++) = (char)(emitm_floatop | emit_b001); \ 587 *((pc)++) = (char)(0xe0 | (op)); } 588 589 /* Integer loads and stores */ 590 # define emitm_fildl(interp, pc, b, i, s, d) \ 591 emitm_fl_2((interp), (pc), emit_b01, 1, emit_b000, (b), (i), (s), (d)) 592 593 # define emitm_fistpl(interp, pc, b, i, s, d) \ 594 emitm_fl_2((interp), (pc), emit_b01, 1, emit_b011, (b), (i), (s), (d)) 595 596 # define emitm_fistl(interp, pc, b, i, s, d) \ 597 emitm_fl_2((interp), (pc), emit_b01, 1, emit_b010, (b), (i), (s), (d)) 598 599 /* long long integer load/store */ 600 # define emitm_fildll(interp, pc, b, i, s, d) \ 601 emitm_fl_2((interp), (pc), emit_b11, 1, emit_b101, (b), (i), (s), (d)) 602 603 # define emitm_fistpll(interp, pc, b, i, s, d) \ 604 emitm_fl_2((interp), (pc), emit_b11, 1, emit_b111, (b), (i), (s), (d)) 605 606 /* Double loads and stores */ 607 # define emitm_fldl(interp, pc, b, i, s, d) \ 608 emitm_fl_2((interp), (pc), emit_b10, 1, emit_b000, (b), (i), (s), (d)) 609 610 # define emitm_fstpl(interp, pc, b, i, s, d) \ 611 emitm_fl_2((interp), (pc), emit_b10, 1, emit_b011, (b), (i), (s), (d)) 612 613 # define emitm_fstl(interp, pc, b, i, s, d) \ 614 emitm_fl_2((interp), (pc), emit_b10, 1, emit_b010, (b), (i), (s), (d)) 615 616 /* long double load / store */ 617 # define emitm_fldt(interp, pc, b, i, s, d) \ 618 emitm_fl_2((interp), (pc), emit_b01, 1, emit_b101, (b), (i), (s), (d)) 619 620 # define emitm_fstpt(interp, pc, b, i, s, d) \ 621 emitm_fl_2((interp), (pc), emit_b01, 1, emit_b111, (b), (i), (s), (d)) 622 623 /* short float load / store */ 624 # define emitm_flds(interp, pc, b, i, s, d) \ 625 emitm_fl_2((interp), (pc), emit_b00, 1, emit_b000, (b), (i), (s), (d)) 626 627 # define emitm_fstps(interp, pc, b, i, s, d) \ 628 emitm_fl_2((interp), (pc), emit_b00, 1, emit_b010, (b), (i), (s), (d)) 629 630 #if NUMVAL_SIZE == 8 631 632 # define jit_emit_fload_m_n(interp, pc, address) \ 633 emitm_fldl((interp), (pc), emit_None, emit_None, emit_None, (address)) 634 635 # define jit_emit_fload_mb_n(interp, pc, base, offs) \ 636 emitm_fldl((interp), (pc), (base), emit_None, 1, (offs)) 637 638 # define jit_emit_fstore_m_n(interp, pc, address) \ 639 emitm_fstpl((interp), (pc), emit_None, emit_None, emit_None, (address)) 640 641 # define jit_emit_fstore_mb_n(interp, pc, base, offs) \ 642 emitm_fstpl((interp), (pc), (base), emit_None, 1, (offs)) 643 644 # define jit_emit_fst_mb_n(interp, pc, base, offs) \ 645 emitm_fstl((interp), (pc), (base), emit_None, 1, (offs)) 646 647 #else /* NUMVAL_SIZE */ 648 649 # define jit_emit_fload_m_n(interp, pc, address) \ 650 emitm_fldt((pc), emit_None, emit_None, emit_None, (address)) 651 652 # define jit_emit_fload_mb_n(interp, pc, base, offs) \ 653 emitm_fldt((pc), (base), emit_None, 1, (offs)) 654 655 # define jit_emit_fstore_m_n(pc, address) \ 656 emitm_fstpt((pc), emit_None, emit_None, emit_None, (address)) 657 658 # define jit_emit_fstore_mb_n(interp, pc, base, offs) \ 659 emitm_fstpt((pc), (base), emit_None, 1, (offs)) 660 661 # define jit_emit_fst_mb_n(interp, pc, base, offs) \ 662 emitm_fstt((pc), (base), emit_None, 1, (offs)) 663 664 #endif /* NUMVAL_SIZE */ 665 666 #if INTVAL_SIZE == 4 667 668 # define jit_emit_fload_m_i(interp, pc, address) \ 669 emitm_fildl((interp), (pc), emit_None, emit_None, emit_None, (address)) 670 # define jit_emit_fload_mb_i(interp, pc, offs) \ 671 emitm_fildl((interp), (pc), emit_EBX, emit_None, 1, (offs)) 672 # define jit_emit_fstore_m_i(pc, m) \ 673 emitm_fistpl((pc), emit_None, emit_None, emit_None, (m)) 674 675 #else /* INTVAL_SIZE */ 676 677 # define jit_emit_fload_m_i(interp, pc, address) \ 678 emitm_fildll((interp), (pc), emit_None, emit_None, emit_None, (address)) 679 # define jit_emit_fload_mb_i(interp, pc, offs) \ 680 emitm_fildll((interp), (pc), emit_EBX, emit_None, 1, (offs)) 681 # define jit_emit_fstore_m_i(pc, m) \ 682 emitm_fistpll((pc), emit_None, emit_None, emit_None, (m)) 683 684 #endif /* INTVAL_SIZE */ 685 686 /* 0xD8 ops */ 687 # define emitm_fadd(pc, sti) emitm_fl_3((pc), emit_b000, emit_b000, (sti)) 688 # define emitm_fmul(pc, sti) emitm_fl_3((pc), emit_b000, emit_b001, (sti)) 689 # define emitm_fsub(pc, sti) emitm_fl_3((pc), emit_b000, emit_b100, (sti)) 690 # define emitm_fdiv(pc, sti) emitm_fl_3((pc), emit_b000, emit_b110, (sti)) 691 692 /* 0xD9 ops */ 693 # define emitm_fldz(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xee; } 694 # define emitm_fld1(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xe8; } 695 # define emitm_fsqrt(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xfa; } 696 # define emitm_fsin(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xfe; } 697 # define emitm_fcos(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xff; } 698 # define emitm_fxam(pc) { *((pc)++) = (char) 0xd9; *((pc)++) = (char) 0xe5; } 699 700 /* FXCH ST, ST(i) , optimize 2 consecutive fxch with same reg */ 701 # define emitm_fxch(pc, sti) { \ 702 emitm_fl_3((pc), emit_b001, emit_b001, (sti)); \ 703 } 704 705 /* FLD ST, ST(i), optimized FSTP(N+1);FLD(N) => FST(N+1) */ 706 extern unsigned char *lastpc; 707 # define emitm_fld(pc, sti) do { \ 708 if ((unsigned char *)(pc) == (lastpc + 2) && \ 709 (int)(*lastpc) == (int)0xDD && \ 710 (int)lastpc[1] == (int)(0xD8+(sti)+1)) \ 711 lastpc[1] = 0xD0+(sti)+1; \ 712 else \ 713 emitm_fl_3((pc), emit_b001, emit_b000, (sti)); \ 714 } while (0) 715 716 /* 0xDA, 0xDB ops */ 717 /* FCMOV*, FCOMI PPRO */ 718 719 /* 0xDC like 0xD8 with reversed operands */ 720 # define emitm_faddr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b000, (sti)) 721 # define emitm_fmulr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b001, (sti)) 722 # define emitm_fsubr(pc, sti) emitm_fl_3((pc), emit_b100, emit_b100, (sti)) 723 724 /* 0xDD ops */ 725 /* FFree ST(i) */ 726 # define emitm_ffree(pc, sti) emitm_fl_3((pc), emit_b101, emit_b000, (sti)) 727 728 /* FST ST(i) = ST */ 729 # define emitm_fst(pc, sti) emitm_fl_3((pc), emit_b101, emit_b010, (sti)) 730 731 /* FSTP ST(i) = ST, POP */ 732 # define emitm_fstp(pc, sti) { \ 733 lastpc = (unsigned char*) (pc); \ 734 emitm_fl_3((pc), emit_b101, emit_b011, (sti)); \ 735 } 736 737 /* FUCOM ST(i) <=> ST unordered compares */ 738 # define emitm_fucom(pc, sti) emitm_fl_3((pc), emit_b101, emit_b100, (sti)) 739 740 /* FUCOMP ST(i) <=> ST, POP */ 741 # define emitm_fucomp(pc, sti) emitm_fl_3((pc), emit_b101, emit_b101, (sti)) 742 743 /* 0xDE ops */ 744 /* FADDP Add ST(i) = ST + ST(i); POP */ 745 # define emitm_faddp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b000, (sti)) 746 747 /* FMULP Mul ST(i) = ST * ST(i); POP */ 748 # define emitm_fmulp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b001, (sti)) 749 750 /* FSUB ST = ST - ST(i) */ 751 752 /* FSUBRP SubR ST(i) = ST - ST(i); POP */ 753 # define emitm_fsubrp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b100, (sti)) 754 755 /* FSUBP Sub ST(i) = ST(i) - ST; POP */ 756 # define emitm_fsubp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b101, (sti)) 757 758 /* FDIVRP DivR ST(i) = ST(i) / ST(0); POP */ 759 # define emitm_fdivrp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b110, (sti)) 760 761 /* FDIVP Div ST(i) = ST(0) / ST(i); POP ST(0) */ 762 # define emitm_fdivp(pc, sti) emitm_fl_3((pc), emit_b110, emit_b111, (sti)) 763 764 /* 0xDF OPS: FCOMIP, FUCOMIP PPRO */ 765 766 /* Negate - called change sign */ 767 # define emitm_fchs(pc) emitm_fl_4((pc), 0) 768 769 /* ABS - ST(0) = ABS(ST(0)) */ 770 # define emitm_fabs(pc) emitm_fl_4((pc), 1) 771 772 /* Comparisons */ 773 774 # define emitm_fcom(pc, sti) emitm_fl_3((pc), emit_b000, emit_b010, (sti)) 775 776 # define emitm_fcomp(pc, sti) emitm_fl_3((pc), emit_b000, emit_b011, (sti)) 777 778 #ifdef PARROT_HAS_JIT_FCOMIP 779 # define emitm_fcomip(pc, sti) emitm_fl_3((pc), emit_b111, emit_b110, (sti)) 780 # define emitm_fcomi(pc, sti) emitm_fl_3((pc), emit_b011, emit_b110, (sti)) 781 #else 782 # define emitm_fcomip(pc, sti) do { \ 783 emitm_fcomp((pc), (sti)); \ 784 emitm_fstw(pc); \ 785 emitm_sahf(pc); \ 786 } while (0) 787 # define emitm_fcomi(pc, sti) do { \ 788 emitm_fcom((pc), (sti)); \ 789 emitm_fstw(pc); \ 790 emitm_sahf(pc); \ 791 } while (0) 792 #endif 793 794 # define emitm_fcompp(pc) { *((pc)++) = (char) 0xde; *((pc)++) = (char) 0xd9; } 795 796 # define emitm_fcom_m(interp, pc, b, i, s, d) \ 797 emitm_fl_2((interp), (pc), emit_b10, 0, emit_b010, (b), (i), (s), (d)) 798 799 # define emitm_fcomp_m(interp, pc, b, i, s, d) \ 800 emitm_fl_2((interp), (pc), emit_b10, 0, emit_b011, (b), (i), (s), (d)) 801 802 /* ST -= real64 */ 803 # define emitm_fsub_m(interp, pc, b, i, s, d) \ 804 emitm_fl_2((interp), (pc), emit_b10, 0, emit_b100, (b), (i), (s), (d)) 805 806 /* ST -= int32_mem */ 807 # define emitm_fisub_m(interp, pc, b, i, s, d) \ 808 emitm_fl_2((interp), (pc), emit_b01, 0, emit_b100, (b), (i), (s), (d)) 809 810 # define emitm_fadd_m(interp, pc, b, i, s, d) \ 811 emitm_fl_2((interp), (pc), emit_b10, 0, emit_b000, (b), (i), (s), (d)) 812 813 /* ST += int32_mem */ 814 # define emitm_fiadd_m(interp, pc, b, i, s, d) \ 815 emitm_fl_2((interp), (pc), emit_b01, 0, emit_b000, (b), (i), (s), (d)) 816 817 /* ST *= real64 */ 818 # define emitm_fmul_m(interp, pc, b, i, s, d) \ 819 emitm_fl_2((interp), (pc), emit_b10, 0, emit_b001, (b), (i), (s), (d)) 820 821 /* ST *= int32_mem */ 822 # define emitm_fimul_m(interp, pc, b, i, s, d) \ 823 emitm_fl_2((interp), (pc), emit_b01, 0, emit_b001, (b), (i), (s), (d)) 824 825 /* ST /= real64 */ 826 # define emitm_fdiv_m(interp, pc, b, i, s, d) \ 827 emitm_fl_2((interp), (pc), emit_b10, 0, emit_b110, (b), (i), (s), (d)) 828 829 /* ST /= int32_mem */ 830 # define emitm_fidiv_m(interp, pc, b, i, s, d) \ 831 emitm_fl_2((interp), (pc), emit_b01, 0, emit_b110, (b), (i), (s), (d)) 832 833 /* Ops Needed to support loading EFLAGs for conditional branches */ 834 # define emitm_fstw(pc) emitm_fl_3((pc), emit_b111, emit_b100, emit_b000) 835 836 # define emitm_sahf(pc) *((pc)++) = (char) 0x9e 837 838 /* misc float */ 839 # define emitm_ftst(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xE4; } 840 # define emitm_fprem(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xF8; } 841 # define emitm_fprem1(pc) { *(pc)++ = 0xd9; *(pc)++ = 0xF5; } 842 843 # define emitm_fldcw(interp, pc, mem) \ 844 emitm_fl_2((interp), (pc), emit_b00, 1, emit_b101, 0, 0, 0, (mem)) 845 846 #if defined(NEG_MINUS_ZERO) 847 # define jit_emit_neg_r_n(pc, r) { \ 848 if (r) { \ 849 emitm_fld((pc), (r)); \ 850 } \ 851 emitm_fchs(pc); \ 852 if (r) { \ 853 emitm_fstp((pc), ((r)+1)); \ 854 } \ 855 } 856 857 # define jit_emit_neg_M_n(interp, pc, mem) { \ 858 jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \ 859 emitm_fchs(pc); \ 860 jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \ 861 } 862 863 #elif defined(NEG_ZERO_SUB) 864 865 # define jit_emit_neg_r_n(pc, r) { \ 866 emitm_fldz(pc); \ 867 emitm_fsubrp((pc), ((r)+1)); \ 868 } 869 870 # define jit_emit_neg_M_n(interp, pc, mem) { \ 871 jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \ 872 emitm_fldz(pc); \ 873 emitm_fsubrp((pc), 1); \ 874 jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \ 875 } 876 #else 877 878 # define jit_emit_neg_r_n(pc, r) { \ 879 if (r) { \ 880 emitm_fld((pc), (r)); \ 881 } \ 882 emitm_ftst(pc); \ 883 emitm_fstw(pc); \ 884 emitm_sahf(pc); \ 885 emitm_jxs((pc), emitm_jz, 2); \ 886 emitm_fchs(pc); \ 887 if (r) { \ 888 emitm_fstp((pc), ((r)+1)); \ 889 } \ 890 } 891 892 # define jit_emit_neg_M_n(interp, pc, mem) { \ 893 jit_emit_fload_mb_n((interp), (pc), emit_EBX, (mem)); \ 894 emitm_ftst(pc); \ 895 emitm_fstw(pc); \ 896 emitm_sahf(pc); \ 897 emitm_jxs((pc), emitm_jz, 2); \ 898 emitm_fchs(pc); \ 899 jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (mem)); \ 900 } 901 #endif 902 903 # define jit_emit_sin_r_n(pc, r) \ 904 if (r) { \ 905 emitm_fld((pc), (r)); \ 906 } \ 907 emitm_fsin(pc); \ 908 if (r) { \ 909 emitm_fstp((pc), ((r)+1)); \ 910 } 911 912 # define jit_emit_cos_r_n(pc, r) \ 913 if (r) { \ 914 emitm_fld((pc), (r)); \ 915 } \ 916 emitm_fcos(pc); \ 917 if (r) { \ 918 emitm_fstp((pc), ((r)+1)); \ 919 } 920 921 # define jit_emit_sqrt_r_n(pc, r) \ 922 if (r) { \ 923 emitm_fld((pc), (r)); \ 924 } \ 925 emitm_fsqrt(pc); \ 926 if (r) { \ 927 emitm_fstp((pc), ((r)+1)); \ 928 } 929 930 # define jit_emit_abs_r_n(pc, r) { \ 931 if (r) { \ 932 emitm_fld((pc), (r)); \ 933 } \ 934 emitm_fabs(pc); \ 935 if (r) { \ 936 emitm_fstp((pc), ((r)+1)); \ 937 } \ 938 } 939 940 # define jit_emit_abs_r_i(pc, r) { \ 941 jit_emit_test_r_i((pc), (r)); \ 942 emitm_jxs((pc), emitm_jns, 3); \ 943 jit_emit_not_r_i((pc), (r)); \ 944 jit_emit_inc_r_i((pc), (r)); \ 945 } 946 947 # define jit_emit_abs_m_n(interp, pc, mem) { \ 948 jit_emit_fload_m_n((interp), (pc), (mem)); \ 949 emitm_fabs(pc); \ 950 jit_emit_fstore_m_n((pc), (mem)); \ 951 } 952 953 /* Integer comparisons */ 954 # define jit_emit_cmp_rr(pc, reg1, reg2) \ 955 emitm_alul_r_r((pc), 0x39, (reg2), (reg1)) 956 # define jit_emit_cmp_rr_i(pc, r1, r2) jit_emit_cmp_rr((pc), (r1), (r2)) 957 958 # define emitm_cmpl_r_m(pc, reg, b, i, s, d) \ 959 emitm_alul_r_m((pc), 0x3b, (reg), (b), (i), (s), (d)) 960 961 # define emitm_cmpl_m_r(pc, reg, b, i, s, d) \ 962 emitm_alul_r_m((pc), 0x39, (reg), (b), (i), (s), (d)) 963 964 # define jit_emit_cmp_ri_i(interp, pc, reg, imm) \ 965 emitm_alul_i_r((pc), 0x81, emit_b111, (imm), (reg)) 966 967 /* Unconditional Jump/Call */ 968 969 # define emitm_call_cfunc(pc, func) emitm_calll((pc), (char *)(func) - (pc) - 4) 970 971 # define emitm_calll(pc, disp) { \ 972 *((pc)++) = (char) 0xe8; \ 973 *(long *)(pc) = (disp); (pc) += 4; } 974 975 # define emitm_callr(pc, reg) { \ 976 *((pc)++) = (char) 0xff; \ 977 *((pc)++) = (char) 0xd0 | ((reg) - 1); } 978 979 # define emitm_callm(pc, b, i, s, d) { \ 980 *((pc)++) = (char) 0xff; \ 981 (pc) = emit_r_X((interp), (pc), emit_reg(emit_b010), (b), (i), (s), (d)); } 982 983 # define emitm_jumps(pc, disp) { \ 984 *((pc)++) = (char) 0xeb; \ 985 *((pc)++) = (disp); } 986 987 # define emitm_jumpl(pc, disp) { \ 988 *((pc)++) = (char) 0xe9; \ 989 *(long *)(pc) = (disp); (pc) += 4; } 990 991 # define emitm_jumpr(pc, reg) { \ 992 *((pc)++) = (char) 0xff; \ 993 *((pc)++) = (char)(0xe0 | ((reg) - 1)); } 994 995 # define emitm_jumpm(pc, b, i, s, d) { \ 996 *((pc)++) = (char) 0xff; \ 997 (pc) = emit_r_X((interp), (pc), emit_reg(emit_b100), (b), (i), (s), (d)); } 998 999 /* Conditional jumps */ 1000 1001 /* Short jump - 8 bit disp */ 1002 # define emitm_jxs(pc, code, disp) { \ 1003 *((pc)++) = (char)(0x70 | (code)); \ 1004 *((pc)++) = (char)(disp); } 1005 1006 /* Long jump - 32 bit disp */ 1007 # define emitm_jxl(pc, code, disp) { \ 1008 *((pc)++) = (char) 0x0f; \ 1009 *((pc)++) = (char)(0x80 | (code)); \ 1010 *(long *)(pc) = (disp); (pc) += 4; } 1011 1012 # define emitm_jo 0 1013 # define emitm_jno 1 1014 # define emitm_jb 2 1015 # define emitm_jnb 3 1016 # define emitm_jz 4 1017 # define emitm_je emitm_jz 1018 # define emitm_jnz 5 1019 # define emitm_jne emitm_jnz 1020 # define emitm_jbe 6 1021 # define emitm_ja 7 1022 # define emitm_js 8 1023 # define emitm_jns 9 1024 # define emitm_jp 10 1025 # define emitm_jnp 11 1026 # define emitm_jl 12 1027 # define emitm_jnl 13 1028 # define emitm_jle 14 1029 # define emitm_jg 15 1030 1031 /* set byte conditional */ 1032 # define jit_emit_setcc_r(pc, cc, r) \ 1033 *(pc)++ = 0x0f; \ 1034 *(pc)++ = 0x90 + (cc); \ 1035 *(pc)++ = (char) emit_alu_X_r(0, (r)) 1036 1037 /* 1038 * core.jit interface 1039 * 1040 * The new offset based versions have uppercase RM or MR inside 1041 * That's probably only during transition time 1042 */ 1043 1044 # define jit_emit_mov_mi_i(pc, dest, immediate) \ 1045 emitm_movl_i_m((pc), (immediate), emit_None, emit_None, emit_None, (dest)) 1046 1047 # define jit_emit_mov_MI_i(interp, pc, offs, immediate) \ 1048 emitm_movl_i_m((pc), (immediate), emit_EBX, emit_None, 1, (offs)) 1049 1050 # define jit_emit_mov_rm_i(interp, pc, reg, address) \ 1051 emitm_movl_m_r((interp), (pc), (reg), emit_None, emit_None, emit_None, (address)) 1052 1053 # define jit_emit_mov_RM_i(interp, pc, reg, offs) \ 1054 emitm_movl_m_r((interp), (pc), (reg), emit_EBX, emit_None, 1, (offs)) 1055 1056 # define jit_emit_mov_mr_i(interp, pc, address, reg) \ 1057 emitm_movl_r_m((interp), (pc), (reg), emit_None, emit_None, emit_None, (address)) 1058 1059 # define jit_emit_mov_MR_i(interp, pc, offs, reg) \ 1060 emitm_movl_r_m((interp), (pc), (reg), emit_EBX, emit_None, 1, (offs)) 1061 1062 # define jit_emit_mul_RM_i(interp, pc, reg, offs) \ 1063 emitm_smull_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs)) 1064 1065 # define jit_emit_sub_RM_i(interp, pc, reg, offs) \ 1066 emitm_subl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs)) 1067 1068 # define jit_emit_sub_MR_i(interp, pc, offs, reg) \ 1069 emitm_subl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs)) 1070 1071 # define jit_emit_sub_MI_i(pc, offs, imm) \ 1072 emitm_subl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs)) 1073 1074 # define jit_emit_add_RM_i(interp, pc, reg, offs) \ 1075 emitm_addl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs)) 1076 1077 # define jit_emit_add_MR_i(interp, pc, offs, reg) \ 1078 emitm_addl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs)) 1079 1080 # define jit_emit_add_MI_i(pc, offs, imm) \ 1081 emitm_addl_i_m((pc), (imm), emit_EBX, emit_None, 1, (offs)) 1082 1083 # define jit_emit_cmp_rm_i(pc, reg, address) \ 1084 emitm_cmpl_r_m((pc), (reg), emit_None, emit_None, emit_None, (address)) 1085 1086 # define jit_emit_cmp_RM_i(interp, pc, reg, offs) \ 1087 emitm_cmpl_r_m((pc), (reg), emit_EBX, emit_None, 1, (offs)) 1088 1089 # define jit_emit_cmp_MR_i(interp, pc, offs, reg) \ 1090 emitm_cmpl_m_r((pc), (reg), emit_EBX, emit_None, 1, (offs)) 1091 1092 /* high level routines, behave like real 2 register FP */ 1093 1094 /* mapped float registers numbers are ST(1)-ST(4). 1095 * scratch register is ST(0) 1096 */ 1097 1098 /* ST(i) <- numvar */ 1099 # define jit_emit_mov_RM_n(interp, pc, r, d) { \ 1100 jit_emit_fload_mb_n((interp), (pc), emit_EBX, (d)); \ 1101 emitm_fstp((pc), ((r)+1)); \ 1102 } 1103 1104 /* ST(i) <= NUM_CONST */ 1105 # define jit_emit_mov_ri_n(interp, pc, r, i) { \ 1106 jit_emit_fload_m_n((interp), (pc), (i)); \ 1107 emitm_fstp((pc), ((r)+1)); \ 1108 } 1109 1110 /* ST(i) <= &INT_CONST */ 1111 # define jit_emit_mov_ri_ni(interp, pc, r, i) { \ 1112 jit_emit_fload_m_i((interp), (pc), (i)); \ 1113 emitm_fstp((pc), ((r)+1)); \ 1114 } 1115 1116 /* ST(i) <= INT_REG */ 1117 # define jit_emit_mov_RM_ni(interp, pc, r, i) { \ 1118 jit_emit_fload_mb_i((interp), (pc), (i)); \ 1119 emitm_fstp((pc), ((r)+1)); \ 1120 } 1121 1122 /* NUM_REG(i) <= &INT_CONST 1123 * the int const i is loaded from the code memory 1124 */ 1125 # define jit_emit_mov_MI_ni(interp, pc, offs, i) { \ 1126 jit_emit_fload_m_i((interp), (pc), (i)); \ 1127 jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \ 1128 } 1129 1130 /* INT_REG <= ST(i) */ 1131 # define jit_emit_mov_mr_in(pc, mem, r) { \ 1132 emitm_fld((pc), (r)); \ 1133 jit_emit_fstore_m_i((pc), (mem)); \ 1134 } 1135 1136 /* numvar <- ST(i) */ 1137 # define jit_emit_mov_mr_n(pc, d, r) { \ 1138 emitm_fld((pc), (r)); \ 1139 jit_emit_fstore_m_n((pc), (d)); \ 1140 } 1141 1142 # define jit_emit_mov_MR_n(interp, pc, d, r) { \ 1143 if (r) { \ 1144 emitm_fld((pc), (r)); \ 1145 jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (d)); \ 1146 } \ 1147 else { \ 1148 jit_emit_fst_mb_n((interp), (pc), emit_EBX, (d)); \ 1149 } \ 1150 } 1151 1152 /* ST(r1) <= ST(r2) */ 1153 # define jit_emit_mov_rr_n(pc, r1, r2) { \ 1154 if ((r1) != (r2)) { \ 1155 if (r2) { \ 1156 emitm_fld((pc), (r2)); \ 1157 emitm_fstp((pc), ((r1)+1)); \ 1158 } \ 1159 else { \ 1160 emitm_fst((pc), (r1)); \ 1161 } \ 1162 } \ 1163 } 1164 1165 /* ST(r1) xchg ST(r2) */ 1166 # define jit_emit_xchg_rr_n(interp, pc, r1, r2) { \ 1167 if ((r1) != (r2)) { \ 1168 emitm_fld((pc), (r1)); \ 1169 emitm_fld((pc), ((r2)+1)); \ 1170 emitm_fstp((pc), ((r1)+2)); \ 1171 emitm_fstp((pc), ((r2)+1)); \ 1172 } \ 1173 } 1174 1175 # define jit_emit_xchg_RM_n(interp, pc, r, offs) { \ 1176 emitm_fld((pc), (r)); \ 1177 jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \ 1178 emitm_fstp((pc), ((r)+2)); \ 1179 jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \ 1180 } 1181 1182 # define jit_emit_xchg_MR_n(interp, pc, offs, r) { \ 1183 emitm_fld((pc), (r)); \ 1184 jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \ 1185 emitm_fstp((pc), ((r)+2)); \ 1186 jit_emit_fstore_mb_n((interp), (pc), emit_EBX, (offs)); \ 1187 } 1188 1189 # define jit_emit_finit(pc) { *((pc)++) = (char) 0xdb; *((pc)++) = (char) 0xe3; } 1190 1191 /* ST(i) op= MEM */ 1192 1193 # define jit_emit_xxx_rm_n(interp, op, pc, r, m) { \ 1194 jit_emit_fload_m_n((interp), (pc), (m)); \ 1195 emitm_f ## op ## p((pc), ((r)+1)); \ 1196 } 1197 1198 # define jit_emit_xxx_RM_n(interp, op, pc, r, offs) { \ 1199 jit_emit_fload_mb_n((interp), (pc), emit_EBX, (offs)); \ 1200 emitm_f ## op ## p((pc), ((r)+1)); \ 1201 } 1202 1203 /* 1204 * float ops in two flavors: abs memory for constants, offsets for regs 1205 */ 1206 1207 # define jit_emit_add_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), add, (pc), (r), (m)) 1208 # define jit_emit_sub_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), sub, (pc), (r), (m)) 1209 # define jit_emit_mul_ri_n(interp, pc, r, m) jit_emit_xxx_rm_n((interp), mul, (pc), (r), (m)) 1210 1211 # define jit_emit_add_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), add, (pc), (r), (o)) 1212 # define jit_emit_sub_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), sub, (pc), (r), (o)) 1213 # define jit_emit_mul_RM_n(interp, pc, r, o) jit_emit_xxx_RM_n((interp), mul, (pc), (r), (o)) 1214 1215 /* ST(r1) += ST(r2) */ 1216 /* r1 == 0: ST(0) <- ST(0) + ST(i) 1217 * r2 == 0: ST(i) <- ST(0) + ST(i) 1218 */ 1219 # define jit_emit_add_rr_n(interp, pc, r1, r2) do { \ 1220 if (!(r1)) { \ 1221 emitm_fadd((pc), (r2)); \ 1222 } \ 1223 else if (!(r2)) { \ 1224 emitm_faddr((pc), (r1)); \ 1225 } \ 1226 else { \ 1227 emitm_fld((pc), (r2)); \ 1228 emitm_faddp((pc), ((r1)+1)); \ 1229 } \ 1230 } \ 1231 while (0) 1232 /* 1233 * ST(r) += INT_REG 1234 */ 1235 # define jit_emit_add_RM_ni(pc, r, offs) { \ 1236 emitm_fld((pc), (r)); \ 1237 emitm_fiadd_m((pc), emit_EBX, 0, 1, (offs)); \ 1238 emitm_fstp((pc), ((r)+1)); \ 1239 } 1240 1241 /* ST(r1) -= ST(r2) */ 1242 /* r1 == 0: ST(0) <- ST(0) - ST(i) 1243 * r2 == 0: ST(i) <- ST(i) - ST(0) 1244 */ 1245 # define jit_emit_sub_rr_n(interp, pc, r1, r2) do { \ 1246 if (!(r1)) { \ 1247 emitm_fsub((pc), (r2)); \ 1248 } \ 1249 else if (!(r2)) { \ 1250 emitm_fsubr((pc), (r1)); \ 1251 } \ 1252 else { \ 1253 emitm_fld((pc), (r2)); \ 1254 emitm_fsubp((pc), ((r1)+1)); \ 1255 } \ 1256 } \ 1257 while (0) 1258 1259 /* 1260 * ST(r) -= INT_REG 1261 */ 1262 # define jit_emit_sub_RM_ni(pc, r, offs) { \ 1263 emitm_fld((pc), (r)); \ 1264 emitm_fisub_m((pc), emit_EBX, 0, 1, (offs)); \ 1265 emitm_fstp((pc), ((r)+1)); \ 1266 } 1267 1268 # define jit_emit_inc_r_n(pc, r) { \ 1269 emitm_fld1(pc); \ 1270 emitm_faddp((pc), ((r)+1)); \ 1271 } 1272 1273 # define jit_emit_dec_r_n(pc, r) { \ 1274 emitm_fld1(pc); \ 1275 emitm_fsubp((pc), ((r)+1)); \ 1276 } 1277 1278 /* ST(r1) *= ST(r2) */ 1279 /* r1 == 0: ST(0) <- ST(0) * ST(i) 1280 * r2 == 0: ST(i) <- ST(0) * ST(i) 1281 */ 1282 # define jit_emit_mul_rr_n(interp, pc, r1, r2) do { \ 1283 if (!(r1)) { \ 1284 emitm_fmul((pc), (r2)); \ 1285 } \ 1286 else if (!(r2)) { \ 1287 emitm_fmulr((pc), (r1)); \ 1288 } \ 1289 else { \ 1290 emitm_fld((pc), (r2)); \ 1291 emitm_fmulp((pc), ((r1)+1)); \ 1292 } \ 1293 } \ 1294 while (0) 1295 1296 /* 1297 * ST(r) *= INT_REG 1298 */ 1299 # define jit_emit_mul_RM_ni(pc, r, offs) { \ 1300 emitm_fld((pc), (r)); \ 1301 emitm_fimul_m((pc), emit_EBX, 0, 1, (offs)); \ 1302 emitm_fstp((pc), ((r)+1)); \ 1303 } 1304 1305 /* 1306 * ST(r) /= INT_REG 1307 */ 1308 # define jit_emit_div_RM_ni(pc, r, offs) { \ 1309 emitm_fld((pc), (r)); \ 1310 emitm_fidiv_m((pc), emit_EBX, 0, 1, (offs)); \ 1311 emitm_fstp((pc), ((r)+1)); \ 1312 } 1313 1314 /* test r for zero */ 1315 # define jit_emit_test_r_n(pc, r) { \ 1316 if (r) { \ 1317 emitm_fxch((pc), (r)); \ 1318 } \ 1319 emitm_fxam(pc); \ 1320 emitm_fstw(pc); \ 1321 emitm_sahf(pc); \ 1322 if (r) { \ 1323 emitm_fxch((pc), (r)); \ 1324 } \ 1325 } 1326 1327 enum { JIT_X86BRANCH, JIT_X86JUMP, JIT_X86CALL }; 1328 1329 # define jit_emit_stack_frame_enter(pc) do { \ 1330 emitm_pushl_r((pc), emit_EBP); \ 1331 jit_emit_mov_rr_i((pc), emit_EBP, emit_ESP); \ 1332 } while (0) 1333 1334 # define jit_emit_stack_frame_leave(pc) do { \ 1335 jit_emit_mov_rr_i((pc), emit_ESP, emit_EBP); \ 1336 emitm_popl_r((pc), emit_EBP); \ 1337 } while (0) 1338 1339 # define jit_emit_end(pc) { \ 1340 jit_emit_add_ri_i((interp), (pc), emit_ESP, 4); \ 1341 emitm_popl_r((pc), emit_EDI); \ 1342 emitm_popl_r((pc), emit_ESI); \ 1343 emitm_popl_r((pc), emit_EBX); \ 1344 emitm_popl_r((pc), emit_EBP); \ 1345 emitm_ret(pc); \ 1346 } 1347 1348 size_t calc_signature_needs(const char *sig, int *strings); 1349 1350 void * Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, 1351 STRING *signature, int *sizeptr); 1352 1353 /* 1354 * register usage 1355 * %edi, %esi ... mapped, preserved 1356 * %edx, %ecx ... mapped, not preserved 1357 * %ebx ... base pointer for register access, preserved 1358 * %eax ... scratch, return value register 1359 */ 1360 1361 #endif /* PARROT_I386_JIT_EMIT_H_GUARD */ 39 #endif /* PARROT_FRAME_BUILDER_H_GUARD */ 1362 40 1363 41 /* 1364 42 * Local variables: -
src/nci_test.c
diff --git a/src/nci_test.c b/src/nci_test.c index 2044d9d..7593431 100644
a b 110 110 PARROT_DYNEXT_EXPORT void nci_vfff(float, float, float); 111 111 PARROT_DYNEXT_EXPORT void nci_vV(const char **); 112 112 PARROT_DYNEXT_EXPORT void nci_vVVV(const char **, const char **, const char **); 113 PARROT_DYNEXT_EXPORT int nci_i20(int, int, int, int, int, int, int, int, int, int, int, int, int, int, 114 int, int, int, int, int); 113 115 114 116 /* Declarations for callback tests */ 115 117 … … 1191 1193 *ptr3 = "Go suck a lemon.\n"; 1192 1194 } 1193 1195 1196 /* 1197 1198 =item C<int 1199 nci_i20(int sel, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9, int v10, 1200 int v11, int v12, int v13, int v14, int v15, int v16, int v17, int v18)> 1201 1202 Prints and returns the nth value in a list of integers. First argument is the selector; subsequents, 1203 the list. 1204 1205 This function is designed to be outside of the range of the static frame builder as an excercise for 1206 the dynamic frame builder. 1207 1208 =cut 1209 1210 */ 1211 PARROT_DYNEXT_EXPORT int 1212 nci_i20(int sel, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9, int v10, 1213 int v11, int v12, int v13, int v14, int v15, int v16, int v17, int v18) { 1214 int *selected; 1215 switch ((sel < 0 ? -sel : sel) % 18) { 1216 case 0: selected = &v1; break; 1217 case 1: selected = &v2; break; 1218 case 2: selected = &v3; break; 1219 case 3: selected = &v4; break; 1220 case 4: selected = &v5; break; 1221 case 5: selected = &v6; break; 1222 case 6: selected = &v7; break; 1223 case 7: selected = &v8; break; 1224 case 8: selected = &v9; break; 1225 case 9: selected = &v10; break; 1226 case 10: selected = &v11; break; 1227 case 11: selected = &v12; break; 1228 case 12: selected = &v13; break; 1229 case 13: selected = &v14; break; 1230 case 14: selected = &v15; break; 1231 case 15: selected = &v16; break; 1232 case 16: selected = &v17; break; 1233 case 17: selected = &v18; break; 1234 default: printf("default case reached (should never happen)"); return -1; 1235 } 1236 printf("%d\n", *selected); 1237 return *selected; 1238 } 1239 1194 1240 #ifdef TEST 1195 1241 1196 1242 char l2 = 4; -
t/pmc/nci.t
diff --git a/t/pmc/nci.t b/t/pmc/nci.t index fbfca27..667da34 100644
a b 17 17 } 18 18 19 19 use Test::More; 20 use Parrot::Test tests => (7 0+ @nci_sigs);20 use Parrot::Test tests => (71 + @nci_sigs); 21 21 use Parrot::Config qw(%PConfig); 22 22 23 23 =head1 NAME … … 2785 2785 Go suck a lemon. 2786 2786 OUTPUT 2787 2787 2788 my $test_code = <<'CODE'; 2789 .sub test :main 2790 .local pmc libnci_test 2791 $S0 = 'libnci_test' 2792 libnci_test = loadlib $S0 2793 2794 .local pmc nci_i20 2795 nci_i20 = dlfunc libnci_test, "nci_i20", "iiiiiiiiiiiiiiiiiiii" 2796 2797 .local pmc args 2798 args = new ['FixedIntegerArray'] 2799 args = 18 2800 2801 $I0 = 2 2802 args[0] = 1 2803 args[1] = 1 2804 2805 LOOP1: 2806 $I1 = $I0 - 1 2807 $I1 = args[$I1] 2808 2809 $I2 = $I0 - 2 2810 $I2 = args[$I2] 2811 2812 $I3 = $I1 + $I2 2813 args[$I0] = $I3 2814 inc $I0 2815 if $I0 < 18 goto LOOP1 2816 2817 $I0 = args 2818 dec $I0 2819 2820 $I1 = args[0] 2821 $I2 = args[1] 2822 $I3 = args[2] 2823 $I4 = args[3] 2824 $I5 = args[4] 2825 $I6 = args[5] 2826 $I7 = args[6] 2827 $I8 = args[7] 2828 $I9 = args[8] 2829 $I10 = args[9] 2830 $I11 = args[10] 2831 $I12 = args[11] 2832 $I13 = args[12] 2833 $I14 = args[13] 2834 $I15 = args[14] 2835 $I16 = args[15] 2836 $I17 = args[16] 2837 $I18 = args[17] 2838 2839 LOOP2: 2840 nci_i20($I0, $I1, $I2, $I3, $I4, $I5, $I6, $I7, $I8, $I9, $I10, $I11, $I12, $I13, $I14, $I15, $I16, $I17, $I18) 2841 $I0 = $I0 / 2 2842 if $I0 > 0 goto LOOP2 2843 .end 2844 CODE 2845 if ($PConfig{cc_build_call_frames}) { 2846 pir_output_is($test_code, <<DYNAMIC_FRAMEBUILDER_OUTPUT, 'dynamic frame builder builds ridiculous call frames'); 2847 2584 2848 34 2849 5 2850 2 2851 1 2852 DYNAMIC_FRAMEBUILDER_OUTPUT 2853 } else { 2854 my $output_re = qr/^Parrot VM: PANIC: iiiiiiiiiiiiiiiiiiii is an unknown signature type./; 2855 pir_error_output_like($test_code, $output_re, "static frame builder can't build ridiculous signatures"); 2856 } 2857 2788 2858 # Local Variables: 2789 2859 # mode: cperl 2790 2860 # cperl-indent-level: 4 -
t/steps/auto/frames-01.t
diff --git a/t/steps/auto/frames-01.t b/t/steps/auto/frames-01.t index a5c549f..d6982e0 100644
a b 5 5 6 6 use strict; 7 7 use warnings; 8 use Test::More tests => 2 7;8 use Test::More tests => 28; 9 9 use lib qw( lib t/configure/testlib ); 10 10 use_ok('config::init::defaults'); 11 11 use_ok('config::auto::frames'); … … 33 33 $conf->options->set( %{$args} ); 34 34 my $step = test_step_constructor_and_description($conf); 35 35 36 # To avoid a warning about an unitialized value, we will set nvsize to 8, 37 # cpuarch to i386 and osname to linux. 36 # To avoid a warning about an uninitialized value, we will set osname to linux. 38 37 # This is normally done during earlier configuration steps. 39 $conf->data->set( nvsize => 8 );40 $conf->data->set( cpuarch => 'i386' );41 38 $conf->data->set( osname => 'linux' ); 42 39 40 $conf->data->set( HAS_LIBJIT => 1 ); 43 41 my $ret = $step->runstep($conf); 44 42 ok( $ret, "runstep() returned true value" ); 45 43 ok( defined ( $step->result() ), 46 44 "Got defined result" ); 47 TODO: { 48 local $TODO = 49 'build frames temporarily disabled at pcc_reapply merge: TT #1132'; 50 is( $step->result(), 'yes', "Result is 'yes', as expected" ); 51 } 45 is( $step->result(), 'yes', "Result is 'yes', as expected" ); 46 47 $conf->data->set( HAS_LIBJIT => undef ); 48 $ret = $step->runstep($conf); 49 ok( $ret, "runstep() returned true value" ); 50 ok( defined ( $step->result() ), 51 "Got defined result" ); 52 is( $step->result(), 'no', "Result is 'no', as expected" ); 53 52 54 $conf->cc_clean(); 53 55 $step->set_result( undef ); 54 56 … … 68 70 ok( ! $can_build_call_frames, 69 71 "_call_frames_buildable() returned false value, as expected" ); 70 72 73 $conf->data->set( HAS_LIBJIT => 1 ); 71 74 $conf->options->set( buildframes => undef ); 72 $conf->data->set( osname => 'linux' );73 $conf->data->set( cpuarch => 'i386' );74 $conf->data->set( nvsize => 8 );75 $can_build_call_frames = auto::frames::_call_frames_buildable($conf);76 TODO: {77 local $TODO =78 'build frames temporarily disabled at pcc_reapply merge: TT #1132';79 ok( $can_build_call_frames,80 "_call_frames_buildable() returned true value, as expected (i386/non darwin/8)"81 );82 }83 84 $conf->data->set( osname => 'darwin' );85 $conf->data->set( cpuarch => 'i386' );86 $conf->data->set( nvsize => 8 );87 $can_build_call_frames = auto::frames::_call_frames_buildable($conf);88 ok( ! $can_build_call_frames,89 "_call_frames_buildable() returned false value, as expected (i386/darwin/8)" );90 91 $conf->data->set( osname => 'linux' );92 $conf->data->set( cpuarch => 'ppc' );93 $conf->data->set( nvsize => 8 );94 75 $can_build_call_frames = auto::frames::_call_frames_buildable($conf); 95 ok( !$can_build_call_frames,96 "_call_frames_buildable() returned false value, as expected (ppc/linux/8)" );76 ok( $can_build_call_frames, 77 "_call_frames_buildable() returned true value, as expected" ); 97 78 98 $conf->data->set( osname => 'linux' ); 99 $conf->data->set( cpuarch => 'i386' ); 100 $conf->data->set( nvsize => 4 ); 79 $conf->data->set( HAS_LIBJIT => undef ); 80 $conf->options->set( buildframes => 0 ); 101 81 $can_build_call_frames = auto::frames::_call_frames_buildable($conf); 102 82 ok( ! $can_build_call_frames, 103 "_call_frames_buildable() returned false value, as expected (i386/linux/4)" );83 "_call_frames_buildable() returned false value, as expected" ); 104 84 105 85 ##### _handle_call_frames_buildable() ##### 106 86 107 $conf->data->set( nvsize => 8 );108 $conf->data->set( cpuarch => 'i386' );109 $conf->data->set( osname => 'linux' );110 111 87 my $rv; 112 88 113 89 $can_build_call_frames = 0; … … 123 99 $conf->data->set( 'has_exec_protect' => undef ); 124 100 125 101 $can_build_call_frames = 1; 126 my $realos = $conf->data->get( 'osname' );127 $conf->data->set( 'osname' => 'foobar' );128 102 $rv = $step->_handle_can_build_call_frames( $conf, $can_build_call_frames ); 129 103 ok( $rv, "_handle_can_build_call_frames() returned true value" ); 130 104 is( $conf->data->get( 'cc_build_call_frames'), '-DCAN_BUILD_CALL_FRAMES', 131 105 "cc_build_call_frames set to expected value" ); 132 is( $conf->data->get( 'has_exec_protect' ), 0,133 "has_exec_protect is 0, as expected" );106 is( $conf->data->get( 'has_exec_protect' ), 1, 107 "has_exec_protect is 1, as expected" ); 134 108 is( $step->result(), 'yes', "Result is 'yes', as expected" ); 135 109 136 110 $conf->data->set( 'cc_build_call_frames' => undef ); 137 111 $conf->data->set( 'has_exec_protect' => undef ); 138 $conf->data->set( 'osname' => $realos );139 112 140 113 pass("Completed all tests in $0"); 141 114 -
(a) /dev/null vs. (b) b/t/steps/auto/libjit-01.t
diff --git a/t/steps/auto/libjit-01.t b/t/steps/auto/libjit-01.t new file mode 100644 index 0000000..004dc6e
a b 1 #! perl 2 # Copyright (C) 2009, Parrot Foundation. 3 # $Id$ 4 # auto/libjit-01.t 5 6 use strict; 7 use warnings; 8 9 use Test::More tests => 34; 10 use lib qw( lib t/configure/testlib ); 11 use Parrot::Configure; 12 use Parrot::Configure::Options 'process_options'; 13 use Parrot::Configure::Test qw( 14 test_step_thru_runstep 15 rerun_defaults_for_testing 16 test_step_constructor_and_description 17 ); 18 use IO::CaptureOutput qw( capture ); 19 20 use_ok('config::init::defaults'); 21 use_ok('config::auto::libjit'); 22 23 my ($args, $step_list_ref) = process_options( { 24 argv => [ q{--without-libjit} ], 25 mode => 'configure', 26 } ); 27 28 my $conf = Parrot::Configure->new; 29 30 my $serialized = $conf->pcfreeze(); 31 32 test_step_thru_runstep( $conf, 'init::defaults', $args ); 33 34 my $pkg = 'auto::libjit'; 35 my ( $step, $ret ); 36 37 $conf->add_steps($pkg); 38 $conf->options->set(%$args); 39 $step = test_step_constructor_and_description($conf); 40 $ret = $step->runstep($conf); 41 ok( $ret, "runstep() returned true value" ); 42 is( $step->result(), 'no', "Result is 'no', as expected" ); 43 is( $conf->data->get( 'HAS_LIBJIT' ), 0, 44 "Got expected result with --without-libjit option" ); 45 $conf->cc_clean(); 46 47 $conf->replenish($serialized); 48 49 ($args, $step_list_ref) = process_options( { 50 argv => [ ], 51 mode => q{configure}, 52 } ); 53 rerun_defaults_for_testing($conf, $args ); 54 $conf->add_steps($pkg); 55 $conf->options->set( %{$args} ); 56 $step = test_step_constructor_and_description($conf); 57 $ret = $step->runstep($conf); 58 ok( $ret, "runstep() returned true value" ); 59 like( $step->result(), qr/yes|no/, "Result is either 'yes' or 'no'" ); 60 ok( defined( $conf->data->get( 'HAS_LIBJIT' ) ), 61 "'HAS_LIBJIT' has defined value" ); 62 $conf->cc_clean(); 63 64 ########## _evaluate_cc_run ########## 65 66 my ($test, $has_libjit, $verbose); 67 68 $step->set_result( undef ); 69 70 $test = q{USES INTERPRETER: 33}; 71 $has_libjit = 0; 72 $verbose = 0; 73 $has_libjit = $step->_evaluate_cc_run($test, $has_libjit, $verbose); 74 ok( $has_libjit, "_evaluate_cc_run() returned true value, as expected" ); 75 is( $step->result(), 'yes', "result is yes, as expected" ); 76 77 $step->set_result( undef ); 78 79 $test = q{foobar}; 80 $has_libjit = 0; 81 $verbose = 0; 82 $has_libjit = $step->_evaluate_cc_run($test, $has_libjit, $verbose); 83 ok( ! $has_libjit, "_evaluate_cc_run() returned false value, as expected" ); 84 ok( ! defined($step->result()), "result is undefined, as expected" ); 85 86 $step->set_result( undef ); 87 88 $test = q{USES INTERPRETER: 33}; 89 $has_libjit = 0; 90 $verbose = 1; 91 { 92 my ($stdout, $stderr); 93 capture( 94 sub { $has_libjit = 95 $step->_evaluate_cc_run($test, $has_libjit, $verbose); }, 96 \$stdout, 97 \$stderr, 98 ); 99 ok( $has_libjit, "_evaluate_cc_run() returned true value, as expected" ); 100 is( $step->result(), 'yes', "result is yes, as expected" ); 101 like( $stdout, qr/\(yes\)/, "Got expected verbose output" ); 102 } 103 104 ########## _handle_has_libjit() ########## 105 106 my $extra_libs; 107 108 $conf->data->set( 'libjit_has_alloca' => undef ); 109 $conf->data->set( 'libs' => '' ); 110 111 $has_libjit = 1; 112 $extra_libs = 'mylibs'; 113 $conf->data->set( 'cpuarch' => 'i386' ); 114 115 auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 116 ok( $conf->data->get( 'libjit_has_alloca'), 117 "on i386 with libJIT, 'libjit_has_alloca' has true value" ); 118 is( $conf->data->get( 'libs' ), " $extra_libs", 119 "Got expected value for libs" ); 120 121 $conf->data->set( 'libjit_has_alloca' => undef ); 122 $conf->data->set( 'libs' => '' ); 123 124 $has_libjit = 1; 125 $extra_libs = 'mylibs'; 126 $conf->data->set( 'cpuarch' => 'ppc' ); 127 128 auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 129 ok( ! $conf->data->get( 'libjit_has_alloca'), 130 "on non-i386 with libJIT, 'libjit_has_alloca' has false value" ); 131 is( $conf->data->get( 'libs' ), " $extra_libs", 132 "Got expected value for libs" ); 133 134 $conf->data->set( 'libjit_has_alloca' => undef ); 135 $conf->data->set( 'libs' => '' ); 136 137 $has_libjit = 0; 138 $extra_libs = 'mylibs'; 139 140 auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 141 ok( ! $conf->data->get( 'libjit_has_alloca'), 142 "without libJIT, 'libjit_has_alloca' has false value" ); 143 is( $conf->data->get( 'libs' ), "", 144 "Got expected value for libs" ); 145 146 ################### DOCUMENTATION ################### 147 148 =head1 NAME 149 150 auto/libjit-01.t - test auto::libjit 151 152 =head1 SYNOPSIS 153 154 % prove t/steps/auto/libjit-01.t 155 156 =head1 DESCRIPTION 157 158 The files in this directory test functionality used by F<Configure.pl>. 159 160 The tests in this file test auto::libjit. 161 162 =head1 SEE ALSO 163 164 config::auto::libjit, F<Configure.pl>. 165 166 =cut 167 168 # Local Variables: 169 # mode: cperl 170 # cperl-indent-level: 4 171 # fill-column: 100 172 # End: 173 # vim: expandtab shiftwidth=4: -
(a) /dev/null vs. (b) b/t/steps/gen/libjit-01.t
diff --git a/t/steps/gen/libjit-01.t b/t/steps/gen/libjit-01.t new file mode 100644 index 0000000..92193cf
a b 1 #! perl 2 # Copyright (C) 2009, Parrot Foundation. 3 # $Id$ 4 # gen/libjit-01.t 5 6 use strict; 7 use warnings; 8 9 use constant NUM_GENERATED_FILES => 2; 10 # use Test::More tests => 8 + 2*NUM_GENERATED_FILES; 11 use Test::More qw( no_plan ); 12 13 use File::Copy 'move'; 14 use File::Temp 'tempfile'; 15 16 use lib 'lib'; 17 use Parrot::Configure; 18 use Parrot::Configure::Options 'process_options'; 19 use Parrot::Configure::Test qw( 20 test_step_thru_runstep 21 rerun_defaults_for_testing 22 test_step_constructor_and_description 23 ); 24 25 use_ok('config::gen::libjit'); 26 27 my ($args, $step_list_ref) = process_options( 28 { 29 argv => [], 30 mode => 'configure', 31 } 32 ); 33 34 my $conf = Parrot::Configure->new; 35 36 my $serialized = $conf->pcfreeze(); 37 38 my $pkg = 'gen::libjit'; 39 $conf->add_steps($pkg); 40 $conf->options->set( %$args ); 41 my $step = test_step_constructor_and_description($conf); 42 43 is( scalar keys %{$step->{targets}}, NUM_GENERATED_FILES, 44 "Expected number of generated files"); 45 is_deeply([keys %{$step->{targets}}], [keys %{$step->{templates}}], 46 "Templates match targets"); 47 48 foreach (keys %{$step->{templates}}) { 49 ok(-f $step->{templates}{$_}, "Able to locate $_ template") 50 } 51 52 my %orig_files; 53 foreach (keys %{$step->{targets}}) { 54 if (-f (my $targ_name = $step->{targets}{$_})) { 55 $orig_files{$_} = tempfile(); 56 move($targ_name, $orig_files{$_}); 57 } 58 } 59 60 my %orig_conf = map { $_ => $conf->data->get($_) } qw[ iv nv ]; 61 $conf->data->set( iv => 'int', nv => 'float' ); 62 # Set a value for 'libjit_has_alloca' to avoid uninitialized value warning. 63 $conf->data->set( 'libjit_has_alloca' => 1 ); 64 my $ret = $step->runstep($conf); 65 ok( $ret, "runstep() returned true value" ); 66 foreach (keys %{$step->{targets}}) { 67 ok(-f $step->{targets}{$_}, "$_ target generated"); 68 } 69 70 # re-set for next test 71 $conf->data->set(%orig_conf); 72 $step->set_result( '' ); 73 foreach (keys %{$step->{targets}}) { 74 if (exists $orig_files{$_}) { 75 move( $orig_files{$_}, $step->{targets}{$_} ); 76 } else { 77 unlink $_; 78 } 79 } 80 81 $conf->replenish($serialized); 82 83 pass("Completed all tests in $0"); 84 85 ################### DOCUMENTATION ################### 86 87 =head1 NAME 88 89 gen/libjit-01.t - test gen::libjit 90 91 =head1 SYNOPSIS 92 93 % prove t/steps/gen/libjit-01.t 94 95 =head1 DESCRIPTION 96 97 The files in this directory test functionality used by F<Configure.pl>. 98 99 The tests in this file test gen::libjit. 100 101 =head1 SEE ALSO 102 103 config::gen::libjit, F<Configure.pl>. 104 105 =cut 106 107 # Local Variables: 108 # mode: cperl 109 # cperl-indent-level: 4 110 # fill-column: 100 111 # End: 112 # vim: expandtab shiftwidth=4: -
tools/build/nativecall.pl
diff --git a/tools/build/nativecall.pl b/tools/build/nativecall.pl index 06341a6..f54d33c 100644
a b 440 440 return F2DPTR(VTABLE_get_pointer(interp, b)); 441 441 } 442 442 else { 443 int jit_size;444 void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, & jit_size);443 void *priv; 444 void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &priv); 445 445 if (result) { 446 struct jit_buffer_private_data *priv;447 446 *jitted = 1; 448 447 temp_pmc = pmc_new(interp, enum_class_ManagedStruct); 449 448 VTABLE_set_pointer(interp, temp_pmc, (void *)result); 450 449 #ifdef PARROT_HAS_EXEC_PROTECT 451 priv = (struct jit_buffer_private_data *)452 mem_sys_allocate(sizeof(struct jit_buffer_private_data));453 priv->size = jit_size;454 450 SETATTR_ManagedStruct_custom_free_func(interp, temp_pmc, Parrot_jit_free_buffer); 455 451 SETATTR_ManagedStruct_custom_free_priv(interp, temp_pmc, priv); 456 452 SETATTR_ManagedStruct_custom_clone_func(interp, temp_pmc, Parrot_jit_clone_buffer);