OSDN Git Service

393c3ade82e7e809d0327b6f0993e4a68ff4d5cc
[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 is this is an arm target not using Thumb
1866 proc check_effective_target_arm_nothumb { } {
1867     return [check_no_compiler_messages arm_nothumb assembly {
1868         #if (defined(__thumb__) || defined(__thumb2__))
1869         #error FOO
1870         #endif
1871     }]
1872 }
1873
1874 # Return 1 if this is an ARM target that only supports aligned vector accesses
1875 proc check_effective_target_arm_vect_no_misalign { } {
1876     return [check_no_compiler_messages arm_vect_no_misalign assembly {
1877         #if !defined(__arm__) \
1878             || (defined(__ARMEL__) \
1879                 && (!defined(__thumb__) || defined(__thumb2__)))
1880         #error FOO
1881         #endif
1882     }]
1883 }
1884
1885
1886 # Return 1 if this is an ARM target supporting -mfpu=vfp
1887 # -mfloat-abi=softfp.  Some multilibs may be incompatible with these
1888 # options.
1889
1890 proc check_effective_target_arm_vfp_ok { } {
1891     if { [check_effective_target_arm32] } {
1892         return [check_no_compiler_messages arm_vfp_ok object {
1893             int dummy;
1894         } "-mfpu=vfp -mfloat-abi=softfp"]
1895     } else {
1896         return 0
1897     }
1898 }
1899
1900 # Return 1 if this is an ARM target supporting -mfpu=vfp
1901 # -mfloat-abi=hard.  Some multilibs may be incompatible with these
1902 # options.
1903
1904 proc check_effective_target_arm_hard_vfp_ok { } {
1905     if { [check_effective_target_arm32] } {
1906         return [check_no_compiler_messages arm_hard_vfp_ok executable {
1907             int main() { return 0;}
1908         } "-mfpu=vfp -mfloat-abi=hard"]
1909     } else {
1910         return 0
1911     }
1912 }
1913
1914 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
1915 # or -mfloat-abi=hard, but if one is already specified by the
1916 # multilib, use it.  Similarly, if a -mfpu option already enables
1917 # NEON, do not add -mfpu=neon.
1918
1919 proc add_options_for_arm_neon { flags } {
1920     if { ! [check_effective_target_arm_neon_ok] } {
1921         return "$flags"
1922     }
1923     global et_arm_neon_flags
1924     return "$flags $et_arm_neon_flags"
1925 }
1926
1927 # Return 1 if this is an ARM target supporting -mfpu=neon
1928 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
1929 # incompatible with these options.  Also set et_arm_neon_flags to the
1930 # best options to add.
1931
1932 proc check_effective_target_arm_neon_ok_nocache { } {
1933     global et_arm_neon_flags
1934     set et_arm_neon_flags ""
1935     if { [check_effective_target_arm32] } {
1936         foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp"} {
1937             if { [check_no_compiler_messages_nocache arm_neon_ok object {
1938                 #include "arm_neon.h"
1939                 int dummy;
1940             } "$flags"] } {
1941                 set et_arm_neon_flags $flags
1942                 return 1
1943             }
1944         }
1945     }
1946
1947     return 0
1948 }
1949
1950 proc check_effective_target_arm_neon_ok { } {
1951     return [check_cached_effective_target arm_neon_ok \
1952                 check_effective_target_arm_neon_ok_nocache]
1953 }
1954
1955 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
1956 # or -mfloat-abi=hard, but if one is already specified by the
1957 # multilib, use it.
1958
1959 proc add_options_for_arm_fp16 { flags } {
1960     if { ! [check_effective_target_arm_fp16_ok] } {
1961         return "$flags"
1962     }
1963     global et_arm_fp16_flags
1964     return "$flags $et_arm_fp16_flags"
1965 }
1966
1967 # Return 1 if this is an ARM target that can support a VFP fp16 variant.
1968 # Skip multilibs that are incompatible with these options and set
1969 # et_arm_fp16_flags to the best options to add.
1970
1971 proc check_effective_target_arm_fp16_ok_nocache { } {
1972     global et_arm_fp16_flags
1973     set et_arm_fp16_flags ""
1974     if { ! [check_effective_target_arm32] } {
1975         return 0;
1976     }
1977     if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" "-mfpu=*fpv[1-9][0-9]*" } ]] {
1978         # Multilib flags would override -mfpu.
1979         return 0
1980     }
1981     if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] {
1982         # Must generate floating-point instructions.
1983         return 0
1984     }
1985     if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] {
1986         # The existing -mfpu value is OK; use it, but add softfp.
1987         set et_arm_fp16_flags "-mfloat-abi=softfp"
1988         return 1;
1989     }
1990     # Add -mfpu for a VFP fp16 variant since there is no preprocessor
1991     # macro to check for this support.
1992     set flags "-mfpu=vfpv4 -mfloat-abi=softfp"
1993     if { [check_no_compiler_messages_nocache arm_fp16_ok assembly {
1994         int dummy;
1995     } "$flags"] } {
1996         set et_arm_fp16_flags "$flags"
1997         return 1
1998     }
1999
2000     return 0
2001 }
2002
2003 proc check_effective_target_arm_fp16_ok { } {
2004     return [check_cached_effective_target arm_fp16_ok \
2005                 check_effective_target_arm_fp16_ok_nocache]
2006 }
2007
2008 # Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
2009 # used.
2010
2011 proc check_effective_target_arm_thumb1_ok { } {
2012     return [check_no_compiler_messages arm_thumb1_ok assembly {
2013         #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
2014         #error FOO
2015         #endif
2016     } "-mthumb"]
2017 }
2018
2019 # Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
2020 # used.
2021
2022 proc check_effective_target_arm_thumb2_ok { } {
2023     return [check_no_compiler_messages arm_thumb2_ok assembly {
2024         #if !defined(__thumb2__)
2025         #error FOO
2026         #endif
2027     } "-mthumb"]
2028 }
2029
2030 # Return 1 is this is an ARM target where is Thumb-2 used.
2031
2032 proc check_effective_target_arm_thumb2 { } {
2033     return [check_no_compiler_messages arm_thumb2 assembly {
2034         #if !defined(__thumb2__)
2035         #error FOO
2036         #endif
2037     } ""]
2038 }
2039
2040 # Return 1 if the target supports executing NEON instructions, 0
2041 # otherwise.  Cache the result.
2042
2043 proc check_effective_target_arm_neon_hw { } {
2044     return [check_runtime arm_neon_hw_available {
2045         int
2046         main (void)
2047         {
2048           long long a = 0, b = 1;
2049           asm ("vorr %P0, %P1, %P2"
2050                : "=w" (a)
2051                : "0" (a), "w" (b));
2052           return (a != 1);
2053         }
2054     } [add_options_for_arm_neon ""]]
2055 }
2056
2057 # Return 1 if this is a ARM target with NEON enabled.
2058
2059 proc check_effective_target_arm_neon { } {
2060     if { [check_effective_target_arm32] } {
2061         return [check_no_compiler_messages arm_neon object {
2062             #ifndef __ARM_NEON__
2063             #error not NEON
2064             #else
2065             int dummy;
2066             #endif
2067         }]
2068     } else {
2069         return 0
2070     }
2071 }
2072
2073 # Return 1 if this a Loongson-2E or -2F target using an ABI that supports
2074 # the Loongson vector modes.
2075
2076 proc check_effective_target_mips_loongson { } {
2077     return [check_no_compiler_messages loongson assembly {
2078         #if !defined(__mips_loongson_vector_rev)
2079         #error FOO
2080         #endif
2081     }]
2082 }
2083
2084 # Return 1 if this is an ARM target that adheres to the ABI for the ARM
2085 # Architecture.
2086
2087 proc check_effective_target_arm_eabi { } {
2088     return [check_no_compiler_messages arm_eabi object {
2089         #ifndef __ARM_EABI__
2090         #error not EABI
2091         #else
2092         int dummy;
2093         #endif
2094     }]
2095 }
2096
2097 # Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
2098 # Some multilibs may be incompatible with this option.
2099
2100 proc check_effective_target_arm_iwmmxt_ok { } {
2101     if { [check_effective_target_arm32] } {
2102         return [check_no_compiler_messages arm_iwmmxt_ok object {
2103             int dummy;
2104         } "-mcpu=iwmmxt"]
2105     } else {
2106         return 0
2107     }
2108 }
2109
2110 # Return 1 if this is a PowerPC target with floating-point registers.
2111
2112 proc check_effective_target_powerpc_fprs { } {
2113     if { [istarget powerpc*-*-*]
2114          || [istarget rs6000-*-*] } {
2115         return [check_no_compiler_messages powerpc_fprs object {
2116             #ifdef __NO_FPRS__
2117             #error no FPRs
2118             #else
2119             int dummy;
2120             #endif
2121         }]
2122     } else {
2123         return 0
2124     }
2125 }
2126
2127 # Return 1 if this is a PowerPC target with hardware double-precision
2128 # floating point.
2129
2130 proc check_effective_target_powerpc_hard_double { } {
2131     if { [istarget powerpc*-*-*]
2132          || [istarget rs6000-*-*] } {
2133         return [check_no_compiler_messages powerpc_hard_double object {
2134             #ifdef _SOFT_DOUBLE
2135             #error soft double
2136             #else
2137             int dummy;
2138             #endif
2139         }]
2140     } else {
2141         return 0
2142     }
2143 }
2144
2145 # Return 1 if this is a PowerPC target supporting -maltivec.
2146
2147 proc check_effective_target_powerpc_altivec_ok { } {
2148     if { ([istarget powerpc*-*-*]
2149          && ![istarget powerpc-*-linux*paired*])
2150          || [istarget rs6000-*-*] } {
2151         # AltiVec is not supported on AIX before 5.3.
2152         if { [istarget powerpc*-*-aix4*]
2153              || [istarget powerpc*-*-aix5.1*] 
2154              || [istarget powerpc*-*-aix5.2*] } {
2155             return 0
2156         }
2157         return [check_no_compiler_messages powerpc_altivec_ok object {
2158             int dummy;
2159         } "-maltivec"]
2160     } else {
2161         return 0
2162     }
2163 }
2164
2165 # Return 1 if this is a PowerPC target supporting -mvsx
2166
2167 proc check_effective_target_powerpc_vsx_ok { } {
2168     if { ([istarget powerpc*-*-*]
2169          && ![istarget powerpc-*-linux*paired*])
2170          || [istarget rs6000-*-*] } {
2171         # AltiVec is not supported on AIX before 5.3.
2172         if { [istarget powerpc*-*-aix4*]
2173              || [istarget powerpc*-*-aix5.1*] 
2174              || [istarget powerpc*-*-aix5.2*] } {
2175             return 0
2176         }
2177         return [check_no_compiler_messages powerpc_vsx_ok object {
2178             int main (void) {
2179 #ifdef __MACH__
2180                 asm volatile ("xxlor vs0,vs0,vs0");
2181 #else
2182                 asm volatile ("xxlor 0,0,0");
2183 #endif
2184                 return 0;
2185             }
2186         } "-mvsx"]
2187     } else {
2188         return 0
2189     }
2190 }
2191
2192 # Return 1 if this is a PowerPC target supporting -mcpu=cell.
2193
2194 proc check_effective_target_powerpc_ppu_ok { } {
2195     if [check_effective_target_powerpc_altivec_ok] {
2196         return [check_no_compiler_messages cell_asm_available object {
2197             int main (void) {
2198 #ifdef __MACH__
2199                 asm volatile ("lvlx v0,v0,v0");
2200 #else
2201                 asm volatile ("lvlx 0,0,0");
2202 #endif
2203                 return 0;
2204             }
2205         }]
2206     } else {
2207         return 0
2208     }
2209 }
2210
2211 # Return 1 if this is a PowerPC target that supports SPU.
2212
2213 proc check_effective_target_powerpc_spu { } {
2214     if [istarget powerpc*-*-linux*] {
2215         return [check_effective_target_powerpc_altivec_ok]
2216     } else {
2217         return 0
2218     }
2219 }
2220
2221 # Return 1 if this is a PowerPC SPE target.  The check includes options
2222 # specified by dg-options for this test, so don't cache the result.
2223
2224 proc check_effective_target_powerpc_spe_nocache { } {
2225     if { [istarget powerpc*-*-*] } {
2226         return [check_no_compiler_messages_nocache powerpc_spe object {
2227             #ifndef __SPE__
2228             #error not SPE
2229             #else
2230             int dummy;
2231             #endif
2232         } [current_compiler_flags]]
2233     } else {
2234         return 0
2235     }
2236 }
2237
2238 # Return 1 if this is a PowerPC target with SPE enabled.
2239
2240 proc check_effective_target_powerpc_spe { } {
2241     if { [istarget powerpc*-*-*] } {
2242         return [check_no_compiler_messages powerpc_spe object {
2243             #ifndef __SPE__
2244             #error not SPE
2245             #else
2246             int dummy;
2247             #endif
2248         }]
2249     } else {
2250         return 0
2251     }
2252 }
2253
2254 # Return 1 if this is a PowerPC target with Altivec enabled.
2255
2256 proc check_effective_target_powerpc_altivec { } {
2257     if { [istarget powerpc*-*-*] } {
2258         return [check_no_compiler_messages powerpc_altivec object {
2259             #ifndef __ALTIVEC__
2260             #error not Altivec
2261             #else
2262             int dummy;
2263             #endif
2264         }]
2265     } else {
2266         return 0
2267     }
2268 }
2269
2270 # Return 1 if this is a PowerPC 405 target.  The check includes options
2271 # specified by dg-options for this test, so don't cache the result.
2272
2273 proc check_effective_target_powerpc_405_nocache { } {
2274     if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } {
2275         return [check_no_compiler_messages_nocache powerpc_405 object {
2276             #ifdef __PPC405__
2277             int dummy;
2278             #else
2279             #error not a PPC405
2280             #endif
2281         } [current_compiler_flags]]
2282     } else {
2283         return 0
2284     }
2285 }
2286
2287 # Return 1 if this is a SPU target with a toolchain that
2288 # supports automatic overlay generation.
2289
2290 proc check_effective_target_spu_auto_overlay { } {
2291     if { [istarget spu*-*-elf*] } {
2292         return [check_no_compiler_messages spu_auto_overlay executable {
2293                 int main (void) { }
2294                 } "-Wl,--auto-overlay" ]
2295     } else {
2296         return 0
2297     }
2298 }
2299
2300 # The VxWorks SPARC simulator accepts only EM_SPARC executables and
2301 # chokes on EM_SPARC32PLUS or EM_SPARCV9 executables.  Return 1 if the
2302 # test environment appears to run executables on such a simulator.
2303
2304 proc check_effective_target_ultrasparc_hw { } {
2305     return [check_runtime ultrasparc_hw {
2306         int main() { return 0; }
2307     } "-mcpu=ultrasparc"]
2308 }
2309
2310 # Return 1 if the target supports hardware vector shift operation.
2311
2312 proc check_effective_target_vect_shift { } {
2313     global et_vect_shift_saved
2314
2315     if [info exists et_vect_shift_saved] {
2316         verbose "check_effective_target_vect_shift: using cached result" 2
2317     } else {
2318         set et_vect_shift_saved 0
2319         if { ([istarget powerpc*-*-*]
2320              && ![istarget powerpc-*-linux*paired*])
2321              || [istarget ia64-*-*]
2322              || [istarget i?86-*-*]
2323              || [istarget x86_64-*-*]
2324              || [check_effective_target_arm32]
2325              || ([istarget mips*-*-*]
2326                  && [check_effective_target_mips_loongson]) } {
2327            set et_vect_shift_saved 1
2328         }
2329     }
2330
2331     verbose "check_effective_target_vect_shift: returning $et_vect_shift_saved" 2
2332     return $et_vect_shift_saved
2333 }
2334
2335 # Return 1 if the target supports hardware vector shift operation with
2336 # scalar shift argument.
2337
2338 proc check_effective_target_vect_shift_scalar { } {
2339     global et_vect_shift_scalar_saved
2340
2341     if [info exists et_vect_shift_scalar_saved] {
2342         verbose "check_effective_target_vect_shift_scalar: using cached result" 2
2343     } else {
2344         set et_vect_shift_scalar_saved 0
2345         if { [istarget x86_64-*-*]
2346              || [istarget i?86-*-*] } {
2347            set et_vect_shift_scalar_saved 1
2348         }
2349     }
2350
2351     verbose "check_effective_target_vect_shift_scalar: returning $et_vect_shift_scalar_saved" 2
2352     return $et_vect_shift_scalar_saved
2353 }
2354
2355
2356 # Return 1 if the target supports hardware vector shift operation for char.
2357
2358 proc check_effective_target_vect_shift_char { } {
2359     global et_vect_shift_char_saved
2360
2361     if [info exists et_vect_shift_char_saved] {
2362         verbose "check_effective_target_vect_shift_char: using cached result" 2
2363     } else {
2364         set et_vect_shift_char_saved 0
2365         if { ([istarget powerpc*-*-*]
2366              && ![istarget powerpc-*-linux*paired*])
2367              || [check_effective_target_arm32] } {
2368            set et_vect_shift_char_saved 1
2369         }
2370     }
2371
2372     verbose "check_effective_target_vect_shift_char: returning $et_vect_shift_char_saved" 2
2373     return $et_vect_shift_char_saved
2374 }
2375
2376 # Return 1 if the target supports hardware vectors of long, 0 otherwise.
2377 #
2378 # This can change for different subtargets so do not cache the result.
2379
2380 proc check_effective_target_vect_long { } {
2381     if { [istarget i?86-*-*]
2382          || (([istarget powerpc*-*-*] 
2383               && ![istarget powerpc-*-linux*paired*]) 
2384               && [check_effective_target_ilp32])
2385          || [istarget x86_64-*-*]
2386          || [check_effective_target_arm32]
2387          || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) } {
2388         set answer 1
2389     } else {
2390         set answer 0
2391     }
2392
2393     verbose "check_effective_target_vect_long: returning $answer" 2
2394     return $answer
2395 }
2396
2397 # Return 1 if the target supports hardware vectors of float, 0 otherwise.
2398 #
2399 # This won't change for different subtargets so cache the result.
2400
2401 proc check_effective_target_vect_float { } {
2402     global et_vect_float_saved
2403
2404     if [info exists et_vect_float_saved] {
2405         verbose "check_effective_target_vect_float: using cached result" 2
2406     } else {
2407         set et_vect_float_saved 0
2408         if { [istarget i?86-*-*]
2409               || [istarget powerpc*-*-*]
2410               || [istarget spu-*-*]
2411               || [istarget mipsisa64*-*-*]
2412               || [istarget x86_64-*-*]
2413               || [istarget ia64-*-*]
2414               || [check_effective_target_arm32] } {
2415            set et_vect_float_saved 1
2416         }
2417     }
2418
2419     verbose "check_effective_target_vect_float: returning $et_vect_float_saved" 2
2420     return $et_vect_float_saved
2421 }
2422
2423 # Return 1 if the target supports hardware vectors of double, 0 otherwise.
2424 #
2425 # This won't change for different subtargets so cache the result.
2426
2427 proc check_effective_target_vect_double { } {
2428     global et_vect_double_saved
2429
2430     if [info exists et_vect_double_saved] {
2431         verbose "check_effective_target_vect_double: using cached result" 2
2432     } else {
2433         set et_vect_double_saved 0
2434         if { [istarget i?86-*-*]
2435               || [istarget x86_64-*-*] } {
2436            if { [check_no_compiler_messages vect_double assembly {
2437                  #ifdef __tune_atom__
2438                  # error No double vectorizer support.
2439                  #endif
2440                 }] } {
2441                 set et_vect_double_saved 1
2442             } else {
2443                 set et_vect_double_saved 0
2444             }
2445         } elseif { [istarget spu-*-*] } {
2446            set et_vect_double_saved 1
2447         }
2448     }
2449
2450     verbose "check_effective_target_vect_double: returning $et_vect_double_saved" 2
2451     return $et_vect_double_saved
2452 }
2453
2454 # Return 1 if the target supports hardware vectors of long long, 0 otherwise.
2455 #
2456 # This won't change for different subtargets so cache the result.
2457
2458 proc check_effective_target_vect_long_long { } {
2459     global et_vect_long_long_saved
2460
2461     if [info exists et_vect_long_long_saved] {
2462         verbose "check_effective_target_vect_long_long: using cached result" 2
2463     } else {
2464         set et_vect_long_long_saved 0
2465         if { [istarget i?86-*-*]
2466               || [istarget x86_64-*-*] } {
2467            set et_vect_long_long_saved 1
2468         }
2469     }
2470
2471     verbose "check_effective_target_vect_long_long: returning $et_vect_long_long_saved" 2
2472     return $et_vect_long_long_saved
2473 }
2474
2475
2476 # Return 1 if the target plus current options does not support a vector
2477 # max instruction on "int", 0 otherwise.
2478 #
2479 # This won't change for different subtargets so cache the result.
2480
2481 proc check_effective_target_vect_no_int_max { } {
2482     global et_vect_no_int_max_saved
2483
2484     if [info exists et_vect_no_int_max_saved] {
2485         verbose "check_effective_target_vect_no_int_max: using cached result" 2
2486     } else {
2487         set et_vect_no_int_max_saved 0
2488         if { [istarget sparc*-*-*]
2489              || [istarget spu-*-*]
2490              || [istarget alpha*-*-*]
2491              || ([istarget mips*-*-*]
2492                  && [check_effective_target_mips_loongson]) } {
2493             set et_vect_no_int_max_saved 1
2494         }
2495     }
2496     verbose "check_effective_target_vect_no_int_max: returning $et_vect_no_int_max_saved" 2
2497     return $et_vect_no_int_max_saved
2498 }
2499
2500 # Return 1 if the target plus current options does not support a vector
2501 # add instruction on "int", 0 otherwise.
2502 #
2503 # This won't change for different subtargets so cache the result.
2504
2505 proc check_effective_target_vect_no_int_add { } {
2506     global et_vect_no_int_add_saved
2507
2508     if [info exists et_vect_no_int_add_saved] {
2509         verbose "check_effective_target_vect_no_int_add: using cached result" 2
2510     } else {
2511         set et_vect_no_int_add_saved 0
2512         # Alpha only supports vector add on V8QI and V4HI.
2513         if { [istarget alpha*-*-*] } {
2514             set et_vect_no_int_add_saved 1
2515         }
2516     }
2517     verbose "check_effective_target_vect_no_int_add: returning $et_vect_no_int_add_saved" 2
2518     return $et_vect_no_int_add_saved
2519 }
2520
2521 # Return 1 if the target plus current options does not support vector
2522 # bitwise instructions, 0 otherwise.
2523 #
2524 # This won't change for different subtargets so cache the result.
2525
2526 proc check_effective_target_vect_no_bitwise { } {
2527     global et_vect_no_bitwise_saved
2528
2529     if [info exists et_vect_no_bitwise_saved] {
2530         verbose "check_effective_target_vect_no_bitwise: using cached result" 2
2531     } else {
2532         set et_vect_no_bitwise_saved 0
2533     }
2534     verbose "check_effective_target_vect_no_bitwise: returning $et_vect_no_bitwise_saved" 2
2535     return $et_vect_no_bitwise_saved
2536 }
2537
2538 # Return 1 if the target plus current options supports vector permutation,
2539 # 0 otherwise.
2540 #
2541 # This won't change for different subtargets so cache the result.
2542
2543 proc check_effective_target_vect_perm { } {
2544     global et_vect_perm
2545
2546     if [info exists et_vect_perm_saved] {
2547         verbose "check_effective_target_vect_perm: using cached result" 2
2548     } else {
2549         set et_vect_perm_saved 0
2550         if { [istarget powerpc*-*-*]
2551              || [istarget spu-*-*]
2552              || [istarget i?86-*-*]
2553              || [istarget x86_64-*-*] } {
2554             set et_vect_perm_saved 1
2555         }
2556     }
2557     verbose "check_effective_target_vect_perm: returning $et_vect_perm_saved" 2
2558     return $et_vect_perm_saved
2559 }
2560
2561 # Return 1 if the target plus current options supports vector permutation
2562 # on byte-sized elements, 0 otherwise.
2563 #
2564 # This won't change for different subtargets so cache the result.
2565
2566 proc check_effective_target_vect_perm_byte { } {
2567     global et_vect_perm_byte
2568
2569     if [info exists et_vect_perm_byte_saved] {
2570         verbose "check_effective_target_vect_perm_byte: using cached result" 2
2571     } else {
2572         set et_vect_perm_byte_saved 0
2573         if { [istarget powerpc*-*-*]
2574              || [istarget spu-*-*] } {
2575             set et_vect_perm_byte_saved 1
2576         }
2577     }
2578     verbose "check_effective_target_vect_perm_byte: returning $et_vect_perm_byte_saved" 2
2579     return $et_vect_perm_byte_saved
2580 }
2581
2582 # Return 1 if the target plus current options supports vector permutation
2583 # on short-sized elements, 0 otherwise.
2584 #
2585 # This won't change for different subtargets so cache the result.
2586
2587 proc check_effective_target_vect_perm_short { } {
2588     global et_vect_perm_short
2589
2590     if [info exists et_vect_perm_short_saved] {
2591         verbose "check_effective_target_vect_perm_short: using cached result" 2
2592     } else {
2593         set et_vect_perm_short_saved 0
2594         if { [istarget powerpc*-*-*]
2595              || [istarget spu-*-*] } {
2596             set et_vect_perm_short_saved 1
2597         }
2598     }
2599     verbose "check_effective_target_vect_perm_short: returning $et_vect_perm_short_saved" 2
2600     return $et_vect_perm_short_saved
2601 }
2602
2603 # Return 1 if the target plus current options supports a vector
2604 # widening summation of *short* args into *int* result, 0 otherwise.
2605 #
2606 # This won't change for different subtargets so cache the result.
2607
2608 proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
2609     global et_vect_widen_sum_hi_to_si_pattern
2610
2611     if [info exists et_vect_widen_sum_hi_to_si_pattern_saved] {
2612         verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: using cached result" 2
2613     } else {
2614         set et_vect_widen_sum_hi_to_si_pattern_saved 0
2615         if { [istarget powerpc*-*-*]
2616              || [istarget ia64-*-*] } {
2617             set et_vect_widen_sum_hi_to_si_pattern_saved 1
2618         }
2619     }
2620     verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: returning $et_vect_widen_sum_hi_to_si_pattern_saved" 2
2621     return $et_vect_widen_sum_hi_to_si_pattern_saved
2622 }
2623
2624 # Return 1 if the target plus current options supports a vector
2625 # widening summation of *short* args into *int* result, 0 otherwise.
2626 # A target can also support this widening summation if it can support
2627 # promotion (unpacking) from shorts to ints.
2628 #
2629 # This won't change for different subtargets so cache the result.
2630                                                                                                 
2631 proc check_effective_target_vect_widen_sum_hi_to_si { } {
2632     global et_vect_widen_sum_hi_to_si
2633
2634     if [info exists et_vect_widen_sum_hi_to_si_saved] {
2635         verbose "check_effective_target_vect_widen_sum_hi_to_si: using cached result" 2
2636     } else {
2637         set et_vect_widen_sum_hi_to_si_saved [check_effective_target_vect_unpack]
2638         if { [istarget powerpc*-*-*] 
2639              || [istarget ia64-*-*] } {
2640             set et_vect_widen_sum_hi_to_si_saved 1
2641         }
2642     }
2643     verbose "check_effective_target_vect_widen_sum_hi_to_si: returning $et_vect_widen_sum_hi_to_si_saved" 2
2644     return $et_vect_widen_sum_hi_to_si_saved
2645 }
2646
2647 # Return 1 if the target plus current options supports a vector
2648 # widening summation of *char* args into *short* result, 0 otherwise.
2649 # A target can also support this widening summation if it can support
2650 # promotion (unpacking) from chars to shorts.
2651 #
2652 # This won't change for different subtargets so cache the result.
2653                                                                                                 
2654 proc check_effective_target_vect_widen_sum_qi_to_hi { } {
2655     global et_vect_widen_sum_qi_to_hi
2656
2657     if [info exists et_vect_widen_sum_qi_to_hi_saved] {
2658         verbose "check_effective_target_vect_widen_sum_qi_to_hi: using cached result" 2
2659     } else {
2660         set et_vect_widen_sum_qi_to_hi_saved 0
2661         if { [check_effective_target_vect_unpack] 
2662              || [istarget ia64-*-*] } {
2663             set et_vect_widen_sum_qi_to_hi_saved 1
2664         }
2665     }
2666     verbose "check_effective_target_vect_widen_sum_qi_to_hi: returning $et_vect_widen_sum_qi_to_hi_saved" 2
2667     return $et_vect_widen_sum_qi_to_hi_saved
2668 }
2669
2670 # Return 1 if the target plus current options supports a vector
2671 # widening summation of *char* args into *int* result, 0 otherwise.
2672 #
2673 # This won't change for different subtargets so cache the result.
2674                                                                                                 
2675 proc check_effective_target_vect_widen_sum_qi_to_si { } {
2676     global et_vect_widen_sum_qi_to_si
2677
2678     if [info exists et_vect_widen_sum_qi_to_si_saved] {
2679         verbose "check_effective_target_vect_widen_sum_qi_to_si: using cached result" 2
2680     } else {
2681         set et_vect_widen_sum_qi_to_si_saved 0
2682         if { [istarget powerpc*-*-*] } {
2683             set et_vect_widen_sum_qi_to_si_saved 1
2684         }
2685     }
2686     verbose "check_effective_target_vect_widen_sum_qi_to_si: returning $et_vect_widen_sum_qi_to_si_saved" 2
2687     return $et_vect_widen_sum_qi_to_si_saved
2688 }
2689
2690 # Return 1 if the target plus current options supports a vector
2691 # widening multiplication of *char* args into *short* result, 0 otherwise.
2692 # A target can also support this widening multplication if it can support
2693 # promotion (unpacking) from chars to shorts, and vect_short_mult (non-widening
2694 # multiplication of shorts).
2695 #
2696 # This won't change for different subtargets so cache the result.
2697
2698
2699 proc check_effective_target_vect_widen_mult_qi_to_hi { } {
2700     global et_vect_widen_mult_qi_to_hi
2701
2702     if [info exists et_vect_widen_mult_qi_to_hi_saved] {
2703         verbose "check_effective_target_vect_widen_mult_qi_to_hi: using cached result" 2
2704     } else {
2705         if { [check_effective_target_vect_unpack]
2706              && [check_effective_target_vect_short_mult] } {
2707             set et_vect_widen_mult_qi_to_hi_saved 1
2708         } else {
2709             set et_vect_widen_mult_qi_to_hi_saved 0
2710         }
2711         if { [istarget powerpc*-*-*]
2712               || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2713             set et_vect_widen_mult_qi_to_hi_saved 1
2714         }
2715     }
2716     verbose "check_effective_target_vect_widen_mult_qi_to_hi: returning $et_vect_widen_mult_qi_to_hi_saved" 2
2717     return $et_vect_widen_mult_qi_to_hi_saved
2718 }
2719
2720 # Return 1 if the target plus current options supports a vector
2721 # widening multiplication of *short* args into *int* result, 0 otherwise.
2722 # A target can also support this widening multplication if it can support
2723 # promotion (unpacking) from shorts to ints, and vect_int_mult (non-widening
2724 # multiplication of ints).
2725 #
2726 # This won't change for different subtargets so cache the result.
2727
2728
2729 proc check_effective_target_vect_widen_mult_hi_to_si { } {
2730     global et_vect_widen_mult_hi_to_si
2731
2732     if [info exists et_vect_widen_mult_hi_to_si_saved] {
2733         verbose "check_effective_target_vect_widen_mult_hi_to_si: using cached result" 2
2734     } else {
2735         if { [check_effective_target_vect_unpack]
2736              && [check_effective_target_vect_int_mult] } {
2737           set et_vect_widen_mult_hi_to_si_saved 1
2738         } else {
2739           set et_vect_widen_mult_hi_to_si_saved 0
2740         }
2741         if { [istarget powerpc*-*-*]
2742               || [istarget spu-*-*]
2743               || [istarget ia64-*-*]
2744               || [istarget i?86-*-*]
2745               || [istarget x86_64-*-*]
2746               || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2747             set et_vect_widen_mult_hi_to_si_saved 1
2748         }
2749     }
2750     verbose "check_effective_target_vect_widen_mult_hi_to_si: returning $et_vect_widen_mult_hi_to_si_saved" 2
2751     return $et_vect_widen_mult_hi_to_si_saved
2752 }
2753
2754 # Return 1 if the target plus current options supports a vector
2755 # widening multiplication of *char* args into *short* result, 0 otherwise.
2756 #
2757 # This won't change for different subtargets so cache the result.
2758
2759 proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
2760     global et_vect_widen_mult_qi_to_hi_pattern
2761
2762     if [info exists et_vect_widen_mult_qi_to_hi_pattern_saved] {
2763         verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: using cached result" 2
2764     } else {
2765         set et_vect_widen_mult_qi_to_hi_pattern_saved 0
2766         if { [istarget powerpc*-*-*]
2767               || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2768             set et_vect_widen_mult_qi_to_hi_pattern_saved 1
2769         }
2770     }
2771     verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: returning $et_vect_widen_mult_qi_to_hi_pattern_saved" 2
2772     return $et_vect_widen_mult_qi_to_hi_pattern_saved
2773 }
2774
2775 # Return 1 if the target plus current options supports a vector
2776 # widening multiplication of *short* args into *int* result, 0 otherwise.
2777 #
2778 # This won't change for different subtargets so cache the result.
2779
2780 proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
2781     global et_vect_widen_mult_hi_to_si_pattern
2782
2783     if [info exists et_vect_widen_mult_hi_to_si_pattern_saved] {
2784         verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: using cached result" 2
2785     } else {
2786         set et_vect_widen_mult_hi_to_si_pattern_saved 0
2787         if { [istarget powerpc*-*-*]
2788               || [istarget spu-*-*]
2789               || [istarget ia64-*-*]
2790               || [istarget i?86-*-*]
2791               || [istarget x86_64-*-*]
2792               || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2793             set et_vect_widen_mult_hi_to_si_pattern_saved 1
2794         }
2795     }
2796     verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: returning $et_vect_widen_mult_hi_to_si_pattern_saved" 2
2797     return $et_vect_widen_mult_hi_to_si_pattern_saved
2798 }
2799
2800 # Return 1 if the target plus current options supports a vector
2801 # dot-product of signed chars, 0 otherwise.
2802 #
2803 # This won't change for different subtargets so cache the result.
2804
2805 proc check_effective_target_vect_sdot_qi { } {
2806     global et_vect_sdot_qi
2807
2808     if [info exists et_vect_sdot_qi_saved] {
2809         verbose "check_effective_target_vect_sdot_qi: using cached result" 2
2810     } else {
2811         set et_vect_sdot_qi_saved 0
2812         if { [istarget ia64-*-*] } {
2813             set et_vect_udot_qi_saved 1
2814         }
2815     }
2816     verbose "check_effective_target_vect_sdot_qi: returning $et_vect_sdot_qi_saved" 2
2817     return $et_vect_sdot_qi_saved
2818 }
2819
2820 # Return 1 if the target plus current options supports a vector
2821 # dot-product of unsigned chars, 0 otherwise.
2822 #
2823 # This won't change for different subtargets so cache the result.
2824
2825 proc check_effective_target_vect_udot_qi { } {
2826     global et_vect_udot_qi
2827
2828     if [info exists et_vect_udot_qi_saved] {
2829         verbose "check_effective_target_vect_udot_qi: using cached result" 2
2830     } else {
2831         set et_vect_udot_qi_saved 0
2832         if { [istarget powerpc*-*-*]
2833              || [istarget ia64-*-*] } {
2834             set et_vect_udot_qi_saved 1
2835         }
2836     }
2837     verbose "check_effective_target_vect_udot_qi: returning $et_vect_udot_qi_saved" 2
2838     return $et_vect_udot_qi_saved
2839 }
2840
2841 # Return 1 if the target plus current options supports a vector
2842 # dot-product of signed shorts, 0 otherwise.
2843 #
2844 # This won't change for different subtargets so cache the result.
2845
2846 proc check_effective_target_vect_sdot_hi { } {
2847     global et_vect_sdot_hi
2848
2849     if [info exists et_vect_sdot_hi_saved] {
2850         verbose "check_effective_target_vect_sdot_hi: using cached result" 2
2851     } else {
2852         set et_vect_sdot_hi_saved 0
2853         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
2854              || [istarget ia64-*-*]
2855              || [istarget i?86-*-*]
2856              || [istarget x86_64-*-*] } {
2857             set et_vect_sdot_hi_saved 1
2858         }
2859     }
2860     verbose "check_effective_target_vect_sdot_hi: returning $et_vect_sdot_hi_saved" 2
2861     return $et_vect_sdot_hi_saved
2862 }
2863
2864 # Return 1 if the target plus current options supports a vector
2865 # dot-product of unsigned shorts, 0 otherwise.
2866 #
2867 # This won't change for different subtargets so cache the result.
2868
2869 proc check_effective_target_vect_udot_hi { } {
2870     global et_vect_udot_hi
2871
2872     if [info exists et_vect_udot_hi_saved] {
2873         verbose "check_effective_target_vect_udot_hi: using cached result" 2
2874     } else {
2875         set et_vect_udot_hi_saved 0
2876         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) } {
2877             set et_vect_udot_hi_saved 1
2878         }
2879     }
2880     verbose "check_effective_target_vect_udot_hi: returning $et_vect_udot_hi_saved" 2
2881     return $et_vect_udot_hi_saved
2882 }
2883
2884
2885 # Return 1 if the target plus current options supports a vector
2886 # demotion (packing) of shorts (to chars) and ints (to shorts) 
2887 # using modulo arithmetic, 0 otherwise.
2888 #
2889 # This won't change for different subtargets so cache the result.
2890                                                                                 
2891 proc check_effective_target_vect_pack_trunc { } {
2892     global et_vect_pack_trunc
2893                                                                                 
2894     if [info exists et_vect_pack_trunc_saved] {
2895         verbose "check_effective_target_vect_pack_trunc: using cached result" 2
2896     } else {
2897         set et_vect_pack_trunc_saved 0
2898         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
2899              || [istarget i?86-*-*]
2900              || [istarget x86_64-*-*]
2901              || [istarget spu-*-*]
2902              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2903             set et_vect_pack_trunc_saved 1
2904         }
2905     }
2906     verbose "check_effective_target_vect_pack_trunc: returning $et_vect_pack_trunc_saved" 2
2907     return $et_vect_pack_trunc_saved
2908 }
2909
2910 # Return 1 if the target plus current options supports a vector
2911 # promotion (unpacking) of chars (to shorts) and shorts (to ints), 0 otherwise.
2912 #
2913 # This won't change for different subtargets so cache the result.
2914                                    
2915 proc check_effective_target_vect_unpack { } {
2916     global et_vect_unpack
2917                                         
2918     if [info exists et_vect_unpack_saved] {
2919         verbose "check_effective_target_vect_unpack: using cached result" 2
2920     } else {
2921         set et_vect_unpack_saved 0
2922         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
2923              || [istarget i?86-*-*]
2924              || [istarget x86_64-*-*] 
2925              || [istarget spu-*-*]
2926              || [istarget ia64-*-*]
2927              || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
2928             set et_vect_unpack_saved 1
2929         }
2930     }
2931     verbose "check_effective_target_vect_unpack: returning $et_vect_unpack_saved" 2  
2932     return $et_vect_unpack_saved
2933 }
2934
2935 # Return 1 if the target plus current options does not guarantee
2936 # that its STACK_BOUNDARY is >= the reguired vector alignment.
2937 #
2938 # This won't change for different subtargets so cache the result.
2939
2940 proc check_effective_target_unaligned_stack { } {
2941     global et_unaligned_stack_saved
2942
2943     if [info exists et_unaligned_stack_saved] {
2944         verbose "check_effective_target_unaligned_stack: using cached result" 2
2945     } else {
2946         set et_unaligned_stack_saved 0
2947     }
2948     verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2
2949     return $et_unaligned_stack_saved
2950 }
2951
2952 # Return 1 if the target plus current options does not support a vector
2953 # alignment mechanism, 0 otherwise.
2954 #
2955 # This won't change for different subtargets so cache the result.
2956
2957 proc check_effective_target_vect_no_align { } {
2958     global et_vect_no_align_saved
2959
2960     if [info exists et_vect_no_align_saved] {
2961         verbose "check_effective_target_vect_no_align: using cached result" 2
2962     } else {
2963         set et_vect_no_align_saved 0
2964         if { [istarget mipsisa64*-*-*]
2965              || [istarget sparc*-*-*]
2966              || [istarget ia64-*-*]
2967              || [check_effective_target_arm_vect_no_misalign]
2968              || ([istarget mips*-*-*]
2969                  && [check_effective_target_mips_loongson]) } {
2970             set et_vect_no_align_saved 1
2971         }
2972     }
2973     verbose "check_effective_target_vect_no_align: returning $et_vect_no_align_saved" 2
2974     return $et_vect_no_align_saved
2975 }
2976
2977 # Return 1 if the target supports a vector misalign access, 0 otherwise.
2978 #
2979 # This won't change for different subtargets so cache the result.
2980
2981 proc check_effective_target_vect_hw_misalign { } {
2982     global et_vect_hw_misalign_saved
2983
2984     if [info exists et_vect_hw_misalign_saved] {
2985         verbose "check_effective_target_vect_hw_misalign: using cached result" 2
2986     } else {
2987         set et_vect_hw_misalign_saved 0
2988        if { ([istarget x86_64-*-*] 
2989             || [istarget i?86-*-*]) } {
2990           set et_vect_hw_misalign_saved 1
2991        }
2992     }
2993     verbose "check_effective_target_vect_hw_misalign: returning $et_vect_hw_misalign_saved" 2
2994     return $et_vect_hw_misalign_saved
2995 }
2996
2997
2998 # Return 1 if arrays are aligned to the vector alignment
2999 # boundary, 0 otherwise.
3000 #
3001 # This won't change for different subtargets so cache the result.
3002
3003 proc check_effective_target_vect_aligned_arrays { } {
3004     global et_vect_aligned_arrays
3005
3006     if [info exists et_vect_aligned_arrays_saved] {
3007         verbose "check_effective_target_vect_aligned_arrays: using cached result" 2
3008     } else {
3009         set et_vect_aligned_arrays_saved 0
3010         if { (([istarget x86_64-*-*]
3011               || [istarget i?86-*-*]) && [is-effective-target lp64])
3012               || [istarget spu-*-*] } {
3013             set et_vect_aligned_arrays_saved 1
3014         }
3015     }
3016     verbose "check_effective_target_vect_aligned_arrays: returning $et_vect_aligned_arrays_saved" 2
3017     return $et_vect_aligned_arrays_saved
3018 }
3019
3020 # Return 1 if types of size 32 bit or less are naturally aligned
3021 # (aligned to their type-size), 0 otherwise.
3022 #
3023 # This won't change for different subtargets so cache the result.
3024
3025 proc check_effective_target_natural_alignment_32 { } {
3026     global et_natural_alignment_32
3027
3028     if [info exists et_natural_alignment_32_saved] {
3029         verbose "check_effective_target_natural_alignment_32: using cached result" 2
3030     } else {
3031         # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
3032         set et_natural_alignment_32_saved 1
3033         if { ([istarget *-*-darwin*] && [is-effective-target lp64]) } {
3034             set et_natural_alignment_32_saved 0
3035         }
3036     }
3037     verbose "check_effective_target_natural_alignment_32: returning $et_natural_alignment_32_saved" 2
3038     return $et_natural_alignment_32_saved
3039 }
3040
3041 # Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
3042 # type-size), 0 otherwise.
3043 #
3044 # This won't change for different subtargets so cache the result.
3045
3046 proc check_effective_target_natural_alignment_64 { } {
3047     global et_natural_alignment_64
3048
3049     if [info exists et_natural_alignment_64_saved] {
3050         verbose "check_effective_target_natural_alignment_64: using cached result" 2
3051     } else {
3052         set et_natural_alignment_64_saved 0
3053         if { ([is-effective-target lp64] && ![istarget *-*-darwin*])
3054              || [istarget spu-*-*] } {
3055             set et_natural_alignment_64_saved 1
3056         }
3057     }
3058     verbose "check_effective_target_natural_alignment_64: returning $et_natural_alignment_64_saved" 2
3059     return $et_natural_alignment_64_saved
3060 }
3061
3062 # Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise.
3063 #
3064 # This won't change for different subtargets so cache the result.
3065
3066 proc check_effective_target_vector_alignment_reachable { } {
3067     global et_vector_alignment_reachable
3068
3069     if [info exists et_vector_alignment_reachable_saved] {
3070         verbose "check_effective_target_vector_alignment_reachable: using cached result" 2
3071     } else {
3072         if { [check_effective_target_vect_aligned_arrays]
3073              || [check_effective_target_natural_alignment_32] } {
3074             set et_vector_alignment_reachable_saved 1
3075         } else {
3076             set et_vector_alignment_reachable_saved 0
3077         }
3078     }
3079     verbose "check_effective_target_vector_alignment_reachable: returning $et_vector_alignment_reachable_saved" 2
3080     return $et_vector_alignment_reachable_saved
3081 }
3082
3083 # Return 1 if vector alignment for 64 bit is reachable, 0 otherwise.
3084 #
3085 # This won't change for different subtargets so cache the result.
3086
3087 proc check_effective_target_vector_alignment_reachable_for_64bit { } {
3088     global et_vector_alignment_reachable_for_64bit
3089
3090     if [info exists et_vector_alignment_reachable_for_64bit_saved] {
3091         verbose "check_effective_target_vector_alignment_reachable_for_64bit: using cached result" 2
3092     } else {
3093         if { [check_effective_target_vect_aligned_arrays] 
3094              || [check_effective_target_natural_alignment_64] } {
3095             set et_vector_alignment_reachable_for_64bit_saved 1
3096         } else {
3097             set et_vector_alignment_reachable_for_64bit_saved 0
3098         }
3099     }
3100     verbose "check_effective_target_vector_alignment_reachable_for_64bit: returning $et_vector_alignment_reachable_for_64bit_saved" 2
3101     return $et_vector_alignment_reachable_for_64bit_saved
3102 }
3103
3104 # Return 1 if the target only requires element alignment for vector accesses
3105
3106 proc check_effective_target_vect_element_align { } {
3107     global et_vect_element_align
3108
3109     if [info exists et_vect_element_align] {
3110         verbose "check_effective_target_vect_element_align: using cached result" 2
3111     } else {
3112         set et_vect_element_align 0
3113         if { [istarget arm*-*-*]
3114              || [check_effective_target_vect_hw_misalign] } {
3115            set et_vect_element_align 1
3116         }
3117     }
3118
3119     verbose "check_effective_target_vect_element_align: returning $et_vect_element_align" 2
3120     return $et_vect_element_align
3121 }
3122
3123 # Return 1 if the target supports vector conditional operations, 0 otherwise.
3124
3125 proc check_effective_target_vect_condition { } {
3126     global et_vect_cond_saved
3127
3128     if [info exists et_vect_cond_saved] {
3129         verbose "check_effective_target_vect_cond: using cached result" 2
3130     } else {
3131         set et_vect_cond_saved 0
3132         if { [istarget powerpc*-*-*]
3133              || [istarget ia64-*-*]
3134              || [istarget i?86-*-*]
3135              || [istarget spu-*-*]
3136              || [istarget x86_64-*-*] } {
3137            set et_vect_cond_saved 1
3138         }
3139     }
3140
3141     verbose "check_effective_target_vect_cond: returning $et_vect_cond_saved" 2
3142     return $et_vect_cond_saved
3143 }
3144
3145 # Return 1 if the target supports vector char multiplication, 0 otherwise.
3146
3147 proc check_effective_target_vect_char_mult { } {
3148     global et_vect_char_mult_saved
3149
3150     if [info exists et_vect_char_mult_saved] {
3151         verbose "check_effective_target_vect_char_mult: using cached result" 2
3152     } else {
3153         set et_vect_char_mult_saved 0
3154         if { [istarget ia64-*-*]
3155              || [istarget i?86-*-*]
3156              || [istarget x86_64-*-*] } {
3157            set et_vect_char_mult_saved 1
3158         }
3159     }
3160
3161     verbose "check_effective_target_vect_char_mult: returning $et_vect_char_mult_saved" 2
3162     return $et_vect_char_mult_saved
3163 }
3164
3165 # Return 1 if the target supports vector short multiplication, 0 otherwise.
3166
3167 proc check_effective_target_vect_short_mult { } {
3168     global et_vect_short_mult_saved
3169
3170     if [info exists et_vect_short_mult_saved] {
3171         verbose "check_effective_target_vect_short_mult: using cached result" 2
3172     } else {
3173         set et_vect_short_mult_saved 0
3174         if { [istarget ia64-*-*]
3175              || [istarget spu-*-*]
3176              || [istarget i?86-*-*]
3177              || [istarget x86_64-*-*]
3178              || [istarget powerpc*-*-*]
3179              || [check_effective_target_arm32]
3180              || ([istarget mips*-*-*]
3181                  && [check_effective_target_mips_loongson]) } {
3182            set et_vect_short_mult_saved 1
3183         }
3184     }
3185
3186     verbose "check_effective_target_vect_short_mult: returning $et_vect_short_mult_saved" 2
3187     return $et_vect_short_mult_saved
3188 }
3189
3190 # Return 1 if the target supports vector int multiplication, 0 otherwise.
3191
3192 proc check_effective_target_vect_int_mult { } {
3193     global et_vect_int_mult_saved
3194
3195     if [info exists et_vect_int_mult_saved] {
3196         verbose "check_effective_target_vect_int_mult: using cached result" 2
3197     } else {
3198         set et_vect_int_mult_saved 0
3199         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
3200              || [istarget spu-*-*]
3201              || [istarget i?86-*-*]
3202              || [istarget x86_64-*-*]
3203              || [istarget ia64-*-*]
3204              || [check_effective_target_arm32] } {
3205            set et_vect_int_mult_saved 1
3206         }
3207     }
3208
3209     verbose "check_effective_target_vect_int_mult: returning $et_vect_int_mult_saved" 2
3210     return $et_vect_int_mult_saved
3211 }
3212
3213 # Return 1 if the target supports vector even/odd elements extraction, 0 otherwise.
3214
3215 proc check_effective_target_vect_extract_even_odd { } {
3216     global et_vect_extract_even_odd_saved
3217     
3218     if [info exists et_vect_extract_even_odd_saved] {
3219         verbose "check_effective_target_vect_extract_even_odd: using cached result" 2
3220     } else {
3221         set et_vect_extract_even_odd_saved 0 
3222         if { [istarget powerpc*-*-*] 
3223              || [istarget i?86-*-*]
3224              || [istarget x86_64-*-*]
3225              || [istarget ia64-*-*]
3226              || [istarget spu-*-*] } {
3227            set et_vect_extract_even_odd_saved 1
3228         }
3229     }
3230
3231     verbose "check_effective_target_vect_extract_even_odd: returning $et_vect_extract_even_odd_saved" 2
3232     return $et_vect_extract_even_odd_saved
3233 }
3234
3235 # Return 1 if the target supports vector interleaving, 0 otherwise.
3236
3237 proc check_effective_target_vect_interleave { } {
3238     global et_vect_interleave_saved
3239     
3240     if [info exists et_vect_interleave_saved] {
3241         verbose "check_effective_target_vect_interleave: using cached result" 2
3242     } else {
3243         set et_vect_interleave_saved 0
3244         if { [istarget powerpc*-*-*]
3245              || [istarget i?86-*-*]
3246              || [istarget x86_64-*-*]
3247              || [istarget ia64-*-*]
3248              || [istarget spu-*-*] } {
3249            set et_vect_interleave_saved 1
3250         }
3251     }
3252
3253     verbose "check_effective_target_vect_interleave: returning $et_vect_interleave_saved" 2
3254     return $et_vect_interleave_saved
3255 }
3256
3257 foreach N {2 3 4 8} {
3258     eval [string map [list N $N] {
3259         # Return 1 if the target supports 2-vector interleaving
3260         proc check_effective_target_vect_stridedN { } {
3261             global et_vect_stridedN_saved
3262
3263             if [info exists et_vect_stridedN_saved] {
3264                 verbose "check_effective_target_vect_stridedN: using cached result" 2
3265             } else {
3266                 set et_vect_stridedN_saved 0
3267                 if { (N & -N) == N
3268                      && [check_effective_target_vect_interleave]
3269                      && [check_effective_target_vect_extract_even_odd] } {
3270                     set et_vect_stridedN_saved 1
3271                 }
3272                 if { [istarget arm*-*-*] && N >= 2 && N <= 4 } {
3273                     set et_vect_stridedN_saved 1
3274                 }
3275             }
3276
3277             verbose "check_effective_target_vect_stridedN: returning $et_vect_stridedN_saved" 2
3278             return $et_vect_stridedN_saved
3279         }
3280     }]
3281 }
3282
3283 # Return 1 if the target supports section-anchors
3284
3285 proc check_effective_target_section_anchors { } {
3286     global et_section_anchors_saved
3287
3288     if [info exists et_section_anchors_saved] {
3289         verbose "check_effective_target_section_anchors: using cached result" 2
3290     } else {
3291         set et_section_anchors_saved 0
3292         if { [istarget powerpc*-*-*]
3293               || [istarget arm*-*-*] } {
3294            set et_section_anchors_saved 1
3295         }
3296     }
3297
3298     verbose "check_effective_target_section_anchors: returning $et_section_anchors_saved" 2
3299     return $et_section_anchors_saved
3300 }
3301
3302 # Return 1 if the target supports atomic operations on "int" and "long".
3303
3304 proc check_effective_target_sync_int_long { } {
3305     global et_sync_int_long_saved
3306
3307     if [info exists et_sync_int_long_saved] {
3308         verbose "check_effective_target_sync_int_long: using cached result" 2
3309     } else {
3310         set et_sync_int_long_saved 0
3311 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
3312 # load-reserved/store-conditional instructions.
3313         if { [istarget ia64-*-*]
3314              || [istarget i?86-*-*]
3315              || [istarget x86_64-*-*]
3316              || [istarget alpha*-*-*] 
3317              || [istarget arm*-*-linux-gnueabi] 
3318              || [istarget bfin*-*linux*]
3319              || [istarget hppa*-*linux*]
3320              || [istarget s390*-*-*] 
3321              || [istarget powerpc*-*-*]
3322              || [istarget sparc64-*-*]
3323              || [istarget sparcv9-*-*]
3324              || [istarget mips*-*-*] } {
3325            set et_sync_int_long_saved 1
3326         }
3327     }
3328
3329     verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
3330     return $et_sync_int_long_saved
3331 }
3332
3333 # Return 1 if the target supports atomic operations on "char" and "short".
3334
3335 proc check_effective_target_sync_char_short { } {
3336     global et_sync_char_short_saved
3337
3338     if [info exists et_sync_char_short_saved] {
3339         verbose "check_effective_target_sync_char_short: using cached result" 2
3340     } else {
3341         set et_sync_char_short_saved 0
3342 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
3343 # load-reserved/store-conditional instructions.
3344         if { [istarget ia64-*-*]
3345              || [istarget i?86-*-*]
3346              || [istarget x86_64-*-*]
3347              || [istarget alpha*-*-*] 
3348              || [istarget arm*-*-linux-gnueabi] 
3349              || [istarget hppa*-*linux*]
3350              || [istarget s390*-*-*] 
3351              || [istarget powerpc*-*-*]
3352              || [istarget sparc64-*-*]
3353              || [istarget sparcv9-*-*]
3354              || [istarget mips*-*-*] } {
3355            set et_sync_char_short_saved 1
3356         }
3357     }
3358
3359     verbose "check_effective_target_sync_char_short: returning $et_sync_char_short_saved" 2
3360     return $et_sync_char_short_saved
3361 }
3362
3363 # Return 1 if the target uses a ColdFire FPU.
3364
3365 proc check_effective_target_coldfire_fpu { } {
3366     return [check_no_compiler_messages coldfire_fpu assembly {
3367         #ifndef __mcffpu__
3368         #error FOO
3369         #endif
3370     }]
3371 }
3372
3373 # Return true if this is a uClibc target.
3374
3375 proc check_effective_target_uclibc {} {
3376     return [check_no_compiler_messages uclibc object {
3377         #include <features.h>
3378         #if !defined (__UCLIBC__)
3379         #error FOO
3380         #endif
3381     }]
3382 }
3383
3384 # Return true if this is a uclibc target and if the uclibc feature
3385 # described by __$feature__ is not present.
3386
3387 proc check_missing_uclibc_feature {feature} {
3388     return [check_no_compiler_messages $feature object "
3389         #include <features.h>
3390         #if !defined (__UCLIBC) || defined (__${feature}__)
3391         #error FOO
3392         #endif
3393     "]
3394 }
3395
3396 # Return true if this is a Newlib target.
3397
3398 proc check_effective_target_newlib {} {
3399     return [check_no_compiler_messages newlib object {
3400         #include <newlib.h>
3401     }]
3402 }
3403
3404 # Return 1 if
3405 #   (a) an error of a few ULP is expected in string to floating-point
3406 #       conversion functions; and
3407 #   (b) overflow is not always detected correctly by those functions.
3408
3409 proc check_effective_target_lax_strtofp {} {
3410     # By default, assume that all uClibc targets suffer from this.
3411     return [check_effective_target_uclibc]
3412 }
3413
3414 # Return 1 if this is a target for which wcsftime is a dummy
3415 # function that always returns 0.
3416
3417 proc check_effective_target_dummy_wcsftime {} {
3418     # By default, assume that all uClibc targets suffer from this.
3419     return [check_effective_target_uclibc]
3420 }
3421
3422 # Return 1 if constructors with initialization priority arguments are
3423 # supposed on this target.
3424
3425 proc check_effective_target_init_priority {} {
3426     return [check_no_compiler_messages init_priority assembly "
3427         void f() __attribute__((constructor (1000)));
3428         void f() \{\}
3429     "]
3430 }
3431
3432 # Return 1 if the target matches the effective target 'arg', 0 otherwise.
3433 # This can be used with any check_* proc that takes no argument and
3434 # returns only 1 or 0.  It could be used with check_* procs that take
3435 # arguments with keywords that pass particular arguments.
3436
3437 proc is-effective-target { arg } {
3438     set selected 0
3439     if { [info procs check_effective_target_${arg}] != [list] } {
3440         set selected [check_effective_target_${arg}]
3441     } else {
3442         switch $arg {
3443           "vmx_hw"         { set selected [check_vmx_hw_available] }
3444           "vsx_hw"         { set selected [check_vsx_hw_available] }
3445           "ppc_recip_hw"   { set selected [check_ppc_recip_hw_available] }
3446           "named_sections" { set selected [check_named_sections_available] }
3447           "gc_sections"    { set selected [check_gc_sections_available] }
3448           "cxa_atexit"     { set selected [check_cxa_atexit_available] }
3449           default          { error "unknown effective target keyword `$arg'" }
3450         }
3451     }
3452     verbose "is-effective-target: $arg $selected" 2
3453     return $selected
3454 }
3455
3456 # Return 1 if the argument is an effective-target keyword, 0 otherwise.
3457
3458 proc is-effective-target-keyword { arg } {
3459     if { [info procs check_effective_target_${arg}] != [list] } {
3460         return 1
3461     } else {
3462         # These have different names for their check_* procs.
3463         switch $arg {
3464           "vmx_hw"         { return 1 }
3465           "vsx_hw"         { return 1 }
3466           "ppc_recip_hw"   { return 1 }
3467           "named_sections" { return 1 }
3468           "gc_sections"    { return 1 }
3469           "cxa_atexit"     { return 1 }
3470           default          { return 0 }
3471         }
3472     }
3473 }
3474
3475 # Return 1 if target default to short enums
3476
3477 proc check_effective_target_short_enums { } {
3478     return [check_no_compiler_messages short_enums assembly {
3479         enum foo { bar };
3480         int s[sizeof (enum foo) == 1 ? 1 : -1];
3481     }]
3482 }
3483
3484 # Return 1 if target supports merging string constants at link time.
3485
3486 proc check_effective_target_string_merging { } {
3487     return [check_no_messages_and_pattern string_merging \
3488                 "rodata\\.str" assembly {
3489                     const char *var = "String";
3490                 } {-O2}]
3491 }
3492
3493 # Return 1 if target has the basic signed and unsigned types in
3494 # <stdint.h>, 0 otherwise.  This will be obsolete when GCC ensures a
3495 # working <stdint.h> for all targets.
3496
3497 proc check_effective_target_stdint_types { } {
3498     return [check_no_compiler_messages stdint_types assembly {
3499         #include <stdint.h>
3500         int8_t a; int16_t b; int32_t c; int64_t d;
3501         uint8_t e; uint16_t f; uint32_t g; uint64_t h;
3502     }]
3503 }
3504
3505 # Return 1 if target has the basic signed and unsigned types in
3506 # <inttypes.h>, 0 otherwise.  This is for tests that GCC's notions of
3507 # these types agree with those in the header, as some systems have
3508 # only <inttypes.h>.
3509
3510 proc check_effective_target_inttypes_types { } {
3511     return [check_no_compiler_messages inttypes_types assembly {
3512         #include <inttypes.h>
3513         int8_t a; int16_t b; int32_t c; int64_t d;
3514         uint8_t e; uint16_t f; uint32_t g; uint64_t h;
3515     }]
3516 }
3517
3518 # Return 1 if programs are intended to be run on a simulator
3519 # (i.e. slowly) rather than hardware (i.e. fast).
3520
3521 proc check_effective_target_simulator { } {
3522
3523     # All "src/sim" simulators set this one.
3524     if [board_info target exists is_simulator] {
3525         return [board_info target is_simulator]
3526     }
3527
3528     # The "sid" simulators don't set that one, but at least they set
3529     # this one.
3530     if [board_info target exists slow_simulator] {
3531         return [board_info target slow_simulator]
3532     }
3533
3534     return 0
3535 }
3536
3537 # Return 1 if the target is a VxWorks kernel.
3538
3539 proc check_effective_target_vxworks_kernel { } {
3540     return [check_no_compiler_messages vxworks_kernel assembly {
3541         #if !defined __vxworks || defined __RTP__
3542         #error NO
3543         #endif
3544     }]
3545 }
3546
3547 # Return 1 if the target is a VxWorks RTP.
3548
3549 proc check_effective_target_vxworks_rtp { } {
3550     return [check_no_compiler_messages vxworks_rtp assembly {
3551         #if !defined __vxworks || !defined __RTP__
3552         #error NO
3553         #endif
3554     }]
3555 }
3556
3557 # Return 1 if the target is expected to provide wide character support.
3558
3559 proc check_effective_target_wchar { } {
3560     if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} {
3561         return 0
3562     }
3563     return [check_no_compiler_messages wchar assembly {
3564         #include <wchar.h>
3565     }]
3566 }
3567
3568 # Return 1 if the target has <pthread.h>.
3569
3570 proc check_effective_target_pthread_h { } {
3571     return [check_no_compiler_messages pthread_h assembly {
3572         #include <pthread.h>
3573     }]
3574 }
3575
3576 # Return 1 if the target can truncate a file from a file-descriptor,
3577 # as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or
3578 # chsize.  We test for a trivially functional truncation; no stubs.
3579 # As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a
3580 # different function to be used.
3581
3582 proc check_effective_target_fd_truncate { } {
3583     set prog {
3584         #define _FILE_OFFSET_BITS 64
3585         #include <unistd.h>
3586         #include <stdio.h>
3587         #include <stdlib.h>
3588         int main ()
3589         {
3590           FILE *f = fopen ("tst.tmp", "wb");
3591           int fd;
3592           const char t[] = "test writing more than ten characters";
3593           char s[11];
3594           fd =  fileno (f);
3595           write (fd, t, sizeof (t) - 1);
3596           lseek (fd, 0, 0);
3597           if (ftruncate (fd, 10) != 0)
3598             exit (1);
3599           close (fd);
3600           f = fopen ("tst.tmp", "rb");
3601           if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0)
3602             exit (1);
3603           exit (0);
3604         }
3605     }
3606
3607     if { [check_runtime ftruncate $prog] } {
3608       return 1;
3609     }
3610
3611     regsub "ftruncate" $prog "chsize" prog
3612     return [check_runtime chsize $prog]
3613 }
3614
3615 # Add to FLAGS all the target-specific flags needed to access the c99 runtime.
3616
3617 proc add_options_for_c99_runtime { flags } {
3618     if { [istarget *-*-solaris2*] } {
3619         return "$flags -std=c99"
3620     }
3621     if { [istarget mips-sgi-irix6.5*] } {
3622         return "$flags -std=c99"
3623     }
3624     if { [istarget powerpc-*-darwin*] } {
3625         return "$flags -mmacosx-version-min=10.3"
3626     }
3627     return $flags
3628 }
3629
3630 # Add to FLAGS all the target-specific flags needed to enable
3631 # full IEEE compliance mode.
3632
3633 proc add_options_for_ieee { flags } {
3634     if { [istarget "alpha*-*-*"]
3635          || [istarget "sh*-*-*"] } {
3636        return "$flags -mieee"
3637     }
3638     if { [istarget "rx-*-*"] } {
3639        return "$flags -mnofpu"
3640     }
3641     return $flags
3642 }
3643
3644 # Add to FLAGS the flags needed to enable functions to bind locally
3645 # when using pic/PIC passes in the testsuite.
3646
3647 proc add_options_for_bind_pic_locally { flags } {
3648     if {[check_no_compiler_messages using_pic2 assembly {
3649         #if __PIC__ != 2
3650         #error FOO
3651         #endif
3652     }]} {
3653         return "$flags -fPIE"
3654     }
3655     if {[check_no_compiler_messages using_pic1 assembly {
3656         #if __PIC__ != 1
3657         #error FOO
3658         #endif
3659     }]} {
3660         return "$flags -fpie"
3661     }
3662
3663     return $flags
3664 }
3665
3666 # Add to FLAGS the flags needed to enable 128-bit vectors.
3667
3668 proc add_options_for_quad_vectors { flags } {
3669     if [is-effective-target arm_neon_ok] {
3670         return "$flags -mvectorize-with-neon-quad"
3671     }
3672
3673     return $flags
3674 }
3675
3676 # Return 1 if the target provides a full C99 runtime.
3677
3678 proc check_effective_target_c99_runtime { } {
3679     return [check_cached_effective_target c99_runtime {
3680         global srcdir
3681
3682         set file [open "$srcdir/gcc.dg/builtins-config.h"]
3683         set contents [read $file]
3684         close $file
3685         append contents {
3686             #ifndef HAVE_C99_RUNTIME
3687             #error FOO
3688             #endif
3689         }
3690         check_no_compiler_messages_nocache c99_runtime assembly \
3691             $contents [add_options_for_c99_runtime ""]
3692     }]
3693 }
3694
3695 # Return 1 if  target wchar_t is at least 4 bytes.
3696
3697 proc check_effective_target_4byte_wchar_t { } {
3698     return [check_no_compiler_messages 4byte_wchar_t object {
3699         int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1];
3700     }]
3701 }
3702
3703 # Return 1 if the target supports automatic stack alignment.
3704
3705 proc check_effective_target_automatic_stack_alignment  { } {
3706     # Ordinarily x86 supports automatic stack alignment ...
3707     if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
3708         if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
3709             # ... except Win64 SEH doesn't.  Succeed for Win32 though.
3710             return [check_effective_target_ilp32];
3711         }
3712         return 1;
3713     }
3714     return 0;
3715 }
3716
3717 # Return 1 if avx instructions can be compiled.
3718
3719 proc check_effective_target_avx { } {
3720     return [check_no_compiler_messages avx object {
3721         void _mm256_zeroall (void)
3722         {
3723            __builtin_ia32_vzeroall ();
3724         }
3725     } "-O2 -mavx" ]
3726 }
3727
3728 # Return 1 if sse instructions can be compiled.
3729 proc check_effective_target_sse { } {
3730     return [check_no_compiler_messages sse object {
3731         int main ()
3732         {
3733             __builtin_ia32_stmxcsr ();
3734             return 0;
3735         }
3736     } "-O2 -msse" ]
3737 }
3738
3739 # Return 1 if sse2 instructions can be compiled.
3740 proc check_effective_target_sse2 { } {
3741     return [check_no_compiler_messages sse2 object {
3742         typedef long long __m128i __attribute__ ((__vector_size__ (16)));
3743         
3744         __m128i _mm_srli_si128 (__m128i __A, int __N)
3745         {
3746             return (__m128i)__builtin_ia32_psrldqi128 (__A, 8);
3747         }
3748     } "-O2 -msse2" ]
3749 }
3750
3751 # Return 1 if F16C instructions can be compiled.
3752
3753 proc check_effective_target_f16c { } {
3754     return [check_no_compiler_messages f16c object {
3755         #include "immintrin.h"
3756         float
3757         foo (unsigned short val)
3758         {
3759           return _cvtsh_ss (val);
3760         }
3761     } "-O2 -mf16c" ]
3762 }
3763
3764 # Return 1 if C wchar_t type is compatible with char16_t.
3765
3766 proc check_effective_target_wchar_t_char16_t_compatible { } {
3767     return [check_no_compiler_messages wchar_t_char16_t object {
3768         __WCHAR_TYPE__ wc;
3769         __CHAR16_TYPE__ *p16 = &wc;
3770         char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
3771     }]
3772 }
3773
3774 # Return 1 if C wchar_t type is compatible with char32_t.
3775
3776 proc check_effective_target_wchar_t_char32_t_compatible { } {
3777     return [check_no_compiler_messages wchar_t_char32_t object {
3778         __WCHAR_TYPE__ wc;
3779         __CHAR32_TYPE__ *p32 = &wc;
3780         char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
3781     }]
3782 }
3783
3784 # Return 1 if pow10 function exists.
3785
3786 proc check_effective_target_pow10 { } {
3787     return [check_runtime pow10 {
3788         #include <math.h>
3789         int main () {
3790         double x;
3791         x = pow10 (1);
3792         return 0;
3793         }
3794     } "-lm" ]
3795 }
3796
3797 # Return 1 if current options generate DFP instructions, 0 otherwise.
3798
3799 proc check_effective_target_hard_dfp {} {
3800     return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly {
3801         typedef float d64 __attribute__((mode(DD)));
3802         d64 x, y, z;
3803         void foo (void) { z = x + y; }
3804     }]
3805 }
3806
3807 # Return 1 if string.h and wchar.h headers provide C++ requires overloads
3808 # for strchr etc. functions.
3809
3810 proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
3811     return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly {
3812         #include <string.h>
3813         #include <wchar.h>
3814         #if !defined(__cplusplus) \
3815             || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \
3816             || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO)
3817         ISO C++ correct string.h and wchar.h protos not supported.
3818         #else
3819         int i;
3820         #endif
3821     }]
3822 }
3823
3824 # Return 1 if GNU as is used.
3825
3826 proc check_effective_target_gas { } {
3827     global use_gas_saved
3828     global tool
3829
3830     if {![info exists use_gas_saved]} {
3831         # Check if the as used by gcc is GNU as.
3832         set gcc_as [lindex [${tool}_target_compile "-print-prog-name=as" "" "none" ""] 0]
3833         # Provide /dev/null as input, otherwise gas times out reading from
3834         # stdin.
3835         set status [remote_exec host "$gcc_as" "-v /dev/null"]
3836         set as_output [lindex $status 1]
3837         if { [ string first "GNU" $as_output ] >= 0 } {
3838             set use_gas_saved 1
3839         } else {
3840             set use_gas_saved 0
3841         }
3842     }
3843     return $use_gas_saved
3844 }
3845
3846 # Return 1 if the compiler has been configure with link-time optimization
3847 # (LTO) support.
3848
3849 proc check_effective_target_lto { } {
3850     global ENABLE_LTO
3851     return [info exists ENABLE_LTO]
3852 }
3853
3854 # Return 1 if this target supports the -fsplit-stack option, 0
3855 # otherwise.
3856
3857 proc check_effective_target_split_stack {} {
3858     return [check_no_compiler_messages split_stack object {
3859         void foo (void) { }
3860     } "-fsplit-stack"]
3861 }
3862
3863 # Return 1 if the language for the compiler under test is C.
3864
3865 proc check_effective_target_c { } {
3866  global tool
3867     if [string match $tool "gcc"] {
3868    return 1
3869     }
3870  return 0
3871 }
3872
3873 # Return 1 if the language for the compiler under test is C++.
3874
3875 proc check_effective_target_c++ { } {
3876  global tool
3877     if [string match $tool "g++"] {
3878    return 1
3879     }
3880  return 0
3881 }
3882
3883 # Return 1 if expensive testcases should be run.
3884
3885 proc check_effective_target_run_expensive_tests { } {
3886     if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } {
3887         return 1
3888     }
3889     return 0
3890 }
3891
3892 # Returns 1 if "mempcpy" is available on the target system.
3893
3894 proc check_effective_target_mempcpy {} {
3895     return [check_function_available "mempcpy"]
3896 }
3897
3898 # Check whether the vectorizer tests are supported by the target and
3899 # append additional target-dependent compile flags to DEFAULT_VECTCFLAGS.
3900 # Set dg-do-what-default to either compile or run, depending on target
3901 # capabilities.  Return 1 if vectorizer tests are supported by
3902 # target, 0 otherwise.
3903
3904 proc check_vect_support_and_set_flags { } {
3905     global DEFAULT_VECTCFLAGS
3906     global dg-do-what-default
3907
3908     if  [istarget "powerpc-*paired*"]  {
3909         lappend DEFAULT_VECTCFLAGS "-mpaired"
3910         if [check_750cl_hw_available] {
3911             set dg-do-what-default run
3912         } else {
3913             set dg-do-what-default compile
3914         }
3915     } elseif [istarget "powerpc*-*-*"] {
3916         # Skip targets not supporting -maltivec.
3917         if ![is-effective-target powerpc_altivec_ok] {
3918             return 0
3919         }
3920
3921         lappend DEFAULT_VECTCFLAGS "-maltivec"
3922         if [check_vsx_hw_available]  {
3923             lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
3924         }
3925
3926         if [check_vmx_hw_available] {
3927             set dg-do-what-default run
3928         } else {
3929             if [is-effective-target ilp32] {
3930                 # Specify a cpu that supports VMX for compile-only tests.
3931                 lappend DEFAULT_VECTCFLAGS "-mcpu=970"
3932             }
3933             set dg-do-what-default compile
3934         }
3935     } elseif { [istarget  "spu-*-*"] } {
3936         set dg-do-what-default run
3937     } elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
3938         lappend DEFAULT_VECTCFLAGS "-msse2"
3939         if { [check_effective_target_sse2_runtime] } {
3940             set dg-do-what-default run
3941         } else {
3942             set dg-do-what-default compile
3943         }
3944     } elseif { [istarget "mips*-*-*"]
3945                && ([check_effective_target_mpaired_single]
3946                     || [check_effective_target_mips_loongson])
3947                && [check_effective_target_nomips16] } {
3948         if { [check_effective_target_mpaired_single] } {
3949             lappend DEFAULT_VECTCFLAGS "-mpaired-single"
3950         }
3951         set dg-do-what-default run
3952     } elseif [istarget "sparc*-*-*"] {
3953         lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
3954         if [check_effective_target_ultrasparc_hw] {
3955             set dg-do-what-default run
3956         } else {
3957             set dg-do-what-default compile
3958         }
3959     } elseif [istarget "alpha*-*-*"] {
3960         # Alpha's vectorization capabilities are extremely limited.
3961         # It's more effort than its worth disabling all of the tests
3962         # that it cannot pass.  But if you actually want to see what
3963         # does work, command out the return.
3964         return 0
3965
3966         lappend DEFAULT_VECTCFLAGS "-mmax"
3967         if [check_alpha_max_hw_available] {
3968             set dg-do-what-default run
3969         } else {
3970             set dg-do-what-default compile
3971         }
3972     } elseif [istarget "ia64-*-*"] {
3973         set dg-do-what-default run
3974     } elseif [is-effective-target arm_neon_ok] {
3975         eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
3976         # NEON does not support denormals, so is not used for vectorization by
3977         # default to avoid loss of precision.  We must pass -ffast-math to test
3978         # vectorization of float operations.
3979         lappend DEFAULT_VECTCFLAGS "-ffast-math"
3980         if [is-effective-target arm_neon_hw] {
3981             set dg-do-what-default run
3982         } else {
3983             set dg-do-what-default compile
3984         }
3985     } else {
3986         return 0
3987     }
3988
3989     return 1
3990 }
3991
3992 proc check_effective_target_non_strict_align {} {
3993     return [check_no_compiler_messages non_strict_align assembly {
3994         char *y;
3995         typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c;
3996         c *z;
3997         void foo(void) { z = (c *) y; }
3998     } "-Wcast-align"]
3999 }