OSDN Git Service

* lib/target-supports.exp (check_effective_target_fortran_large_real,
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / lib / target-supports.exp
1 #   Copyright (C) 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
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
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
7 #
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.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
17 # Please email any bugs, comments, and/or additions to this file to:
18 # gcc-patches@gcc.gnu.org
19
20 # This file defines procs for determining features supported by the target.
21
22 # Try to compile some code and return the messages printed by the compiler.
23 #
24 # BASENAME is a basename to use for temporary files.
25 # TYPE is the type of compilation to perform (see target_compile).
26 # CONTENTS gives the contents of the input file.
27 # The rest is optional:
28 # OPTIONS: additional compiler options to use.
29 proc get_compiler_messages {basename type contents args} {
30     global tool
31
32     if { [llength $args] > 0 } {
33         set options "additional_flags=[lindex $args 0]"
34     } else {
35         set options ""
36     }
37
38     set src ${basename}[pid].c
39     switch $type {
40         assembly { set output ${basename}[pid].s }
41         object { set output ${basename}[pid].o }
42     }
43     set f [open $src "w"]
44     puts $f $contents
45     close $f
46     set lines [${tool}_target_compile $src $output $type "$options"]
47     file delete $src
48     remote_file build delete $output
49
50     return $lines
51 }
52
53 proc current_target_name { } {
54     global target_info
55     if [info exists target_info(target,name)] {
56         set answer $target_info(target,name)
57     } else {
58         set answer ""
59     }
60     return $answer
61 }
62
63 ###############################
64 # proc check_weak_available { }
65 ###############################
66
67 # weak symbols are only supported in some configs/object formats
68 # this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure
69
70 proc check_weak_available { } {
71     global target_triplet
72     global target_cpu
73
74     # All mips targets should support it
75
76     if { [ string first "mips" $target_cpu ] >= 0 } {
77         return 1
78     }
79
80     # All solaris2 targets should support it
81
82     if { [regexp ".*-solaris2.*" $target_triplet] } {
83         return 1
84     }
85
86     # DEC OSF/1/Digital UNIX/Tru64 UNIX supports it
87
88     if { [regexp "alpha.*osf.*" $target_triplet] } {
89         return 1
90     }
91
92     # Windows targets Cygwin and MingW32 support it
93
94     if { [regexp ".*mingw32|.*cygwin" $target_triplet] } {
95         return 1
96     }
97
98     # HP-UX 10.X doesn't support it
99
100     if { [regexp "hppa.*hpux10" $target_triplet] } {
101         return 0
102     }
103
104     # ELF and ECOFF support it. a.out does with gas/gld but may also with
105     # other linkers, so we should try it
106
107     set objformat [gcc_target_object_format]
108
109     switch $objformat {
110         elf      { return 1 }
111         ecoff    { return 1 }
112         a.out    { return 1 }
113         mach-o   { return 1 }
114         som      { return 1 }
115         unknown  { return -1 }
116         default  { return 0 }
117     }
118 }
119
120 ###############################
121 # proc check_visibility_available { what_kind }
122 ###############################
123
124 # The visibility attribute is only support in some object formats
125 # This proc returns 1 if it is supported, 0 if not.
126 # The argument is the kind of visibility, default/protected/hidden/internal.
127
128 proc check_visibility_available { what_kind } {
129     global visibility_available_saved
130     global tool
131     global target_triplet
132
133     # On NetWare, support makes no sense.
134     if { [string match "*-*-netware*" $target_triplet] } {
135         return 0
136     }
137
138     if [string match "" $what_kind] { set what_kind "hidden" }
139
140     if { [info exists visibility_available_saved] } {
141         verbose "Saved result is <$visibility_available_saved>" 1
142         if { [ lsearch -exact $visibility_available_saved $what_kind ] != -1 } {
143             return 1
144         } elseif { [ lsearch -exact $visibility_available_saved "!$what_kind" ] != -1 } {
145             return 0
146         }
147     }
148
149     set lines [get_compiler_messages visibility object "
150         void f() __attribute__((visibility(\"$what_kind\")));
151         void f() {}
152     "]
153     if [string match "" $lines] then {
154         set answer 1
155         lappend visibility_available_saved $what_kind
156     } else {
157         set answer 0
158         lappend visibility_available_saved "!$what_kind"
159     }
160     return $answer
161 }
162
163 ###############################
164 # proc check_alias_available { }
165 ###############################
166
167 # Determine if the target toolchain supports the alias attribute.
168
169 # Returns 2 if the target supports aliases.  Returns 1 if the target
170 # only supports weak aliased.  Returns 0 if the target does not
171 # support aliases at all.  Returns -1 if support for aliases could not
172 # be determined.
173
174 proc check_alias_available { } {
175     global alias_available_saved
176     global tool
177
178     if [info exists alias_available_saved] {
179         verbose "check_alias_available  returning saved $alias_available_saved" 2
180     } else {
181         set src alias[pid].c
182         set obj alias[pid].o
183         verbose "check_alias_available  compiling testfile $src" 2
184         set f [open $src "w"]
185         # Compile a small test program.  The definition of "g" is
186         # necessary to keep the Solaris assembler from complaining
187         # about the program.
188         puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
189         puts $f "void g() {} void f() __attribute__((alias(\"g\")));"
190         close $f
191         set lines [${tool}_target_compile $src $obj object ""]
192         file delete $src
193         remote_file build delete $obj
194
195         if [string match "" $lines] then {
196             # No error messages, everything is OK.
197             set alias_available_saved 2
198         } else {
199             if [regexp "alias definitions not supported" $lines] {
200                 verbose "check_alias_available  target does not support aliases" 2
201
202                 set objformat [gcc_target_object_format]
203
204                 if { $objformat == "elf" } {
205                     verbose "check_alias_available  but target uses ELF format, so it ought to" 2
206                     set alias_available_saved -1
207                 } else {
208                     set alias_available_saved 0
209                 }
210             } else {
211                 if [regexp "only weak aliases are supported" $lines] {
212                 verbose "check_alias_available  target supports only weak aliases" 2
213                 set alias_available_saved 1
214                 } else {
215                     set alias_available_saved -1
216                 }
217             }
218         }
219
220         verbose "check_alias_available  returning $alias_available_saved" 2
221     }
222
223     return $alias_available_saved
224 }
225
226 # Returns true if --gc-sections is supported on the target.
227
228 proc check_gc_sections_available { } {
229     global gc_sections_available_saved
230     global tool
231
232     if {![info exists gc_sections_available_saved]} {
233         # Some targets don't support gc-sections despite whatever's
234         # advertised by ld's options.
235         if { [istarget alpha*-*-*]
236              || [istarget ia64-*-*] } {
237             set gc_sections_available_saved 0
238             return 0
239         }
240
241         # Check if the ld used by gcc supports --gc-sections.
242         set gcc_spec [${tool}_target_compile "-dumpspecs" "" "none" ""]
243         regsub ".*\n\*linker:\[ \t\]*\n(\[^ \t\n\]*).*" "$gcc_spec" {\1} linker
244         set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=$linker" "" "none" ""] 0]
245         set ld_output [remote_exec host "$gcc_ld" "--help"]
246         if { [ string first "--gc-sections" $ld_output ] >= 0 } {
247             set gc_sections_available_saved 1
248         } else {
249             set gc_sections_available_saved 0
250         }
251     }
252     return $gc_sections_available_saved
253 }
254
255 # Return true if profiling is supported on the target.
256
257 proc check_profiling_available { test_what } {
258     global profiling_available_saved
259
260     verbose "Profiling argument is <$test_what>" 1
261
262     # These conditions depend on the argument so examine them before
263     # looking at the cache variable.
264
265     # Support for -p on solaris2 relies on mcrt1.o which comes with the
266     # vendor compiler.  We cannot reliably predict the directory where the
267     # vendor compiler (and thus mcrt1.o) is installed so we can't
268     # necessarily find mcrt1.o even if we have it.
269     if { [istarget *-*-solaris2*] && [lindex $test_what 1] == "-p" } {
270         return 0
271     }
272
273     # Support for -p on irix relies on libprof1.a which doesn't appear to
274     # exist on any irix6 system currently posting testsuite results.
275     # Support for -pg on irix relies on gcrt1.o which doesn't exist yet.
276     # See: http://gcc.gnu.org/ml/gcc/2002-10/msg00169.html
277     if { [istarget mips*-*-irix*]
278     && ([lindex $test_what 1] == "-p" || [lindex $test_what 1] == "-pg") } {
279         return 0
280     }
281
282     # Now examine the cache variable.
283     if {![info exists profiling_available_saved]} {
284         # Some targets don't have any implementation of __bb_init_func or are
285         # missing other needed machinery.
286         if { [istarget mmix-*-*]
287              || [istarget arm*-*-eabi*]
288              || [istarget arm*-*-elf]
289              || [istarget arm*-*-symbianelf*]
290              || [istarget powerpc-*-eabi*]
291              || [istarget strongarm*-*-elf]
292              || [istarget xscale*-*-elf]
293              || [istarget cris-*-*]
294              || [istarget h8300-*-*]
295              || [istarget mips*-*-elf]
296              || [istarget xtensa-*-elf]
297              || [istarget *-*-windiss] } {
298             set profiling_available_saved 0
299         } else {
300             set profiling_available_saved 1
301         }
302     }
303
304     return $profiling_available_saved
305 }
306
307 # Return 1 if -fpic and -fPIC are supported, as in no warnings or errors
308 # emitted, 0 otherwise.  Whether a shared library can actually be built is
309 # out of scope for this test.
310 #
311 # When the target name changes, replace the cached result.
312
313 proc check_effective_target_fpic { } {
314     global et_fpic_saved
315     global et_fpic_target_name
316
317     if { ![info exists et_fpic_target_name] } {
318         set et_fpic_target_name ""
319     }
320
321     # If the target has changed since we set the cached value, clear it.
322     set current_target [current_target_name]
323     if { $current_target != $et_fpic_target_name } {
324         verbose "check_effective_target_fpic: `$et_fpic_target_name'" 2
325         set et_fpic_target_name $current_target
326         if [info exists et_fpic_saved] {
327             verbose "check_effective_target_fpic: removing cached result" 2
328             unset et_fpic_saved
329         }
330     }
331
332     if [info exists et_fpic_saved] {
333         verbose "check_effective_target_fpic: using cached result" 2
334     } else {
335         verbose "check_effective_target_fpic: compiling source" 2
336
337         # Note that M68K has a multilib that supports -fpic but not
338         # -fPIC, so we need to check both.  We test with a program that
339         # requires GOT references.
340         set et_fpic_saved [string match "" [get_compiler_messages fpic object {
341             extern int foo (void); extern int bar;
342             int baz (void) { return foo () + bar; }
343         } "-fpic"]]
344
345         if { $et_fpic_saved != 0 } {
346             set et_fpic_saved [string match "" [get_compiler_messages fpic object {
347                 extern int foo (void); extern int bar;
348                 int baz (void) { return foo () + bar; }
349             } "-fPIC"]]
350         }
351     }
352     verbose "check_effective_target_fpic: returning $et_fpic_saved" 2
353     return $et_fpic_saved
354 }
355
356 # Return true if iconv is supported on the target. In particular IBM1047.
357
358 proc check_iconv_available { test_what } {
359     global tool
360     global libiconv
361
362     set result ""
363
364     set src iconv[pid].c
365     set exe iconv[pid].x
366     verbose "check_iconv_available compiling testfile $src" 2
367     set f [open $src "w"]
368     # Compile a small test program.
369     puts $f "#include <iconv.h>\n"
370     puts $f "int main (void)\n {\n iconv_t cd; \n"
371     puts $f "cd = iconv_open (\"[lindex $test_what 1]\", \"UTF-8\");\n"
372     puts $f "if (cd == (iconv_t) -1)\n return 1;\n"
373     puts $f "return 0;\n}"
374     close $f
375
376     # If the tool configuration file has not set libiconv, try "-liconv"
377     if { ![info exists libiconv] } {
378         set libiconv "-liconv"
379     }
380     set lines [${tool}_target_compile $src $exe executable "libs=$libiconv" ]
381     file delete $src
382
383     if [string match "" $lines] then {
384         # No error messages, everything is OK.
385
386         set result [${tool}_load "./$exe" "" ""]
387         set status [lindex $result 0]
388         remote_file build delete $exe
389
390         verbose "check_iconv_available status is <$status>" 2
391
392         if { $status == "pass" } then {
393             return 1
394         }
395     }
396
397     return 0
398 }
399
400 # Return true if named sections are supported on this target.
401 # This proc does not cache results, because the answer may vary
402 # when cycling over subtarget options (e.g. irix o32/n32/n64) in
403 # the same test run.
404 proc check_named_sections_available { } {
405     verbose "check_named_sections_available: compiling source" 2
406     set answer [string match "" [get_compiler_messages named object {
407         int __attribute__ ((section("whatever"))) foo;
408     }]]
409     verbose "check_named_sections_available: returning $answer" 2
410     return $answer
411 }
412
413 # Return 1 if the target supports Fortran real kinds larger than real(8),
414 # 0 otherwise.
415 #
416 # When the target name changes, replace the cached result.
417
418 proc check_effective_target_fortran_large_real { } {
419     global et_fortran_large_real_saved
420     global et_fortran_large_real_target_name
421     global tool
422
423     if { ![info exists et_fortran_large_real_target_name] } {
424         set et_fortran_large_real_target_name ""
425     }
426
427     # If the target has changed since we set the cached value, clear it.
428     set current_target [current_target_name]
429     if { $current_target != $et_fortran_large_real_target_name } {
430         verbose "check_effective_target_fortran_large_real: `$et_fortran_large_real_target_name' `$current_target'" 2
431         set et_fortran_large_real_target_name $current_target
432         if [info exists et_fortran_large_real_saved] {
433             verbose "check_effective_target_fortran_large_real: removing cached result" 2
434             unset et_fortran_large_real_saved
435         }
436     }
437
438     if [info exists et_fortran_large_real_saved] {
439         verbose "check_effective_target_fortran_large_real returning saved $et_fortran_large_real_saved" 2
440     } else {
441         set et_fortran_large_real_saved 0
442
443         # Set up, compile, and execute a test program using large real
444         # kinds.  Include the current process ID in the file names to
445         # prevent conflicts with invocations for multiple testsuites.
446         set src real[pid].f90
447         set exe real[pid].x
448
449         set f [open $src "w"]
450         puts $f "integer,parameter :: k = &"
451         puts $f "  selected_real_kind (precision (0.0_8) + 1)"
452         puts $f "real(kind=k) :: x"
453         puts $f "end"
454         close $f
455
456         verbose "check_effective_target_fortran_large_real compiling testfile $src" 2
457         set lines [${tool}_target_compile $src $exe executable ""]
458         file delete $src
459
460         if [string match "" $lines] then {
461             # No error message, compilation succeeded.
462             set et_fortran_large_real_saved 1
463         }
464     }
465
466     return $et_fortran_large_real_saved
467 }
468
469 # Return 1 if the target supports Fortran integer kinds larger than
470 # integer(8), 0 otherwise.
471 #
472 # When the target name changes, replace the cached result.
473
474 proc check_effective_target_fortran_large_int { } {
475     global et_fortran_large_int_saved
476     global et_fortran_large_int_target_name
477     global tool
478
479     if { ![info exists et_fortran_large_int_target_name] } {
480         set et_fortran_large_int_target_name ""
481     }
482
483     # If the target has changed since we set the cached value, clear it.
484     set current_target [current_target_name]
485     if { $current_target != $et_fortran_large_int_target_name } {
486         verbose "check_effective_target_fortran_large_int: `$et_fortran_large_int_target_name' `$current_target'" 2
487         set et_fortran_large_int_target_name $current_target
488         if [info exists et_fortran_large_int_saved] {
489             verbose "check_effective_target_fortran_large_int: removing cached result" 2
490             unset et_fortran_large_int_saved
491         }
492     }
493
494     if [info exists et_fortran_large_int_saved] {
495         verbose "check_effective_target_fortran_large_int returning saved $et_fortran_large_int_saved" 2
496     } else {
497         set et_fortran_large_int_saved 0
498
499         # Set up, compile, and execute a test program using large integer
500         # kinds.  Include the current process ID in the file names to
501         # prevent conflicts with invocations for multiple testsuites.
502         set src int[pid].f90
503         set exe int[pid].x
504
505         set f [open $src "w"]
506         puts $f "integer,parameter :: k = &"
507         puts $f "  selected_int_kind (range (0_8) + 1)"
508         puts $f "integer(kind=k) :: i"
509         puts $f "end"
510         close $f
511
512         verbose "check_effective_target_fortran_large_int compiling testfile $src" 2
513         set lines [${tool}_target_compile $src $exe executable ""]
514         file delete $src
515
516         if [string match "" $lines] then {
517             # No error message, compilation succeeded.
518             set et_fortran_large_int_saved 1
519         }
520     }
521
522     return $et_fortran_large_int_saved
523 }
524
525 # Return 1 if the target supports executing AltiVec instructions, 0
526 # otherwise.  Cache the result.
527
528 proc check_vmx_hw_available { } {
529     global vmx_hw_available_saved
530     global tool
531
532     if [info exists vmx_hw_available_saved] {
533         verbose "check_hw_available  returning saved $vmx_hw_available_saved" 2
534     } else {
535         set vmx_hw_available_saved 0
536
537         # Some simulators are known to not support VMX instructions.
538         if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } {
539             verbose "check_hw_available  returning 0" 2
540             return $vmx_hw_available_saved
541         }
542
543         # Set up, compile, and execute a test program containing VMX
544         # instructions.  Include the current process ID in the file
545         # names to prevent conflicts with invocations for multiple
546         # testsuites.
547         set src vmx[pid].c
548         set exe vmx[pid].x
549
550         set f [open $src "w"]
551         puts $f "int main() {"
552         puts $f "#ifdef __MACH__"
553         puts $f "  asm volatile (\"vor v0,v0,v0\");"
554         puts $f "#else"
555         puts $f "  asm volatile (\"vor 0,0,0\");"
556         puts $f "#endif"
557         puts $f "  return 0; }"
558         close $f
559
560         # Most targets don't require special flags for this test case, but
561         # Darwin does.
562         if [istarget *-*-darwin*] {
563           set opts "additional_flags=-maltivec"
564         } else {
565           set opts ""
566         }
567
568         verbose "check_vmx_hw_available  compiling testfile $src" 2
569         set lines [${tool}_target_compile $src $exe executable "$opts"]
570         file delete $src
571
572         if [string match "" $lines] then {
573             # No error message, compilation succeeded.
574             set result [${tool}_load "./$exe" "" ""]
575             set status [lindex $result 0]
576             remote_file build delete $exe
577             verbose "check_vmx_hw_available testfile status is <$status>" 2
578
579             if { $status == "pass" } then {
580                 set vmx_hw_available_saved 1
581             }
582         } else {
583             verbose "check_vmx_hw_availalble testfile compilation failed" 2
584         }
585     }
586
587     return $vmx_hw_available_saved
588 }
589
590 # GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing
591 # complex float arguments.  This affects gfortran tests that call cabsf
592 # in libm built by an earlier compiler.  Return 1 if libm uses the same
593 # argument passing as the compiler under test, 0 otherwise.
594 #
595 # When the target name changes, replace the cached result.
596
597 proc check_effective_target_broken_cplxf_arg { } {
598     global et_broken_cplxf_arg_saved
599     global et_broken_cplxf_arg_target_name
600     global tool
601
602     # Skip the work for targets known not to be affected.
603     if { ![istarget powerpc64-*-linux*] } {
604         return 0
605     } elseif { [is-effective-target ilp32] } {
606         return 0
607     }
608
609     if { ![info exists et_broken_cplxf_arg_target_name] } {
610         set et_broken_cplxf_arg_target_name ""
611     }
612
613     # If the target has changed since we set the cached value, clear it.
614     set current_target [current_target_name]
615     if { $current_target != $et_broken_cplxf_arg_target_name } {
616         verbose "check_effective_target_broken_cplxf_arg: `$et_broken_cplxf_arg_target_name'" 2
617         set et_broken_cplxf_arg_target_name $current_target
618         if [info exists et_broken_cplxf_arg_saved] {
619             verbose "check_effective_target_broken_cplxf_arg: removing cached result" 2
620             unset et_broken_cplxf_arg_saved
621         }
622     }
623
624     if [info exists et_broken_cplxf_arg_saved] {
625         verbose "check_effective_target_broken_cplxf_arg: using cached result" 2
626     } else {
627         set et_broken_cplxf_arg_saved 0
628         # This is only known to affect one target.
629         if { ![istarget powerpc64-*-linux*] || ![is-effective-target lp64] } {
630             set et_broken_cplxf_arg_saved 0
631             verbose "check_effective_target_broken_cplxf_arg: caching 0" 2
632             return $et_broken_cplxf_arg_saved
633         }
634
635         # Set up, compile, and execute a C test program that calls cabsf.
636         set src cabsf[pid].c
637         set exe cabsf[pid].x
638
639         set f [open $src "w"]
640         puts $f "#include <complex.h>"
641         puts $f "extern void abort (void);"
642         puts $f "float fabsf (float);"
643         puts $f "float cabsf (_Complex float);"
644         puts $f "int main ()"
645         puts $f "{"
646         puts $f "  _Complex float cf;"
647         puts $f "  float f;"
648         puts $f "  cf = 3 + 4.0fi;"
649         puts $f "  f = cabsf (cf);"
650         puts $f "  if (fabsf (f - 5.0) > 0.0001) abort ();"
651         puts $f "  return 0;"
652         puts $f "}"
653         close $f
654
655         set lines [${tool}_target_compile $src $exe executable "-lm"]
656         file delete $src
657
658         if [string match "" $lines] {
659             # No error message, compilation succeeded.
660             set result [${tool}_load "./$exe" "" ""]
661             set status [lindex $result 0]
662             remote_file build delete $exe
663
664             verbose "check_effective_target_broken_cplxf_arg: status is <$status>" 2
665
666             if { $status != "pass" } {
667                 set et_broken_cplxf_arg_saved 1
668             }
669         } else {
670             verbose "check_effective_target_broken_cplxf_arg: compilation failed" 2
671         }
672     }
673     return $et_broken_cplxf_arg_saved
674 }
675
676 proc check_alpha_max_hw_available { } {
677     global alpha_max_hw_available_saved
678     global tool
679
680     if [info exists alpha_max_hw_available_saved] {
681         verbose "check_alpha_max_hw_available returning saved $alpha_max_hw_available_saved" 2
682     } else {
683         set alpha_max_hw_available_saved 0
684
685         # Set up, compile, and execute a test program probing bit 8 of the
686         # architecture mask, which indicates presence of MAX instructions.
687         set src max[pid].c
688         set exe max[pid].x
689
690         set f [open $src "w"]
691         puts $f "int main() { return __builtin_alpha_amask(1<<8) != 0; }"
692         close $f
693
694         verbose "check_alpha_max_hw_available compiling testfile $src" 2
695         set lines [${tool}_target_compile $src $exe executable ""]
696         file delete $src
697
698         if [string match "" $lines] then {
699             # No error message, compilation succeeded.
700             set result [${tool}_load "./$exe" "" ""]
701             set status [lindex $result 0]
702             remote_file build delete $exe
703             verbose "check_alpha_max_hw_available testfile status is <$status>" 2
704
705             if { $status == "pass" } then {
706                 set alpha_max_hw_available_saved 1
707             }
708         } else {
709             verbose "check_alpha_max_hw_availalble testfile compilation failed" 2
710         }
711     }
712
713     return $alpha_max_hw_available_saved
714 }
715
716 # Returns true iff the FUNCTION is available on the target system.
717 # (This is essentially a Tcl implementation of Autoconf's
718 # AC_CHECK_FUNC.)
719
720 proc check_function_available { function } {
721     set var "${function}_available_saved"
722     global $var
723     global tool
724
725     if {![info exists $var]} {
726         # Assume it exists.
727         set $var 1
728         # Check to make sure.
729         set src "function[pid].c"
730         set exe "function[pid].exe"
731
732         set f [open $src "w"]
733         puts $f "int main () { $function (); }"
734         close $f
735
736         set lines [${tool}_target_compile $src $exe executable ""]
737         file delete $src
738         file delete $exe
739
740         if {![string match "" $lines]} then {
741             set $var 0
742             verbose -log "$function is not available"
743         } else {
744             verbose -log "$function is available"
745         }
746     }
747
748     eval return \$$var
749 }
750
751 # Returns true iff "fork" is available on the target system.
752
753 proc check_fork_available {} {
754     return [check_function_available "fork"]
755 }
756
757 # Returns true iff "mkfifo" is available on the target system.
758
759 proc check_mkfifo_available {} {
760     if {[istarget *-*-cygwin*]} {
761        # Cygwin has mkfifo, but support is incomplete.
762        return 0
763      }
764
765     return [check_function_available "mkfifo"]
766 }
767
768 # Return 1 if we're generating 32-bit code using default options, 0
769 # otherwise.
770 #
771 # When the target name changes, replace the cached result.
772
773 proc check_effective_target_ilp32 { } {
774     global et_ilp32_saved
775     global et_ilp32_target_name
776
777     if { ![info exists et_ilp32_target_name] } {
778         set et_ilp32_target_name ""
779     }
780
781     # If the target has changed since we set the cached value, clear it.
782     set current_target [current_target_name]
783     if { $current_target != $et_ilp32_target_name } {
784         verbose "check_effective_target_ilp32: `$et_ilp32_target_name' `$current_target'" 2
785         set et_ilp32_target_name $current_target
786         if { [info exists et_ilp32_saved] } {
787             verbose "check_effective_target_ilp32: removing cached result" 2
788             unset et_ilp32_saved
789         }
790     }
791
792     if [info exists et_ilp32_saved] {
793         verbose "check-effective_target_ilp32: using cached result" 2
794     } else {
795         verbose "check_effective_target_ilp32: compiling source" 2
796         set et_ilp32_saved [string match "" [get_compiler_messages ilp32 object {
797             int dummy[(sizeof (int) == 4 && sizeof (void *) == 4 && sizeof (long) == 4 ) ? 1 : -1];
798         }]]
799     }
800     verbose "check_effective_target_ilp32: returning $et_ilp32_saved" 2
801     return $et_ilp32_saved
802 }
803
804 # Return 1 if we're generating 64-bit code using default options, 0
805 # otherwise.
806 #
807 # When the target name changes, replace the cached result.
808
809 proc check_effective_target_lp64 { } {
810     global et_lp64_saved
811     global et_lp64_target_name
812
813     if { ![info exists et_lp64_target_name] } {
814         set et_lp64_target_name ""
815     }
816
817     # If the target has changed since we set the cached value, clear it.
818     set current_target [current_target_name]
819     if { $current_target != $et_lp64_target_name } {
820         verbose "check_effective_target_lp64: `$et_lp64_target_name' `$current_target'" 2
821         set et_lp64_target_name $current_target
822         if [info exists et_lp64_saved] {
823             verbose "check_effective_target_lp64: removing cached result" 2
824             unset et_lp64_saved
825         }
826     }
827
828     if [info exists et_lp64_saved] {
829         verbose "check_effective_target_lp64: using cached result" 2
830     } else {
831         verbose "check_effective_target_lp64: compiling source" 2
832         set et_lp64_saved [string match "" [get_compiler_messages lp64 object {
833             int dummy[(sizeof (int) == 4 && sizeof (void *) == 8 && sizeof (long) == 8 ) ? 1 : -1];
834         }]]
835     }
836     verbose "check_effective_target_lp64: returning $et_lp64_saved" 2
837     return $et_lp64_saved
838 }
839
840 # Return 1 if the target needs a command line argument to enable a SIMD
841 # instruction set.
842 #
843 # This won't change for different subtargets so cache the result.
844
845 proc check_effective_target_vect_cmdline_needed { } {
846     global et_vect_cmdline_needed_saved
847
848     if [info exists et_vect_cmdline_needed_saved] {
849         verbose "check_effective_target_vect_cmdline_needed: using cached result" 2
850     } else {
851         set et_vect_cmdline_needed_saved 1
852         if { [istarget ia64-*-*]
853               || [istarget x86_64-*-*] } {
854            set et_vect_cmdline_needed_saved 0
855         }
856     }
857
858     verbose "check_effective_target_vect_cmdline_needed: returning $et_vect_cmdline_needed_saved" 2
859     return $et_vect_cmdline_needed_saved
860 }
861
862 # Return 1 if the target supports hardware vectors of int, 0 otherwise.
863 #
864 # This won't change for different subtargets so cache the result.
865
866 proc check_effective_target_vect_int { } {
867     global et_vect_int_saved
868
869     if [info exists et_vect_int_saved] {
870         verbose "check_effective_target_vect_int: using cached result" 2
871     } else {
872         set et_vect_int_saved 0
873         if { [istarget i?86-*-*]
874               || [istarget powerpc*-*-*]
875               || [istarget x86_64-*-*]
876               || [istarget sparc*-*-*]
877               || [istarget alpha*-*-*]
878               || [istarget ia64-*-*] } {
879            set et_vect_int_saved 1
880         }
881     }
882
883     verbose "check_effective_target_vect_int: returning $et_vect_int_saved" 2
884     return $et_vect_int_saved
885 }
886
887 # Return 1 is this is an arm target using 32-bit instructions
888 proc check_effective_target_arm32 { } {
889     global et_arm32_saved
890     global et_arm32_target_name
891     global compiler_flags
892
893     if { ![info exists et_arm32_target_name] } {
894         set et_arm32_target_name ""
895     }
896
897     # If the target has changed since we set the cached value, clear it.
898     set current_target [current_target_name]
899     if { $current_target != $et_arm32_target_name } {
900         verbose "check_effective_target_arm32: `$et_arm32_target_name' `$current_target'" 2
901         set et_arm32_target_name $current_target
902         if { [info exists et_arm32_saved] } {
903             verbose "check_effective_target_arm32: removing cached result" 2
904             unset et_arm32_saved
905         }
906     }
907
908     if [info exists et_arm32_saved] {
909         verbose "check-effective_target_arm32: using cached result" 2
910     } else {
911         set et_arm32_saved 0
912         if { [istarget arm-*-*]
913               || [istarget strongarm*-*-*]
914               || [istarget xscale-*-*] } {
915             if ![string match "*-mthumb *" $compiler_flags] {
916                 set et_arm32_saved 1
917             }
918         }
919     }
920     verbose "check_effective_target_arm32: returning $et_arm32_saved" 2
921     return $et_arm32_saved
922 }
923
924 # Return 1 if the target supports hardware vector shift operation.
925
926 proc check_effective_target_vect_shift { } {
927     global et_vect_shift_saved
928
929     if [info exists et_vect_shift_saved] {
930         verbose "check_effective_target_vect_shift: using cached result" 2
931     } else {
932         set et_vect_shift_saved 0
933         if { [istarget powerpc*-*-*]
934              || [istarget ia64-*-*]
935              || [istarget i?86-*-*]
936              || [istarget x86_64-*-*] } {
937            set et_vect_shift_saved 1
938         }
939     }
940
941     verbose "check_effective_target_vect_shift: returning $et_vect_shift_saved" 2
942     return $et_vect_shift_saved
943 }
944
945 # Return 1 if the target supports hardware vectors of long, 0 otherwise.
946 #
947 # This can change for different subtargets so do not cache the result.
948
949 proc check_effective_target_vect_long { } {
950     if { [istarget i?86-*-*]
951          || ([istarget powerpc*-*-*] && [check_effective_target_ilp32])
952          || [istarget x86_64-*-*]
953          || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) } {
954         set answer 1
955     } else {
956         set answer 0
957     }
958
959     verbose "check_effective_target_vect_long: returning $answer" 2
960     return $answer
961 }
962
963 # Return 1 if the target supports hardware vectors of float, 0 otherwise.
964 #
965 # This won't change for different subtargets so cache the result.
966
967 proc check_effective_target_vect_float { } {
968     global et_vect_float_saved
969
970     if [info exists et_vect_float_saved] {
971         verbose "check_effective_target_vect_float: using cached result" 2
972     } else {
973         set et_vect_float_saved 0
974         if { [istarget i?86-*-*]
975               || [istarget powerpc*-*-*]
976               || [istarget mipsisa64*-*-*]
977               || [istarget x86_64-*-*]
978               || [istarget ia64-*-*] } {
979            set et_vect_float_saved 1
980         }
981     }
982
983     verbose "check_effective_target_vect_float: returning $et_vect_float_saved" 2
984     return $et_vect_float_saved
985 }
986
987 # Return 1 if the target supports hardware vectors of double, 0 otherwise.
988 #
989 # This won't change for different subtargets so cache the result.
990
991 proc check_effective_target_vect_double { } {
992     global et_vect_double_saved
993
994     if [info exists et_vect_double_saved] {
995         verbose "check_effective_target_vect_double: using cached result" 2
996     } else {
997         set et_vect_double_saved 0
998         if { [istarget i?86-*-*]
999               || [istarget x86_64-*-*] } {
1000            set et_vect_double_saved 1
1001         }
1002     }
1003
1004     verbose "check_effective_target_vect_double: returning $et_vect_double_saved" 2
1005     return $et_vect_double_saved
1006 }
1007
1008 # Return 1 if the target plus current options does not support a vector
1009 # max instruction on "int", 0 otherwise.
1010 #
1011 # This won't change for different subtargets so cache the result.
1012
1013 proc check_effective_target_vect_no_int_max { } {
1014     global et_vect_no_int_max_saved
1015
1016     if [info exists et_vect_no_int_max_saved] {
1017         verbose "check_effective_target_vect_no_int_max: using cached result" 2
1018     } else {
1019         set et_vect_no_int_max_saved 0
1020         if { [istarget sparc*-*-*]
1021              || [istarget alpha*-*-*] } {
1022             set et_vect_no_int_max_saved 1
1023         }
1024     }
1025     verbose "check_effective_target_vect_no_int_max: returning $et_vect_no_int_max_saved" 2
1026     return $et_vect_no_int_max_saved
1027 }
1028
1029 # Return 1 if the target plus current options does not support a vector
1030 # add instruction on "int", 0 otherwise.
1031 #
1032 # This won't change for different subtargets so cache the result.
1033
1034 proc check_effective_target_vect_no_int_add { } {
1035     global et_vect_no_int_add_saved
1036
1037     if [info exists et_vect_no_int_add_saved] {
1038         verbose "check_effective_target_vect_no_int_add: using cached result" 2
1039     } else {
1040         set et_vect_no_int_add_saved 0
1041         # Alpha only supports vector add on V8QI and V4HI.
1042         if { [istarget alpha*-*-*] } {
1043             set et_vect_no_int_add_saved 1
1044         }
1045     }
1046     verbose "check_effective_target_vect_no_int_add: returning $et_vect_no_int_add_saved" 2
1047     return $et_vect_no_int_add_saved
1048 }
1049
1050 # Return 1 if the target plus current options does not support vector
1051 # bitwise instructions, 0 otherwise.
1052 #
1053 # This won't change for different subtargets so cache the result.
1054
1055 proc check_effective_target_vect_no_bitwise { } {
1056     global et_vect_no_bitwise_saved
1057
1058     if [info exists et_vect_no_bitwise_saved] {
1059         verbose "check_effective_target_vect_no_bitwise: using cached result" 2
1060     } else {
1061         set et_vect_no_bitwise_saved 0
1062     }
1063     verbose "check_effective_target_vect_no_bitwise: returning $et_vect_no_bitwise_saved" 2
1064     return $et_vect_no_bitwise_saved
1065 }
1066
1067 # Return 1 if the target plus current options does not support a vector
1068 # alignment mechanism, 0 otherwise.
1069 #
1070 # This won't change for different subtargets so cache the result.
1071
1072 proc check_effective_target_vect_no_align { } {
1073     global et_vect_no_align_saved
1074
1075     if [info exists et_vect_no_align_saved] {
1076         verbose "check_effective_target_vect_no_align: using cached result" 2
1077     } else {
1078         set et_vect_no_align_saved 0
1079         if { [istarget mipsisa64*-*-*]
1080              || [istarget sparc*-*-*]
1081              || [istarget ia64-*-*] } {
1082             set et_vect_no_align_saved 1
1083         }
1084     }
1085     verbose "check_effective_target_vect_no_align: returning $et_vect_no_align_saved" 2
1086     return $et_vect_no_align_saved
1087 }
1088
1089 # Return 1 if the target supports vector conditional operations, 0 otherwise.
1090
1091 proc check_effective_target_vect_condition { } {
1092     global et_vect_cond_saved
1093
1094     if [info exists et_vect_cond_saved] {
1095         verbose "check_effective_target_vect_cond: using cached result" 2
1096     } else {
1097         set et_vect_cond_saved 0
1098         if { [istarget powerpc*-*-*]
1099              || [istarget ia64-*-*]
1100              || [istarget i?86-*-*]
1101              || [istarget x86_64-*-*] } {
1102            set et_vect_cond_saved 1
1103         }
1104     }
1105
1106     verbose "check_effective_target_vect_cond: returning $et_vect_cond_saved" 2
1107     return $et_vect_cond_saved
1108 }
1109
1110 # Return 1 if the target supports vector int multiplication, 0 otherwise.
1111
1112 proc check_effective_target_vect_int_mult { } {
1113     global et_vect_int_mult_saved
1114
1115     if [info exists et_vect_int_mult_saved] {
1116         verbose "check_effective_target_vect_int_mult: using cached result" 2
1117     } else {
1118         set et_vect_int_mult_saved 0
1119         if { [istarget powerpc*-*-*]
1120              || [istarget i?86-*-*]
1121              || [istarget x86_64-*-*] } {
1122            set et_vect_int_mult_saved 1
1123         }
1124     }
1125
1126     verbose "check_effective_target_vect_int_mult: returning $et_vect_int_mult_saved" 2
1127     return $et_vect_int_mult_saved
1128 }
1129
1130 # Return 1 if the target supports atomic operations on "int" and "long".
1131
1132 proc check_effective_target_sync_int_long { } {
1133     global et_sync_int_long_saved
1134
1135     if [info exists et_sync_int_long_saved] {
1136         verbose "check_effective_target_sync_int_long: using cached result" 2
1137     } else {
1138         set et_sync_int_long_saved 0
1139 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
1140 # load-reserved/store-conditional instructions.
1141         if { [istarget ia64-*-*]
1142              || [istarget i?86-*-*]
1143              || [istarget x86_64-*-*]
1144              || [istarget alpha*-*-*] 
1145              || [istarget s390*-*-*] 
1146              || [istarget powerpc*-*-*] } {
1147            set et_sync_int_long_saved 1
1148         }
1149     }
1150
1151     verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
1152     return $et_sync_int_long_saved
1153 }
1154
1155 # Return 1 if the target supports atomic operations on "char" and "short".
1156
1157 proc check_effective_target_sync_char_short { } {
1158     global et_sync_char_short_saved
1159
1160     if [info exists et_sync_char_short_saved] {
1161         verbose "check_effective_target_sync_char_short: using cached result" 2
1162     } else {
1163         set et_sync_char_short_saved 0
1164 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
1165 # load-reserved/store-conditional instructions.
1166         if { [istarget ia64-*-*]
1167              || [istarget i?86-*-*]
1168              || [istarget x86_64-*-*]
1169              || [istarget alpha*-*-*] 
1170              || [istarget powerpc*-*-*] } {
1171            set et_sync_char_short_saved 1
1172         }
1173     }
1174
1175     verbose "check_effective_target_sync_char_short: returning $et_sync_char_short_saved" 2
1176     return $et_sync_char_short_saved
1177 }
1178
1179 # Return 1 if the target matches the effective target 'arg', 0 otherwise.
1180 # This can be used with any check_* proc that takes no argument and
1181 # returns only 1 or 0.  It could be used with check_* procs that take
1182 # arguments with keywords that pass particular arguments.
1183
1184 proc is-effective-target { arg } {
1185     set selected 0
1186     if { [info procs check_effective_target_${arg}] != [list] } {
1187         set selected [check_effective_target_${arg}]
1188     } else {
1189         switch $arg {
1190           "vmx_hw"         { set selected [check_vmx_hw_available] }
1191           "named_sections" { set selected [check_named_sections_available] }
1192           "gc_sections"    { set selected [check_gc_sections_available] }
1193           default          { error "unknown effective target keyword `$arg'" }
1194         }
1195     }
1196     verbose "is-effective-target: $arg $selected" 2
1197     return $selected
1198 }
1199
1200 # Return 1 if the argument is an effective-target keyword, 0 otherwise.
1201
1202 proc is-effective-target-keyword { arg } {
1203     if { [info procs check_effective_target_${arg}] != [list] } {
1204         return 1
1205     } else {
1206         # These have different names for their check_* procs.
1207         switch $arg {
1208           "vmx_hw"         { return 1 }
1209           "named_sections" { return 1 }
1210           "gc_sections"    { return 1 }
1211           default          { return 0 }
1212         }
1213     }
1214 }