]>
Commit | Line | Data |
---|---|---|
b4b575ce | 1 | # Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. |
8a6b509e AT |
2 | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
748086b7 | 5 | # the Free Software Foundation; either version 3 of the License, or |
8a6b509e | 6 | # (at your option) any later version. |
7a54c850 | 7 | # |
8a6b509e AT |
8 | # This program is distributed in the hope that it will be useful, |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
7a54c850 | 12 | # |
8a6b509e | 13 | # You should have received a copy of the GNU General Public License |
748086b7 JJ |
14 | # along with this program; see the file COPYING3. If not see |
15 | # <http://www.gnu.org/licenses/>. | |
8a6b509e | 16 | |
fdc69597 | 17 | proc load_gcc_lib { filename } { |
8ec7c36a SH |
18 | global srcdir loaded_libs |
19 | ||
4e70f25f | 20 | load_file $srcdir/../../gcc/testsuite/lib/$filename |
8ec7c36a | 21 | set loaded_libs($filename) "" |
fdc69597 RE |
22 | } |
23 | ||
8a6b509e AT |
24 | load_lib dg.exp |
25 | load_lib libgloss.exp | |
1df8e834 | 26 | load_gcc_lib target-libpath.exp |
fdc69597 | 27 | load_gcc_lib wrapper.exp |
70d8f2a1 AT |
28 | |
29 | ||
8a6b509e AT |
30 | # Define libffi callbacks for dg.exp. |
31 | ||
32 | proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } { | |
727e729b HPN |
33 | |
34 | # To get all \n in dg-output test strings to match printf output | |
35 | # in a system that outputs it as \015\012 (i.e. not just \012), we | |
36 | # need to change all \n into \r?\n. As there is no dejagnu flag | |
37 | # or hook to do that, we simply change the text being tested. | |
38 | # Unfortunately, we have to know that the variable is called | |
39 | # dg-output-text and lives in the caller of libffi-dg-test, which | |
40 | # is two calls up. Overriding proc dg-output would be longer and | |
41 | # would necessarily have the same assumption. | |
42 | upvar 2 dg-output-text output_match | |
43 | ||
44 | if { [llength $output_match] > 1 } { | |
fc0ad8d9 | 45 | regsub -all "\n" [lindex $output_match 1] "\r?\n" x |
727e729b HPN |
46 | set output_match [lreplace $output_match 1 1 $x] |
47 | } | |
48 | ||
8a6b509e AT |
49 | # Set up the compiler flags, based on what we're going to do. |
50 | ||
51 | set options [list] | |
52 | switch $do_what { | |
53 | "compile" { | |
54 | set compile_type "assembly" | |
55 | set output_file "[file rootname [file tail $prog]].s" | |
56 | } | |
57 | "link" { | |
58 | set compile_type "executable" | |
59 | set output_file "[file rootname [file tail $prog]].exe" | |
60 | # The following line is needed for targets like the i960 where | |
61 | # the default output file is b.out. Sigh. | |
62 | } | |
63 | "run" { | |
64 | set compile_type "executable" | |
65 | # FIXME: "./" is to cope with "." not being in $PATH. | |
66 | # Should this be handled elsewhere? | |
67 | # YES. | |
68 | set output_file "./[file rootname [file tail $prog]].exe" | |
69 | # This is the only place where we care if an executable was | |
70 | # created or not. If it was, dg.exp will try to run it. | |
71 | remote_file build delete $output_file; | |
72 | } | |
73 | default { | |
74 | perror "$do_what: not a valid dg-do keyword" | |
75 | return "" | |
76 | } | |
77 | } | |
78 | ||
79 | if { $extra_tool_flags != "" } { | |
80 | lappend options "additional_flags=$extra_tool_flags" | |
81 | } | |
82 | ||
83 | set comp_output [libffi_target_compile "$prog" "$output_file" "$compile_type" $options]; | |
84 | ||
85 | ||
86 | return [list $comp_output $output_file] | |
87 | } | |
88 | ||
89 | ||
90 | proc libffi-dg-test { prog do_what extra_tool_flags } { | |
91 | return [libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags] | |
92 | } | |
93 | ||
94 | proc libffi-init { args } { | |
95 | global gluefile wrap_flags; | |
96 | global srcdir | |
97 | global blddirffi | |
fdc69597 | 98 | global objdir |
4e70f25f | 99 | global blddircxx |
8a6b509e | 100 | global TOOL_OPTIONS |
fc9051dd | 101 | global tool |
8a6b509e | 102 | global libffi_include |
7a54c850 | 103 | global libffi_link_flags |
8a6b509e | 104 | global tool_root_dir |
1df8e834 | 105 | global ld_library_path |
8a6b509e | 106 | |
4e70f25f | 107 | set blddirffi [lookfor_file [get_multilibs] libffi] |
8a6b509e | 108 | verbose "libffi $blddirffi" |
4e70f25f AS |
109 | set blddircxx [lookfor_file [get_multilibs] libstdc++-v3] |
110 | verbose "libstdc++ $blddircxx" | |
8a6b509e AT |
111 | |
112 | set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] | |
33d1a550 L |
113 | if {$gccdir != ""} { |
114 | set gccdir [file dirname $gccdir] | |
33cde516 RS |
115 | } |
116 | verbose "gccdir $gccdir" | |
117 | ||
118 | set ld_library_path "." | |
119 | append ld_library_path ":${gccdir}" | |
120 | ||
121 | set compiler "${gccdir}/xgcc" | |
122 | if { [is_remote host] == 0 && [which $compiler] != 0 } { | |
123 | foreach i "[exec $compiler --print-multi-lib]" { | |
124 | set mldir "" | |
125 | regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir | |
126 | set mldir [string trimright $mldir "\;@"] | |
127 | if { "$mldir" == "." } { | |
128 | continue | |
129 | } | |
130 | if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } { | |
131 | append ld_library_path ":${gccdir}/${mldir}" | |
132 | } | |
133 | } | |
33d1a550 | 134 | } |
8a6b509e | 135 | # add the library path for libffi. |
33cde516 | 136 | append ld_library_path ":${blddirffi}/.libs" |
4e70f25f AS |
137 | # add the library path for libstdc++ as well. |
138 | append ld_library_path ":${blddircxx}/src/.libs" | |
8a6b509e AT |
139 | |
140 | verbose "ld_library_path: $ld_library_path" | |
141 | ||
142 | # Point to the Libffi headers in libffi. | |
143 | set libffi_include "${blddirffi}/include" | |
144 | verbose "libffi_include $libffi_include" | |
7a54c850 | 145 | |
8a6b509e AT |
146 | set libffi_dir "${blddirffi}/.libs" |
147 | verbose "libffi_dir $libffi_dir" | |
148 | if { $libffi_dir != "" } { | |
149 | set libffi_dir [file dirname ${libffi_dir}] | |
150 | set libffi_link_flags "-L${libffi_dir}/.libs" | |
4e70f25f | 151 | lappend libffi_link_flags "-L${blddircxx}/src/.libs" |
8a6b509e | 152 | } |
7a54c850 | 153 | |
1df8e834 | 154 | set_ld_library_path_env_vars |
fdc69597 RE |
155 | libffi_maybe_build_wrapper "${objdir}/testglue.o" |
156 | } | |
157 | ||
158 | proc libffi_exit { } { | |
159 | global gluefile; | |
160 | ||
161 | if [info exists gluefile] { | |
162 | file_on_build delete $gluefile; | |
163 | unset gluefile; | |
164 | } | |
8a6b509e AT |
165 | } |
166 | ||
167 | proc libffi_target_compile { source dest type options } { | |
168 | global gluefile wrap_flags; | |
169 | global srcdir | |
170 | global blddirffi | |
171 | global TOOL_OPTIONS | |
8a6b509e AT |
172 | global libffi_link_flags |
173 | global libffi_include | |
70d8f2a1 | 174 | global target_triplet |
7a54c850 | 175 | |
8a6b509e AT |
176 | |
177 | if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } { | |
178 | lappend options "libs=${gluefile}" | |
179 | lappend options "ldflags=$wrap_flags" | |
180 | } | |
181 | ||
182 | # TOOL_OPTIONS must come first, so that it doesn't override testcase | |
183 | # specific options. | |
184 | if [info exists TOOL_OPTIONS] { | |
185 | lappend options [concat "additional_flags=$TOOL_OPTIONS" $options]; | |
186 | } | |
187 | ||
eb26c76c | 188 | # search for ffi_mips.h in srcdir, too |
5196736e | 189 | lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.." |
8a6b509e | 190 | lappend options "additional_flags=${libffi_link_flags}" |
9e6c3ecb | 191 | |
7bbcc286 AT |
192 | # Darwin needs a stack execution allowed flag. |
193 | ||
194 | if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"] | |
195 | || [istarget "*-*-darwin2*"] } { | |
196 | lappend options "additional_flags=-Wl,-allow_stack_execute" | |
197 | } | |
198 | ||
0363db46 GK |
199 | # If you're building the compiler with --prefix set to a place |
200 | # where it's not yet installed, then the linker won't be able to | |
201 | # find the libgcc used by libffi.dylib. We could pass the | |
202 | # -dylib_file option, but that's complicated, and it's much easier | |
203 | # to just make the linker find libgcc using -L options. | |
204 | if { [string match "*-*-darwin*" $target_triplet] } { | |
205 | lappend options "libs= -shared-libgcc" | |
9e6c3ecb AT |
206 | } |
207 | ||
cb14fcb8 AT |
208 | if { [string match "*-*-openbsd*" $target_triplet] } { |
209 | lappend options "libs= -lpthread" | |
210 | } | |
211 | ||
9e6c3ecb | 212 | lappend options "libs= -lffi" |
70d8f2a1 | 213 | |
b4b575ce AG |
214 | if { [string match "aarch64*-*-linux*" $target_triplet] } { |
215 | lappend options "libs= -lpthread" | |
216 | } | |
217 | ||
8a6b509e AT |
218 | verbose "options: $options" |
219 | return [target_compile $source $dest $type $options] | |
220 | } | |
221 | ||
222 | # Utility routines. | |
223 | ||
224 | # | |
225 | # search_for -- looks for a string match in a file | |
226 | # | |
227 | proc search_for { file pattern } { | |
228 | set fd [open $file r] | |
229 | while { [gets $fd cur_line]>=0 } { | |
230 | if [string match "*$pattern*" $cur_line] then { | |
231 | close $fd | |
232 | return 1 | |
233 | } | |
234 | } | |
235 | close $fd | |
236 | return 0 | |
237 | } | |
238 | ||
239 | # Modified dg-runtest that can cycle through a list of optimization options | |
240 | # as c-torture does. | |
241 | proc libffi-dg-runtest { testcases default-extra-flags } { | |
242 | global runtests | |
243 | ||
244 | foreach test $testcases { | |
7a54c850 | 245 | # If we're only testing specific files and this isn't one of |
8a6b509e AT |
246 | # them, skip it. |
247 | if ![runtest_file_p $runtests $test] { | |
248 | continue | |
7a54c850 | 249 | } |
8a6b509e AT |
250 | |
251 | # Look for a loop within the source code - if we don't find one, | |
252 | # don't pass -funroll[-all]-loops. | |
253 | global torture_with_loops torture_without_loops | |
254 | if [expr [search_for $test "for*("]+[search_for $test "while*("]] { | |
255 | set option_list $torture_with_loops | |
256 | } else { | |
257 | set option_list $torture_without_loops | |
258 | } | |
259 | ||
260 | set nshort [file tail [file dirname $test]]/[file tail $test] | |
261 | ||
262 | foreach flags $option_list { | |
263 | verbose "Testing $nshort, $flags" 1 | |
264 | dg-test $test $flags ${default-extra-flags} | |
265 | } | |
266 | } | |
267 | } | |
268 | ||
269 | ||
270 | # Like check_conditional_xfail, but callable from a dg test. | |
271 | ||
272 | proc dg-xfail-if { args } { | |
273 | set args [lreplace $args 0 0] | |
274 | set selector "target [join [lindex $args 1]]" | |
275 | if { [dg-process-target $selector] == "S" } { | |
276 | global compiler_conditional_xfail_data | |
277 | set compiler_conditional_xfail_data $args | |
278 | } | |
279 | } | |
280 | ||
46e0720d CLT |
281 | proc check-flags { args } { |
282 | ||
283 | # The args are within another list; pull them out. | |
284 | set args [lindex $args 0] | |
285 | ||
286 | # The next two arguments are optional. If they were not specified, | |
287 | # use the defaults. | |
288 | if { [llength $args] == 2 } { | |
289 | lappend $args [list "*"] | |
290 | } | |
291 | if { [llength $args] == 3 } { | |
292 | lappend $args [list ""] | |
293 | } | |
294 | ||
295 | # If the option strings are the defaults, or the same as the | |
296 | # defaults, there is no need to call check_conditional_xfail to | |
297 | # compare them to the actual options. | |
298 | if { [string compare [lindex $args 2] "*"] == 0 | |
299 | && [string compare [lindex $args 3] "" ] == 0 } { | |
300 | set result 1 | |
301 | } else { | |
302 | # The target list might be an effective-target keyword, so replace | |
303 | # the original list with "*-*-*", since we already know it matches. | |
304 | set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]] | |
305 | } | |
306 | ||
307 | return $result | |
308 | } | |
309 | ||
310 | proc dg-skip-if { args } { | |
311 | # Verify the number of arguments. The last two are optional. | |
312 | set args [lreplace $args 0 0] | |
313 | if { [llength $args] < 2 || [llength $args] > 4 } { | |
314 | error "dg-skip-if 2: need 2, 3, or 4 arguments" | |
315 | } | |
316 | ||
317 | # Don't bother if we're already skipping the test. | |
318 | upvar dg-do-what dg-do-what | |
319 | if { [lindex ${dg-do-what} 1] == "N" } { | |
320 | return | |
321 | } | |
322 | ||
323 | set selector [list target [lindex $args 1]] | |
324 | if { [dg-process-target $selector] == "S" } { | |
325 | if [check-flags $args] { | |
326 | upvar dg-do-what dg-do-what | |
327 | set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] | |
328 | } | |
329 | } | |
330 | } | |
8a6b509e AT |
331 | |
332 | # We need to make sure that additional_files and additional_sources | |
333 | # are both cleared out after every test. It is not enough to clear | |
334 | # them out *before* the next test run because gcc-target-compile gets | |
335 | # run directly from some .exp files (outside of any test). (Those | |
7a54c850 | 336 | # uses should eventually be eliminated.) |
8a6b509e AT |
337 | |
338 | # Because the DG framework doesn't provide a hook that is run at the | |
339 | # end of a test, we must replace dg-test with a wrapper. | |
340 | ||
341 | if { [info procs saved-dg-test] == [list] } { | |
342 | rename dg-test saved-dg-test | |
343 | ||
344 | proc dg-test { args } { | |
345 | global additional_files | |
346 | global additional_sources | |
347 | global errorInfo | |
348 | ||
349 | if { [ catch { eval saved-dg-test $args } errmsg ] } { | |
350 | set saved_info $errorInfo | |
351 | set additional_files "" | |
352 | set additional_sources "" | |
353 | error $errmsg $saved_info | |
354 | } | |
355 | set additional_files "" | |
356 | set additional_sources "" | |
357 | } | |
358 | } | |
359 | ||
360 | # Local Variables: | |
361 | # tcl-indent-level:4 | |
70d8f2a1 | 362 | # End: |