* lib/Parrot/Pmc2c/MethodEmitter.pm:
[parrot.git] / config / auto / jit.pm
blob1ce77718bb7d6a841b17ca325f5309f590a604fa
1 # Copyright (C) 2001-2008, The Perl Foundation.
2 # $Id$
4 =head1 NAME
6 config/auto/jit - JIT Capability
8 =head1 DESCRIPTION
10 Determines whether there is JIT capability available. Use the
11 C<--jitcapable> and C<--execcapable> options to override the default
12 value calculated specifically for your CPU architecture and operating
13 system.
15 Code formerly found in this step class used to determine characteristics
16 of the CPU has been moved into the preceding step class, auto::arch.
18 =cut
20 package auto::jit;
22 use strict;
23 use warnings;
26 use base qw(Parrot::Configure::Step);
28 use Parrot::Configure::Utils qw(copy_if_diff);
30 sub _init {
31 my $self = shift;
32 my %data;
33 $data{description} = q{Determining architecture, OS and JIT capability};
34 $data{result} = q{};
35 $data{jit_is_working} = {
36 i386 => 1,
37 ppc => 1,
39 return \%data;
42 sub runstep {
43 my ( $self, $conf ) = @_;
45 if ( $conf->options->get('miniparrot') ) {
46 $self->set_result('skipped');
47 return 1;
50 my $verbose = $conf->options->get('verbose');
51 $verbose and print "\n";
53 my $cpuarch = $conf->data->get('cpuarch');
54 my $osname = $conf->data->get('osname');
56 my $jitbase = 'src/jit'; # base path for jit sources
58 my $corejit = "$jitbase/$cpuarch/core.jit";
59 print( qq{-e $corejit = },
60 -e $corejit ? 'yes' : 'no', "\n" )
61 if $verbose;
63 my $jitcapable = 0;
64 if ( -e $corejit ) {
66 # Just because there is a "$jitbase/$cpuarch/core.jit" file,
67 # doesn't mean the JIT is working on that platform.
68 # So build JIT per default only on platforms where JIT in known
69 # to work. Building JIT on other platform most likely breaks the build.
70 # Developer can always call: Configure.pl --jitcapable
71 # This was discussed in RT #43145 (which has been resolved).
72 if ( $self->{jit_is_working}->{$cpuarch} ) {
73 $jitcapable = 1;
76 # Another exception
77 if ( $cpuarch eq 'i386' && $osname eq 'darwin' ) {
78 $jitcapable = 0;
82 my $jitarchname = "$cpuarch-$osname";
83 my $sjit = "$jitbase/$cpuarch/$jitarchname.s";
84 my $asm = "$jitbase/$cpuarch/asm.s";
85 if ( -e $sjit ) {
86 copy_if_diff( $sjit, "src/asmfun.s" );
87 $conf->data->set( asmfun_o => 'src/asmfun$(O)' );
89 elsif ( -e $asm ) {
90 copy_if_diff( $asm, "src/asmfun.s" );
91 $conf->data->set( asmfun_o => 'src/asmfun$(O)' );
93 else {
94 $conf->data->set( asmfun_o => '' );
97 # let developers override the default JIT capability
98 $jitcapable = $conf->options->get('jitcapable')
99 if defined $conf->options->get('jitcapable');
101 if ($jitcapable) {
102 my ( $jitcpuarch, $jitosname ) = split( /-/, $jitarchname );
104 $conf->data->set(
105 jitarchname => $jitarchname,
106 jitcpuarch => $jitcpuarch,
107 jitcpu => uc($jitcpuarch),
108 jitosname => uc($jitosname),
109 jitcapable => 1,
110 cc_hasjit => " -DHAS_JIT -D\U$jitcpuarch",
111 TEMP_jit_o =>
112 '$(SRC_DIR)/jit$(O) $(SRC_DIR)/jit_cpu$(O) $(SRC_DIR)/jit_debug$(O) $(SRC_DIR)/jit_debug_xcoff$(O)'
115 my $execcapable = 0;
116 if ( ( $jitcpuarch eq 'i386' )
117 || ( $jitcpuarch eq 'ppc' )
118 || ( $jitcpuarch eq 'arm' ) )
120 $execcapable = 1;
121 unless ( ( $osname eq 'openbsd' )
122 || ( $osname eq 'freebsd' )
123 || ( $osname eq 'netbsd' )
124 || ( $osname eq 'linux' )
125 || ( $osname eq 'darwin' )
126 || ( $osname eq 'cygwin' )
127 || ( $osname eq 'MSWin32' ) )
129 $execcapable = 0;
132 $execcapable = $conf->options->get('execcapable')
133 if defined $conf->options->get('execcapable');
134 _handle_execcapable($conf, $execcapable);
136 # test for executable malloced memory
137 if ( -e "config/auto/jit/test_exec_$osname.in" ) {
138 print " (has_exec_protect " if $verbose;
139 $conf->cc_gen("config/auto/jit/test_exec_$osname.in");
140 eval { $conf->cc_build(); };
141 if ($@) {
142 print " $@) " if $verbose;
144 else {
145 if ( $conf->cc_run(0) !~ /ok/ && $conf->cc_run(1) =~ /ok/ ) {
146 $conf->data->set( has_exec_protect => 1 );
147 print "yes) " if $verbose;
149 else {
150 print "no) " if $verbose;
153 $conf->cc_clean();
156 # RT #43146 use executable memory for this test if needed
158 # test for some instructions
159 if ( $jitcpuarch eq 'i386' ) {
160 $conf->cc_gen('config/auto/jit/test_c.in');
161 eval { $conf->cc_build(); };
162 unless ( $@ || $conf->cc_run() !~ /ok/ ) {
163 $conf->data->set( jit_i386 => 'fcomip' );
165 $conf->cc_clean();
168 else {
169 $conf->data->set(
170 jitarchname => 'nojit',
171 jitcpuarch => $cpuarch,
172 jitcpu => $cpuarch,
173 jitosname => $osname,
174 jitcapable => 0,
175 execcapable => 0,
176 cc_hasjit => '',
177 TEMP_jit_o => '',
178 TEMP_exec_h => '',
179 TEMP_exec_o => '',
180 TEMP_exec_dep => '',
184 return 1;
187 sub _handle_execcapable {
188 my ($conf, $execcapable) = @_;
189 if ($execcapable) {
190 my $cpuarch = $conf->data->get('cpuarch');
191 $conf->data->set(
192 TEMP_exec_h =>
193 '$(SRC_DIR)/jit.h $(INC_DIR)/exec.h $(SRC_DIR)/exec_dep.h $(SRC_DIR)/exec_save.h',
194 TEMP_exec_o =>
195 '$(SRC_DIR)/exec$(O) $(SRC_DIR)/exec_cpu$(O) $(SRC_DIR)/exec_dep$(O) $(SRC_DIR)/exec_save$(O)',
196 TEMP_exec_dep =>
197 "\$(SRC_DIR)/exec_dep.c : \$(SRC_DIR)/jit/$cpuarch/exec_dep.c\n"
198 . "\t\$(CP) \$(SRC_DIR)/jit/$cpuarch/exec_dep.c \$(SRC_DIR)/exec_dep.c",
199 execcapable => 1
202 else {
203 $conf->data->set(
204 TEMP_exec_h => '',
205 TEMP_exec_o => '',
206 TEMP_exec_dep => '',
207 execcapable => 0,
210 return 1;
215 # Local Variables:
216 # mode: cperl
217 # cperl-indent-level: 4
218 # fill-column: 100
219 # End:
220 # vim: expandtab shiftwidth=4: