Ticket #1105: merge.patch

File merge.patch, 139.9 KB (added by plobsing, 12 years ago)

auto_libjit, patched (TT1147) trunk merge

  • MANIFEST

    diff --git a/MANIFEST b/MANIFEST
    index 840b7f8..0f3bd1b 100644
    a b  
    234234config/auto/env/test_unsetenv_c.in                          [] 
    235235config/auto/format.pm                                       [] 
    236236config/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                   [] 
    240237config/auto/gc.pm                                           [] 
    241238config/auto/gc/test_c.in                                    [] 
    242239config/auto/gcc.pm                                          [] 
     
    258255config/auto/isreg.pm                                        [] 
    259256config/auto/isreg/test_c.in                                 [] 
    260257config/auto/jit.pm                                          [] 
     258config/auto/libjit.pm                                       [] 
     259config/auto/libjit/libjit_c.in                              [] 
    261260config/auto/memalign.pm                                     [] 
    262261config/auto/memalign/test2_c.in                             [] 
    263262config/auto/memalign/test_c.in                              [] 
     
    310309config/gen/crypto.pm                                        [] 
    311310config/gen/crypto/digest_pmc.in                             [] 
    312311config/gen/crypto/digest_t.in                               [] 
     312config/gen/libjit.pm                                        [] 
     313config/gen/libjit/frame_builder_libjit_c.in                 [] 
     314config/gen/libjit/frame_builder_libjit_h.in                 [] 
    313315config/gen/makefiles.pm                                     [] 
    314316config/gen/makefiles/CFLAGS.in                              [] 
    315317config/gen/makefiles/data_json.in                           [] 
     
    19401942t/steps/auto/inline-01.t                                    [test] 
    19411943t/steps/auto/isreg-01.t                                     [test] 
    19421944t/steps/auto/jit-01.t                                       [test] 
     1945t/steps/auto/libjit-01.t                                    [test] 
    19431946t/steps/auto/memalign-01.t                                  [test] 
    19441947t/steps/auto/msvc-01.t                                      [test] 
    19451948t/steps/auto/neg_0-01.t                                     [test] 
     
    19641967t/steps/gen/config_pm-01.t                                  [test] 
    19651968t/steps/gen/core_pmcs-01.t                                  [test] 
    19661969t/steps/gen/crypto-01.t                                     [test] 
     1970t/steps/gen/libjit-01.t                                     [test] 
    19671971t/steps/gen/makefiles-01.t                                  [test] 
    19681972t/steps/gen/opengl-01.t                                     [test] 
    19691973t/steps/gen/parrot_include-01.t                             [test] 
  • MANIFEST.SKIP

    diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP
    index 38d117d..772755c 100644
    a b  
    11# ex: set ro: 
    22# $Id$ 
    3 # generated by tools/dev/mk_manifest_and_skip.pl Sun Sep 27 09:00:39 2009 UT 
     3# generated by tools/dev/mk_manifest_and_skip.pl Sun Oct 18 15:34:28 2009 UT 
    44# 
    55# This file should contain a transcript of the svn:ignore properties 
    66# of the directories in the Parrot subversion repository. (Needed for 
     
    653653^src/extend_vtable\.c/ 
    654654^src/fingerprint\.c$ 
    655655^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/ 
    656660^src/glut_callbacks\.c$ 
    657661^src/glut_callbacks\.c/ 
    658662^src/install_config\.c$ 
  • MANIFEST.generated

    diff --git a/MANIFEST.generated b/MANIFEST.generated
    index ff86d1e..ee0aad0 100644
    a b  
    11# $Id$ 
     2# Please re-sort this file after *EVERY* modification 
    23# See tools/dev/install_files.pl for documentation on the 
    34# format of this file. 
    45# Please re-sort this file after *EVERY* modification 
     
    78blib/lib/libparrot.dylib                          [main]lib 
    89blib/lib/libparrot.so.1.7.0                       [main]lib 
    910blib/lib/libparrot.so                             [main]lib 
     11blib/lib/libparrot.so.1.6.0                       [main]lib 
    1012compilers/data_json/data_json.pbc                 [data_json] 
    1113compilers/json/JSON.pbc                           [json] 
    1214compilers/json/JSON/grammar.pbc                   [json] 
     
    3739include/parrot/extend_vtable.h                    [main]include 
    3840include/parrot/feature.h                          [main]include 
    3941include/parrot/has_header.h                       [main]include 
     42include/parrot/oplib/core_ops.h                   [main]include 
    4043include/parrot/oplib/core_ops_cg.h                [main]include 
    4144include/parrot/oplib/core_ops_cgp.h               [main]include 
    42 include/parrot/oplib/core_ops.h                   [main]include 
    4345include/parrot/oplib/core_ops_switch.h            [main]include 
    4446include/parrot/oplib/ops.h                        [main]include 
    4547include/parrot/pbcversion.h                       [devel]include 
     
    4850include/parrot/platform_limits.h                  [devel]include 
    4951include/parrot/vtable.h                           [main]include 
    5052install_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 
     53installable_parrot                                [main]bin 
     54installable_parrot.exe                            [main]bin 
    5455installable_parrot_config                         [main]bin 
    55 installable_parrot_debugger.exe                   [main]bin 
     56installable_parrot_config.exe                     [main]bin 
    5657installable_parrot_debugger                       [main]bin 
    57 installable_parrot.exe                            [main]bin 
    58 installable_parrot                                [main]bin 
    59 installable_pbc_disassemble.exe                   [main]bin 
     58installable_parrot_debugger.exe                   [main]bin 
     59installable_parrot_nqp                            [main]bin 
     60installable_parrot_nqp.exe                        [main]bin 
    6061installable_pbc_disassemble                       [main]bin 
    61 installable_pbc_dump.exe                          [main]bin 
     62installable_pbc_disassemble.exe                   [main]bin 
    6263installable_pbc_dump                              [main]bin 
    63 installable_pbc_merge.exe                         [main]bin 
     64installable_pbc_dump.exe                          [main]bin 
    6465installable_pbc_merge                             [main]bin 
    65 installable_pbc_to_exe.exe                        [main]bin 
     66installable_pbc_merge.exe                         [main]bin 
    6667installable_pbc_to_exe                            [main]bin 
    67 installable_parrot_nqp.exe                        [main]bin 
    68 installable_parrot_nqp                            [main]bin 
     68installable_pbc_to_exe.exe                        [main]bin 
    6969lib/Parrot/Config/Generated.pm                    [devel]lib 
    70 libparrot.dll                                     [main]bin 
    71 libparrot.lib                                     [main]bin 
    7270lib/Parrot/OpLib/core.pm                          [devel]lib 
    73 lib/Parrot/Pmc2c/PCCMETHOD_BITS.pm                [devel]lib 
    7471lib/Parrot/PMC.pm                                 [devel]lib 
     72lib/Parrot/Pmc2c/PCCMETHOD_BITS.pm                [devel]lib 
     73libparrot.dll                                     [main]bin 
     74libparrot.lib                                     [main]bin 
    7575parrot.pc                                         [main]pkgconfig 
    7676runtime/parrot/dynext/digest_group.bundle         [library] 
    7777runtime/parrot/dynext/digest_group.dll            [library] 
     
    9797runtime/parrot/dynext/match_group.dll             [library] 
    9898runtime/parrot/dynext/match_group.dylib           [library] 
    9999runtime/parrot/dynext/match_group.so              [library] 
    100 runtime/parrot/dynext/math_ops.so                 [library] 
    101100runtime/parrot/dynext/math_ops.bundle             [library] 
    102101runtime/parrot/dynext/math_ops.dll                [library] 
    103102runtime/parrot/dynext/math_ops.dylib              [library] 
     103runtime/parrot/dynext/math_ops.so                 [library] 
    104104runtime/parrot/dynext/obscure_ops.bundle          [library] 
    105105runtime/parrot/dynext/obscure_ops.dll             [library] 
    106106runtime/parrot/dynext/obscure_ops.dylib           [library] 
     
    145145runtime/parrot/include/warnings.pasm              [main] 
    146146runtime/parrot/library/CGI/QueryHash.pbc          [main] 
    147147runtime/parrot/library/Config/JSON.pbc            [main] 
    148 runtime/parrot/library/config.pbc                 [main] 
    149 runtime/parrot/library/config.pir                 [main] 
    150148runtime/parrot/library/Crow.pbc                   [main] 
     149runtime/parrot/library/Data/Dumper.pbc            [main] 
    151150runtime/parrot/library/Data/Dumper/Base.pbc       [main] 
    152151runtime/parrot/library/Data/Dumper/Default.pbc    [main] 
    153 runtime/parrot/library/Data/Dumper.pbc            [main] 
    154152runtime/parrot/library/Data/Replace.pbc           [main] 
    155153runtime/parrot/library/Digest/MD5.pbc             [main] 
    156 runtime/parrot/library/dumper.pbc                 [main] 
    157154runtime/parrot/library/Getopt/Obj.pbc             [main] 
    158155runtime/parrot/library/HTTP/Daemon.pbc            [main] 
    159156runtime/parrot/library/Iter.pbc                   [main] 
    160157runtime/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] 
    164158runtime/parrot/library/MIME/Base64.pbc            [main] 
     159runtime/parrot/library/Math/Rand.pbc              [main] 
     160runtime/parrot/library/Math/Random/mt19937ar.pbc  [main] 
    165161runtime/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] 
    169162runtime/parrot/library/OpenGL.pbc                 [main] 
     163runtime/parrot/library/OpenGL_funcs.pbc           [main] 
     164runtime/parrot/library/OpenGL_funcs.pir           [main] 
    170165runtime/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] 
     166runtime/parrot/library/PCT.pbc                    [main] 
    178167runtime/parrot/library/PCT/Grammar.pbc            [main] 
    179168runtime/parrot/library/PCT/HLLCompiler.pbc        [main] 
    180169runtime/parrot/library/PCT/PAST.pbc               [main] 
    181 runtime/parrot/library/PCT.pbc                    [main] 
     170runtime/parrot/library/PGE.pbc                    [main] 
    182171runtime/parrot/library/PGE/Dumper.pbc             [main] 
    183172runtime/parrot/library/PGE/Glob.pbc               [main] 
    184173runtime/parrot/library/PGE/Hs.pbc                 [main] 
    185 runtime/parrot/library/PGE.pbc                    [main] 
    186174runtime/parrot/library/PGE/Perl6Grammar.pbc       [main] 
    187175runtime/parrot/library/PGE/Text.pbc               [main] 
    188176runtime/parrot/library/PGE/Util.pbc               [main] 
     177runtime/parrot/library/Parrot/Capture_PIR.pbc     [main] 
     178runtime/parrot/library/Parrot/Coroutine.pbc       [main] 
     179runtime/parrot/library/Parrot/Exception.pbc       [main] 
     180runtime/parrot/library/Parrot/HLLCompiler.pbc     [main] 
    189181runtime/parrot/library/Protoobject.pbc            [main] 
    190182runtime/parrot/library/Range.pbc                  [main] 
    191183runtime/parrot/library/Stream/Base.pbc            [main] 
     
    197189runtime/parrot/library/Stream/Replay.pbc          [main] 
    198190runtime/parrot/library/Stream/Sub.pbc             [main] 
    199191runtime/parrot/library/Stream/Writer.pbc          [main] 
     192runtime/parrot/library/TGE.pbc                    [tge] 
    200193runtime/parrot/library/Tcl/Glob.pbc               [main] 
    201194runtime/parrot/library/TclLibrary.pbc             [main] 
     195runtime/parrot/library/Test/Builder.pbc           [main] 
     196runtime/parrot/library/Test/Builder/Output.pbc    [main] 
    202197runtime/parrot/library/Test/Builder/Test.pbc      [main] 
    203 runtime/parrot/library/Test/Builder/Tester.pbc    [main] 
    204198runtime/parrot/library/Test/Builder/TestPlan.pbc  [main] 
    205 runtime/parrot/library/Test/Builder/Output.pbc    [main] 
    206 runtime/parrot/library/Test/Builder.pbc           [main] 
     199runtime/parrot/library/Test/Builder/Tester.pbc    [main] 
    207200runtime/parrot/library/Test/Class.pbc             [main] 
    208201runtime/parrot/library/Test/More.pbc              [main] 
    209 runtime/parrot/library/TGE.pbc                    [tge] 
    210 runtime/parrot/library/uuid.pbc                   [main] 
     202runtime/parrot/library/YAML/Dumper.pbc            [main] 
    211203runtime/parrot/library/YAML/Dumper/Base.pmc       [main] 
    212204runtime/parrot/library/YAML/Dumper/Default.pmc    [main] 
    213 runtime/parrot/library/YAML/Dumper.pbc            [main] 
     205runtime/parrot/library/config.pbc                 [main] 
     206runtime/parrot/library/config.pir                 [main] 
     207runtime/parrot/library/dumper.pbc                 [main] 
     208runtime/parrot/library/libpcre.pbc                [main] 
     209runtime/parrot/library/ncurses.pbc                [main] 
     210runtime/parrot/library/parrotlib.pbc              [main] 
     211runtime/parrot/library/pcore.pbc                  [main] 
     212runtime/parrot/library/pcre.pbc                   [main] 
     213runtime/parrot/library/uuid.pbc                   [main] 
    214214src/call_list.txt                                 [devel]src 
     215src/frame_builder_libjit.c                        [devel]src 
     216src/frame_builder_libjit.h                        [devel]src 
    215217src/glut_callbacks.c                              [] 
     218src/install_config.o                              [main]lib 
     219src/install_config.obj                            [main]lib 
    216220src/jit_emit.h                                    [] 
    217221src/nci.c                                         [] 
    218222src/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  
    4040 
    4141sub _call_frames_buildable { 
    4242    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'); 
    4743    my $can_build_call_frames; 
    4844 
    4945    if (defined $conf->options->get('buildframes')) { 
    5046        $can_build_call_frames = $conf->options->get('buildframes'); 
    5147    } 
    5248    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'); 
    5850    } 
    5951    return $can_build_call_frames; 
    6052} 
     
    6355    my ($self, $conf, $can_build_call_frames) = @_; 
    6456    if ( $can_build_call_frames ) { 
    6557        $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, 
    6760        ); 
    68         # test for executable malloced memory 
    69         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         } 
    9261        $self->set_result( 'yes' ); 
    9362    } 
    9463    else { 
    95         $conf->data->set( cc_build_call_frames  => ''); 
     64        $conf->data->set(cc_build_call_frames  => ''); 
    9665        $self->set_result( 'no' ); 
    9766    } 
    9867    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 privs 
    6 */ 
    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_SIZE 
    17 #  define PAGE_SIZE getpagesize() 
    18 #endif 
    19 # 
    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 int 
    36 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     else 
    66         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 privs 
    6  */ 
    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_SIZE 
    16 #  define PAGE_SIZE getpagesize() 
    17 #endif 
    18  
    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 int 
    34 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     else 
    61         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 privs 
    6 */ 
    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_SIZE 
    16 #  define PAGE_SIZE sysconf(_SC_PAGESIZE) 
    17 #endif 
    18  
    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 int 
    34 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     else 
    61         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 
     6config/auto/libjit - Check whether LibJIT is installed 
     7 
     8=head1 DESCRIPTION 
     9 
     10Determines whether libjit is present is installed and functional on the system. 
     11It is OK when it doesn't exist. 
     12 
     13The libjit library implements just-in-time compilation functionality. Unlike 
     14other JITs, this one is designed to be independent of any particular virtual 
     15machine bytecode format or language.  
     16 
     17libjit can be obtained from L<http://freshmeat.net/projects/libjit/> or through 
     18your distribution's package manager. Developer documentation is available from 
     19L<http://www.gnu.org/software/dotgnu/libjit-doc/libjit.html> 
     20 
     21=cut 
     22 
     23package auto::libjit; 
     24 
     25use strict; 
     26use warnings; 
     27 
     28use base 'Parrot::Configure::Step'; 
     29 
     30use Parrot::Configure::Utils ':auto'; 
     31 
     32sub _init { 
     33    my $self = shift; 
     34    my %data = ( 
     35        description => 'Is LibJIT installed', 
     36        result        => '', 
     37    ); 
     38    return \%data; 
     39} 
     40 
     41sub 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 
     90sub _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 
     100sub _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 
     1131; 
     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 
     10int 
     11main(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 
     6config/gen/libjit.pm - LibJIT Code Generation 
     7 
     8=head1 DESCRIPTION 
     9 
     10Populate F<config/gen/frame_builder_libjit_h.in> and 
     11F<configu/gen/frame_builder_libjit_c.in> with system appropriate 
     12type information and automatically generated parrot function and 
     13vtable jit wrappers. 
     14 
     15=cut 
     16 
     17package gen::libjit; 
     18 
     19use strict; 
     20use warnings; 
     21 
     22use base 'Parrot::Configure::Step'; 
     23 
     24use Parrot::Configure::Utils ':gen'; 
     25 
     26 
     27sub _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 
     77sub 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 
     129sub 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 }; 
     149jit_value_t 
     150jit__vtable_$entry_name(jit_function_t, jit_value_t, jit_value_t $_arg_decls_t); 
     151DECL 
     152jit_value_t 
     153jit__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} 
     166DEFN 
     167} 
     168 
     169sub 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 }; 
     184jit_value_t 
     185jit__$func_name(jit_function_t, $arg_decls_t); 
     186DECL 
     187jit_value_t 
     188jit__$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} 
     197DEFN 
     198} 
     199 
     200sub 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 
     2101; 
     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/* 
     2Copyright (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 
     24Public interface to NCI function interface builder. 
     25 
     26=cut 
     27 
     28*/ 
     29 
     30void * 
     31Parrot_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 
     49This is a callback to implement the proper freeing semantics.  It is called by 
     50the ManagedStruct PMC as it is garbage collected. 
     51 
     52=cut 
     53 
     54*/ 
     55 
     56void 
     57Parrot_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 
     69This is a callback to implement the proper cloning semantics for jit buffers. 
     70It is called by the ManagedStruct PMC's clone() function. 
     71 
     72=back 
     73 
     74=cut 
     75 
     76*/ 
     77 
     78PMC * 
     79Parrot_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 
     111void * 
     112Parrot_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 
     201void 
     202Parrot_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 
     353jit_type_t 
     354Parrot_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 
     399void 
     400Parrot_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 
     467void 
     468Parrot_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 
     536jit_value_t 
     537jit_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 */ 
     546jit_value_t 
     547jit__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 */ 
     27struct 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 
     44void * 
     45Parrot_jit_create_thunk(Interp *, char *, void *); 
     46 
     47void 
     48Parrot_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 
     51jit_type_t 
     52Parrot_jit_parse_sig_ret_pre(Interp *, char *); 
     53 
     54void 
     55Parrot_jit_parse_sig_ret_post(Interp *, char *, jit_function_t, jit_value_t, jit_value_t, jit_value_t); 
     56 
     57void 
     58Parrot_jit_parse_sig_args_post(Interp *, char *, int, jit_function_t, jit_value_t, jit_value_t *, jit_value_t *); 
     59 
     60jit_value_t 
     61jit_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 */ 
     79jit_value_t 
     80jit__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  
    217217    myconfig  \ 
    218218    $(GEN_PASM_INCLUDES) \ 
    219219    $(SRC_DIR)/call_list.txt \ 
     220    $(SRC_DIR)/frame_builder_libjit.h \ 
     221    $(SRC_DIR)/frame_builder_libjit.c \ 
    220222    MANIFEST.configure.generated \ 
    221223    .configure_trace.sto \ 
    222224    .parrot_current_rev 
     
    442444    $(SRC_DIR)/misc$(O) \ 
    443445    $(SRC_DIR)/multidispatch$(O) \ 
    444446    $(SRC_DIR)/frame_builder$(O) \ 
     447    $(SRC_DIR)/frame_builder_libjit$(O) \ 
    445448    $(SRC_DIR)/nci$(O) \ 
    446449    $(SRC_DIR)/oo$(O) \ 
    447450    $(SRC_DIR)/packfile$(O) \ 
     
    625628    $(SRC_DIR)/library.str \ 
    626629    $(SRC_DIR)/multidispatch.str \ 
    627630    $(SRC_DIR)/frame_builder.str \ 
     631    $(SRC_DIR)/frame_builder_libjit.str \ 
    628632    $(SRC_DIR)/nci.str \ 
    629633    $(SRC_DIR)/packfile.str \ 
    630634    $(SRC_DIR)/pmc.str \ 
     
    12011205 
    12021206$(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str \ 
    12031207        $(SRC_DIR)/frame_builder$(O) \ 
    1204         $(SRC_DIR)/pmc/pmc_unmanagedstruct.h \ 
     1208        $(SRC_DIR)/frame_builder_libjit$(O) \ 
    12051209        $(SRC_DIR)/pmc/pmc_managedstruct.h \ 
    12061210        $(SRC_DIR)/pmc/pmc_nci.h \ 
    12071211        $(SRC_DIR)/pmc/pmc_pointer.h 
    12081212 
    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) 
    12101225 
    12111226$(SRC_DIR)/vtables$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/vtables.c 
    12121227 
  • 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  
    105105   --without-gmp        Build parrot without GMP support 
    106106   --without-opengl     Build parrot without OpenGL support (GL/GLU/GLUT) 
    107107   --without-pcre       Build parrot without pcre support 
     108   --without-libjit     Build parrot without LibJIT support 
    108109 
    109110ICU Options: 
    110111 
  • 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  
    7575    without-gettext 
    7676    without-gmp 
    7777    without-icu 
     78    without-libjit 
    7879    without-opengl 
    7980    without-pcre 
    8081    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  
    3939    auto::format 
    4040    auto::isreg 
    4141    auto::arch 
     42    auto::libjit 
    4243    auto::jit 
    4344    auto::frames 
    4445    auto::cpu 
     
    7071    gen::parrot_include 
    7172    gen::opengl 
    7273    gen::call_list 
     74    gen::libjit 
    7375    gen::makefiles 
    7476    gen::platform 
    7577    gen::config_pm 
    7678); 
    7779 
     80=pod 
     81 
     82=cut 
     83 
    7884sub get_steps_list { return @steps; } 
    7985 
    80861; 
  • lib/Parrot/Distribution.pm

    diff --git a/lib/Parrot/Distribution.pm b/lib/Parrot/Distribution.pm
    index 9c668b9..7b48377 100644
    a b  
    433433            include/parrot/config.h 
    434434            include/parrot/has_header.h 
    435435            src/gc/malloc.c 
     436            src/frame_builder_libjit.h 
     437            src/frame_builder_libjit.c 
    436438            } unless @exemptions; 
    437439 
    438440        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  
    77/* HEADERIZER STOP */ 
    88 
    99#include "parrot/parrot.h" 
    10 #include "pmc/pmc_fixedintegerarray.h" 
    11 #include "pmc/pmc_unmanagedstruct.h" 
    12 #include "pmc/pmc_managedstruct.h" 
    1310#include "frame_builder.h" 
    1411 
    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) 
     12INTVAL 
     13get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n) 
    3014{ 
    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"); 
    3518 
    36 /* 
     19    Parrot_fetch_arg_nci(interp, st); 
    3720 
    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} 
    4223 
    43 =back 
     24FLOATVAL 
     25get_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"); 
    4430 
    45 =cut 
     31    Parrot_fetch_arg_nci(interp, st); 
    4632 
    47 */ 
     33    return UVal_num(st->val); 
     34} 
    4835 
    49 PMC * 
    50 Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv) 
     36PARROT_WARN_UNUSED_RESULT 
     37PARROT_CANNOT_RETURN_NULL 
     38STRING* 
     39get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n) 
    5140{ 
    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"); 
    8745 
    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); 
    9947 
    100     return rv; 
     48    return UVal_str(st->val); 
    10149} 
    10250 
    103  
    104 int 
    105 emit_is8bit(long disp) 
     51PARROT_WARN_UNUSED_RESULT 
     52PARROT_CAN_RETURN_NULL 
     53PMC* 
     54get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n) 
    10655{ 
    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; 
    10868} 
    10969 
    110 char * 
    111 emit_disp8_32(char *pc, int disp) 
     70PARROT_WARN_UNUSED_RESULT 
     71PARROT_CAN_RETURN_NULL 
     72void* 
     73get_nci_p(PARROT_INTERP, ARGMOD(call_state *st), int n) 
    11274{ 
    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; 
    12187} 
    12288 
     89/* 
     90 * set return value 
     91 */ 
    12392void 
    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) 
     93set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val) 
    15394{ 
    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); 
    187100    } 
    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; 
    203101} 
    204102 
    205 char * 
    206 emit_shift_i_r(PARROT_INTERP, char *pc, int opcode, int imm, int reg) 
     103void 
     104set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val) 
    207105{ 
    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); 
    215111    } 
    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; 
    238112} 
    239113 
    240 unsigned char *lastpc; 
    241  
    242 size_t 
    243 calc_signature_needs(const char *sig, int *strings) 
     114void 
     115set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val) 
    244116{ 
    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); 
    260122    } 
    261     return stack_size; 
    262  
    263123} 
    264124 
    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) 
     125void 
     126set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val) 
    280127{ 
    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); 
    451133    } 
    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), %eax 
    550                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.c 
    588              */ 
    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); 
    611134} 
    612135 
    613136/* 
  • src/frame_builder.h

    diff --git a/src/frame_builder.h b/src/frame_builder.h
    index 8825ff9..3d4b6cd 100644
    a b  
    11/* 
    22 * Copyright (C) 2002-2009, Parrot Foundation. 
    3  */ 
    4  
    5 /* 
    6  * frame_builder.h 
    73 * 
    8  * i386 
     4 * frame_builder.h 
    95 * 
    106 * $Id$ 
    117 */ 
    128 
    13 #ifndef PARROT_I386_JIT_EMIT_H_GUARD 
    14 #define PARROT_I386_JIT_EMIT_H_GUARD 
     9#ifndef PARROT_FRAME_BUILDER_H_GUARD 
     10#define PARROT_FRAME_BUILDER_H_GUARD 
    1511 
    1612#if defined(__cplusplus) 
    1713#  define EXTERN extern "C" 
     
    2117 
    2218#include <assert.h> 
    2319#include "parrot/parrot.h" 
    24 #include "parrot/hash.h" 
    25 #include "parrot/oplib/ops.h" 
    2620 
    2721/* 
    2822 * NCI interface 
    2923 */ 
     24 
    3025void * 
    31 Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *); 
     26Parrot_jit_build_call_func(Interp *, PMC *, STRING *, void **); 
    3227 
    3328/* custom pmc callback functions */ 
    3429void 
     
    3732PMC* 
    3833Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv); 
    3934 
    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  
    5635/* 
    5736 * helper funcs - get argument n 
    5837 */ 
    5938 
    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 */ 
    136240 
    136341/* 
    136442 * Local variables: 
  • src/nci_test.c

    diff --git a/src/nci_test.c b/src/nci_test.c
    index 2044d9d..7593431 100644
    a b  
    110110PARROT_DYNEXT_EXPORT void   nci_vfff(float, float, float); 
    111111PARROT_DYNEXT_EXPORT void   nci_vV(const char **); 
    112112PARROT_DYNEXT_EXPORT void   nci_vVVV(const char **, const char **, const char **); 
     113PARROT_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); 
    113115 
    114116/* Declarations for callback tests */ 
    115117 
     
    11911193  *ptr3 = "Go suck a lemon.\n"; 
    11921194} 
    11931195 
     1196/* 
     1197 
     1198=item C<int 
     1199nci_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 
     1202Prints and returns the nth value in a list of integers. First argument is the selector; subsequents, 
     1203the list. 
     1204 
     1205This function is designed to be outside of the range of the static frame builder as an excercise for 
     1206the dynamic frame builder. 
     1207 
     1208=cut 
     1209 
     1210*/ 
     1211PARROT_DYNEXT_EXPORT int 
     1212nci_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 
    11941240#ifdef TEST 
    11951241 
    11961242char l2 = 4; 
  • t/pmc/nci.t

    diff --git a/t/pmc/nci.t b/t/pmc/nci.t
    index fbfca27..667da34 100644
    a b  
    1717} 
    1818 
    1919use Test::More; 
    20 use Parrot::Test tests => (70 + @nci_sigs); 
     20use Parrot::Test tests => (71 + @nci_sigs); 
    2121use Parrot::Config qw(%PConfig); 
    2222 
    2323=head1 NAME 
     
    27852785Go suck a lemon. 
    27862786OUTPUT 
    27872787 
     2788my $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 
     2805LOOP1: 
     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 
     2839LOOP2: 
     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 
     2844CODE 
     2845if ($PConfig{cc_build_call_frames}) { 
     2846    pir_output_is($test_code, <<DYNAMIC_FRAMEBUILDER_OUTPUT, 'dynamic frame builder builds ridiculous call frames'); 
     28472584 
     284834 
     28495 
     28502 
     28511 
     2852DYNAMIC_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 
    27882858# Local Variables: 
    27892859#   mode: cperl 
    27902860#   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  
    55 
    66use strict; 
    77use warnings; 
    8 use Test::More tests => 27; 
     8use Test::More tests => 28; 
    99use lib qw( lib t/configure/testlib ); 
    1010use_ok('config::init::defaults'); 
    1111use_ok('config::auto::frames'); 
     
    3333$conf->options->set( %{$args} ); 
    3434my $step = test_step_constructor_and_description($conf); 
    3535 
    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. 
    3837# This is normally done during earlier configuration steps. 
    39 $conf->data->set( nvsize => 8 ); 
    40 $conf->data->set( cpuarch => 'i386' ); 
    4138$conf->data->set( osname => 'linux' ); 
    4239 
     40$conf->data->set( HAS_LIBJIT => 1 ); 
    4341my $ret = $step->runstep($conf); 
    4442ok( $ret, "runstep() returned true value" ); 
    4543ok( defined ( $step->result() ), 
    4644    "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 } 
     45is( $step->result(), 'yes', "Result is 'yes', as expected" ); 
     46 
     47$conf->data->set( HAS_LIBJIT => undef ); 
     48$ret = $step->runstep($conf); 
     49ok( $ret, "runstep() returned true value" ); 
     50ok( defined ( $step->result() ), 
     51    "Got defined result" ); 
     52is( $step->result(), 'no', "Result is 'no', as expected" ); 
     53 
    5254$conf->cc_clean(); 
    5355$step->set_result( undef ); 
    5456 
     
    6870ok( ! $can_build_call_frames, 
    6971    "_call_frames_buildable() returned false value, as expected" ); 
    7072 
     73$conf->data->set( HAS_LIBJIT => 1 ); 
    7174$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 ); 
    9475$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)" ); 
     76ok( $can_build_call_frames, 
     77    "_call_frames_buildable() returned true value, as expected" ); 
    9778 
    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 ); 
    10181$can_build_call_frames = auto::frames::_call_frames_buildable($conf); 
    10282ok( ! $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" ); 
    10484 
    10585##### _handle_call_frames_buildable() ##### 
    10686 
    107 $conf->data->set( nvsize => 8 ); 
    108 $conf->data->set( cpuarch => 'i386' ); 
    109 $conf->data->set( osname => 'linux' ); 
    110  
    11187my $rv; 
    11288 
    11389$can_build_call_frames = 0; 
     
    12399$conf->data->set( 'has_exec_protect' => undef ); 
    124100 
    125101$can_build_call_frames = 1; 
    126 my $realos = $conf->data->get( 'osname' ); 
    127 $conf->data->set( 'osname' => 'foobar' ); 
    128102$rv = $step->_handle_can_build_call_frames( $conf, $can_build_call_frames ); 
    129103ok( $rv, "_handle_can_build_call_frames() returned true value" ); 
    130104is( $conf->data->get( 'cc_build_call_frames'), '-DCAN_BUILD_CALL_FRAMES', 
    131105    "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" ); 
     106is( $conf->data->get( 'has_exec_protect' ), 1, 
     107    "has_exec_protect is 1, as expected" ); 
    134108is( $step->result(), 'yes', "Result is 'yes', as expected" ); 
    135109 
    136110$conf->data->set( 'cc_build_call_frames' => undef ); 
    137111$conf->data->set( 'has_exec_protect' => undef ); 
    138 $conf->data->set( 'osname' => $realos ); 
    139112 
    140113pass("Completed all tests in $0"); 
    141114 
  • (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 
     6use strict; 
     7use warnings; 
     8 
     9use Test::More tests => 34; 
     10use lib qw( lib t/configure/testlib ); 
     11use Parrot::Configure; 
     12use Parrot::Configure::Options 'process_options'; 
     13use Parrot::Configure::Test qw( 
     14    test_step_thru_runstep 
     15    rerun_defaults_for_testing 
     16    test_step_constructor_and_description 
     17); 
     18use IO::CaptureOutput qw( capture ); 
     19 
     20use_ok('config::init::defaults'); 
     21use_ok('config::auto::libjit'); 
     22 
     23my ($args, $step_list_ref) = process_options( { 
     24        argv => [ q{--without-libjit} ], 
     25        mode => 'configure', 
     26} ); 
     27 
     28my $conf = Parrot::Configure->new; 
     29 
     30my $serialized = $conf->pcfreeze(); 
     31 
     32test_step_thru_runstep( $conf, 'init::defaults', $args ); 
     33 
     34my $pkg = 'auto::libjit'; 
     35my ( $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); 
     41ok( $ret, "runstep() returned true value" ); 
     42is( $step->result(), 'no', "Result is 'no', as expected" ); 
     43is( $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} ); 
     53rerun_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); 
     58ok( $ret, "runstep() returned true value" ); 
     59like( $step->result(), qr/yes|no/, "Result is either 'yes' or 'no'" ); 
     60ok( defined( $conf->data->get( 'HAS_LIBJIT' ) ), 
     61   "'HAS_LIBJIT' has defined value" ); 
     62$conf->cc_clean(); 
     63 
     64########## _evaluate_cc_run ########## 
     65 
     66my ($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); 
     74ok( $has_libjit, "_evaluate_cc_run() returned true value, as expected" ); 
     75is( $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); 
     83ok( ! $has_libjit, "_evaluate_cc_run() returned false value, as expected" ); 
     84ok( ! 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 
     106my $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 
     115auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 
     116ok( $conf->data->get( 'libjit_has_alloca'), 
     117    "on i386 with libJIT, 'libjit_has_alloca' has true value" ); 
     118is( $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 
     128auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 
     129ok( ! $conf->data->get( 'libjit_has_alloca'), 
     130    "on non-i386 with libJIT, 'libjit_has_alloca' has false value" ); 
     131is( $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 
     140auto::libjit::_handle_has_libjit($conf, $has_libjit, $extra_libs); 
     141ok( ! $conf->data->get( 'libjit_has_alloca'), 
     142    "without libJIT, 'libjit_has_alloca' has false value" ); 
     143is( $conf->data->get( 'libs' ), "", 
     144    "Got expected value for libs" ); 
     145 
     146################### DOCUMENTATION ################### 
     147 
     148=head1 NAME 
     149 
     150auto/libjit-01.t - test auto::libjit 
     151 
     152=head1 SYNOPSIS 
     153 
     154    % prove t/steps/auto/libjit-01.t 
     155 
     156=head1 DESCRIPTION 
     157 
     158The files in this directory test functionality used by F<Configure.pl>. 
     159 
     160The tests in this file test auto::libjit. 
     161 
     162=head1 SEE ALSO 
     163 
     164config::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 
     6use strict; 
     7use warnings; 
     8 
     9use constant NUM_GENERATED_FILES => 2; 
     10# use Test::More tests => 8 + 2*NUM_GENERATED_FILES; 
     11use Test::More qw( no_plan ); 
     12 
     13use File::Copy 'move'; 
     14use File::Temp 'tempfile'; 
     15 
     16use lib 'lib'; 
     17use Parrot::Configure; 
     18use Parrot::Configure::Options 'process_options'; 
     19use Parrot::Configure::Test qw( 
     20    test_step_thru_runstep 
     21    rerun_defaults_for_testing 
     22    test_step_constructor_and_description 
     23); 
     24 
     25use_ok('config::gen::libjit'); 
     26 
     27my ($args, $step_list_ref) = process_options( 
     28    { 
     29        argv => [], 
     30        mode => 'configure', 
     31    } 
     32); 
     33 
     34my $conf = Parrot::Configure->new; 
     35 
     36my $serialized = $conf->pcfreeze(); 
     37 
     38my $pkg = 'gen::libjit'; 
     39$conf->add_steps($pkg); 
     40$conf->options->set( %$args ); 
     41my $step = test_step_constructor_and_description($conf); 
     42 
     43is( scalar keys %{$step->{targets}}, NUM_GENERATED_FILES, 
     44    "Expected number of generated files"); 
     45is_deeply([keys %{$step->{targets}}], [keys %{$step->{templates}}], 
     46    "Templates match targets"); 
     47 
     48foreach (keys %{$step->{templates}}) { 
     49    ok(-f $step->{templates}{$_}, "Able to locate $_ template") 
     50} 
     51 
     52my %orig_files; 
     53foreach (keys %{$step->{targets}}) { 
     54    if (-f (my $targ_name = $step->{targets}{$_})) { 
     55        $orig_files{$_} = tempfile(); 
     56        move($targ_name, $orig_files{$_}); 
     57    } 
     58} 
     59 
     60my %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 ); 
     64my $ret = $step->runstep($conf); 
     65ok( $ret, "runstep() returned true value" ); 
     66foreach (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( '' ); 
     73foreach (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 
     83pass("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 
     97The files in this directory test functionality used by F<Configure.pl>. 
     98 
     99The tests in this file test gen::libjit. 
     100 
     101=head1 SEE ALSO 
     102 
     103config::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  
    440440        return F2DPTR(VTABLE_get_pointer(interp, b)); 
    441441    } 
    442442    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); 
    445445        if (result) { 
    446             struct jit_buffer_private_data *priv; 
    447446            *jitted = 1; 
    448447            temp_pmc = pmc_new(interp, enum_class_ManagedStruct); 
    449448            VTABLE_set_pointer(interp, temp_pmc, (void *)result); 
    450449#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; 
    454450            SETATTR_ManagedStruct_custom_free_func(interp, temp_pmc, Parrot_jit_free_buffer); 
    455451            SETATTR_ManagedStruct_custom_free_priv(interp, temp_pmc, priv); 
    456452            SETATTR_ManagedStruct_custom_clone_func(interp, temp_pmc, Parrot_jit_clone_buffer);