OSDN Git Service

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