OSDN Git Service

* lib/scanasm.exp (dg-scan, scan-assembler-times, scan-assembler-dem,
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / lib / target-supports.exp
1 #   Copyright (C) 1999, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2 #   2011 Free Software Foundation, Inc.
3
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with GCC; see the file COPYING3.  If not see
16 # <http://www.gnu.org/licenses/>.
17
18 # Please email any bugs, comments, and/or additions to this file to:
19 # gcc-patches@gcc.gnu.org
20
21 # This file defines procs for determining features supported by the target.
22
23 # Try to compile the code given by CONTENTS into an output file of
24 # type TYPE, where TYPE is as for target_compile.  Return a list
25 # whose first element contains the compiler messages and whose
26 # second element is the name of the output file.
27 #
28 # BASENAME is a prefix to use for source and output files.
29 # If ARGS is not empty, its first element is a string that
30 # should be added to the command line.
31 #
32 # Assume by default that CONTENTS is C code.  
33 # Otherwise, code should contain:
34 # "// C++" for c++,
35 # "! Fortran" for Fortran code,
36 # "/* ObjC", for ObjC
37 # "// ObjC++" for ObjC++
38 # and "// Go" for Go
39 # If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to 
40 # allow for ObjC/ObjC++ specific flags.
41 proc check_compile {basename type contents args} {
42     global tool
43     verbose "check_compile tool: $tool for $basename" 
44
45     if { [llength $args] > 0 } {
46         set options [list "additional_flags=[lindex $args 0]"]
47     } else {
48         set options ""
49     }
50     switch -glob -- $contents {
51         "*! Fortran*" { set src ${basename}[pid].f90 }
52         "*// C++*" { set src ${basename}[pid].cc }
53         "*// ObjC++*" { set src ${basename}[pid].mm }
54         "*/* ObjC*" { set src ${basename}[pid].m }
55         "*// Go*" { set src ${basename}[pid].go }
56         default {
57             switch -- $tool {
58                 "objc" { set src ${basename}[pid].m }
59                 "obj-c++" { set src ${basename}[pid].mm }
60                 default { set src ${basename}[pid].c }
61             }
62         }
63     }
64
65     set compile_type $type
66     switch -glob $type {
67         assembly { set output ${basename}[pid].s }
68         object { set output ${basename}[pid].o }
69         executable { set output ${basename}[pid].exe }
70         "rtl-*" {
71             set output ${basename}[pid].s
72             lappend options "additional_flags=-fdump-$type"
73             set compile_type assembly
74         }
75     }
76     set f [open $src "w"]
77     puts $f $contents
78     close $f
79     set lines [${tool}_target_compile $src $output $compile_type "$options"]
80     file delete $src
81
82     set scan_output $output
83     # Don't try folding this into the switch above; calling "glob" before the
84     # file is created won't work.
85     if [regexp "rtl-(.*)" $type dummy rtl_type] {
86         set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]"
87         file delete $output
88     }
89
90     return [list $lines $scan_output]
91 }
92
93 proc current_target_name { } {
94     global target_info
95     if [info exists target_info(target,name)] {
96         set answer $target_info(target,name)
97     } else {
98         set answer ""
99     }
100     return $answer
101 }
102
103 # Implement an effective-target check for property PROP by invoking
104 # the Tcl command ARGS and seeing if it returns true.
105
106 proc check_cached_effective_target { prop args } {
107     global et_cache
108
109     set target [current_target_name]
110     if {![info exists et_cache($prop,target)]
111         || $et_cache($prop,target) != $target} {
112         verbose "check_cached_effective_target $prop: checking $target" 2
113         set et_cache($prop,target) $target
114         set et_cache($prop,value) [uplevel eval $args]
115     }
116     set value $et_cache($prop,value)
117     verbose "check_cached_effective_target $prop: returning $value for $target" 2
118     return $value
119 }
120
121 # Like check_compile, but delete the output file and return true if the
122 # compiler printed no messages.
123 proc check_no_compiler_messages_nocache {args} {
124     set result [eval check_compile $args]
125     set lines [lindex $result 0]
126     set output [lindex $result 1]
127     remote_file build delete $output
128     return [string match "" $lines]
129 }
130
131 # Like check_no_compiler_messages_nocache, but cache the result.
132 # PROP is the property we're checking, and doubles as a prefix for
133 # temporary filenames.
134 proc check_no_compiler_messages {prop args} {
135     return [check_cached_effective_target $prop {
136         eval [list check_no_compiler_messages_nocache $prop] $args
137     }]
138 }
139
140 # Like check_compile, but return true if the compiler printed no
141 # messages and if the contents of the output file satisfy PATTERN.
142 # If PATTERN has the form "!REGEXP", the contents satisfy it if they
143 # don't match regular expression REGEXP, otherwise they satisfy it
144 # if they do match regular expression PATTERN.  (PATTERN can start
145 # with something like "[!]" if the regular expression needs to match
146 # "!" as the first character.)
147 #
148 # Delete the output file before returning.  The other arguments are
149 # as for check_compile.
150 proc check_no_messages_and_pattern_nocache {basename pattern args} {
151     global tool
152
153     set result [eval [list check_compile $basename] $args]
154     set lines [lindex $result 0]
155     set output [lindex $result 1]
156
157     set ok 0
158     if { [string match "" $lines] } {
159         set chan [open "$output"]
160         set invert [regexp {^!(.*)} $pattern dummy pattern]
161         set ok [expr { [regexp $pattern [read $chan]] != $invert }]
162         close $chan
163     }
164
165     remote_file build delete $output
166     return $ok
167 }
168
169 # Like check_no_messages_and_pattern_nocache, but cache the result.
170 # PROP is the property we're checking, and doubles as a prefix for
171 # temporary filenames.
172 proc check_no_messages_and_pattern {prop pattern args} {
173     return [check_cached_effective_target $prop {
174         eval [list check_no_messages_and_pattern_nocache $prop $pattern] $args
175     }]
176 }
177
178 # Try to compile and run an executable from code CONTENTS.  Return true
179 # if the compiler reports no messages and if execution "passes" in the
180 # usual DejaGNU sense.  The arguments are as for check_compile, with
181 # TYPE implicitly being "executable".
182 proc check_runtime_nocache {basename contents args} {
183     global tool
184
185     set result [eval [list check_compile $basename executable $contents] $args]
186     set lines [lindex $result 0]
187     set output [lindex $result 1]
188
189     set ok 0
190     if { [string match "" $lines] } {
191         # No error messages, everything is OK.
192         set result [remote_load target "./$output" "" ""]
193         set status [lindex $result 0]
194         verbose "check_runtime_nocache $basename: status is <$status>" 2
195         if { $status == "pass" } {
196             set ok 1
197         }
198     }
199     remote_file build delete $output
200     return $ok
201 }
202
203 # Like check_runtime_nocache, but cache the result.  PROP is the
204 # property we're checking, and doubles as a prefix for temporary
205 # filenames.
206 proc check_runtime {prop args} {
207     global tool
208
209     return [check_cached_effective_target $prop {
210         eval [list check_runtime_nocache $prop] $args
211     }]
212 }
213
214 ###############################
215 # proc check_weak_available { }
216 ###############################
217
218 # weak symbols are only supported in some configs/object formats
219 # this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure
220
221 proc check_weak_available { } {
222     global target_triplet
223     global target_cpu
224
225     # All mips targets should support it
226
227     if { [ string first "mips" $target_cpu ] >= 0 } {
228         return 1
229     }
230
231     # All solaris2 targets should support it
232
233     if { [regexp ".*-solaris2.*" $target_triplet] } {
234         return 1
235     }
236
237     # DEC OSF/1/Digital UNIX/Tru64 UNIX supports it
238
239     if { [regexp "alpha.*osf.*" $target_triplet] } {
240         return 1
241     }
242
243     # Windows targets Cygwin and MingW32 support it
244
245     if { [regexp ".*mingw32|.*cygwin" $target_triplet] } {
246         return 1
247     }
248
249     # HP-UX 10.X doesn't support it
250
251     if { [istarget "hppa*-*-hpux10*"] } {
252         return 0
253     }
254
255     # ELF and ECOFF support it. a.out does with gas/gld but may also with
256     # other linkers, so we should try it
257
258     set objformat [gcc_target_object_format]
259
260     switch $objformat {
261         elf      { return 1 }
262         ecoff    { return 1 }
263         a.out    { return 1 }
264         mach-o   { return 1 }
265         som      { return 1 }
266         unknown  { return -1 }
267         default  { return 0 }
268     }
269 }
270
271 ###############################
272 # proc check_weak_override_available { }
273 ###############################
274
275 # Like check_weak_available, but return 0 if weak symbol definitions
276 # cannot be overridden.
277
278 proc check_weak_override_available { } {
279     if { [istarget "*-*-mingw*"] } {
280         return 0
281     }
282     return [check_weak_available]
283 }
284
285 ###############################
286 # proc check_visibility_available { what_kind }
287 ###############################
288
289 # The visibility attribute is only support in some object formats
290 # This proc returns 1 if it is supported, 0 if not.
291 # The argument is the kind of visibility, default/protected/hidden/internal.
292
293 proc check_visibility_available { what_kind } {
294     global tool
295     global target_triplet
296
297     # On NetWare, support makes no sense.
298     if { [istarget *-*-netware*] } {
299         return 0
300     }
301
302     if [string match "" $what_kind] { set what_kind "hidden" }
303
304     return [check_no_compiler_messages visibility_available_$what_kind object "
305         void f() __attribute__((visibility(\"$what_kind\")));
306         void f() {}
307     "]
308 }
309
310 ###############################
311 # proc check_alias_available { }
312 ###############################
313
314 # Determine if the target toolchain supports the alias attribute.
315
316 # Returns 2 if the target supports aliases.  Returns 1 if the target
317 # only supports weak aliased.  Returns 0 if the target does not
318 # support aliases at all.  Returns -1 if support for aliases could not
319 # be determined.
320
321 proc check_alias_available { } {
322     global alias_available_saved
323     global tool
324
325     if [info exists alias_available_saved] {
326         verbose "check_alias_available  returning saved $alias_available_saved" 2
327     } else {
328         set src alias[pid].c
329         set obj alias[pid].o
330         verbose "check_alias_available  compiling testfile $src" 2
331         set f [open $src "w"]
332         # Compile a small test program.  The definition of "g" is
333         # necessary to keep the Solaris assembler from complaining
334         # about the program.
335         puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
336         puts $f "void g() {} void f() __attribute__((alias(\"g\")));"
337         close $f
338         set lines [${tool}_target_compile $src $obj object ""]
339         file delete $src
340         remote_file build delete $obj
341
342         if [string match "" $lines] then {
343             # No error messages, everything is OK.
344             set alias_available_saved 2
345         } else {
346             if [regexp "alias definitions not supported" $lines] {
347                 verbose "check_alias_available  target does not support aliases" 2
348
349                 set objformat [gcc_target_object_format]
350
351                 if { $objformat == "elf" } {
352                     verbose "check_alias_available  but target uses ELF format, so it ought to" 2
353                     set alias_available_saved -1
354                 } else {
355                     set alias_available_saved 0
356                 }
357             } else {
358                 if [regexp "only weak aliases are supported" $lines] {
359                 verbose "check_alias_available  target supports only weak aliases" 2
360                 set alias_available_saved 1
361                 } else {
362                     set alias_available_saved -1
363                 }
364             }
365         }
366
367         verbose "check_alias_available  returning $alias_available_saved" 2
368     }
369
370     return $alias_available_saved
371 }
372
373 ###############################
374 # proc check_ifunc_available { }
375 ###############################
376
377 # Determine if the target toolchain supports the ifunc attribute.
378
379 # Returns 1 if the target supports ifunc.  Returns 0 if the target
380 # does not support ifunc.
381
382 proc check_ifunc_available { } {
383     global ifunc_available_saved
384     global tool
385
386     if [info exists ifunc_available_saved] {
387         verbose "check_ifunc_available  returning saved $ifunc_available_saved" 2
388     } else {
389         set src ifunc[pid].c
390         set obj ifunc[pid].o
391         verbose "check_ifunc_available  compiling testfile $src" 2
392         set f [open $src "w"]
393         puts $f "#endif"
394         puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif"
395         puts $f "void g() {}"
396         puts $f "void f() __attribute__((ifunc(\"g\")));"
397         close $f
398         set lines [${tool}_target_compile $src $obj object ""]
399         file delete $src
400         remote_file build delete $obj
401
402         if [string match "" $lines] then {
403             set ifunc_available_saved 1
404         } else {
405             set ifunc_available_saved 0
406         }
407
408         verbose "check_ifunc_available  returning $ifunc_available_saved" 2
409     }
410
411     return $ifunc_available_saved
412 }
413
414 # Returns true if --gc-sections is supported on the target.
415
416 proc check_gc_sections_available { } {
417     global gc_sections_available_saved
418     global tool
419
420     if {![info exists gc_sections_available_saved]} {
421         # Some targets don't support gc-sections despite whatever's
422         # advertised by ld's options.
423         if { [istarget alpha*-*-*]
424              || [istarget ia64-*-*] } {
425             set gc_sections_available_saved 0
426             return 0
427         }
428
429         # elf2flt uses -q (--emit-relocs), which is incompatible with
430         # --gc-sections.
431         if { [board_info target exists ldflags]
432              && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
433             set gc_sections_available_saved 0
434             return 0
435         }
436
437         # VxWorks kernel modules are relocatable objects linked with -r,
438         # while RTP executables are linked with -q (--emit-relocs).
439         # Both of these options are incompatible with --gc-sections.
440         if { [istarget *-*-vxworks*] } {
441             set gc_sections_available_saved 0
442             return 0
443         }
444
445         # Check if the ld used by gcc supports --gc-sections.
446         set gcc_spec [${tool}_target_compile "-dumpspecs" "" "none" ""]
447         regsub ".*\n\\*linker:\[ \t\]*\n(\[^ \t\n\]*).*" "$gcc_spec" {\1} linker
448         set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=$linker" "" "none" ""] 0]
449         set ld_output [remote_exec host "$gcc_ld" "--help"]
450         if { [ string first "--gc-sections" $ld_output ] >= 0 } {
451             set gc_sections_available_saved 1
452         } else {
453             set gc_sections_available_saved 0
454         }
455     }
456     return $gc_sections_available_saved
457 }
458
459 # Return 1 if according to target_info struct and explicit target list
460 # target is supposed to support trampolines.
461  
462 proc check_effective_target_trampolines { } {
463     if [target_info exists no_trampolines] {
464       return 0
465     }
466     if { [istarget avr-*-*]
467          || [istarget hppa2.0w-hp-hpux11.23]
468         || [istarget hppa64-hp-hpux11.23] } {
469         return 0;   
470     }
471     return 1
472 }
473
474 # Return 1 if according to target_info struct and explicit target list
475 # target is supposed to keep null pointer checks. This could be due to 
476 # use of option fno-delete-null-pointer-checks or hardwired in target.
477  
478 proc check_effective_target_keeps_null_pointer_checks { } {
479     if [target_info exists keeps_null_pointer_checks] {
480       return 1
481     }
482     if { [istarget avr-*-*] } {
483         return 1;   
484     }
485     return 0
486 }
487
488 # Return true if profiling is supported on the target.
489
490 proc check_profiling_available { test_what } {
491     global profiling_available_saved
492
493     verbose "Profiling argument is <$test_what>" 1
494
495     # These conditions depend on the argument so examine them before
496     # looking at the cache variable.
497
498     # Tree profiling requires TLS runtime support.
499     if { $test_what == "-fprofile-generate" } {
500         return [check_effective_target_tls_runtime]
501     }
502
503     # Support for -p on solaris2 relies on mcrt1.o which comes with the
504     # vendor compiler.  We cannot reliably predict the directory where the
505     # vendor compiler (and thus mcrt1.o) is installed so we can't
506     # necessarily find mcrt1.o even if we have it.
507     if { [istarget *-*-solaris2*] && $test_what == "-p" } {
508         return 0
509     }
510
511     # Support for -p on irix relies on libprof1.a which doesn't appear to
512     # exist on any irix6 system currently posting testsuite results.
513     # Support for -pg on irix relies on gcrt1.o which doesn't exist yet.
514     # See: http://gcc.gnu.org/ml/gcc/2002-10/msg00169.html
515     if { [istarget mips*-*-irix*]
516          && ($test_what == "-p" || $test_what == "-pg") } {
517         return 0
518     }
519
520     # We don't yet support profiling for MIPS16.
521     if { [istarget mips*-*-*]
522          && ![check_effective_target_nomips16]
523          && ($test_what == "-p" || $test_what == "-pg") } {
524         return 0
525     }
526
527     # MinGW does not support -p.
528     if { [istarget *-*-mingw*] && $test_what == "-p" } {
529         return 0
530     }
531
532     # cygwin does not support -p.
533     if { [istarget *-*-cygwin*] && $test_what == "-p" } {
534         return 0
535     }
536
537     # uClibc does not have gcrt1.o.
538     if { [check_effective_target_uclibc]
539          && ($test_what == "-p" || $test_what == "-pg") } {
540         return 0
541     }
542
543     # Now examine the cache variable.
544     if {![info exists profiling_available_saved]} {
545         # Some targets don't have any implementation of __bb_init_func or are
546         # missing other needed machinery.
547         if {    [istarget am3*-*-linux*]
548              || [istarget arm*-*-eabi*]
549              || [istarget arm*-*-elf]
550              || [istarget arm*-*-symbianelf*]
551              || [istarget avr-*-*]
552              || [istarget bfin-*-*]
553              || [istarget cris-*-*]
554              || [istarget crisv32-*-*]
555              || [istarget fido-*-elf]
556              || [istarget h8300-*-*]
557              || [istarget lm32-*-*]
558              || [istarget m32c-*-elf]
559              || [istarget m68k-*-elf]
560              || [istarget m68k-*-uclinux*]
561              || [istarget mep-*-elf]
562              || [istarget mips*-*-elf*]
563              || [istarget mmix-*-*]
564              || [istarget mn10300-*-elf*]
565              || [istarget moxie-*-elf*]
566              || [istarget picochip-*-*]
567              || [istarget powerpc-*-eabi*]
568              || [istarget powerpc-*-elf]
569              || [istarget rx-*-*]       
570              || [istarget xstormy16-*]
571              || [istarget xtensa*-*-elf]
572              || [istarget *-*-netware*]
573              || [istarget *-*-rtems*]
574              || [istarget *-*-vxworks*] } {
575             set profiling_available_saved 0
576         } else {
577             set profiling_available_saved 1
578         }
579     }
580
581     return $profiling_available_saved
582 }
583
584 # Check to see if a target is "freestanding". This is as per the definition
585 # in Section 4 of C99 standard. Effectively, it is a target which supports no
586 # extra headers or libraries other than what is considered essential.
587 proc check_effective_target_freestanding { } {
588     if { [istarget picochip-*-*] } then {
589         return 1
590     } else {
591         return 0
592     }
593 }
594
595 # Return 1 if target has packed layout of structure members by
596 # default, 0 otherwise.  Note that this is slightly different than
597 # whether the target has "natural alignment": both attributes may be
598 # false.
599
600 proc check_effective_target_default_packed { } {
601     return [check_no_compiler_messages default_packed assembly {
602         struct x { char a; long b; } c;
603         int s[sizeof (c) == sizeof (char) + sizeof (long) ? 1 : -1];
604     }]
605 }
606
607 # Return 1 if target has PCC_BITFIELD_TYPE_MATTERS defined.  See
608 # documentation, where the test also comes from.
609
610 proc check_effective_target_pcc_bitfield_type_matters { } {
611     # PCC_BITFIELD_TYPE_MATTERS isn't just about unnamed or empty
612     # bitfields, but let's stick to the example code from the docs.
613     return [check_no_compiler_messages pcc_bitfield_type_matters assembly {
614         struct foo1 { char x; char :0; char y; };
615         struct foo2 { char x; int :0; char y; };
616         int s[sizeof (struct foo1) != sizeof (struct foo2) ? 1 : -1];
617     }]
618 }
619
620 # Add to FLAGS all the target-specific flags needed to use thread-local storage.
621
622 proc add_options_for_tls { flags } {
623     # Tru64 UNIX uses emutls, which relies on a couple of pthread functions
624     # which only live in libpthread, so always pass -pthread for TLS.
625     if { [istarget *-*-osf*] } {
626         return "$flags -pthread"
627     }
628     # On Solaris 8 and 9, __tls_get_addr/___tls_get_addr only lives in
629     # libthread, so always pass -pthread for native TLS.
630     # Need to duplicate native TLS check from
631     # check_effective_target_tls_native to avoid recursion.
632     if { [istarget *-*-solaris2.\[89\]*] &&
633          [check_no_messages_and_pattern tls_native "!emutls" assembly {
634              __thread int i;
635              int f (void) { return i; }
636              void g (int j) { i = j; }
637          }] } {
638         return "$flags -pthread"
639     }
640     return $flags
641 }
642
643 # Return 1 if thread local storage (TLS) is supported, 0 otherwise.
644
645 proc check_effective_target_tls {} {
646     return [check_no_compiler_messages tls assembly {
647         __thread int i;
648         int f (void) { return i; }
649         void g (int j) { i = j; }
650     }]
651 }
652
653 # Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise.
654
655 proc check_effective_target_tls_native {} {
656     # VxWorks uses emulated TLS machinery, but with non-standard helper
657     # functions, so we fail to automatically detect it.
658     global target_triplet
659     if { [regexp ".*-.*-vxworks.*" $target_triplet] } {
660         return 0
661     }
662     
663     return [check_no_messages_and_pattern tls_native "!emutls" assembly {
664         __thread int i;
665         int f (void) { return i; }
666         void g (int j) { i = j; }
667     }]
668 }
669
670 # Return 1 if *emulated* thread local storage (TLS) is supported, 0 otherwise.
671
672 proc check_effective_target_tls_emulated {} {
673     # VxWorks uses emulated TLS machinery, but with non-standard helper
674     # functions, so we fail to automatically detect it.
675     global target_triplet
676     if { [regexp ".*-.*-vxworks.*" $target_triplet] } {
677         return 1
678     }
679     
680     return [check_no_messages_and_pattern tls_emulated "emutls" assembly {
681         __thread int i;
682         int f (void) { return i; }
683         void g (int j) { i = j; }
684     }]
685 }
686
687 # Return 1 if TLS executables can run correctly, 0 otherwise.
688
689 proc check_effective_target_tls_runtime {} {
690     return [check_runtime tls_runtime {
691         __thread int thr = 0;
692         int main (void) { return thr; }
693     } [add_options_for_tls ""]]
694 }
695
696 # Return 1 if -ffunction-sections is supported, 0 otherwise.
697
698 proc check_effective_target_function_sections {} {
699     # Darwin has its own scheme and silently accepts -ffunction-sections.
700     global target_triplet
701     if { [regexp ".*-.*-darwin.*" $target_triplet] } {
702         return 0
703     }
704     
705     return [check_no_compiler_messages functionsections assembly {
706         void foo (void) { }
707     } "-ffunction-sections"]
708 }
709
710 # Return 1 if compilation with -fgraphite is error-free for trivial 
711 # code, 0 otherwise.
712
713 proc check_effective_target_fgraphite {} {
714     return [check_no_compiler_messages fgraphite object {
715         void foo (void) { }
716     } "-O1 -fgraphite"]
717 }
718
719 # Return 1 if compilation with -fopenmp is error-free for trivial
720 # code, 0 otherwise.
721
722 proc check_effective_target_fopenmp {} {
723     return [check_no_compiler_messages fopenmp object {
724         void foo (void) { }
725     } "-fopenmp"]
726 }
727
728 # Return 1 if compilation with -pthread is error-free for trivial
729 # code, 0 otherwise.
730
731 proc check_effective_target_pthread {} {
732     return [check_no_compiler_messages pthread object {
733         void foo (void) { }
734     } "-pthread"]
735 }
736
737 # Return 1 if compilation with -mpe-aligned-commons is error-free
738 # for trivial code, 0 otherwise.
739
740 proc check_effective_target_pe_aligned_commons {} {
741     if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
742         return [check_no_compiler_messages pe_aligned_commons object {
743             int foo;
744         } "-mpe-aligned-commons"]
745     }
746     return 0
747 }
748
749 # Return 1 if the target supports -static
750 proc check_effective_target_static {} {
751     return [check_no_compiler_messages static executable {
752         int main (void) { return 0; }
753     } "-static"]
754 }
755
756 # Return 1 if the target supports -fstack-protector
757 proc check_effective_target_fstack_protector {} {
758     return [check_runtime fstack_protector {
759         int main (void) { return 0; }
760     } "-fstack-protector"]
761 }
762
763 # Return 1 if compilation with -freorder-blocks-and-partition is error-free
764 # for trivial code, 0 otherwise.
765
766 proc check_effective_target_freorder {} {
767     return [check_no_compiler_messages freorder object {
768         void foo (void) { }
769     } "-freorder-blocks-and-partition"]
770 }
771
772 # Return 1 if -fpic and -fPIC are supported, as in no warnings or errors
773 # emitted, 0 otherwise.  Whether a shared library can actually be built is
774 # out of scope for this test.
775
776 proc check_effective_target_fpic { } {
777     # Note that M68K has a multilib that supports -fpic but not
778     # -fPIC, so we need to check both.  We test with a program that
779     # requires GOT references.
780     foreach arg {fpic fPIC} {
781         if [check_no_compiler_messages $arg object {
782             extern int foo (void); extern int bar;
783             int baz (void) { return foo () + bar; }
784         } "-$arg"] {
785             return 1
786         }
787     }
788     return 0
789 }
790
791 # Return 1 if -pie, -fpie and -fPIE are supported, 0 otherwise.
792
793 proc check_effective_target_pie { } {
794     if { [istarget *-*-darwin\[912\]*]
795          || [istarget *-*-linux*] } {
796         return 1;
797     }
798     return 0
799 }
800
801 # Return true if the target supports -mpaired-single (as used on MIPS).
802
803 proc check_effective_target_mpaired_single { } {
804     return [check_no_compiler_messages mpaired_single object {
805         void foo (void) { }
806     } "-mpaired-single"]
807 }
808
809 # Return true if the target has access to FPU instructions.
810
811 proc check_effective_target_hard_float { } {
812     if { [istarget mips*-*-*] } {
813         return [check_no_compiler_messages hard_float assembly {
814                 #if (defined __mips_soft_float || defined __mips16)
815                 #error FOO
816                 #endif
817         }]
818     }
819
820     # This proc is actually checking the availabilty of FPU
821     # support for doubles, so on the RX we must fail if the
822     # 64-bit double multilib has been selected.
823     if { [istarget rx-*-*] } {
824         return 0
825         # return [check_no_compiler_messages hard_float assembly {
826                 #if defined __RX_64_BIT_DOUBLES__
827                 #error FOO
828                 #endif
829         # }]
830     }
831
832     # The generic test equates hard_float with "no call for adding doubles".
833     return [check_no_messages_and_pattern hard_float "!\\(call" rtl-expand {
834         double a (double b, double c) { return b + c; }
835     }]
836 }
837
838 # Return true if the target is a 64-bit MIPS target.
839
840 proc check_effective_target_mips64 { } {
841     return [check_no_compiler_messages mips64 assembly {
842         #ifndef __mips64
843         #error FOO
844         #endif
845     }]
846 }
847
848 # Return true if the target is a MIPS target that does not produce
849 # MIPS16 code.
850
851 proc check_effective_target_nomips16 { } {
852     return [check_no_compiler_messages nomips16 object {
853         #ifndef __mips
854         #error FOO
855         #else
856         /* A cheap way of testing for -mflip-mips16.  */
857         void foo (void) { asm ("addiu $20,$20,1"); }
858         void bar (void) { asm ("addiu $20,$20,1"); }
859         #endif
860     }]
861 }
862
863 # Add the options needed for MIPS16 function attributes.  At the moment,
864 # we don't support MIPS16 PIC.
865
866 proc add_options_for_mips16_attribute { flags } {
867     return "$flags -mno-abicalls -fno-pic -DMIPS16=__attribute__((mips16))"
868 }
869
870 # Return true if we can force a mode that allows MIPS16 code generation.
871 # We don't support MIPS16 PIC, and only support MIPS16 -mhard-float
872 # for o32 and o64.
873
874 proc check_effective_target_mips16_attribute { } {
875     return [check_no_compiler_messages mips16_attribute assembly {
876         #ifdef PIC
877         #error FOO
878         #endif
879         #if defined __mips_hard_float \
880             && (!defined _ABIO32 || _MIPS_SIM != _ABIO32) \
881             && (!defined _ABIO64 || _MIPS_SIM != _ABIO64)
882         #error FOO
883         #endif
884     } [add_options_for_mips16_attribute ""]]
885 }
886
887 # Return 1 if the target supports long double larger than double when
888 # using the new ABI, 0 otherwise.
889
890 proc check_effective_target_mips_newabi_large_long_double { } {
891     return [check_no_compiler_messages mips_newabi_large_long_double object {
892         int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
893     } "-mabi=64"]
894 }
895
896 # Return 1 if the current multilib does not generate PIC by default.
897
898 proc check_effective_target_nonpic { } {
899     return [check_no_compiler_messages nonpic assembly {
900         #if __PIC__
901         #error FOO
902         #endif
903     }]
904 }
905
906 # Return 1 if the target does not use a status wrapper.
907
908 proc check_effective_target_unwrapped { } {
909     if { [target_info needs_status_wrapper] != "" \
910              && [target_info needs_status_wrapper] != "0" } {
911         return 0
912     }
913     return 1
914 }
915
916 # Return true if iconv is supported on the target. In particular IBM1047.
917
918 proc check_iconv_available { test_what } {
919     global libiconv
920
921     # If the tool configuration file has not set libiconv, try "-liconv"
922     if { ![info exists libiconv] } {
923         set libiconv "-liconv"
924     }
925     set test_what [lindex $test_what 1]
926     return [check_runtime_nocache $test_what [subst {
927         #include <iconv.h>
928         int main (void)
929         {
930           iconv_t cd;
931
932           cd = iconv_open ("$test_what", "UTF-8");
933           if (cd == (iconv_t) -1)
934             return 1;
935           return 0;
936         }
937     }] $libiconv]
938 }
939
940 # Return 1 if an ASCII locale is supported on this host, 0 otherwise.
941
942 proc check_ascii_locale_available { } {
943     if { ([ishost alpha*-dec-osf*] || [ishost mips-sgi-irix*]) } {
944         # Neither Tru64 UNIX nor IRIX support an ASCII locale.
945         return 0
946     } else {
947         return 1
948     }
949 }
950
951 # Return true if named sections are supported on this target.
952
953 proc check_named_sections_available { } {
954     return [check_no_compiler_messages named_sections assembly {
955         int __attribute__ ((section("whatever"))) foo;
956     }]
957 }
958
959 # Return 1 if the target supports Fortran real kinds larger than real(8),
960 # 0 otherwise.
961 #
962 # When the target name changes, replace the cached result.
963
964 proc check_effective_target_fortran_large_real { } {
965     return [check_no_compiler_messages fortran_large_real executable {
966         ! Fortran
967         integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1)
968         real(kind=k) :: x
969         x = cos (x)
970         end
971     }]
972 }
973
974 # Return 1 if the target supports Fortran real kind real(16),
975 # 0 otherwise. Contrary to check_effective_target_fortran_large_real
976 # this checks for Real(16) only; the other returned real(10) if
977 # both real(10) and real(16) are available.
978 #
979 # When the target name changes, replace the cached result.
980
981 proc check_effective_target_fortran_real_16 { } {
982     return [check_no_compiler_messages fortran_real_16 executable {
983         ! Fortran
984         real(kind=16) :: x
985         x = cos (x)
986         end
987     }]
988 }
989
990 # Return 1 if the target supports Fortran integer kinds larger than
991 # integer(8), 0 otherwise.
992 #
993 # When the target name changes, replace the cached result.
994
995 proc check_effective_target_fortran_large_int { } {
996     return [check_no_compiler_messages fortran_large_int executable {
997         ! Fortran
998         integer,parameter :: k = selected_int_kind (range (0_8) + 1)
999         integer(kind=k) :: i
1000         end
1001     }]
1002 }
1003
1004 # Return 1 if the target supports Fortran integer(16), 0 otherwise.
1005 #
1006 # When the target name changes, replace the cached result.
1007
1008 proc check_effective_target_fortran_integer_16 { } {
1009     return [check_no_compiler_messages fortran_integer_16 executable {
1010         ! Fortran
1011         integer(16) :: i
1012         end
1013     }]
1014 }
1015
1016 # Return 1 if we can statically link libgfortran, 0 otherwise.
1017 #
1018 # When the target name changes, replace the cached result.
1019
1020 proc check_effective_target_static_libgfortran { } {
1021     return [check_no_compiler_messages static_libgfortran executable {
1022         ! Fortran
1023         print *, 'test'
1024         end
1025     } "-static"]
1026 }
1027
1028 proc check_linker_plugin_available { } {
1029   return [check_no_compiler_messages_nocache linker_plugin executable {
1030      int main() { return 0; }
1031   } "-flto -fuse-linker-plugin"]
1032 }
1033
1034 # Return 1 if the target supports executing 750CL paired-single instructions, 0
1035 # otherwise.  Cache the result.
1036
1037 proc check_750cl_hw_available { } {
1038     return [check_cached_effective_target 750cl_hw_available {
1039         # If this is not the right target then we can skip the test.
1040         if { ![istarget powerpc-*paired*] } {
1041             expr 0
1042         } else {
1043             check_runtime_nocache 750cl_hw_available {
1044                  int main()
1045                  {
1046                  #ifdef __MACH__
1047                    asm volatile ("ps_mul v0,v0,v0");
1048                  #else
1049                    asm volatile ("ps_mul 0,0,0");
1050                  #endif
1051                    return 0;
1052                  }
1053             } "-mpaired"
1054         }
1055     }]
1056 }
1057
1058 # Return 1 if the target OS supports running SSE executables, 0
1059 # otherwise.  Cache the result.
1060
1061 proc check_sse_os_support_available { } {
1062     return [check_cached_effective_target sse_os_support_available {
1063         # If this is not the right target then we can skip the test.
1064         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1065             expr 0
1066         } elseif { [istarget i?86-*-solaris2*] } {
1067             # The Solaris 2 kernel doesn't save and restore SSE registers
1068             # before Solaris 9 4/04.  Before that, executables die with SIGILL.
1069             check_runtime_nocache sse_os_support_available {
1070                 int main ()
1071                 {
1072                     __asm__ volatile ("movaps %xmm0,%xmm0");
1073                     return 0;
1074                 }
1075             } "-msse"
1076         } else {
1077             expr 1
1078         }
1079     }]
1080 }
1081
1082 # Return 1 if the target supports executing SSE instructions, 0
1083 # otherwise.  Cache the result.
1084
1085 proc check_sse_hw_available { } {
1086     return [check_cached_effective_target sse_hw_available {
1087         # If this is not the right target then we can skip the test.
1088         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1089             expr 0
1090         } else {
1091             check_runtime_nocache sse_hw_available {
1092                 #include "cpuid.h"
1093                 int main ()
1094                 {
1095                   unsigned int eax, ebx, ecx, edx;
1096                   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1097                     return !(edx & bit_SSE);
1098                   return 1;
1099                 }
1100             } ""
1101         }
1102     }]
1103 }
1104
1105 # Return 1 if the target supports executing SSE2 instructions, 0
1106 # otherwise.  Cache the result.
1107
1108 proc check_sse2_hw_available { } {
1109     return [check_cached_effective_target sse2_hw_available {
1110         # If this is not the right target then we can skip the test.
1111         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1112             expr 0
1113         } else {
1114             check_runtime_nocache sse2_hw_available {
1115                 #include "cpuid.h"
1116                 int main ()
1117                 {
1118                   unsigned int eax, ebx, ecx, edx;
1119                   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1120                     return !(edx & bit_SSE2);
1121                   return 1;
1122                 }
1123             } ""
1124         }
1125     }]
1126 }
1127
1128 # Return 1 if the target supports executing AVX instructions, 0
1129 # otherwise.  Cache the result.
1130
1131 proc check_avx_hw_available { } {
1132     return [check_cached_effective_target avx_hw_available {
1133         # If this is not the right target then we can skip the test.
1134         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1135             expr 0
1136         } else {
1137             check_runtime_nocache avx_hw_available {
1138                 #include "cpuid.h"
1139                 int main ()
1140                 {
1141                   unsigned int eax, ebx, ecx, edx;
1142                   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1143                     return ((ecx & (bit_AVX | bit_OSXSAVE))
1144                             != (bit_AVX | bit_OSXSAVE));
1145                   return 1;
1146                 }
1147             } ""
1148         }
1149     }]
1150 }
1151
1152 # Return 1 if the target supports running SSE executables, 0 otherwise.
1153
1154 proc check_effective_target_sse_runtime { } {
1155     if { [check_effective_target_sse]
1156          && [check_sse_hw_available]
1157          && [check_sse_os_support_available] } {
1158         return 1
1159     }
1160     return 0
1161 }
1162
1163 # Return 1 if the target supports running SSE2 executables, 0 otherwise.
1164
1165 proc check_effective_target_sse2_runtime { } {
1166     if { [check_effective_target_sse2]
1167          && [check_sse2_hw_available]
1168          && [check_sse_os_support_available] } {
1169         return 1
1170     }
1171     return 0
1172 }
1173
1174 # Return 1 if the target supports running AVX executables, 0 otherwise.
1175
1176 proc check_effective_target_avx_runtime { } {
1177     if { [check_effective_target_avx]
1178          && [check_avx_hw_available] } {
1179         return 1
1180     }
1181     return 0
1182 }
1183
1184 # Return 1 if the target supports executing VSX instructions, 0
1185 # otherwise.  Cache the result.
1186
1187 proc check_vsx_hw_available { } {
1188     return [check_cached_effective_target vsx_hw_available {
1189         # Some simulators are known to not support VSX instructions.
1190         # For now, disable on Darwin
1191         if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
1192             expr 0
1193         } else {
1194             set options "-mvsx"
1195             check_runtime_nocache vsx_hw_available {
1196                 int main()
1197                 {
1198                 #ifdef __MACH__
1199                   asm volatile ("xxlor vs0,vs0,vs0");
1200                 #else
1201                   asm volatile ("xxlor 0,0,0");
1202                 #endif
1203                   return 0;
1204                 }
1205             } $options
1206         }
1207     }]
1208 }
1209
1210 # Return 1 if the target supports executing AltiVec instructions, 0
1211 # otherwise.  Cache the result.
1212
1213 proc check_vmx_hw_available { } {
1214     return [check_cached_effective_target vmx_hw_available {
1215         # Some simulators are known to not support VMX instructions.
1216         if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } {
1217             expr 0
1218         } else {
1219             # Most targets don't require special flags for this test case, but
1220             # Darwin does.  Just to be sure, make sure VSX is not enabled for
1221             # the altivec tests.
1222             if { [istarget *-*-darwin*]
1223                  || [istarget *-*-aix*] } {
1224                 set options "-maltivec -mno-vsx"
1225             } else {
1226                 set options "-mno-vsx"
1227             }
1228             check_runtime_nocache vmx_hw_available {
1229                 int main()
1230                 {
1231                 #ifdef __MACH__
1232                   asm volatile ("vor v0,v0,v0");
1233                 #else
1234                   asm volatile ("vor 0,0,0");
1235                 #endif
1236                   return 0;
1237                 }
1238             } $options
1239         }
1240     }]
1241 }
1242
1243 proc check_ppc_recip_hw_available { } {
1244     return [check_cached_effective_target ppc_recip_hw_available {
1245         # Some simulators may not support FRE/FRES/FRSQRTE/FRSQRTES
1246         # For now, disable on Darwin
1247         if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
1248             expr 0
1249         } else {
1250             set options "-mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb"
1251             check_runtime_nocache ppc_recip_hw_available {
1252                 volatile double d_recip, d_rsqrt, d_four = 4.0;
1253                 volatile float f_recip, f_rsqrt, f_four = 4.0f;
1254                 int main()
1255                 {
1256                   asm volatile ("fres %0,%1" : "=f" (f_recip) : "f" (f_four));
1257                   asm volatile ("fre %0,%1" : "=d" (d_recip) : "d" (d_four));
1258                   asm volatile ("frsqrtes %0,%1" : "=f" (f_rsqrt) : "f" (f_four));
1259                   asm volatile ("frsqrte %0,%1" : "=f" (d_rsqrt) : "d" (d_four));
1260                   return 0;
1261                 }
1262             } $options
1263         }
1264     }]
1265 }
1266
1267 # Return 1 if the target supports executing AltiVec and Cell PPU
1268 # instructions, 0 otherwise.  Cache the result.
1269
1270 proc check_effective_target_cell_hw { } {
1271     return [check_cached_effective_target cell_hw_available {
1272         # Some simulators are known to not support VMX and PPU instructions.
1273         if { [istarget powerpc-*-eabi*] } {
1274             expr 0
1275         } else {
1276             # Most targets don't require special flags for this test
1277             # case, but Darwin and AIX do.
1278             if { [istarget *-*-darwin*]
1279                  || [istarget *-*-aix*] } {
1280                 set options "-maltivec -mcpu=cell"
1281             } else {
1282                 set options "-mcpu=cell"
1283             }
1284             check_runtime_nocache cell_hw_available {
1285                 int main()
1286                 {
1287                 #ifdef __MACH__
1288                   asm volatile ("vor v0,v0,v0");
1289                   asm volatile ("lvlx v0,r0,r0");
1290                 #else
1291                   asm volatile ("vor 0,0,0");
1292                   asm volatile ("lvlx 0,0,0");
1293                 #endif
1294                   return 0;
1295                 }
1296             } $options
1297         }
1298     }]
1299 }
1300
1301 # Return 1 if the target supports executing 64-bit instructions, 0
1302 # otherwise.  Cache the result.
1303
1304 proc check_effective_target_powerpc64 { } {
1305     global powerpc64_available_saved
1306     global tool
1307
1308     if [info exists powerpc64_available_saved] {
1309         verbose "check_effective_target_powerpc64 returning saved $powerpc64_available_saved" 2
1310     } else {
1311         set powerpc64_available_saved 0
1312
1313         # Some simulators are known to not support powerpc64 instructions.
1314         if { [istarget powerpc-*-eabi*] || [istarget powerpc-ibm-aix*] } {
1315             verbose "check_effective_target_powerpc64 returning 0" 2
1316             return $powerpc64_available_saved
1317         }
1318
1319         # Set up, compile, and execute a test program containing a 64-bit
1320         # instruction.  Include the current process ID in the file
1321         # names to prevent conflicts with invocations for multiple
1322         # testsuites.
1323         set src ppc[pid].c
1324         set exe ppc[pid].x
1325
1326         set f [open $src "w"]
1327         puts $f "int main() {"
1328         puts $f "#ifdef __MACH__"
1329         puts $f "  asm volatile (\"extsw r0,r0\");"
1330         puts $f "#else"
1331         puts $f "  asm volatile (\"extsw 0,0\");"
1332         puts $f "#endif"
1333         puts $f "  return 0; }"
1334         close $f
1335
1336         set opts "additional_flags=-mcpu=G5"
1337
1338         verbose "check_effective_target_powerpc64 compiling testfile $src" 2
1339         set lines [${tool}_target_compile $src $exe executable "$opts"]
1340         file delete $src
1341
1342         if [string match "" $lines] then {
1343             # No error message, compilation succeeded.
1344             set result [${tool}_load "./$exe" "" ""]
1345             set status [lindex $result 0]
1346             remote_file build delete $exe
1347             verbose "check_effective_target_powerpc64 testfile status is <$status>" 2
1348
1349             if { $status == "pass" } then {
1350                 set powerpc64_available_saved 1
1351             }
1352         } else {
1353             verbose "check_effective_target_powerpc64 testfile compilation failed" 2
1354         }
1355     }
1356
1357     return $powerpc64_available_saved
1358 }
1359
1360 # GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing
1361 # complex float arguments.  This affects gfortran tests that call cabsf
1362 # in libm built by an earlier compiler.  Return 1 if libm uses the same
1363 # argument passing as the compiler under test, 0 otherwise.
1364 #
1365 # When the target name changes, replace the cached result.
1366
1367 proc check_effective_target_broken_cplxf_arg { } {
1368     return [check_cached_effective_target broken_cplxf_arg {
1369         # Skip the work for targets known not to be affected.
1370         if { ![istarget powerpc64-*-linux*] } {
1371             expr 0
1372         } elseif { ![is-effective-target lp64] } {
1373             expr 0
1374         } else {
1375             check_runtime_nocache broken_cplxf_arg {
1376                 #include <complex.h>
1377                 extern void abort (void);
1378                 float fabsf (float);
1379                 float cabsf (_Complex float);
1380                 int main ()
1381                 {
1382                   _Complex float cf;
1383                   float f;
1384                   cf = 3 + 4.0fi;
1385                   f = cabsf (cf);
1386                   if (fabsf (f - 5.0) > 0.0001)
1387                     abort ();
1388                   return 0;
1389                 }
1390             } "-lm"
1391         }
1392     }]
1393 }
1394
1395 proc check_alpha_max_hw_available { } {
1396     return [check_runtime alpha_max_hw_available {
1397         int main() { return __builtin_alpha_amask(1<<8) != 0; }
1398     }]
1399 }
1400
1401 # Returns true iff the FUNCTION is available on the target system.
1402 # (This is essentially a Tcl implementation of Autoconf's
1403 # AC_CHECK_FUNC.)
1404
1405 proc check_function_available { function } {
1406     return [check_no_compiler_messages ${function}_available \
1407                 executable [subst {
1408         #ifdef __cplusplus
1409         extern "C"
1410         #endif
1411         char $function ();
1412         int main () { $function (); }
1413     }] "-fno-builtin" ]
1414 }
1415
1416 # Returns true iff "fork" is available on the target system.
1417
1418 proc check_fork_available {} {
1419     return [check_function_available "fork"]
1420 }
1421
1422 # Returns true iff "mkfifo" is available on the target system.
1423
1424 proc check_mkfifo_available {} {
1425     if {[istarget *-*-cygwin*]} {
1426        # Cygwin has mkfifo, but support is incomplete.
1427        return 0
1428      }
1429
1430     return [check_function_available "mkfifo"]
1431 }
1432
1433 # Returns true iff "__cxa_atexit" is used on the target system.
1434
1435 proc check_cxa_atexit_available { } {
1436     return [check_cached_effective_target cxa_atexit_available {
1437         if { [istarget "hppa*-*-hpux10*"] } {
1438             # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes.
1439             expr 0
1440         } elseif { [istarget "*-*-vxworks"] } {
1441             # vxworks doesn't have __cxa_atexit but subsequent test passes.
1442             expr 0
1443         } else {
1444             check_runtime_nocache cxa_atexit_available {
1445                 // C++
1446                 #include <stdlib.h>
1447                 static unsigned int count;
1448                 struct X
1449                 {
1450                   X() { count = 1; }
1451                   ~X()
1452                   {
1453                     if (count != 3)
1454                       exit(1);
1455                     count = 4;
1456                   }
1457                 };
1458                 void f()
1459                 {
1460                   static X x;
1461                 }
1462                 struct Y
1463                 {
1464                   Y() { f(); count = 2; }
1465                   ~Y()
1466                   {
1467                     if (count != 2)
1468                       exit(1);
1469                     count = 3;
1470                   }
1471                 };
1472                 Y y;
1473                 int main() { return 0; }
1474             }
1475         }
1476     }]
1477 }
1478
1479 proc check_effective_target_objc2 { } {
1480     return [check_no_compiler_messages objc2 object {
1481         #ifdef __OBJC2__
1482         int dummy[1];
1483         #else
1484         #error
1485         #endif 
1486     }]
1487 }
1488
1489 proc check_effective_target_next_runtime { } {
1490     return [check_no_compiler_messages objc2 object {
1491         #ifdef __NEXT_RUNTIME__
1492         int dummy[1];
1493         #else
1494         #error
1495         #endif 
1496     }]
1497 }
1498
1499 # Return 1 if we're generating 32-bit code using default options, 0
1500 # otherwise.
1501
1502 proc check_effective_target_ilp32 { } {
1503     return [check_no_compiler_messages ilp32 object {
1504         int dummy[sizeof (int) == 4
1505                   && sizeof (void *) == 4
1506                   && sizeof (long) == 4 ? 1 : -1];
1507     }]
1508 }
1509
1510 # Return 1 if we're generating 32-bit or larger integers using default
1511 # options, 0 otherwise.
1512
1513 proc check_effective_target_int32plus { } {
1514     return [check_no_compiler_messages int32plus object {
1515         int dummy[sizeof (int) >= 4 ? 1 : -1];
1516     }]
1517 }
1518
1519 # Return 1 if we're generating 32-bit or larger pointers using default
1520 # options, 0 otherwise.
1521
1522 proc check_effective_target_ptr32plus { } {
1523     return [check_no_compiler_messages ptr32plus object {
1524         int dummy[sizeof (void *) >= 4 ? 1 : -1];
1525     }]
1526 }
1527
1528 # Return 1 if we support 32-bit or larger array and structure sizes
1529 # using default options, 0 otherwise.
1530
1531 proc check_effective_target_size32plus { } {
1532     return [check_no_compiler_messages size32plus object {
1533         char dummy[65537];
1534     }]
1535 }
1536
1537 # Returns 1 if we're generating 16-bit or smaller integers with the
1538 # default options, 0 otherwise.
1539
1540 proc check_effective_target_int16 { } {
1541     return [check_no_compiler_messages int16 object {
1542         int dummy[sizeof (int) < 4 ? 1 : -1];
1543     }]
1544 }
1545
1546 # Return 1 if we're generating 64-bit code using default options, 0
1547 # otherwise.
1548
1549 proc check_effective_target_lp64 { } {
1550     return [check_no_compiler_messages lp64 object {
1551         int dummy[sizeof (int) == 4
1552                   && sizeof (void *) == 8
1553                   && sizeof (long) == 8 ? 1 : -1];
1554     }]
1555 }
1556
1557 # Return 1 if we're generating 64-bit code using default llp64 options,
1558 # 0 otherwise.
1559
1560 proc check_effective_target_llp64 { } {
1561     return [check_no_compiler_messages llp64 object {
1562         int dummy[sizeof (int) == 4
1563                   && sizeof (void *) == 8
1564                   && sizeof (long long) == 8
1565                   && sizeof (long) == 4 ? 1 : -1];
1566     }]
1567 }
1568
1569 # Return 1 if the target supports long double larger than double,
1570 # 0 otherwise.
1571
1572 proc check_effective_target_large_long_double { } {
1573     return [check_no_compiler_messages large_long_double object {
1574         int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
1575     }]
1576 }
1577
1578 # Return 1 if the target supports double larger than float,
1579 # 0 otherwise.
1580
1581 proc check_effective_target_large_double { } {
1582     return [check_no_compiler_messages large_double object {
1583         int dummy[sizeof(double) > sizeof(float) ? 1 : -1];
1584     }]
1585 }
1586
1587 # Return 1 if the target supports double of 64 bits,
1588 # 0 otherwise.
1589
1590 proc check_effective_target_double64 { } {
1591     return [check_no_compiler_messages double64 object {
1592         int dummy[sizeof(double) == 8 ? 1 : -1];
1593     }]
1594 }
1595
1596 # Return 1 if the target supports double of at least 64 bits,
1597 # 0 otherwise.
1598
1599 proc check_effective_target_double64plus { } {
1600     return [check_no_compiler_messages double64plus object {
1601         int dummy[sizeof(double) >= 8 ? 1 : -1];
1602     }]
1603 }
1604
1605 # Return 1 if the target supports compiling fixed-point,
1606 # 0 otherwise.
1607
1608 proc check_effective_target_fixed_point { } {
1609     return [check_no_compiler_messages fixed_point object {
1610         _Sat _Fract x; _Sat _Accum y;
1611     }]
1612 }
1613
1614 # Return 1 if the target supports compiling decimal floating point,
1615 # 0 otherwise.
1616
1617 proc check_effective_target_dfp_nocache { } {
1618     verbose "check_effective_target_dfp_nocache: compiling source" 2
1619     set ret [check_no_compiler_messages_nocache dfp object {
1620         float x __attribute__((mode(DD)));
1621     }]
1622     verbose "check_effective_target_dfp_nocache: returning $ret" 2
1623     return $ret
1624 }
1625
1626 proc check_effective_target_dfprt_nocache { } {
1627     return [check_runtime_nocache dfprt {
1628         typedef float d64 __attribute__((mode(DD)));
1629         d64 x = 1.2df, y = 2.3dd, z;
1630         int main () { z = x + y; return 0; }
1631     }]
1632 }
1633
1634 # Return 1 if the target supports compiling Decimal Floating Point,
1635 # 0 otherwise.
1636 #
1637 # This won't change for different subtargets so cache the result.
1638
1639 proc check_effective_target_dfp { } {
1640     return [check_cached_effective_target dfp {
1641         check_effective_target_dfp_nocache
1642     }]
1643 }
1644
1645 # Return 1 if the target supports linking and executing Decimal Floating
1646 # Point, 0 otherwise.
1647 #
1648 # This won't change for different subtargets so cache the result.
1649
1650 proc check_effective_target_dfprt { } {
1651     return [check_cached_effective_target dfprt {
1652         check_effective_target_dfprt_nocache
1653     }]
1654 }
1655
1656 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
1657
1658 proc check_effective_target_ucn_nocache { } {
1659     # -std=c99 is only valid for C
1660     if [check_effective_target_c] {
1661         set ucnopts "-std=c99"
1662     }
1663     append ucnopts " -fextended-identifiers"
1664     verbose "check_effective_target_ucn_nocache: compiling source" 2
1665     set ret [check_no_compiler_messages_nocache ucn object {
1666         int \u00C0;
1667     } $ucnopts]
1668     verbose "check_effective_target_ucn_nocache: returning $ret" 2
1669     return $ret
1670 }
1671
1672 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
1673 #
1674 # This won't change for different subtargets, so cache the result.
1675
1676 proc check_effective_target_ucn { } {
1677     return [check_cached_effective_target ucn {
1678         check_effective_target_ucn_nocache
1679     }]
1680 }
1681
1682 # Return 1 if the target needs a command line argument to enable a SIMD
1683 # instruction set.
1684
1685 proc check_effective_target_vect_cmdline_needed { } {
1686     global et_vect_cmdline_needed_saved
1687     global et_vect_cmdline_needed_target_name
1688
1689     if { ![info exists et_vect_cmdline_needed_target_name] } {
1690         set et_vect_cmdline_needed_target_name ""
1691     }
1692
1693     # If the target has changed since we set the cached value, clear it.
1694     set current_target [current_target_name]
1695     if { $current_target != $et_vect_cmdline_needed_target_name } {
1696         verbose "check_effective_target_vect_cmdline_needed: `$et_vect_cmdline_needed_target_name' `$current_target'" 2
1697         set et_vect_cmdline_needed_target_name $current_target
1698         if { [info exists et_vect_cmdline_needed_saved] } {
1699             verbose "check_effective_target_vect_cmdline_needed: removing cached result" 2
1700             unset et_vect_cmdline_needed_saved
1701         }
1702     }
1703
1704     if [info exists et_vect_cmdline_needed_saved] {
1705         verbose "check_effective_target_vect_cmdline_needed: using cached result" 2
1706     } else {
1707         set et_vect_cmdline_needed_saved 1
1708         if { [istarget alpha*-*-*]
1709              || [istarget ia64-*-*]
1710              || (([istarget x86_64-*-*] || [istarget i?86-*-*])
1711                  && [check_effective_target_lp64])
1712              || ([istarget powerpc*-*-*]
1713                  && ([check_effective_target_powerpc_spe]
1714                      || [check_effective_target_powerpc_altivec]))
1715              || [istarget spu-*-*]
1716              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
1717            set et_vect_cmdline_needed_saved 0
1718         }
1719     }
1720
1721     verbose "check_effective_target_vect_cmdline_needed: returning $et_vect_cmdline_needed_saved" 2
1722     return $et_vect_cmdline_needed_saved
1723 }
1724
1725 # Return 1 if the target supports hardware vectors of int, 0 otherwise.
1726 #
1727 # This won't change for different subtargets so cache the result.
1728
1729 proc check_effective_target_vect_int { } {
1730     global et_vect_int_saved
1731
1732     if [info exists et_vect_int_saved] {
1733         verbose "check_effective_target_vect_int: using cached result" 2
1734     } else {
1735         set et_vect_int_saved 0
1736         if { [istarget i?86-*-*]
1737              || ([istarget powerpc*-*-*]
1738                   && ![istarget powerpc-*-linux*paired*])
1739               || [istarget spu-*-*]
1740               || [istarget x86_64-*-*]
1741               || [istarget sparc*-*-*]
1742               || [istarget alpha*-*-*]
1743               || [istarget ia64-*-*] 
1744               || [check_effective_target_arm32]
1745               || ([istarget mips*-*-*]
1746                   && [check_effective_target_mips_loongson]) } {
1747            set et_vect_int_saved 1
1748         }
1749     }
1750
1751     verbose "check_effective_target_vect_int: returning $et_vect_int_saved" 2
1752     return $et_vect_int_saved
1753 }
1754
1755 # Return 1 if the target supports signed int->float conversion 
1756 #
1757
1758 proc check_effective_target_vect_intfloat_cvt { } {
1759     global et_vect_intfloat_cvt_saved
1760
1761     if [info exists et_vect_intfloat_cvt_saved] {
1762         verbose "check_effective_target_vect_intfloat_cvt: using cached result" 2
1763     } else {
1764         set et_vect_intfloat_cvt_saved 0
1765         if { [istarget i?86-*-*]
1766               || ([istarget powerpc*-*-*]
1767                    && ![istarget powerpc-*-linux*paired*])
1768               || [istarget x86_64-*-*] } {
1769            set et_vect_intfloat_cvt_saved 1
1770         }
1771     }
1772
1773     verbose "check_effective_target_vect_intfloat_cvt: returning $et_vect_intfloat_cvt_saved" 2
1774     return $et_vect_intfloat_cvt_saved
1775 }
1776
1777 #Return 1 if we're supporting __int128 for target, 0 otherwise.
1778
1779 proc check_effective_target_int128 { } {
1780     return [check_no_compiler_messages int128 object {
1781         int dummy[
1782         #ifndef __SIZEOF_INT128__
1783         -1
1784         #else
1785         1
1786         #endif
1787         ];
1788     }]
1789 }
1790
1791 # Return 1 if the target supports unsigned int->float conversion 
1792 #
1793
1794 proc check_effective_target_vect_uintfloat_cvt { } {
1795     global et_vect_uintfloat_cvt_saved
1796
1797     if [info exists et_vect_uintfloat_cvt_saved] {
1798         verbose "check_effective_target_vect_uintfloat_cvt: using cached result" 2
1799     } else {
1800         set et_vect_uintfloat_cvt_saved 0
1801         if { [istarget i?86-*-*]
1802               || ([istarget powerpc*-*-*]
1803                   && ![istarget powerpc-*-linux*paired*])
1804               || [istarget x86_64-*-*] } {
1805            set et_vect_uintfloat_cvt_saved 1
1806         }
1807     }
1808
1809     verbose "check_effective_target_vect_uintfloat_cvt: returning $et_vect_uintfloat_cvt_saved" 2
1810     return $et_vect_uintfloat_cvt_saved
1811 }
1812
1813
1814 # Return 1 if the target supports signed float->int conversion
1815 #
1816
1817 proc check_effective_target_vect_floatint_cvt { } {
1818     global et_vect_floatint_cvt_saved
1819
1820     if [info exists et_vect_floatint_cvt_saved] {
1821         verbose "check_effective_target_vect_floatint_cvt: using cached result" 2
1822     } else {
1823         set et_vect_floatint_cvt_saved 0
1824         if { [istarget i?86-*-*]
1825               || ([istarget powerpc*-*-*]
1826                    && ![istarget powerpc-*-linux*paired*])
1827               || [istarget x86_64-*-*] } {
1828            set et_vect_floatint_cvt_saved 1
1829         }
1830     }
1831
1832     verbose "check_effective_target_vect_floatint_cvt: returning $et_vect_floatint_cvt_saved" 2
1833     return $et_vect_floatint_cvt_saved
1834 }
1835
1836 # Return 1 if the target supports unsigned float->int conversion
1837 #
1838
1839 proc check_effective_target_vect_floatuint_cvt { } {
1840     global et_vect_floatuint_cvt_saved
1841
1842     if [info exists et_vect_floatuint_cvt_saved] {
1843         verbose "check_effective_target_vect_floatuint_cvt: using cached result" 2
1844     } else {
1845         set et_vect_floatuint_cvt_saved 0
1846         if { ([istarget powerpc*-*-*]
1847               && ![istarget powerpc-*-linux*paired*]) } {
1848            set et_vect_floatuint_cvt_saved 1
1849         }
1850     }
1851
1852     verbose "check_effective_target_vect_floatuint_cvt: returning $et_vect_floatuint_cvt_saved" 2
1853     return $et_vect_floatuint_cvt_saved
1854 }
1855
1856 # Return 1 is this is an arm target using 32-bit instructions
1857 proc check_effective_target_arm32 { } {
1858     return [check_no_compiler_messages arm32 assembly {
1859         #if !defined(__arm__) || (defined(__thumb__) && !defined(__thumb2__))
1860         #error FOO
1861         #endif
1862     }]
1863 }
1864
1865 # Return 1 if this is an ARM target that only supports aligned vector accesses
1866 proc check_effective_target_arm_vect_no_misalign { } {
1867     return [check_no_compiler_messages arm_vect_no_misalign assembly {
1868         #if !defined(__arm__) \
1869             || (defined(__ARMEL__) \
1870                 && (!defined(__thumb__) || defined(__thumb2__)))
1871         #error FOO
1872         #endif
1873     }]
1874 }
1875
1876
1877 # Return 1 if this is an ARM target supporting -mfpu=vfp
1878 # -mfloat-abi=softfp.  Some multilibs may be incompatible with these
1879 # options.
1880
1881 proc check_effective_target_arm_vfp_ok { } {
1882     if { [check_effective_target_arm32] } {
1883         return [check_no_compiler_messages arm_vfp_ok object {
1884             int dummy;
1885         } "-mfpu=vfp -mfloat-abi=softfp"]
1886     } else {
1887         return 0
1888     }
1889 }
1890
1891 # Return 1 if this is an ARM target supporting -mfpu=vfp
1892 # -mfloat-abi=hard.  Some multilibs may be incompatible with these
1893 # options.
1894
1895 proc check_effective_target_arm_hard_vfp_ok { } {
1896     if { [check_effective_target_arm32] } {
1897         return [check_no_compiler_messages arm_hard_vfp_ok executable {
1898             int main() { return 0;}
1899         } "-mfpu=vfp -mfloat-abi=hard"]
1900     } else {
1901         return 0
1902     }
1903 }
1904
1905 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
1906 # or -mfloat-abi=hard, but if one is already specified by the
1907 # multilib, use it.  Similarly, if a -mfpu option already enables
1908 # NEON, do not add -mfpu=neon.
1909
1910 proc add_options_for_arm_neon { flags } {
1911     if { ! [check_effective_target_arm_neon_ok] } {
1912         return "$flags"
1913     }
1914     global et_arm_neon_flags
1915     return "$flags $et_arm_neon_flags"
1916 }
1917
1918 # Return 1 if this is an ARM target supporting -mfpu=neon
1919 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
1920 # incompatible with these options.  Also set et_arm_neon_flags to the
1921 # best options to add.
1922
1923 proc check_effective_target_arm_neon_ok_nocache { } {
1924     global et_arm_neon_flags
1925     set et_arm_neon_flags ""
1926     if { [check_effective_target_arm32] } {
1927         foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp"} {
1928             if { [check_no_compiler_messages_nocache arm_neon_ok object {
1929                 #include "arm_neon.h"
1930                 int dummy;
1931             } "$flags"] } {
1932                 set et_arm_neon_flags $flags
1933                 return 1
1934             }
1935         }
1936     }
1937
1938     return 0
1939 }
1940
1941 proc check_effective_target_arm_neon_ok { } {
1942     return [check_cached_effective_target arm_neon_ok \
1943                 check_effective_target_arm_neon_ok_nocache]
1944 }
1945
1946 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
1947 # or -mfloat-abi=hard, but if one is already specified by the
1948 # multilib, use it.
1949
1950 proc add_options_for_arm_fp16 { flags } {
1951     if { ! [check_effective_target_arm_fp16_ok] } {
1952         return "$flags"
1953     }
1954     global et_arm_fp16_flags
1955     return "$flags $et_arm_fp16_flags"
1956 }
1957
1958 # Return 1 if this is an ARM target that can support a VFP fp16 variant.
1959 # Skip multilibs that are incompatible with these options and set
1960 # et_arm_fp16_flags to the best options to add.
1961
1962 proc check_effective_target_arm_fp16_ok_nocache { } {
1963     global et_arm_fp16_flags
1964     set et_arm_fp16_flags ""
1965     if { ! [check_effective_target_arm32] } {
1966         return 0;
1967     }
1968     if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" "-mfpu=*fpv[1-9][0-9]*" } ]] {
1969         # Multilib flags would override -mfpu.
1970         return 0
1971     }
1972     if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] {
1973         # Must generate floating-point instructions.
1974         return 0
1975     }
1976     if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] {
1977         # The existing -mfpu value is OK; use it, but add softfp.
1978         set et_arm_fp16_flags "-mfloat-abi=softfp"
1979         return 1;
1980     }
1981     # Add -mfpu for a VFP fp16 variant since there is no preprocessor
1982     # macro to check for this support.
1983     set flags "-mfpu=vfpv4 -mfloat-abi=softfp"
1984     if { [check_no_compiler_messages_nocache arm_fp16_ok assembly {
1985         int dummy;
1986     } "$flags"] } {
1987         set et_arm_fp16_flags "$flags"
1988         return 1
1989     }
1990
1991     return 0
1992 }
1993
1994 proc check_effective_target_arm_fp16_ok { } {
1995     return [check_cached_effective_target arm_fp16_ok \
1996                 check_effective_target_arm_fp16_ok_nocache]
1997 }
1998
1999 # Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
2000 # used.
2001
2002 proc check_effective_target_arm_thumb1_ok { } {
2003     return [check_no_compiler_messages arm_thumb1_ok assembly {
2004         #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
2005         #error FOO
2006         #endif
2007     } "-mthumb"]
2008 }
2009
2010 # Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
2011 # used.
2012
2013 proc check_effective_target_arm_thumb2_ok { } {
2014     return [check_no_compiler_messages arm_thumb2_ok assembly {
2015         #if !defined(__thumb2__)
2016         #error FOO
2017         #endif
2018     } "-mthumb"]
2019 }
2020
2021 # Return 1 if the target supports executing NEON instructions, 0
2022 # otherwise.  Cache the result.
2023
2024 proc check_effective_target_arm_neon_hw { } {
2025     return [check_runtime arm_neon_hw_available {
2026         int
2027         main (void)
2028         {
2029           long long a = 0, b = 1;
2030           asm ("vorr %P0, %P1, %P2"
2031                : "=w" (a)
2032                : "0" (a), "w" (b));
2033           return (a != 1);
2034         }
2035     } [add_options_for_arm_neon ""]]
2036 }
2037
2038 # Return 1 if this is a ARM target with NEON enabled.
2039
2040 proc check_effective_target_arm_neon { } {
2041     if { [check_effective_target_arm32] } {
2042         return [check_no_compiler_messages arm_neon object {
2043             #ifndef __ARM_NEON__
2044             #error not NEON
2045             #else
2046             int dummy;
2047             #endif
2048         }]
2049     } else {
2050         return 0
2051     }
2052 }
2053
2054 # Return 1 if this a Loongson-2E or -2F target using an ABI that supports
2055 # the Loongson vector modes.
2056
2057 proc check_effective_target_mips_loongson { } {
2058     return [check_no_compiler_messages loongson assembly {
2059         #if !defined(__mips_loongson_vector_rev)
2060         #error FOO
2061         #endif
2062     }]
2063 }
2064
2065 # Return 1 if this is an ARM target that adheres to the ABI for the ARM
2066 # Architecture.
2067
2068 proc check_effective_target_arm_eabi { } {
2069     return [check_no_compiler_messages arm_eabi object {
2070         #ifndef __ARM_EABI__
2071         #error not EABI
2072         #else
2073         int dummy;
2074         #endif
2075     }]
2076 }
2077
2078 # Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
2079 # Some multilibs may be incompatible with this option.
2080
2081 proc check_effective_target_arm_iwmmxt_ok { } {
2082     if { [check_effective_target_arm32] } {
2083         return [check_no_compiler_messages arm_iwmmxt_ok object {
2084             int dummy;
2085         } "-mcpu=iwmmxt"]
2086     } else {
2087         return 0
2088     }
2089 }
2090
2091 # Return 1 if this is a PowerPC target with floating-point registers.
2092
2093 proc check_effective_target_powerpc_fprs { } {
2094     if { [istarget powerpc*-*-*]
2095          || [istarget rs6000-*-*] } {
2096         return [check_no_compiler_messages powerpc_fprs object {
2097             #ifdef __NO_FPRS__
2098             #error no FPRs
2099             #else
2100             int dummy;
2101             #endif
2102         }]
2103     } else {
2104         return 0
2105     }
2106 }
2107
2108 # Return 1 if this is a PowerPC target with hardware double-precision
2109 # floating point.
2110
2111 proc check_effective_target_powerpc_hard_double { } {
2112     if { [istarget powerpc*-*-*]
2113          || [istarget rs6000-*-*] } {
2114         return [check_no_compiler_messages powerpc_hard_double object {
2115             #ifdef _SOFT_DOUBLE
2116             #error soft double
2117             #else
2118             int dummy;
2119             #endif
2120         }]
2121     } else {
2122         return 0
2123     }
2124 }
2125
2126 # Return 1 if this is a PowerPC target supporting -maltivec.
2127
2128 proc check_effective_target_powerpc_altivec_ok { } {
2129     if { ([istarget powerpc*-*-*]
2130          && ![istarget powerpc-*-linux*paired*])
2131          || [istarget rs6000-*-*] } {
2132         # AltiVec is not supported on AIX before 5.3.
2133         if { [istarget powerpc*-*-aix4*]
2134              || [istarget powerpc*-*-aix5.1*] 
2135              || [istarget powerpc*-*-aix5.2*] } {
2136             return 0
2137         }
2138         return [check_no_compiler_messages powerpc_altivec_ok object {
2139             int dummy;
2140         } "-maltivec"]
2141     } else {
2142         return 0
2143     }
2144 }
2145
2146 # Return 1 if this is a PowerPC target supporting -mvsx
2147
2148 proc check_effective_target_powerpc_vsx_ok { } {
2149     if { ([istarget powerpc*-*-*]
2150          && ![istarget powerpc-*-linux*paired*])
2151          || [istarget rs6000-*-*] } {
2152         # AltiVec is not supported on AIX before 5.3.
2153         if { [istarget powerpc*-*-aix4*]
2154              || [istarget powerpc*-*-aix5.1*] 
2155              || [istarget powerpc*-*-aix5.2*] } {
2156             return 0
2157         }
2158         return [check_no_compiler_messages powerpc_vsx_ok object {
2159             int main (void) {
2160 #ifdef __MACH__
2161                 asm volatile ("xxlor vs0,vs0,vs0");
2162 #else
2163                 asm volatile ("xxlor 0,0,0");
2164 #endif
2165                 return 0;
2166             }
2167         } "-mvsx"]
2168     } else {
2169         return 0
2170     }
2171 }
2172
2173 # Return 1 if this is a PowerPC target supporting -mcpu=cell.
2174
2175 proc check_effective_target_powerpc_ppu_ok { } {
2176     if [check_effective_target_powerpc_altivec_ok] {
2177         return [check_no_compiler_messages cell_asm_available object {
2178             int main (void) {
2179 #ifdef __MACH__
2180                 asm volatile ("lvlx v0,v0,v0");
2181 #else
2182                 asm volatile ("lvlx 0,0,0");
2183 #endif
2184                 return 0;
2185             }
2186         }]
2187     } else {
2188         return 0
2189     }
2190 }
2191
2192 # Return 1 if this is a PowerPC target that supports SPU.
2193
2194 proc check_effective_target_powerpc_spu { } {
2195     if [istarget powerpc*-*-linux*] {
2196         return [check_effective_target_powerpc_altivec_ok]
2197     } else {
2198         return 0
2199     }
2200 }
2201
2202 # Return 1 if this is a PowerPC SPE target.  The check includes options
2203 # specified by dg-options for this test, so don't cache the result.
2204
2205 proc check_effective_target_powerpc_spe_nocache { } {
2206     if { [istarget powerpc*-*-*] } {
2207         return [check_no_compiler_messages_nocache powerpc_spe object {
2208             #ifndef __SPE__
2209             #error not SPE
2210             #else
2211             int dummy;
2212             #endif
2213         } [current_compiler_flags]]
2214     } else {
2215         return 0
2216     }
2217 }
2218
2219 # Return 1 if this is a PowerPC target with SPE enabled.
2220
2221 proc check_effective_target_powerpc_spe { } {
2222     if { [istarget powerpc*-*-*] } {
2223         return [check_no_compiler_messages powerpc_spe object {
2224             #ifndef __SPE__
2225             #error not SPE
2226             #else
2227             int dummy;
2228             #endif
2229         }]
2230     } else {
2231         return 0
2232     }
2233 }
2234
2235 # Return 1 if this is a PowerPC target with Altivec enabled.
2236
2237 proc check_effective_target_powerpc_altivec { } {
2238     if { [istarget powerpc*-*-*] } {
2239         return [check_no_compiler_messages powerpc_altivec object {
2240             #ifndef __ALTIVEC__
2241             #error not Altivec
2242             #else
2243             int dummy;
2244             #endif
2245         }]
2246     } else {
2247         return 0
2248     }
2249 }
2250
2251 # Return 1 if this is a PowerPC 405 target.  The check includes options
2252 # specified by dg-options for this test, so don't cache the result.
2253
2254 proc check_effective_target_powerpc_405_nocache { } {
2255     if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } {
2256         return [check_no_compiler_messages_nocache powerpc_405 object {
2257             #ifdef __PPC405__
2258             int dummy;
2259             #else
2260             #error not a PPC405
2261             #endif
2262         } [current_compiler_flags]]
2263     } else {
2264         return 0
2265     }
2266 }
2267
2268 # Return 1 if this is a SPU target with a toolchain that
2269 # supports automatic overlay generation.
2270
2271 proc check_effective_target_spu_auto_overlay { } {
2272     if { [istarget spu*-*-elf*] } {
2273         return [check_no_compiler_messages spu_auto_overlay executable {
2274                 int main (void) { }
2275                 } "-Wl,--auto-overlay" ]
2276     } else {
2277         return 0
2278     }
2279 }
2280
2281 # The VxWorks SPARC simulator accepts only EM_SPARC executables and
2282 # chokes on EM_SPARC32PLUS or EM_SPARCV9 executables.  Return 1 if the
2283 # test environment appears to run executables on such a simulator.
2284
2285 proc check_effective_target_ultrasparc_hw { } {
2286     return [check_runtime ultrasparc_hw {
2287         int main() { return 0; }
2288     } "-mcpu=ultrasparc"]
2289 }
2290
2291 # Return 1 if the target supports hardware vector shift operation.
2292
2293 proc check_effective_target_vect_shift { } {
2294     global et_vect_shift_saved
2295
2296     if [info exists et_vect_shift_saved] {
2297         verbose "check_effective_target_vect_shift: using cached result" 2
2298     } else {
2299         set et_vect_shift_saved 0
2300         if { ([istarget powerpc*-*-*]
2301              && ![istarget powerpc-*-linux*paired*])
2302              || [istarget ia64-*-*]
2303              || [istarget i?86-*-*]
2304              || [istarget x86_64-*-*]
2305              || [check_effective_target_arm32]
2306              || ([istarget mips*-*-*]
2307                  && [check_effective_target_mips_loongson]) } {
2308            set et_vect_shift_saved 1
2309         }
2310     }
2311
2312     verbose "check_effective_target_vect_shift: returning $et_vect_shift_saved" 2
2313     return $et_vect_shift_saved
2314 }
2315
2316 # Return 1 if the target supports hardware vector shift operation with
2317 # scalar shift argument.
2318
2319 proc check_effective_target_vect_shift_scalar { } {
2320     global et_vect_shift_scalar_saved
2321
2322     if [info exists et_vect_shift_scalar_saved] {
2323         verbose "check_effective_target_vect_shift_scalar: using cached result" 2
2324     } else {
2325         set et_vect_shift_scalar_saved 0
2326         if { [istarget x86_64-*-*]
2327              || [istarget i?86-*-*] } {
2328            set et_vect_shift_scalar_saved 1
2329         }
2330     }
2331
2332     verbose "check_effective_target_vect_shift_scalar: returning $et_vect_shift_scalar_saved" 2
2333     return $et_vect_shift_scalar_saved
2334 }
2335
2336
2337 # Return 1 if the target supports hardware vector shift operation for char.
2338
2339 proc check_effective_target_vect_shift_char { } {
2340     global et_vect_shift_char_saved
2341
2342     if [info exists et_vect_shift_char_saved] {
2343         verbose "check_effective_target_vect_shift_char: using cached result" 2
2344     } else {
2345         set et_vect_shift_char_saved 0
2346         if { ([istarget powerpc*-*-*]
2347              && ![istarget powerpc-*-linux*paired*])
2348              || [check_effective_target_arm32] } {
2349            set et_vect_shift_char_saved 1
2350         }
2351     }
2352
2353     verbose "check_effective_target_vect_shift_char: returning $et_vect_shift_char_saved" 2
2354     return $et_vect_shift_char_saved
2355 }
2356
2357 # Return 1 if the target supports hardware vectors of long, 0 otherwise.
2358 #
2359 # This can change for different subtargets so do not cache the result.
2360
2361 proc check_effective_target_vect_long { } {
2362     if { [istarget i?86-*-*]
2363          || (([istarget powerpc*-*-*] 
2364               && ![istarget powerpc-*-linux*paired*]) 
2365               && [check_effective_target_ilp32])
2366          || [istarget x86_64-*-*]
2367          || [check_effective_target_arm32]
2368          || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) } {
2369         set answer 1
2370     } else {
2371         set answer 0
2372     }
2373
2374     verbose "check_effective_target_vect_long: returning $answer" 2
2375     return $answer
2376 }
2377
2378 # Return 1 if the target supports hardware vectors of float, 0 otherwise.
2379 #
2380 # This won't change for different subtargets so cache the result.
2381
2382 proc check_effective_target_vect_float { } {
2383     global et_vect_float_saved
2384
2385     if [info exists et_vect_float_saved] {
2386         verbose "check_effective_target_vect_float: using cached result" 2
2387     } else {
2388         set et_vect_float_saved 0
2389         if { [istarget i?86-*-*]
2390               || [istarget powerpc*-*-*]
2391               || [istarget spu-*-*]
2392               || [istarget mipsisa64*-*-*]
2393               || [istarget x86_64-*-*]
2394               || [istarget ia64-*-*]
2395               || [check_effective_target_arm32] } {
2396            set et_vect_float_saved 1
2397         }
2398     }
2399
2400     verbose "check_effective_target_vect_float: returning $et_vect_float_saved" 2
2401     return $et_vect_float_saved
2402 }
2403
2404 # Return 1 if the target supports hardware vectors of double, 0 otherwise.
2405 #
2406 # This won't change for different subtargets so cache the result.
2407
2408 proc check_effective_target_vect_double { } {
2409     global et_vect_double_saved
2410
2411     if [info exists et_vect_double_saved] {
2412         verbose "check_effective_target_vect_double: using cached result" 2
2413     } else {
2414         set et_vect_double_saved 0
2415         if { [istarget i?86-*-*]
2416               || [istarget x86_64-*-*] } {
2417            if { [check_no_compiler_messages vect_double assembly {
2418                  #ifdef __tune_atom__
2419                  # error No double vectorizer support.
2420                  #endif
2421                 }] } {
2422                 set et_vect_double_saved 1
2423             } else {
2424                 set et_vect_double_saved 0
2425             }
2426         } elseif { [istarget spu-*-*] } {
2427            set et_vect_double_saved 1
2428         }
2429     }
2430
2431     verbose "check_effective_target_vect_double: returning $et_vect_double_saved" 2
2432     return $et_vect_double_saved
2433 }
2434
2435 # Return 1 if the target supports hardware vectors of long long, 0 otherwise.
2436 #
2437 # This won't change for different subtargets so cache the result.
2438
2439 proc check_effective_target_vect_long_long { } {
2440     global et_vect_long_long_saved
2441
2442     if [info exists et_vect_long_long_saved] {
2443         verbose "check_effective_target_vect_long_long: using cached result" 2
2444     } else {
2445         set et_vect_long_long_saved 0
2446         if { [istarget i?86-*-*]
2447               || [istarget x86_64-*-*] } {
2448            set et_vect_long_long_saved 1
2449         }
2450     }
2451
2452     verbose "check_effective_target_vect_long_long: returning $et_vect_long_long_saved" 2
2453     return $et_vect_long_long_saved
2454 }
2455
2456
2457 # Return 1 if the target plus current options does not support a vector
2458 # max instruction on "int", 0 otherwise.
2459 #
2460 # This won't change for different subtargets so cache the result.
2461
2462 proc check_effective_target_vect_no_int_max { } {
2463     global et_vect_no_int_max_saved
2464
2465     if [info exists et_vect_no_int_max_saved] {
2466         verbose "check_effective_target_vect_no_int_max: using cached result" 2
2467     } else {
2468         set et_vect_no_int_max_saved 0
2469         if { [istarget sparc*-*-*]
2470              || [istarget spu-*-*]
2471              || [istarget alpha*-*-*]
2472              || ([istarget mips*-*-*]
2473                  && [check_effective_target_mips_loongson]) } {
2474             set et_vect_no_int_max_saved 1
2475         }
2476     }
2477     verbose "check_effective_target_vect_no_int_max: returning $et_vect_no_int_max_saved" 2
2478     return $et_vect_no_int_max_saved
2479 }
2480
2481 # Return 1 if the target plus current options does not support a vector
2482 # add instruction on "int", 0 otherwise.
2483 #
2484 # This won't change for different subtargets so cache the result.
2485
2486 proc check_effective_target_vect_no_int_add { } {
2487     global et_vect_no_int_add_saved
2488
2489     if [info exists et_vect_no_int_add_saved] {
2490         verbose "check_effective_target_vect_no_int_add: using cached result" 2
2491     } else {
2492         set et_vect_no_int_add_saved 0
2493         # Alpha only supports vector add on V8QI and V4HI.
2494         if { [istarget alpha*-*-*] } {
2495             set et_vect_no_int_add_saved 1
2496         }
2497     }
2498     verbose "check_effective_target_vect_no_int_add: returning $et_vect_no_int_add_saved" 2
2499     return $et_vect_no_int_add_saved
2500 }
2501
2502 # Return 1 if the target plus current options does not support vector
2503 # bitwise instructions, 0 otherwise.
2504 #
2505 # This won't change for different subtargets so cache the result.
2506
2507 proc check_effective_target_vect_no_bitwise { } {
2508     global et_vect_no_bitwise_saved
2509
2510     if [info exists et_vect_no_bitwise_saved] {
2511         verbose "check_effective_target_vect_no_bitwise: using cached result" 2
2512     } else {
2513         set et_vect_no_bitwise_saved 0
2514     }
2515     verbose "check_effective_target_vect_no_bitwise: returning $et_vect_no_bitwise_saved" 2
2516     return $et_vect_no_bitwise_saved
2517 }
2518
2519 # Return 1 if the target plus current options supports vector permutation,
2520 # 0 otherwise.
2521 #
2522 # This won't change for different subtargets so cache the result.
2523
2524 proc check_effective_target_vect_perm { } {
2525     global et_vect_perm
2526
2527     if [info exists et_vect_perm_saved] {
2528         verbose "check_effective_target_vect_perm: using cached result" 2
2529     } else {
2530         set et_vect_perm_saved 0
2531         if { [istarget powerpc*-*-*]
2532              || [istarget spu-*-*]
2533              || [istarget i?86-*-*]
2534              || [istarget x86_64-*-*] } {
2535             set et_vect_perm_saved 1
2536         }
2537     }
2538     verbose "check_effective_target_vect_perm: returning $et_vect_perm_saved" 2
2539     return $et_vect_perm_saved
2540 }
2541
2542 # Return 1 if the target plus current options supports vector permutation
2543 # on byte-sized elements, 0 otherwise.
2544 #
2545 # This won't change for different subtargets so cache the result.
2546
2547 proc check_effective_target_vect_perm_byte { } {
2548     global et_vect_perm_byte
2549
2550     if [info exists et_vect_perm_byte_saved] {
2551         verbose "check_effective_target_vect_perm_byte: using cached result" 2
2552     } else {
2553         set et_vect_perm_byte_saved 0
2554         if { [istarget powerpc*-*-*]
2555              || [istarget spu-*-*] } {
2556             set et_vect_perm_byte_saved 1
2557         }
2558     }
2559     verbose "check_effective_target_vect_perm_byte: returning $et_vect_perm_byte_saved" 2
2560     return $et_vect_perm_byte_saved
2561 }
2562
2563 # Return 1 if the target plus current options supports vector permutation
2564 # on short-sized elements, 0 otherwise.
2565 #
2566 # This won't change for different subtargets so cache the result.
2567
2568 proc check_effective_target_vect_perm_short { } {
2569     global et_vect_perm_short
2570
2571     if [info exists et_vect_perm_short_saved] {
2572         verbose "check_effective_target_vect_perm_short: using cached result" 2
2573     } else {
2574         set et_vect_perm_short_saved 0
2575         if { [istarget powerpc*-*-*]
2576              || [istarget spu-*-*] } {
2577             set et_vect_perm_short_saved 1
2578         }
2579     }
2580     verbose "check_effective_target_vect_perm_short: returning $et_vect_perm_short_saved" 2
2581     return $et_vect_perm_short_saved
2582 }
2583
2584 # Return 1 if the target plus current options supports a vector
2585 # widening summation of *short* args into *int* result, 0 otherwise.
2586 #
2587 # This won't change for different subtargets so cache the result.
2588
2589 proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
2590     global et_vect_widen_sum_hi_to_si_pattern
2591
2592     if [info exists et_vect_widen_sum_hi_to_si_pattern_saved] {
2593         verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: using cached result" 2
2594     } else {
2595         set et_vect_widen_sum_hi_to_si_pattern_saved 0
2596         if { [istarget powerpc*-*-*]
2597              || [istarget ia64-*-*] } {
2598             set et_vect_widen_sum_hi_to_si_pattern_saved 1
2599         }
2600     }
2601     verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: returning $et_vect_widen_sum_hi_to_si_pattern_saved" 2
2602     return $et_vect_widen_sum_hi_to_si_pattern_saved
2603 }
2604
2605 # Return 1 if the target plus current options supports a vector
2606 # widening summation of *short* args into *int* result, 0 otherwise.
2607 # A target can also support this widening summation if it can support
2608 # promotion (unpacking) from shorts to ints.
2609 #
2610 # This won't change for different subtargets so cache the result.
2611                                                                                                 
2612 proc check_effective_target_vect_widen_sum_hi_to_si { } {
2613     global et_vect_widen_sum_hi_to_si
2614
2615     if [info exists et_vect_widen_sum_hi_to_si_saved] {
2616         verbose "check_effective_target_vect_widen_sum_hi_to_si: using cached result" 2
2617     } else {
2618         set et_vect_widen_sum_hi_to_si_saved [check_effective_target_vect_unpack]
2619         if { [istarget powerpc*-*-*] 
2620              || [istarget ia64-*-*] } {
2621             set et_vect_widen_sum_hi_to_si_saved 1
2622         }
2623     }
2624     verbose "check_effective_target_vect_widen_sum_hi_to_si: returning $et_vect_widen_sum_hi_to_si_saved" 2
2625     return $et_vect_widen_sum_hi_to_si_saved
2626 }
2627
2628 # Return 1 if the target plus current options supports a vector
2629 # widening summation of *char* args into *short* result, 0 otherwise.
2630 # A target can also support this widening summation if it can support
2631 # promotion (unpacking) from chars to shorts.
2632 #
2633 # This won't change for different subtargets so cache the result.
2634                                                                                                 
2635 proc check_effective_target_vect_widen_sum_qi_to_hi { } {
2636     global et_vect_widen_sum_qi_to_hi
2637
2638     if [info exists et_vect_widen_sum_qi_to_hi_saved] {
2639         verbose "check_effective_target_vect_widen_sum_qi_to_hi: using cached result" 2
2640     } else {
2641         set et_vect_widen_sum_qi_to_hi_saved 0
2642         if { [check_effective_target_vect_unpack] 
2643              || [istarget ia64-*-*] } {
2644             set et_vect_widen_sum_qi_to_hi_saved 1
2645         }
2646     }
2647     verbose "check_effective_target_vect_widen_sum_qi_to_hi: returning $et_vect_widen_sum_qi_to_hi_saved" 2
2648     return $et_vect_widen_sum_qi_to_hi_saved
2649 }
2650
2651 # Return 1 if the target plus current options supports a vector
2652 # widening summation of *char* args into *int* result, 0 otherwise.
2653 #
2654 # This won't change for different subtargets so cache the result.
2655                                                                                                 
2656 proc check_effective_target_vect_widen_sum_qi_to_si { } {
2657     global et_vect_widen_sum_qi_to_si
2658
2659     if [info exists et_vect_widen_sum_qi_to_si_saved] {
2660         verbose "check_effective_target_vect_widen_sum_qi_to_si: using cached result" 2
2661     } else {
2662         set et_vect_widen_sum_qi_to_si_saved 0
2663         if { [istarget powerpc*-*-*] } {
2664             set et_vect_widen_sum_qi_to_si_saved 1
2665         }
2666     }
2667     verbose "check_effective_target_vect_widen_sum_qi_to_si: returning $et_vect_widen_sum_qi_to_si_saved" 2
2668     return $et_vect_widen_sum_qi_to_si_saved
2669 }
2670
2671 # Return 1 if the target plus current options supports a vector
2672 # widening multiplication of *char* args into *short* result, 0 otherwise.
2673 # A target can also support this widening multplication if it can support
2674 # promotion (unpacking) from chars to shorts, and vect_short_mult (non-widening
2675 # multiplication of shorts).
2676 #
2677 # This won't change for different subtargets so cache the result.
2678
2679
2680 proc check_effective_target_vect_widen_mult_qi_to_hi { } {
2681     global et_vect_widen_mult_qi_to_hi
2682
2683     if [info exists et_vect_widen_mult_qi_to_hi_saved] {
2684         verbose "check_effective_target_vect_widen_mult_qi_to_hi: using cached result" 2
2685     } else {
2686         if { [check_effective_target_vect_unpack]
2687              && [check_effective_target_vect_short_mult] } {
2688             set et_vect_widen_mult_qi_to_hi_saved 1
2689         } else {
2690             set et_vect_widen_mult_qi_to_hi_saved 0
2691         }
2692         if { [istarget powerpc*-*-*]
2693               || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2694             set et_vect_widen_mult_qi_to_hi_saved 1
2695         }
2696     }
2697     verbose "check_effective_target_vect_widen_mult_qi_to_hi: returning $et_vect_widen_mult_qi_to_hi_saved" 2
2698     return $et_vect_widen_mult_qi_to_hi_saved
2699 }
2700
2701 # Return 1 if the target plus current options supports a vector
2702 # widening multiplication of *short* args into *int* result, 0 otherwise.
2703 # A target can also support this widening multplication if it can support
2704 # promotion (unpacking) from shorts to ints, and vect_int_mult (non-widening
2705 # multiplication of ints).
2706 #
2707 # This won't change for different subtargets so cache the result.
2708
2709
2710 proc check_effective_target_vect_widen_mult_hi_to_si { } {
2711     global et_vect_widen_mult_hi_to_si
2712
2713     if [info exists et_vect_widen_mult_hi_to_si_saved] {
2714         verbose "check_effective_target_vect_widen_mult_hi_to_si: using cached result" 2
2715     } else {
2716         if { [check_effective_target_vect_unpack]
2717              && [check_effective_target_vect_int_mult] } {
2718           set et_vect_widen_mult_hi_to_si_saved 1
2719         } else {
2720           set et_vect_widen_mult_hi_to_si_saved 0
2721         }
2722         if { [istarget powerpc*-*-*]
2723               || [istarget spu-*-*]
2724               || [istarget ia64-*-*]
2725               || [istarget i?86-*-*]
2726               || [istarget x86_64-*-*]
2727               || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2728             set et_vect_widen_mult_hi_to_si_saved 1
2729         }
2730     }
2731     verbose "check_effective_target_vect_widen_mult_hi_to_si: returning $et_vect_widen_mult_hi_to_si_saved" 2
2732     return $et_vect_widen_mult_hi_to_si_saved
2733 }
2734
2735 # Return 1 if the target plus current options supports a vector
2736 # widening multiplication of *char* args into *short* result, 0 otherwise.
2737 #
2738 # This won't change for different subtargets so cache the result.
2739
2740 proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
2741     global et_vect_widen_mult_qi_to_hi_pattern
2742
2743     if [info exists et_vect_widen_mult_qi_to_hi_pattern_saved] {
2744         verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: using cached result" 2
2745     } else {
2746         set et_vect_widen_mult_qi_to_hi_pattern_saved 0
2747         if { [istarget powerpc*-*-*]
2748               || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2749             set et_vect_widen_mult_qi_to_hi_pattern_saved 1
2750         }
2751     }
2752     verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: returning $et_vect_widen_mult_qi_to_hi_pattern_saved" 2
2753     return $et_vect_widen_mult_qi_to_hi_pattern_saved
2754 }
2755
2756 # Return 1 if the target plus current options supports a vector
2757 # widening multiplication of *short* args into *int* result, 0 otherwise.
2758 #
2759 # This won't change for different subtargets so cache the result.
2760
2761 proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
2762     global et_vect_widen_mult_hi_to_si_pattern
2763
2764     if [info exists et_vect_widen_mult_hi_to_si_pattern_saved] {
2765         verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: using cached result" 2
2766     } else {
2767         set et_vect_widen_mult_hi_to_si_pattern_saved 0
2768         if { [istarget powerpc*-*-*]
2769               || [istarget spu-*-*]
2770               || [istarget ia64-*-*]
2771               || [istarget i?86-*-*]
2772               || [istarget x86_64-*-*]
2773               || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2774             set et_vect_widen_mult_hi_to_si_pattern_saved 1
2775         }
2776     }
2777     verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: returning $et_vect_widen_mult_hi_to_si_pattern_saved" 2
2778     return $et_vect_widen_mult_hi_to_si_pattern_saved
2779 }
2780
2781 # Return 1 if the target plus current options supports a vector
2782 # dot-product of signed chars, 0 otherwise.
2783 #
2784 # This won't change for different subtargets so cache the result.
2785
2786 proc check_effective_target_vect_sdot_qi { } {
2787     global et_vect_sdot_qi
2788
2789     if [info exists et_vect_sdot_qi_saved] {
2790         verbose "check_effective_target_vect_sdot_qi: using cached result" 2
2791     } else {
2792         set et_vect_sdot_qi_saved 0
2793         if { [istarget ia64-*-*] } {
2794             set et_vect_udot_qi_saved 1
2795         }
2796     }
2797     verbose "check_effective_target_vect_sdot_qi: returning $et_vect_sdot_qi_saved" 2
2798     return $et_vect_sdot_qi_saved
2799 }
2800
2801 # Return 1 if the target plus current options supports a vector
2802 # dot-product of unsigned chars, 0 otherwise.
2803 #
2804 # This won't change for different subtargets so cache the result.
2805
2806 proc check_effective_target_vect_udot_qi { } {
2807     global et_vect_udot_qi
2808
2809     if [info exists et_vect_udot_qi_saved] {
2810         verbose "check_effective_target_vect_udot_qi: using cached result" 2
2811     } else {
2812         set et_vect_udot_qi_saved 0
2813         if { [istarget powerpc*-*-*]
2814              || [istarget ia64-*-*] } {
2815             set et_vect_udot_qi_saved 1
2816         }
2817     }
2818     verbose "check_effective_target_vect_udot_qi: returning $et_vect_udot_qi_saved" 2
2819     return $et_vect_udot_qi_saved
2820 }
2821
2822 # Return 1 if the target plus current options supports a vector
2823 # dot-product of signed shorts, 0 otherwise.
2824 #
2825 # This won't change for different subtargets so cache the result.
2826
2827 proc check_effective_target_vect_sdot_hi { } {
2828     global et_vect_sdot_hi
2829
2830     if [info exists et_vect_sdot_hi_saved] {
2831         verbose "check_effective_target_vect_sdot_hi: using cached result" 2
2832     } else {
2833         set et_vect_sdot_hi_saved 0
2834         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
2835              || [istarget ia64-*-*]
2836              || [istarget i?86-*-*]
2837              || [istarget x86_64-*-*] } {
2838             set et_vect_sdot_hi_saved 1
2839         }
2840     }
2841     verbose "check_effective_target_vect_sdot_hi: returning $et_vect_sdot_hi_saved" 2
2842     return $et_vect_sdot_hi_saved
2843 }
2844
2845 # Return 1 if the target plus current options supports a vector
2846 # dot-product of unsigned shorts, 0 otherwise.
2847 #
2848 # This won't change for different subtargets so cache the result.
2849
2850 proc check_effective_target_vect_udot_hi { } {
2851     global et_vect_udot_hi
2852
2853     if [info exists et_vect_udot_hi_saved] {
2854         verbose "check_effective_target_vect_udot_hi: using cached result" 2
2855     } else {
2856         set et_vect_udot_hi_saved 0
2857         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) } {
2858             set et_vect_udot_hi_saved 1
2859         }
2860     }
2861     verbose "check_effective_target_vect_udot_hi: returning $et_vect_udot_hi_saved" 2
2862     return $et_vect_udot_hi_saved
2863 }
2864
2865
2866 # Return 1 if the target plus current options supports a vector
2867 # demotion (packing) of shorts (to chars) and ints (to shorts) 
2868 # using modulo arithmetic, 0 otherwise.
2869 #
2870 # This won't change for different subtargets so cache the result.
2871                                                                                 
2872 proc check_effective_target_vect_pack_trunc { } {
2873     global et_vect_pack_trunc
2874                                                                                 
2875     if [info exists et_vect_pack_trunc_saved] {
2876         verbose "check_effective_target_vect_pack_trunc: using cached result" 2
2877     } else {
2878         set et_vect_pack_trunc_saved 0
2879         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
2880              || [istarget i?86-*-*]
2881              || [istarget x86_64-*-*]
2882              || [istarget spu-*-*]
2883              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2884             set et_vect_pack_trunc_saved 1
2885         }
2886     }
2887     verbose "check_effective_target_vect_pack_trunc: returning $et_vect_pack_trunc_saved" 2
2888     return $et_vect_pack_trunc_saved
2889 }
2890
2891 # Return 1 if the target plus current options supports a vector
2892 # promotion (unpacking) of chars (to shorts) and shorts (to ints), 0 otherwise.
2893 #
2894 # This won't change for different subtargets so cache the result.
2895                                    
2896 proc check_effective_target_vect_unpack { } {
2897     global et_vect_unpack
2898                                         
2899     if [info exists et_vect_unpack_saved] {
2900         verbose "check_effective_target_vect_unpack: using cached result" 2
2901     } else {
2902         set et_vect_unpack_saved 0
2903         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
2904              || [istarget i?86-*-*]
2905              || [istarget x86_64-*-*] 
2906              || [istarget spu-*-*]
2907              || [istarget ia64-*-*]
2908              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2909             set et_vect_unpack_saved 1
2910         }
2911     }
2912     verbose "check_effective_target_vect_unpack: returning $et_vect_unpack_saved" 2  
2913     return $et_vect_unpack_saved
2914 }
2915
2916 # Return 1 if the target plus current options does not guarantee
2917 # that its STACK_BOUNDARY is >= the reguired vector alignment.
2918 #
2919 # This won't change for different subtargets so cache the result.
2920
2921 proc check_effective_target_unaligned_stack { } {
2922     global et_unaligned_stack_saved
2923
2924     if [info exists et_unaligned_stack_saved] {
2925         verbose "check_effective_target_unaligned_stack: using cached result" 2
2926     } else {
2927         set et_unaligned_stack_saved 0
2928     }
2929     verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2
2930     return $et_unaligned_stack_saved
2931 }
2932
2933 # Return 1 if the target plus current options does not support a vector
2934 # alignment mechanism, 0 otherwise.
2935 #
2936 # This won't change for different subtargets so cache the result.
2937
2938 proc check_effective_target_vect_no_align { } {
2939     global et_vect_no_align_saved
2940
2941     if [info exists et_vect_no_align_saved] {
2942         verbose "check_effective_target_vect_no_align: using cached result" 2
2943     } else {
2944         set et_vect_no_align_saved 0
2945         if { [istarget mipsisa64*-*-*]
2946              || [istarget sparc*-*-*]
2947              || [istarget ia64-*-*]
2948              || [check_effective_target_arm_vect_no_misalign]
2949              || ([istarget mips*-*-*]
2950                  && [check_effective_target_mips_loongson]) } {
2951             set et_vect_no_align_saved 1
2952         }
2953     }
2954     verbose "check_effective_target_vect_no_align: returning $et_vect_no_align_saved" 2
2955     return $et_vect_no_align_saved
2956 }
2957
2958 # Return 1 if the target supports a vector misalign access, 0 otherwise.
2959 #
2960 # This won't change for different subtargets so cache the result.
2961
2962 proc check_effective_target_vect_hw_misalign { } {
2963     global et_vect_hw_misalign_saved
2964
2965     if [info exists et_vect_hw_misalign_saved] {
2966         verbose "check_effective_target_vect_hw_misalign: using cached result" 2
2967     } else {
2968         set et_vect_hw_misalign_saved 0
2969        if { ([istarget x86_64-*-*] 
2970             || [istarget i?86-*-*]) } {
2971           set et_vect_hw_misalign_saved 1
2972        }
2973     }
2974     verbose "check_effective_target_vect_hw_misalign: returning $et_vect_hw_misalign_saved" 2
2975     return $et_vect_hw_misalign_saved
2976 }
2977
2978
2979 # Return 1 if arrays are aligned to the vector alignment
2980 # boundary, 0 otherwise.
2981 #
2982 # This won't change for different subtargets so cache the result.
2983
2984 proc check_effective_target_vect_aligned_arrays { } {
2985     global et_vect_aligned_arrays
2986
2987     if [info exists et_vect_aligned_arrays_saved] {
2988         verbose "check_effective_target_vect_aligned_arrays: using cached result" 2
2989     } else {
2990         set et_vect_aligned_arrays_saved 0
2991         if { (([istarget x86_64-*-*]
2992               || [istarget i?86-*-*]) && [is-effective-target lp64])
2993               || [istarget spu-*-*] } {
2994             set et_vect_aligned_arrays_saved 1
2995         }
2996     }
2997     verbose "check_effective_target_vect_aligned_arrays: returning $et_vect_aligned_arrays_saved" 2
2998     return $et_vect_aligned_arrays_saved
2999 }
3000
3001 # Return 1 if types of size 32 bit or less are naturally aligned
3002 # (aligned to their type-size), 0 otherwise.
3003 #
3004 # This won't change for different subtargets so cache the result.
3005
3006 proc check_effective_target_natural_alignment_32 { } {
3007     global et_natural_alignment_32
3008
3009     if [info exists et_natural_alignment_32_saved] {
3010         verbose "check_effective_target_natural_alignment_32: using cached result" 2
3011     } else {
3012         # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
3013         set et_natural_alignment_32_saved 1
3014         if { ([istarget *-*-darwin*] && [is-effective-target lp64]) } {
3015             set et_natural_alignment_32_saved 0
3016         }
3017     }
3018     verbose "check_effective_target_natural_alignment_32: returning $et_natural_alignment_32_saved" 2
3019     return $et_natural_alignment_32_saved
3020 }
3021
3022 # Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
3023 # type-size), 0 otherwise.
3024 #
3025 # This won't change for different subtargets so cache the result.
3026
3027 proc check_effective_target_natural_alignment_64 { } {
3028     global et_natural_alignment_64
3029
3030     if [info exists et_natural_alignment_64_saved] {
3031         verbose "check_effective_target_natural_alignment_64: using cached result" 2
3032     } else {
3033         set et_natural_alignment_64_saved 0
3034         if { ([is-effective-target lp64] && ![istarget *-*-darwin*])
3035              || [istarget spu-*-*] } {
3036             set et_natural_alignment_64_saved 1
3037         }
3038     }
3039     verbose "check_effective_target_natural_alignment_64: returning $et_natural_alignment_64_saved" 2
3040     return $et_natural_alignment_64_saved
3041 }
3042
3043 # Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise.
3044 #
3045 # This won't change for different subtargets so cache the result.
3046
3047 proc check_effective_target_vector_alignment_reachable { } {
3048     global et_vector_alignment_reachable
3049
3050     if [info exists et_vector_alignment_reachable_saved] {
3051         verbose "check_effective_target_vector_alignment_reachable: using cached result" 2
3052     } else {
3053         if { [check_effective_target_vect_aligned_arrays]
3054              || [check_effective_target_natural_alignment_32] } {
3055             set et_vector_alignment_reachable_saved 1
3056         } else {
3057             set et_vector_alignment_reachable_saved 0
3058         }
3059     }
3060     verbose "check_effective_target_vector_alignment_reachable: returning $et_vector_alignment_reachable_saved" 2
3061     return $et_vector_alignment_reachable_saved
3062 }
3063
3064 # Return 1 if vector alignment for 64 bit is reachable, 0 otherwise.
3065 #
3066 # This won't change for different subtargets so cache the result.
3067
3068 proc check_effective_target_vector_alignment_reachable_for_64bit { } {
3069     global et_vector_alignment_reachable_for_64bit
3070
3071     if [info exists et_vector_alignment_reachable_for_64bit_saved] {
3072         verbose "check_effective_target_vector_alignment_reachable_for_64bit: using cached result" 2
3073     } else {
3074         if { [check_effective_target_vect_aligned_arrays] 
3075              || [check_effective_target_natural_alignment_64] } {
3076             set et_vector_alignment_reachable_for_64bit_saved 1
3077         } else {
3078             set et_vector_alignment_reachable_for_64bit_saved 0
3079         }
3080     }
3081     verbose "check_effective_target_vector_alignment_reachable_for_64bit: returning $et_vector_alignment_reachable_for_64bit_saved" 2
3082     return $et_vector_alignment_reachable_for_64bit_saved
3083 }
3084
3085 # Return 1 if the target only requires element alignment for vector accesses
3086
3087 proc check_effective_target_vect_element_align { } {
3088     global et_vect_element_align
3089
3090     if [info exists et_vect_element_align] {
3091         verbose "check_effective_target_vect_element_align: using cached result" 2
3092     } else {
3093         set et_vect_element_align 0
3094         if { [istarget arm*-*-*]
3095              || [check_effective_target_vect_hw_misalign] } {
3096            set et_vect_element_align 1
3097         }
3098     }
3099
3100     verbose "check_effective_target_vect_element_align: returning $et_vect_element_align" 2
3101     return $et_vect_element_align
3102 }
3103
3104 # Return 1 if the target supports vector conditional operations, 0 otherwise.
3105
3106 proc check_effective_target_vect_condition { } {
3107     global et_vect_cond_saved
3108
3109     if [info exists et_vect_cond_saved] {
3110         verbose "check_effective_target_vect_cond: using cached result" 2
3111     } else {
3112         set et_vect_cond_saved 0
3113         if { [istarget powerpc*-*-*]
3114              || [istarget ia64-*-*]
3115              || [istarget i?86-*-*]
3116              || [istarget spu-*-*]
3117              || [istarget x86_64-*-*] } {
3118            set et_vect_cond_saved 1
3119         }
3120     }
3121
3122     verbose "check_effective_target_vect_cond: returning $et_vect_cond_saved" 2
3123     return $et_vect_cond_saved
3124 }
3125
3126 # Return 1 if the target supports vector char multiplication, 0 otherwise.
3127
3128 proc check_effective_target_vect_char_mult { } {
3129     global et_vect_char_mult_saved
3130
3131     if [info exists et_vect_char_mult_saved] {
3132         verbose "check_effective_target_vect_char_mult: using cached result" 2
3133     } else {
3134         set et_vect_char_mult_saved 0
3135         if { [istarget ia64-*-*]
3136              || [istarget i?86-*-*]
3137              || [istarget x86_64-*-*] } {
3138            set et_vect_char_mult_saved 1
3139         }
3140     }
3141
3142     verbose "check_effective_target_vect_char_mult: returning $et_vect_char_mult_saved" 2
3143     return $et_vect_char_mult_saved
3144 }
3145
3146 # Return 1 if the target supports vector short multiplication, 0 otherwise.
3147
3148 proc check_effective_target_vect_short_mult { } {
3149     global et_vect_short_mult_saved
3150
3151     if [info exists et_vect_short_mult_saved] {
3152         verbose "check_effective_target_vect_short_mult: using cached result" 2
3153     } else {
3154         set et_vect_short_mult_saved 0
3155         if { [istarget ia64-*-*]
3156              || [istarget spu-*-*]
3157              || [istarget i?86-*-*]
3158              || [istarget x86_64-*-*]
3159              || [istarget powerpc*-*-*]
3160              || [check_effective_target_arm32]
3161              || ([istarget mips*-*-*]
3162                  && [check_effective_target_mips_loongson]) } {
3163            set et_vect_short_mult_saved 1
3164         }
3165     }
3166
3167     verbose "check_effective_target_vect_short_mult: returning $et_vect_short_mult_saved" 2
3168     return $et_vect_short_mult_saved
3169 }
3170
3171 # Return 1 if the target supports vector int multiplication, 0 otherwise.
3172
3173 proc check_effective_target_vect_int_mult { } {
3174     global et_vect_int_mult_saved
3175
3176     if [info exists et_vect_int_mult_saved] {
3177         verbose "check_effective_target_vect_int_mult: using cached result" 2
3178     } else {
3179         set et_vect_int_mult_saved 0
3180         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
3181              || [istarget spu-*-*]
3182              || [istarget i?86-*-*]
3183              || [istarget x86_64-*-*]
3184              || [istarget ia64-*-*]
3185              || [check_effective_target_arm32] } {
3186            set et_vect_int_mult_saved 1
3187         }
3188     }
3189
3190     verbose "check_effective_target_vect_int_mult: returning $et_vect_int_mult_saved" 2
3191     return $et_vect_int_mult_saved
3192 }
3193
3194 # Return 1 if the target supports vector even/odd elements extraction, 0 otherwise.
3195
3196 proc check_effective_target_vect_extract_even_odd { } {
3197     global et_vect_extract_even_odd_saved
3198     
3199     if [info exists et_vect_extract_even_odd_saved] {
3200         verbose "check_effective_target_vect_extract_even_odd: using cached result" 2
3201     } else {
3202         set et_vect_extract_even_odd_saved 0 
3203         if { [istarget powerpc*-*-*] 
3204              || [istarget i?86-*-*]
3205              || [istarget x86_64-*-*]
3206              || [istarget ia64-*-*]
3207              || [istarget spu-*-*] } {
3208            set et_vect_extract_even_odd_saved 1
3209         }
3210     }
3211
3212     verbose "check_effective_target_vect_extract_even_odd: returning $et_vect_extract_even_odd_saved" 2
3213     return $et_vect_extract_even_odd_saved
3214 }
3215
3216 # Return 1 if the target supports vector interleaving, 0 otherwise.
3217
3218 proc check_effective_target_vect_interleave { } {
3219     global et_vect_interleave_saved
3220     
3221     if [info exists et_vect_interleave_saved] {
3222         verbose "check_effective_target_vect_interleave: using cached result" 2
3223     } else {
3224         set et_vect_interleave_saved 0
3225         if { [istarget powerpc*-*-*]
3226              || [istarget i?86-*-*]
3227              || [istarget x86_64-*-*]
3228              || [istarget ia64-*-*]
3229              || [istarget spu-*-*] } {
3230            set et_vect_interleave_saved 1
3231         }
3232     }
3233
3234     verbose "check_effective_target_vect_interleave: returning $et_vect_interleave_saved" 2
3235     return $et_vect_interleave_saved
3236 }
3237
3238 foreach N {2 3 4 8} {
3239     eval [string map [list N $N] {
3240         # Return 1 if the target supports 2-vector interleaving
3241         proc check_effective_target_vect_stridedN { } {
3242             global et_vect_stridedN_saved
3243
3244             if [info exists et_vect_stridedN_saved] {
3245                 verbose "check_effective_target_vect_stridedN: using cached result" 2
3246             } else {
3247                 set et_vect_stridedN_saved 0
3248                 if { (N & -N) == N
3249                      && [check_effective_target_vect_interleave]
3250                      && [check_effective_target_vect_extract_even_odd] } {
3251                     set et_vect_stridedN_saved 1
3252                 }
3253                 if { [istarget arm*-*-*] && N >= 2 && N <= 4 } {
3254                     set et_vect_stridedN_saved 1
3255                 }
3256             }
3257
3258             verbose "check_effective_target_vect_stridedN: returning $et_vect_stridedN_saved" 2
3259             return $et_vect_stridedN_saved
3260         }
3261     }]
3262 }
3263
3264 # Return 1 if the target supports section-anchors
3265
3266 proc check_effective_target_section_anchors { } {
3267     global et_section_anchors_saved
3268
3269     if [info exists et_section_anchors_saved] {
3270         verbose "check_effective_target_section_anchors: using cached result" 2
3271     } else {
3272         set et_section_anchors_saved 0
3273         if { [istarget powerpc*-*-*]
3274               || [istarget arm*-*-*] } {
3275            set et_section_anchors_saved 1
3276         }
3277     }
3278
3279     verbose "check_effective_target_section_anchors: returning $et_section_anchors_saved" 2
3280     return $et_section_anchors_saved
3281 }
3282
3283 # Return 1 if the target supports atomic operations on "int" and "long".
3284
3285 proc check_effective_target_sync_int_long { } {
3286     global et_sync_int_long_saved
3287
3288     if [info exists et_sync_int_long_saved] {
3289         verbose "check_effective_target_sync_int_long: using cached result" 2
3290     } else {
3291         set et_sync_int_long_saved 0
3292 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
3293 # load-reserved/store-conditional instructions.
3294         if { [istarget ia64-*-*]
3295              || [istarget i?86-*-*]
3296              || [istarget x86_64-*-*]
3297              || [istarget alpha*-*-*] 
3298              || [istarget arm*-*-linux-gnueabi] 
3299              || [istarget bfin*-*linux*]
3300              || [istarget hppa*-*linux*]
3301              || [istarget s390*-*-*] 
3302              || [istarget powerpc*-*-*]
3303              || [istarget sparc64-*-*]
3304              || [istarget sparcv9-*-*]
3305              || [istarget mips*-*-*] } {
3306            set et_sync_int_long_saved 1
3307         }
3308     }
3309
3310     verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
3311     return $et_sync_int_long_saved
3312 }
3313
3314 # Return 1 if the target supports atomic operations on "char" and "short".
3315
3316 proc check_effective_target_sync_char_short { } {
3317     global et_sync_char_short_saved
3318
3319     if [info exists et_sync_char_short_saved] {
3320         verbose "check_effective_target_sync_char_short: using cached result" 2
3321     } else {
3322         set et_sync_char_short_saved 0
3323 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
3324 # load-reserved/store-conditional instructions.
3325         if { [istarget ia64-*-*]
3326              || [istarget i?86-*-*]
3327              || [istarget x86_64-*-*]
3328              || [istarget alpha*-*-*] 
3329              || [istarget arm*-*-linux-gnueabi] 
3330              || [istarget hppa*-*linux*]
3331              || [istarget s390*-*-*] 
3332              || [istarget powerpc*-*-*]
3333              || [istarget sparc64-*-*]
3334              || [istarget sparcv9-*-*]
3335              || [istarget mips*-*-*] } {
3336            set et_sync_char_short_saved 1
3337         }
3338     }
3339
3340     verbose "check_effective_target_sync_char_short: returning $et_sync_char_short_saved" 2
3341     return $et_sync_char_short_saved
3342 }
3343
3344 # Return 1 if the target uses a ColdFire FPU.
3345
3346 proc check_effective_target_coldfire_fpu { } {
3347     return [check_no_compiler_messages coldfire_fpu assembly {
3348         #ifndef __mcffpu__
3349         #error FOO
3350         #endif
3351     }]
3352 }
3353
3354 # Return true if this is a uClibc target.
3355
3356 proc check_effective_target_uclibc {} {
3357     return [check_no_compiler_messages uclibc object {
3358         #include <features.h>
3359         #if !defined (__UCLIBC__)
3360         #error FOO
3361         #endif
3362     }]
3363 }
3364
3365 # Return true if this is a uclibc target and if the uclibc feature
3366 # described by __$feature__ is not present.
3367
3368 proc check_missing_uclibc_feature {feature} {
3369     return [check_no_compiler_messages $feature object "
3370         #include <features.h>
3371         #if !defined (__UCLIBC) || defined (__${feature}__)
3372         #error FOO
3373         #endif
3374     "]
3375 }
3376
3377 # Return true if this is a Newlib target.
3378
3379 proc check_effective_target_newlib {} {
3380     return [check_no_compiler_messages newlib object {
3381         #include <newlib.h>
3382     }]
3383 }
3384
3385 # Return 1 if
3386 #   (a) an error of a few ULP is expected in string to floating-point
3387 #       conversion functions; and
3388 #   (b) overflow is not always detected correctly by those functions.
3389
3390 proc check_effective_target_lax_strtofp {} {
3391     # By default, assume that all uClibc targets suffer from this.
3392     return [check_effective_target_uclibc]
3393 }
3394
3395 # Return 1 if this is a target for which wcsftime is a dummy
3396 # function that always returns 0.
3397
3398 proc check_effective_target_dummy_wcsftime {} {
3399     # By default, assume that all uClibc targets suffer from this.
3400     return [check_effective_target_uclibc]
3401 }
3402
3403 # Return 1 if constructors with initialization priority arguments are
3404 # supposed on this target.
3405
3406 proc check_effective_target_init_priority {} {
3407     return [check_no_compiler_messages init_priority assembly "
3408         void f() __attribute__((constructor (1000)));
3409         void f() \{\}
3410     "]
3411 }
3412
3413 # Return 1 if the target matches the effective target 'arg', 0 otherwise.
3414 # This can be used with any check_* proc that takes no argument and
3415 # returns only 1 or 0.  It could be used with check_* procs that take
3416 # arguments with keywords that pass particular arguments.
3417
3418 proc is-effective-target { arg } {
3419     set selected 0
3420     if { [info procs check_effective_target_${arg}] != [list] } {
3421         set selected [check_effective_target_${arg}]
3422     } else {
3423         switch $arg {
3424           "vmx_hw"         { set selected [check_vmx_hw_available] }
3425           "vsx_hw"         { set selected [check_vsx_hw_available] }
3426           "ppc_recip_hw"   { set selected [check_ppc_recip_hw_available] }
3427           "named_sections" { set selected [check_named_sections_available] }
3428           "gc_sections"    { set selected [check_gc_sections_available] }
3429           "cxa_atexit"     { set selected [check_cxa_atexit_available] }
3430           default          { error "unknown effective target keyword `$arg'" }
3431         }
3432     }
3433     verbose "is-effective-target: $arg $selected" 2
3434     return $selected
3435 }
3436
3437 # Return 1 if the argument is an effective-target keyword, 0 otherwise.
3438
3439 proc is-effective-target-keyword { arg } {
3440     if { [info procs check_effective_target_${arg}] != [list] } {
3441         return 1
3442     } else {
3443         # These have different names for their check_* procs.
3444         switch $arg {
3445           "vmx_hw"         { return 1 }
3446           "vsx_hw"         { return 1 }
3447           "ppc_recip_hw"   { return 1 }
3448           "named_sections" { return 1 }
3449           "gc_sections"    { return 1 }
3450           "cxa_atexit"     { return 1 }
3451           default          { return 0 }
3452         }
3453     }
3454 }
3455
3456 # Return 1 if target default to short enums
3457
3458 proc check_effective_target_short_enums { } {
3459     return [check_no_compiler_messages short_enums assembly {
3460         enum foo { bar };
3461         int s[sizeof (enum foo) == 1 ? 1 : -1];
3462     }]
3463 }
3464
3465 # Return 1 if target supports merging string constants at link time.
3466
3467 proc check_effective_target_string_merging { } {
3468     return [check_no_messages_and_pattern string_merging \
3469                 "rodata\\.str" assembly {
3470                     const char *var = "String";
3471                 } {-O2}]
3472 }
3473
3474 # Return 1 if target has the basic signed and unsigned types in
3475 # <stdint.h>, 0 otherwise.  This will be obsolete when GCC ensures a
3476 # working <stdint.h> for all targets.
3477
3478 proc check_effective_target_stdint_types { } {
3479     return [check_no_compiler_messages stdint_types assembly {
3480         #include <stdint.h>
3481         int8_t a; int16_t b; int32_t c; int64_t d;
3482         uint8_t e; uint16_t f; uint32_t g; uint64_t h;
3483     }]
3484 }
3485
3486 # Return 1 if target has the basic signed and unsigned types in
3487 # <inttypes.h>, 0 otherwise.  This is for tests that GCC's notions of
3488 # these types agree with those in the header, as some systems have
3489 # only <inttypes.h>.
3490
3491 proc check_effective_target_inttypes_types { } {
3492     return [check_no_compiler_messages inttypes_types assembly {
3493         #include <inttypes.h>
3494         int8_t a; int16_t b; int32_t c; int64_t d;
3495         uint8_t e; uint16_t f; uint32_t g; uint64_t h;
3496     }]
3497 }
3498
3499 # Return 1 if programs are intended to be run on a simulator
3500 # (i.e. slowly) rather than hardware (i.e. fast).
3501
3502 proc check_effective_target_simulator { } {
3503
3504     # All "src/sim" simulators set this one.
3505     if [board_info target exists is_simulator] {
3506         return [board_info target is_simulator]
3507     }
3508
3509     # The "sid" simulators don't set that one, but at least they set
3510     # this one.
3511     if [board_info target exists slow_simulator] {
3512         return [board_info target slow_simulator]
3513     }
3514
3515     return 0
3516 }
3517
3518 # Return 1 if the target is a VxWorks kernel.
3519
3520 proc check_effective_target_vxworks_kernel { } {
3521     return [check_no_compiler_messages vxworks_kernel assembly {
3522         #if !defined __vxworks || defined __RTP__
3523         #error NO
3524         #endif
3525     }]
3526 }
3527
3528 # Return 1 if the target is a VxWorks RTP.
3529
3530 proc check_effective_target_vxworks_rtp { } {
3531     return [check_no_compiler_messages vxworks_rtp assembly {
3532         #if !defined __vxworks || !defined __RTP__
3533         #error NO
3534         #endif
3535     }]
3536 }
3537
3538 # Return 1 if the target is expected to provide wide character support.
3539
3540 proc check_effective_target_wchar { } {
3541     if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} {
3542         return 0
3543     }
3544     return [check_no_compiler_messages wchar assembly {
3545         #include <wchar.h>
3546     }]
3547 }
3548
3549 # Return 1 if the target has <pthread.h>.
3550
3551 proc check_effective_target_pthread_h { } {
3552     return [check_no_compiler_messages pthread_h assembly {
3553         #include <pthread.h>
3554     }]
3555 }
3556
3557 # Return 1 if the target can truncate a file from a file-descriptor,
3558 # as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or
3559 # chsize.  We test for a trivially functional truncation; no stubs.
3560 # As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a
3561 # different function to be used.
3562
3563 proc check_effective_target_fd_truncate { } {
3564     set prog {
3565         #define _FILE_OFFSET_BITS 64
3566         #include <unistd.h>
3567         #include <stdio.h>
3568         #include <stdlib.h>
3569         int main ()
3570         {
3571           FILE *f = fopen ("tst.tmp", "wb");
3572           int fd;
3573           const char t[] = "test writing more than ten characters";
3574           char s[11];
3575           fd =  fileno (f);
3576           write (fd, t, sizeof (t) - 1);
3577           lseek (fd, 0, 0);
3578           if (ftruncate (fd, 10) != 0)
3579             exit (1);
3580           close (fd);
3581           f = fopen ("tst.tmp", "rb");
3582           if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0)
3583             exit (1);
3584           exit (0);
3585         }
3586     }
3587
3588     if { [check_runtime ftruncate $prog] } {
3589       return 1;
3590     }
3591
3592     regsub "ftruncate" $prog "chsize" prog
3593     return [check_runtime chsize $prog]
3594 }
3595
3596 # Add to FLAGS all the target-specific flags needed to access the c99 runtime.
3597
3598 proc add_options_for_c99_runtime { flags } {
3599     if { [istarget *-*-solaris2*] } {
3600         return "$flags -std=c99"
3601     }
3602     if { [istarget mips-sgi-irix6.5*] } {
3603         return "$flags -std=c99"
3604     }
3605     if { [istarget powerpc-*-darwin*] } {
3606         return "$flags -mmacosx-version-min=10.3"
3607     }
3608     return $flags
3609 }
3610
3611 # Add to FLAGS all the target-specific flags needed to enable
3612 # full IEEE compliance mode.
3613
3614 proc add_options_for_ieee { flags } {
3615     if { [istarget "alpha*-*-*"]
3616          || [istarget "sh*-*-*"] } {
3617        return "$flags -mieee"
3618     }
3619     if { [istarget "rx-*-*"] } {
3620        return "$flags -mnofpu"
3621     }
3622     return $flags
3623 }
3624
3625 # Add to FLAGS the flags needed to enable functions to bind locally
3626 # when using pic/PIC passes in the testsuite.
3627
3628 proc add_options_for_bind_pic_locally { flags } {
3629     if {[check_no_compiler_messages using_pic2 assembly {
3630         #if __PIC__ != 2
3631         #error FOO
3632         #endif
3633     }]} {
3634         return "$flags -fPIE"
3635     }
3636     if {[check_no_compiler_messages using_pic1 assembly {
3637         #if __PIC__ != 1
3638         #error FOO
3639         #endif
3640     }]} {
3641         return "$flags -fpie"
3642     }
3643
3644     return $flags
3645 }
3646
3647 # Add to FLAGS the flags needed to enable 128-bit vectors.
3648
3649 proc add_options_for_quad_vectors { flags } {
3650     if [is-effective-target arm_neon_ok] {
3651         return "$flags -mvectorize-with-neon-quad"
3652     }
3653
3654     return $flags
3655 }
3656
3657 # Return 1 if the target provides a full C99 runtime.
3658
3659 proc check_effective_target_c99_runtime { } {
3660     return [check_cached_effective_target c99_runtime {
3661         global srcdir
3662
3663         set file [open "$srcdir/gcc.dg/builtins-config.h"]
3664         set contents [read $file]
3665         close $file
3666         append contents {
3667             #ifndef HAVE_C99_RUNTIME
3668             #error FOO
3669             #endif
3670         }
3671         check_no_compiler_messages_nocache c99_runtime assembly \
3672             $contents [add_options_for_c99_runtime ""]
3673     }]
3674 }
3675
3676 # Return 1 if  target wchar_t is at least 4 bytes.
3677
3678 proc check_effective_target_4byte_wchar_t { } {
3679     return [check_no_compiler_messages 4byte_wchar_t object {
3680         int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1];
3681     }]
3682 }
3683
3684 # Return 1 if the target supports automatic stack alignment.
3685
3686 proc check_effective_target_automatic_stack_alignment  { } {
3687     # Ordinarily x86 supports automatic stack alignment ...
3688     if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
3689         if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
3690             # ... except Win64 SEH doesn't.  Succeed for Win32 though.
3691             return [check_effective_target_ilp32];
3692         }
3693         return 1;
3694     }
3695     return 0;
3696 }
3697
3698 # Return 1 if avx instructions can be compiled.
3699
3700 proc check_effective_target_avx { } {
3701     return [check_no_compiler_messages avx object {
3702         void _mm256_zeroall (void)
3703         {
3704            __builtin_ia32_vzeroall ();
3705         }
3706     } "-O2 -mavx" ]
3707 }
3708
3709 # Return 1 if sse instructions can be compiled.
3710 proc check_effective_target_sse { } {
3711     return [check_no_compiler_messages sse object {
3712         int main ()
3713         {
3714             __builtin_ia32_stmxcsr ();
3715             return 0;
3716         }
3717     } "-O2 -msse" ]
3718 }
3719
3720 # Return 1 if sse2 instructions can be compiled.
3721 proc check_effective_target_sse2 { } {
3722     return [check_no_compiler_messages sse2 object {
3723         typedef long long __m128i __attribute__ ((__vector_size__ (16)));
3724         
3725         __m128i _mm_srli_si128 (__m128i __A, int __N)
3726         {
3727             return (__m128i)__builtin_ia32_psrldqi128 (__A, 8);
3728         }
3729     } "-O2 -msse2" ]
3730 }
3731
3732 # Return 1 if F16C instructions can be compiled.
3733
3734 proc check_effective_target_f16c { } {
3735     return [check_no_compiler_messages f16c object {
3736         #include "immintrin.h"
3737         float
3738         foo (unsigned short val)
3739         {
3740           return _cvtsh_ss (val);
3741         }
3742     } "-O2 -mf16c" ]
3743 }
3744
3745 # Return 1 if C wchar_t type is compatible with char16_t.
3746
3747 proc check_effective_target_wchar_t_char16_t_compatible { } {
3748     return [check_no_compiler_messages wchar_t_char16_t object {
3749         __WCHAR_TYPE__ wc;
3750         __CHAR16_TYPE__ *p16 = &wc;
3751         char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
3752     }]
3753 }
3754
3755 # Return 1 if C wchar_t type is compatible with char32_t.
3756
3757 proc check_effective_target_wchar_t_char32_t_compatible { } {
3758     return [check_no_compiler_messages wchar_t_char32_t object {
3759         __WCHAR_TYPE__ wc;
3760         __CHAR32_TYPE__ *p32 = &wc;
3761         char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
3762     }]
3763 }
3764
3765 # Return 1 if pow10 function exists.
3766
3767 proc check_effective_target_pow10 { } {
3768     return [check_runtime pow10 {
3769         #include <math.h>
3770         int main () {
3771         double x;
3772         x = pow10 (1);
3773         return 0;
3774         }
3775     } "-lm" ]
3776 }
3777
3778 # Return 1 if current options generate DFP instructions, 0 otherwise.
3779
3780 proc check_effective_target_hard_dfp {} {
3781     return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly {
3782         typedef float d64 __attribute__((mode(DD)));
3783         d64 x, y, z;
3784         void foo (void) { z = x + y; }
3785     }]
3786 }
3787
3788 # Return 1 if string.h and wchar.h headers provide C++ requires overloads
3789 # for strchr etc. functions.
3790
3791 proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
3792     return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly {
3793         #include <string.h>
3794         #include <wchar.h>
3795         #if !defined(__cplusplus) \
3796             || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \
3797             || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO)
3798         ISO C++ correct string.h and wchar.h protos not supported.
3799         #else
3800         int i;
3801         #endif
3802     }]
3803 }
3804
3805 # Return 1 if GNU as is used.
3806
3807 proc check_effective_target_gas { } {
3808     global use_gas_saved
3809     global tool
3810
3811     if {![info exists use_gas_saved]} {
3812         # Check if the as used by gcc is GNU as.
3813         set gcc_as [lindex [${tool}_target_compile "-print-prog-name=as" "" "none" ""] 0]
3814         # Provide /dev/null as input, otherwise gas times out reading from
3815         # stdin.
3816         set status [remote_exec host "$gcc_as" "-v /dev/null"]
3817         set as_output [lindex $status 1]
3818         if { [ string first "GNU" $as_output ] >= 0 } {
3819             set use_gas_saved 1
3820         } else {
3821             set use_gas_saved 0
3822         }
3823     }
3824     return $use_gas_saved
3825 }
3826
3827 # Return 1 if the compiler has been configure with link-time optimization
3828 # (LTO) support.
3829
3830 proc check_effective_target_lto { } {
3831     global ENABLE_LTO
3832     return [info exists ENABLE_LTO]
3833 }
3834
3835 # Return 1 if this target supports the -fsplit-stack option, 0
3836 # otherwise.
3837
3838 proc check_effective_target_split_stack {} {
3839     return [check_no_compiler_messages split_stack object {
3840         void foo (void) { }
3841     } "-fsplit-stack"]
3842 }
3843
3844 # Return 1 if the language for the compiler under test is C.
3845
3846 proc check_effective_target_c { } {
3847  global tool
3848     if [string match $tool "gcc"] {
3849    return 1
3850     }
3851  return 0
3852 }
3853
3854 # Return 1 if the language for the compiler under test is C++.
3855
3856 proc check_effective_target_c++ { } {
3857  global tool
3858     if [string match $tool "g++"] {
3859    return 1
3860     }
3861  return 0
3862 }
3863
3864 # Return 1 if expensive testcases should be run.
3865
3866 proc check_effective_target_run_expensive_tests { } {
3867     if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } {
3868         return 1
3869     }
3870     return 0
3871 }
3872
3873 # Returns 1 if "mempcpy" is available on the target system.
3874
3875 proc check_effective_target_mempcpy {} {
3876     return [check_function_available "mempcpy"]
3877 }
3878
3879 # Check whether the vectorizer tests are supported by the target and
3880 # append additional target-dependent compile flags to DEFAULT_VECTCFLAGS.
3881 # Set dg-do-what-default to either compile or run, depending on target
3882 # capabilities.  Return 1 if vectorizer tests are supported by
3883 # target, 0 otherwise.
3884
3885 proc check_vect_support_and_set_flags { } {
3886     global DEFAULT_VECTCFLAGS
3887     global dg-do-what-default
3888
3889     if  [istarget "powerpc-*paired*"]  {
3890         lappend DEFAULT_VECTCFLAGS "-mpaired"
3891         if [check_750cl_hw_available] {
3892             set dg-do-what-default run
3893         } else {
3894             set dg-do-what-default compile
3895         }
3896     } elseif [istarget "powerpc*-*-*"] {
3897         # Skip targets not supporting -maltivec.
3898         if ![is-effective-target powerpc_altivec_ok] {
3899             return 0
3900         }
3901
3902         lappend DEFAULT_VECTCFLAGS "-maltivec"
3903         if [check_vsx_hw_available]  {
3904             lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
3905         }
3906
3907         if [check_vmx_hw_available] {
3908             set dg-do-what-default run
3909         } else {
3910             if [is-effective-target ilp32] {
3911                 # Specify a cpu that supports VMX for compile-only tests.
3912                 lappend DEFAULT_VECTCFLAGS "-mcpu=970"
3913             }
3914             set dg-do-what-default compile
3915         }
3916     } elseif { [istarget  "spu-*-*"] } {
3917         set dg-do-what-default run
3918     } elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
3919         lappend DEFAULT_VECTCFLAGS "-msse2"
3920         if { [check_effective_target_sse2_runtime] } {
3921             set dg-do-what-default run
3922         } else {
3923             set dg-do-what-default compile
3924         }
3925     } elseif { [istarget "mips*-*-*"]
3926                && ([check_effective_target_mpaired_single]
3927                     || [check_effective_target_mips_loongson])
3928                && [check_effective_target_nomips16] } {
3929         if { [check_effective_target_mpaired_single] } {
3930             lappend DEFAULT_VECTCFLAGS "-mpaired-single"
3931         }
3932         set dg-do-what-default run
3933     } elseif [istarget "sparc*-*-*"] {
3934         lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
3935         if [check_effective_target_ultrasparc_hw] {
3936             set dg-do-what-default run
3937         } else {
3938             set dg-do-what-default compile
3939         }
3940     } elseif [istarget "alpha*-*-*"] {
3941         # Alpha's vectorization capabilities are extremely limited.
3942         # It's more effort than its worth disabling all of the tests
3943         # that it cannot pass.  But if you actually want to see what
3944         # does work, command out the return.
3945         return 0
3946
3947         lappend DEFAULT_VECTCFLAGS "-mmax"
3948         if [check_alpha_max_hw_available] {
3949             set dg-do-what-default run
3950         } else {
3951             set dg-do-what-default compile
3952         }
3953     } elseif [istarget "ia64-*-*"] {
3954         set dg-do-what-default run
3955     } elseif [is-effective-target arm_neon_ok] {
3956         eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
3957         # NEON does not support denormals, so is not used for vectorization by
3958         # default to avoid loss of precision.  We must pass -ffast-math to test
3959         # vectorization of float operations.
3960         lappend DEFAULT_VECTCFLAGS "-ffast-math"
3961         if [is-effective-target arm_neon_hw] {
3962             set dg-do-what-default run
3963         } else {
3964             set dg-do-what-default compile
3965         }
3966     } else {
3967         return 0
3968     }
3969
3970     return 1
3971 }
3972
3973 proc check_effective_target_non_strict_align {} {
3974     return [check_no_compiler_messages non_strict_align assembly {
3975         char *y;
3976         typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c;
3977         c *z;
3978         void foo(void) { z = (c *) y; }
3979     } "-Wcast-align"]
3980 }