re PR testsuite/60773 (FAIL: gcc.dg/vect/pr60656.c -flto -ffat-lto-objects scan...
[platform/upstream/gcc.git] / gcc / testsuite / lib / target-supports.exp
1 #   Copyright (C) 1999-2014 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with GCC; see the file COPYING3.  If not see
15 # <http://www.gnu.org/licenses/>.
16
17 # Please email any bugs, comments, and/or additions to this file to:
18 # gcc-patches@gcc.gnu.org
19
20 # This file defines procs for determining features supported by the target.
21
22 # Try to compile the code given by CONTENTS into an output file of
23 # type TYPE, where TYPE is as for target_compile.  Return a list
24 # whose first element contains the compiler messages and whose
25 # second element is the name of the output file.
26 #
27 # BASENAME is a prefix to use for source and output files.
28 # If ARGS is not empty, its first element is a string that
29 # should be added to the command line.
30 #
31 # Assume by default that CONTENTS is C code.  
32 # Otherwise, code should contain:
33 # "// C++" for c++,
34 # "! Fortran" for Fortran code,
35 # "/* ObjC", for ObjC
36 # "// ObjC++" for ObjC++
37 # and "// Go" for Go
38 # If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to 
39 # allow for ObjC/ObjC++ specific flags.
40 proc check_compile {basename type contents args} {
41     global tool
42     verbose "check_compile tool: $tool for $basename" 
43
44     if { [llength $args] > 0 } {
45         set options [list "additional_flags=[lindex $args 0]"]
46     } else {
47         set options ""
48     }
49     switch -glob -- $contents {
50         "*! Fortran*" { set src ${basename}[pid].f90 }
51         "*// C++*" { set src ${basename}[pid].cc }
52         "*// ObjC++*" { set src ${basename}[pid].mm }
53         "*/* ObjC*" { set src ${basename}[pid].m }
54         "*// Go*" { set src ${basename}[pid].go }
55         default {
56             switch -- $tool {
57                 "objc" { set src ${basename}[pid].m }
58                 "obj-c++" { set src ${basename}[pid].mm }
59                 default { set src ${basename}[pid].c }
60             }
61         }
62     }
63
64     set compile_type $type
65     switch -glob $type {
66         assembly { set output ${basename}[pid].s }
67         object { set output ${basename}[pid].o }
68         executable { set output ${basename}[pid].exe }
69         "rtl-*" {
70             set output ${basename}[pid].s
71             lappend options "additional_flags=-fdump-$type"
72             set compile_type assembly
73         }
74     }
75     set f [open $src "w"]
76     puts $f $contents
77     close $f
78     set lines [${tool}_target_compile $src $output $compile_type "$options"]
79     file delete $src
80
81     set scan_output $output
82     # Don't try folding this into the switch above; calling "glob" before the
83     # file is created won't work.
84     if [regexp "rtl-(.*)" $type dummy rtl_type] {
85         set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]"
86         file delete $output
87     }
88
89     return [list $lines $scan_output]
90 }
91
92 proc current_target_name { } {
93     global target_info
94     if [info exists target_info(target,name)] {
95         set answer $target_info(target,name)
96     } else {
97         set answer ""
98     }
99     return $answer
100 }
101
102 # Implement an effective-target check for property PROP by invoking
103 # the Tcl command ARGS and seeing if it returns true.
104
105 proc check_cached_effective_target { prop args } {
106     global et_cache
107
108     set target [current_target_name]
109     if {![info exists et_cache($prop,target)]
110         || $et_cache($prop,target) != $target} {
111         verbose "check_cached_effective_target $prop: checking $target" 2
112         set et_cache($prop,target) $target
113         set et_cache($prop,value) [uplevel eval $args]
114     }
115     set value $et_cache($prop,value)
116     verbose "check_cached_effective_target $prop: returning $value for $target" 2
117     return $value
118 }
119
120 # Like check_compile, but delete the output file and return true if the
121 # compiler printed no messages.
122 proc check_no_compiler_messages_nocache {args} {
123     set result [eval check_compile $args]
124     set lines [lindex $result 0]
125     set output [lindex $result 1]
126     remote_file build delete $output
127     return [string match "" $lines]
128 }
129
130 # Like check_no_compiler_messages_nocache, but cache the result.
131 # PROP is the property we're checking, and doubles as a prefix for
132 # temporary filenames.
133 proc check_no_compiler_messages {prop args} {
134     return [check_cached_effective_target $prop {
135         eval [list check_no_compiler_messages_nocache $prop] $args
136     }]
137 }
138
139 # Like check_compile, but return true if the compiler printed no
140 # messages and if the contents of the output file satisfy PATTERN.
141 # If PATTERN has the form "!REGEXP", the contents satisfy it if they
142 # don't match regular expression REGEXP, otherwise they satisfy it
143 # if they do match regular expression PATTERN.  (PATTERN can start
144 # with something like "[!]" if the regular expression needs to match
145 # "!" as the first character.)
146 #
147 # Delete the output file before returning.  The other arguments are
148 # as for check_compile.
149 proc check_no_messages_and_pattern_nocache {basename pattern args} {
150     global tool
151
152     set result [eval [list check_compile $basename] $args]
153     set lines [lindex $result 0]
154     set output [lindex $result 1]
155
156     set ok 0
157     if { [string match "" $lines] } {
158         set chan [open "$output"]
159         set invert [regexp {^!(.*)} $pattern dummy pattern]
160         set ok [expr { [regexp $pattern [read $chan]] != $invert }]
161         close $chan
162     }
163
164     remote_file build delete $output
165     return $ok
166 }
167
168 # Like check_no_messages_and_pattern_nocache, but cache the result.
169 # PROP is the property we're checking, and doubles as a prefix for
170 # temporary filenames.
171 proc check_no_messages_and_pattern {prop pattern args} {
172     return [check_cached_effective_target $prop {
173         eval [list check_no_messages_and_pattern_nocache $prop $pattern] $args
174     }]
175 }
176
177 # Try to compile and run an executable from code CONTENTS.  Return true
178 # if the compiler reports no messages and if execution "passes" in the
179 # usual DejaGNU sense.  The arguments are as for check_compile, with
180 # TYPE implicitly being "executable".
181 proc check_runtime_nocache {basename contents args} {
182     global tool
183
184     set result [eval [list check_compile $basename executable $contents] $args]
185     set lines [lindex $result 0]
186     set output [lindex $result 1]
187
188     set ok 0
189     if { [string match "" $lines] } {
190         # No error messages, everything is OK.
191         set result [remote_load target "./$output" "" ""]
192         set status [lindex $result 0]
193         verbose "check_runtime_nocache $basename: status is <$status>" 2
194         if { $status == "pass" } {
195             set ok 1
196         }
197     }
198     remote_file build delete $output
199     return $ok
200 }
201
202 # Like check_runtime_nocache, but cache the result.  PROP is the
203 # property we're checking, and doubles as a prefix for temporary
204 # filenames.
205 proc check_runtime {prop args} {
206     global tool
207
208     return [check_cached_effective_target $prop {
209         eval [list check_runtime_nocache $prop] $args
210     }]
211 }
212
213 ###############################
214 # proc check_weak_available { }
215 ###############################
216
217 # weak symbols are only supported in some configs/object formats
218 # this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure
219
220 proc check_weak_available { } {
221     global target_cpu
222
223     # All mips targets should support it
224
225     if { [ string first "mips" $target_cpu ] >= 0 } {
226         return 1
227     }
228
229     # All AIX targets should support it
230
231     if { [istarget *-*-aix*] } {
232         return 1
233     }
234
235     # All solaris2 targets should support it
236
237     if { [istarget *-*-solaris2*] } {
238         return 1
239     }
240
241     # Windows targets Cygwin and MingW32 support it
242
243     if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
244         return 1
245     }
246
247     # HP-UX 10.X doesn't support it
248
249     if { [istarget hppa*-*-hpux10*] } {
250         return 0
251     }
252
253     # ELF and ECOFF support it. a.out does with gas/gld but may also with
254     # other linkers, so we should try it
255
256     set objformat [gcc_target_object_format]
257
258     switch $objformat {
259         elf      { return 1 }
260         ecoff    { return 1 }
261         a.out    { return 1 }
262         mach-o   { return 1 }
263         som      { return 1 }
264         unknown  { return -1 }
265         default  { return 0 }
266     }
267 }
268
269 ###############################
270 # proc check_weak_override_available { }
271 ###############################
272
273 # Like check_weak_available, but return 0 if weak symbol definitions
274 # cannot be overridden.
275
276 proc check_weak_override_available { } {
277     if { [istarget *-*-mingw*] } {
278         return 0
279     }
280     return [check_weak_available]
281 }
282
283 ###############################
284 # proc check_visibility_available { what_kind }
285 ###############################
286
287 # The visibility attribute is only support in some object formats
288 # This proc returns 1 if it is supported, 0 if not.
289 # The argument is the kind of visibility, default/protected/hidden/internal.
290
291 proc check_visibility_available { what_kind } {
292     if [string match "" $what_kind] { set what_kind "hidden" }
293
294     return [check_no_compiler_messages visibility_available_$what_kind object "
295         void f() __attribute__((visibility(\"$what_kind\")));
296         void f() {}
297     "]
298 }
299
300 ###############################
301 # proc check_alias_available { }
302 ###############################
303
304 # Determine if the target toolchain supports the alias attribute.
305
306 # Returns 2 if the target supports aliases.  Returns 1 if the target
307 # only supports weak aliased.  Returns 0 if the target does not
308 # support aliases at all.  Returns -1 if support for aliases could not
309 # be determined.
310
311 proc check_alias_available { } {
312     global alias_available_saved
313     global tool
314
315     if [info exists alias_available_saved] {
316         verbose "check_alias_available  returning saved $alias_available_saved" 2
317     } else {
318         set src alias[pid].c
319         set obj alias[pid].o
320         verbose "check_alias_available  compiling testfile $src" 2
321         set f [open $src "w"]
322         # Compile a small test program.  The definition of "g" is
323         # necessary to keep the Solaris assembler from complaining
324         # about the program.
325         puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
326         puts $f "void g() {} void f() __attribute__((alias(\"g\")));"
327         close $f
328         set lines [${tool}_target_compile $src $obj object ""]
329         file delete $src
330         remote_file build delete $obj
331
332         if [string match "" $lines] then {
333             # No error messages, everything is OK.
334             set alias_available_saved 2
335         } else {
336             if [regexp "alias definitions not supported" $lines] {
337                 verbose "check_alias_available  target does not support aliases" 2
338
339                 set objformat [gcc_target_object_format]
340
341                 if { $objformat == "elf" } {
342                     verbose "check_alias_available  but target uses ELF format, so it ought to" 2
343                     set alias_available_saved -1
344                 } else {
345                     set alias_available_saved 0
346                 }
347             } else {
348                 if [regexp "only weak aliases are supported" $lines] {
349                 verbose "check_alias_available  target supports only weak aliases" 2
350                 set alias_available_saved 1
351                 } else {
352                     set alias_available_saved -1
353                 }
354             }
355         }
356
357         verbose "check_alias_available  returning $alias_available_saved" 2
358     }
359
360     return $alias_available_saved
361 }
362
363 # Returns 1 if the target toolchain supports strong aliases, 0 otherwise.
364
365 proc check_effective_target_alias { } {
366     if { [check_alias_available] < 2 } {
367         return 0
368     } else {
369         return 1
370     }
371 }
372
373 # Returns 1 if the target toolchain supports ifunc, 0 otherwise.
374
375 proc check_ifunc_available { } {
376     return [check_no_compiler_messages ifunc_available object {
377         #ifdef __cplusplus
378         extern "C"
379         #endif
380         void g() {}
381         void f() __attribute__((ifunc("g")));
382     }]
383 }
384
385 # Returns true if --gc-sections is supported on the target.
386
387 proc check_gc_sections_available { } {
388     global gc_sections_available_saved
389     global tool
390
391     if {![info exists gc_sections_available_saved]} {
392         # Some targets don't support gc-sections despite whatever's
393         # advertised by ld's options.
394         if { [istarget alpha*-*-*]
395              || [istarget ia64-*-*] } {
396             set gc_sections_available_saved 0
397             return 0
398         }
399
400         # elf2flt uses -q (--emit-relocs), which is incompatible with
401         # --gc-sections.
402         if { [board_info target exists ldflags]
403              && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
404             set gc_sections_available_saved 0
405             return 0
406         }
407
408         # VxWorks kernel modules are relocatable objects linked with -r,
409         # while RTP executables are linked with -q (--emit-relocs).
410         # Both of these options are incompatible with --gc-sections.
411         if { [istarget *-*-vxworks*] } {
412             set gc_sections_available_saved 0
413             return 0
414         }
415
416         # Check if the ld used by gcc supports --gc-sections.
417         set gcc_spec [${tool}_target_compile "-dumpspecs" "" "none" ""]
418         regsub ".*\n\\*linker:\[ \t\]*\n(\[^ \t\n\]*).*" "$gcc_spec" {\1} linker
419         set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=$linker" "" "none" ""] 0]
420         set ld_output [remote_exec host "$gcc_ld" "--help"]
421         if { [ string first "--gc-sections" $ld_output ] >= 0 } {
422             set gc_sections_available_saved 1
423         } else {
424             set gc_sections_available_saved 0
425         }
426     }
427     return $gc_sections_available_saved
428 }
429
430 # Return 1 if according to target_info struct and explicit target list
431 # target is supposed to support trampolines.
432  
433 proc check_effective_target_trampolines { } {
434     if [target_info exists no_trampolines] {
435       return 0
436     }
437     if { [istarget avr-*-*]
438          || [istarget msp430-*-*]
439          || [istarget hppa2.0w-hp-hpux11.23]
440          || [istarget hppa64-hp-hpux11.23] } {
441         return 0;
442     }
443     return 1
444 }
445
446 # Return 1 if according to target_info struct and explicit target list
447 # target is supposed to keep null pointer checks. This could be due to 
448 # use of option fno-delete-null-pointer-checks or hardwired in target.
449  
450 proc check_effective_target_keeps_null_pointer_checks { } {
451     if [target_info exists keeps_null_pointer_checks] {
452       return 1
453     }
454     if { [istarget avr-*-*] } {
455         return 1;   
456     }
457     return 0
458 }
459
460 # Return true if profiling is supported on the target.
461
462 proc check_profiling_available { test_what } {
463     global profiling_available_saved
464
465     verbose "Profiling argument is <$test_what>" 1
466
467     # These conditions depend on the argument so examine them before
468     # looking at the cache variable.
469
470     # Tree profiling requires TLS runtime support.
471     if { $test_what == "-fprofile-generate" } {
472         if { ![check_effective_target_tls_runtime] } {
473             return 0
474         }
475     }
476
477     # Support for -p on solaris2 relies on mcrt1.o which comes with the
478     # vendor compiler.  We cannot reliably predict the directory where the
479     # vendor compiler (and thus mcrt1.o) is installed so we can't
480     # necessarily find mcrt1.o even if we have it.
481     if { [istarget *-*-solaris2*] && $test_what == "-p" } {
482         return 0
483     }
484
485     # We don't yet support profiling for MIPS16.
486     if { [istarget mips*-*-*]
487          && ![check_effective_target_nomips16]
488          && ($test_what == "-p" || $test_what == "-pg") } {
489         return 0
490     }
491
492     # MinGW does not support -p.
493     if { [istarget *-*-mingw*] && $test_what == "-p" } {
494         return 0
495     }
496
497     # cygwin does not support -p.
498     if { [istarget *-*-cygwin*] && $test_what == "-p" } {
499         return 0
500     }
501
502     # uClibc does not have gcrt1.o.
503     if { [check_effective_target_uclibc]
504          && ($test_what == "-p" || $test_what == "-pg") } {
505         return 0
506     }
507
508     # Now examine the cache variable.
509     if {![info exists profiling_available_saved]} {
510         # Some targets don't have any implementation of __bb_init_func or are
511         # missing other needed machinery.
512         if {    [istarget aarch64*-*-elf]
513              || [istarget am3*-*-linux*]
514              || [istarget arm*-*-eabi*]
515              || [istarget arm*-*-elf]
516              || [istarget arm*-*-symbianelf*]
517              || [istarget avr-*-*]
518              || [istarget bfin-*-*]
519              || [istarget cris-*-*]
520              || [istarget crisv32-*-*]
521              || [istarget fido-*-elf]
522              || [istarget h8300-*-*]
523              || [istarget lm32-*-*]
524              || [istarget m32c-*-elf]
525              || [istarget m68k-*-elf]
526              || [istarget m68k-*-uclinux*]
527              || [istarget mep-*-elf]
528              || [istarget mips*-*-elf*]
529              || [istarget mmix-*-*]
530              || [istarget mn10300-*-elf*]
531              || [istarget moxie-*-elf*]
532              || [istarget msp430-*-*]
533              || [istarget nds32*-*-elf]
534              || [istarget nios2-*-elf]
535              || [istarget picochip-*-*]
536              || [istarget powerpc-*-eabi*]
537              || [istarget powerpc-*-elf]
538              || [istarget rx-*-*]       
539              || [istarget tic6x-*-elf]
540              || [istarget xstormy16-*]
541              || [istarget xtensa*-*-elf]
542              || [istarget *-*-rtems*]
543              || [istarget *-*-vxworks*] } {
544             set profiling_available_saved 0
545         } else {
546             set profiling_available_saved 1
547         }
548     }
549
550     return $profiling_available_saved
551 }
552
553 # Check to see if a target is "freestanding". This is as per the definition
554 # in Section 4 of C99 standard. Effectively, it is a target which supports no
555 # extra headers or libraries other than what is considered essential.
556 proc check_effective_target_freestanding { } {
557     if { [istarget picochip-*-*] } then {
558         return 1
559     } else {
560         return 0
561     }
562 }
563
564 # Return 1 if target has packed layout of structure members by
565 # default, 0 otherwise.  Note that this is slightly different than
566 # whether the target has "natural alignment": both attributes may be
567 # false.
568
569 proc check_effective_target_default_packed { } {
570     return [check_no_compiler_messages default_packed assembly {
571         struct x { char a; long b; } c;
572         int s[sizeof (c) == sizeof (char) + sizeof (long) ? 1 : -1];
573     }]
574 }
575
576 # Return 1 if target has PCC_BITFIELD_TYPE_MATTERS defined.  See
577 # documentation, where the test also comes from.
578
579 proc check_effective_target_pcc_bitfield_type_matters { } {
580     # PCC_BITFIELD_TYPE_MATTERS isn't just about unnamed or empty
581     # bitfields, but let's stick to the example code from the docs.
582     return [check_no_compiler_messages pcc_bitfield_type_matters assembly {
583         struct foo1 { char x; char :0; char y; };
584         struct foo2 { char x; int :0; char y; };
585         int s[sizeof (struct foo1) != sizeof (struct foo2) ? 1 : -1];
586     }]
587 }
588
589 # Add to FLAGS all the target-specific flags needed to use thread-local storage.
590
591 proc add_options_for_tls { flags } {
592     # On Solaris 9, __tls_get_addr/___tls_get_addr only lives in
593     # libthread, so always pass -pthread for native TLS. Same for AIX.
594     # Need to duplicate native TLS check from
595     # check_effective_target_tls_native to avoid recursion.
596     if { ([istarget *-*-solaris2.9*] || [istarget powerpc-ibm-aix*]) &&
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     # MSP430 runtime does not have TLS support, but just
653     # running the test below is insufficient to show this.
654     if { [istarget msp430-*-*] } {
655         return 0
656     }
657     return [check_runtime tls_runtime {
658         __thread int thr = 0;
659         int main (void) { return thr; }
660     } [add_options_for_tls ""]]
661 }
662
663 # Return 1 if atomic compare-and-swap is supported on 'int'
664
665 proc check_effective_target_cas_char {} {
666     return [check_no_compiler_messages cas_char assembly {
667         #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
668         #error unsupported
669         #endif
670     } ""]
671 }
672
673 proc check_effective_target_cas_int {} {
674     return [check_no_compiler_messages cas_int assembly {
675         #if __INT_MAX__ == 0x7fff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
676         /* ok */
677         #elif __INT_MAX__ == 0x7fffffff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
678         /* ok */
679         #else
680         #error unsupported
681         #endif
682     } ""]
683 }
684
685 # Return 1 if -ffunction-sections is supported, 0 otherwise.
686
687 proc check_effective_target_function_sections {} {
688     # Darwin has its own scheme and silently accepts -ffunction-sections.
689     if { [istarget *-*-darwin*] } {
690         return 0
691     }
692     
693     return [check_no_compiler_messages functionsections assembly {
694         void foo (void) { }
695     } "-ffunction-sections"]
696 }
697
698 # Return 1 if instruction scheduling is available, 0 otherwise.
699
700 proc check_effective_target_scheduling {} {
701     return [check_no_compiler_messages scheduling object {
702         void foo (void) { }
703     } "-fschedule-insns"]
704 }
705
706 # Return 1 if trapping arithmetic is available, 0 otherwise.
707
708 proc check_effective_target_trapping {} {
709     return [check_no_compiler_messages scheduling object {
710         add (int a, int b) { return a + b; }
711     } "-ftrapv"]
712 }
713
714 # Return 1 if compilation with -fgraphite is error-free for trivial 
715 # code, 0 otherwise.
716
717 proc check_effective_target_fgraphite {} {
718     return [check_no_compiler_messages fgraphite object {
719         void foo (void) { }
720     } "-O1 -fgraphite"]
721 }
722
723 # Return 1 if compilation with -fopenmp is error-free for trivial
724 # code, 0 otherwise.
725
726 proc check_effective_target_fopenmp {} {
727     return [check_no_compiler_messages fopenmp object {
728         void foo (void) { }
729     } "-fopenmp"]
730 }
731
732 # Return 1 if compilation with -fgnu-tm is error-free for trivial
733 # code, 0 otherwise.
734
735 proc check_effective_target_fgnu_tm {} {
736     return [check_no_compiler_messages fgnu_tm object {
737         void foo (void) { }
738     } "-fgnu-tm"]
739 }
740
741 # Return 1 if the target supports mmap, 0 otherwise.
742
743 proc check_effective_target_mmap {} {
744     return [check_function_available "mmap"]
745 }
746
747 # Return 1 if the target supports dlopen, 0 otherwise.
748 proc check_effective_target_dlopen {} {
749     return [check_no_compiler_messages dlopen executable {
750         #include <dlfcn.h>
751         int main(void) { dlopen ("dummy.so", RTLD_NOW); }
752     } [add_options_for_dlopen ""]]
753 }
754
755 proc add_options_for_dlopen { flags } {
756     return "$flags -ldl"
757 }
758
759 # Return 1 if the target supports clone, 0 otherwise.
760 proc check_effective_target_clone {} {
761     return [check_function_available "clone"]
762 }
763
764 # Return 1 if the target supports setrlimit, 0 otherwise.
765 proc check_effective_target_setrlimit {} {
766     # Darwin has non-posix compliant RLIMIT_AS
767     if { [istarget *-*-darwin*] } {
768         return 0
769     }
770     return [check_function_available "setrlimit"]
771 }
772
773 # Return 1 if the target supports swapcontext, 0 otherwise.
774 proc check_effective_target_swapcontext {} {
775     return [check_no_compiler_messages swapcontext executable {
776         #include <ucontext.h>
777         int main (void)
778         {
779           ucontext_t orig_context,child_context;
780           if (swapcontext(&child_context, &orig_context) < 0) { }
781         }
782     }]
783 }
784
785 # Return 1 if compilation with -pthread is error-free for trivial
786 # code, 0 otherwise.
787
788 proc check_effective_target_pthread {} {
789     return [check_no_compiler_messages pthread object {
790         void foo (void) { }
791     } "-pthread"]
792 }
793
794 # Return 1 if compilation with -mpe-aligned-commons is error-free
795 # for trivial code, 0 otherwise.
796
797 proc check_effective_target_pe_aligned_commons {} {
798     if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
799         return [check_no_compiler_messages pe_aligned_commons object {
800             int foo;
801         } "-mpe-aligned-commons"]
802     }
803     return 0
804 }
805
806 # Return 1 if the target supports -static
807 proc check_effective_target_static {} {
808     return [check_no_compiler_messages static executable {
809         int main (void) { return 0; }
810     } "-static"]
811 }
812
813 # Return 1 if the target supports -fstack-protector
814 proc check_effective_target_fstack_protector {} {
815     return [check_runtime fstack_protector {
816         int main (void) { return 0; }
817     } "-fstack-protector"]
818 }
819
820 # Return 1 if compilation with -freorder-blocks-and-partition is error-free
821 # for trivial code, 0 otherwise.
822
823 proc check_effective_target_freorder {} {
824     return [check_no_compiler_messages freorder object {
825         void foo (void) { }
826     } "-freorder-blocks-and-partition"]
827 }
828
829 # Return 1 if -fpic and -fPIC are supported, as in no warnings or errors
830 # emitted, 0 otherwise.  Whether a shared library can actually be built is
831 # out of scope for this test.
832
833 proc check_effective_target_fpic { } {
834     # Note that M68K has a multilib that supports -fpic but not
835     # -fPIC, so we need to check both.  We test with a program that
836     # requires GOT references.
837     foreach arg {fpic fPIC} {
838         if [check_no_compiler_messages $arg object {
839             extern int foo (void); extern int bar;
840             int baz (void) { return foo () + bar; }
841         } "-$arg"] {
842             return 1
843         }
844     }
845     return 0
846 }
847
848 # Return 1 if -pie, -fpie and -fPIE are supported, 0 otherwise.
849
850 proc check_effective_target_pie { } {
851     if { [istarget *-*-darwin\[912\]*]
852          || [istarget *-*-linux*]
853          || [istarget *-*-gnu*] } {
854         return 1;
855     }
856     return 0
857 }
858
859 # Return true if the target supports -mpaired-single (as used on MIPS).
860
861 proc check_effective_target_mpaired_single { } {
862     return [check_no_compiler_messages mpaired_single object {
863         void foo (void) { }
864     } "-mpaired-single"]
865 }
866
867 # Return true if the target has access to FPU instructions.
868
869 proc check_effective_target_hard_float { } {
870     if { [istarget mips*-*-*] } {
871         return [check_no_compiler_messages hard_float assembly {
872                 #if (defined __mips_soft_float || defined __mips16)
873                 #error FOO
874                 #endif
875         }]
876     }
877
878     # This proc is actually checking the availabilty of FPU
879     # support for doubles, so on the RX we must fail if the
880     # 64-bit double multilib has been selected.
881     if { [istarget rx-*-*] } {
882         return 0
883         # return [check_no_compiler_messages hard_float assembly {
884                 #if defined __RX_64_BIT_DOUBLES__
885                 #error FOO
886                 #endif
887         # }]
888     }
889
890     # The generic test equates hard_float with "no call for adding doubles".
891     return [check_no_messages_and_pattern hard_float "!\\(call" rtl-expand {
892         double a (double b, double c) { return b + c; }
893     }]
894 }
895
896 # Return true if the target is a 64-bit MIPS target.
897
898 proc check_effective_target_mips64 { } {
899     return [check_no_compiler_messages mips64 assembly {
900         #ifndef __mips64
901         #error FOO
902         #endif
903     }]
904 }
905
906 # Return true if the target is a MIPS target that does not produce
907 # MIPS16 code.
908
909 proc check_effective_target_nomips16 { } {
910     return [check_no_compiler_messages nomips16 object {
911         #ifndef __mips
912         #error FOO
913         #else
914         /* A cheap way of testing for -mflip-mips16.  */
915         void foo (void) { asm ("addiu $20,$20,1"); }
916         void bar (void) { asm ("addiu $20,$20,1"); }
917         #endif
918     }]
919 }
920
921 # Add the options needed for MIPS16 function attributes.  At the moment,
922 # we don't support MIPS16 PIC.
923
924 proc add_options_for_mips16_attribute { flags } {
925     return "$flags -mno-abicalls -fno-pic -DMIPS16=__attribute__((mips16))"
926 }
927
928 # Return true if we can force a mode that allows MIPS16 code generation.
929 # We don't support MIPS16 PIC, and only support MIPS16 -mhard-float
930 # for o32 and o64.
931
932 proc check_effective_target_mips16_attribute { } {
933     return [check_no_compiler_messages mips16_attribute assembly {
934         #ifdef PIC
935         #error FOO
936         #endif
937         #if defined __mips_hard_float \
938             && (!defined _ABIO32 || _MIPS_SIM != _ABIO32) \
939             && (!defined _ABIO64 || _MIPS_SIM != _ABIO64)
940         #error FOO
941         #endif
942     } [add_options_for_mips16_attribute ""]]
943 }
944
945 # Return 1 if the target supports long double larger than double when
946 # using the new ABI, 0 otherwise.
947
948 proc check_effective_target_mips_newabi_large_long_double { } {
949     return [check_no_compiler_messages mips_newabi_large_long_double object {
950         int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
951     } "-mabi=64"]
952 }
953
954 # Return true if the target is a MIPS target that has access
955 # to the LL and SC instructions.
956
957 proc check_effective_target_mips_llsc { } {
958     if { ![istarget mips*-*-*] } {
959         return 0
960     }
961     # Assume that these instructions are always implemented for
962     # non-elf* targets, via emulation if necessary.
963     if { ![istarget *-*-elf*] } {
964         return 1
965     }
966     # Otherwise assume LL/SC support for everything but MIPS I.
967     return [check_no_compiler_messages mips_llsc assembly {
968         #if __mips == 1
969         #error FOO
970         #endif
971     }]
972 }
973
974 # Return true if the target is a MIPS target that uses in-place relocations.
975
976 proc check_effective_target_mips_rel { } {
977     if { ![istarget mips*-*-*] } {
978         return 0
979     }
980     return [check_no_compiler_messages mips_rel object {
981         #if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
982             || (defined _ABI64 && _MIPS_SIM == _ABI64)
983         #error FOO
984         #endif
985     }]
986 }
987
988 # Return true if the target is a MIPS target that uses the EABI.
989
990 proc check_effective_target_mips_eabi { } {
991     if { ![istarget mips*-*-*] } {
992         return 0
993     }
994     return [check_no_compiler_messages mips_eabi object {
995         #ifndef __mips_eabi
996         #error FOO
997         #endif
998     }]
999 }
1000
1001 # Return 1 if the current multilib does not generate PIC by default.
1002
1003 proc check_effective_target_nonpic { } {
1004     return [check_no_compiler_messages nonpic assembly {
1005         #if __PIC__
1006         #error FOO
1007         #endif
1008     }]
1009 }
1010
1011 # Return 1 if the target does not use a status wrapper.
1012
1013 proc check_effective_target_unwrapped { } {
1014     if { [target_info needs_status_wrapper] != "" \
1015              && [target_info needs_status_wrapper] != "0" } {
1016         return 0
1017     }
1018     return 1
1019 }
1020
1021 # Return true if iconv is supported on the target. In particular IBM1047.
1022
1023 proc check_iconv_available { test_what } {
1024     global libiconv
1025
1026     # If the tool configuration file has not set libiconv, try "-liconv"
1027     if { ![info exists libiconv] } {
1028         set libiconv "-liconv"
1029     }
1030     set test_what [lindex $test_what 1]
1031     return [check_runtime_nocache $test_what [subst {
1032         #include <iconv.h>
1033         int main (void)
1034         {
1035           iconv_t cd;
1036
1037           cd = iconv_open ("$test_what", "UTF-8");
1038           if (cd == (iconv_t) -1)
1039             return 1;
1040           return 0;
1041         }
1042     }] $libiconv]
1043 }
1044
1045 # Return true if Cilk Library is supported on the target.
1046 proc check_libcilkrts_available { } {
1047   return [ check_no_compiler_messages_nocache libcilkrts_available executable {
1048         #ifdef __cplusplus
1049         extern "C" 
1050         #endif
1051            int __cilkrts_set_param (const char *, const char *);
1052             int main (void) { 
1053                 int x = __cilkrts_set_param ("nworkers", "0");
1054                 return x; 
1055             }
1056         } "-fcilkplus -lcilkrts" ]
1057 }
1058
1059 # Return 1 if an ASCII locale is supported on this host, 0 otherwise.
1060
1061 proc check_ascii_locale_available { } {
1062     return 1
1063 }
1064
1065 # Return true if named sections are supported on this target.
1066
1067 proc check_named_sections_available { } {
1068     return [check_no_compiler_messages named_sections assembly {
1069         int __attribute__ ((section("whatever"))) foo;
1070     }]
1071 }
1072
1073 # Return true if the "naked" function attribute is supported on this target.
1074
1075 proc check_effective_target_naked_functions { } {
1076     return [check_no_compiler_messages naked_functions assembly {
1077         void f() __attribute__((naked));
1078     }]
1079 }
1080
1081 # Return 1 if the target supports Fortran real kinds larger than real(8),
1082 # 0 otherwise.
1083 #
1084 # When the target name changes, replace the cached result.
1085
1086 proc check_effective_target_fortran_large_real { } {
1087     return [check_no_compiler_messages fortran_large_real executable {
1088         ! Fortran
1089         integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1)
1090         real(kind=k) :: x
1091         x = cos (x)
1092         end
1093     }]
1094 }
1095
1096 # Return 1 if the target supports Fortran real kind real(16),
1097 # 0 otherwise. Contrary to check_effective_target_fortran_large_real
1098 # this checks for Real(16) only; the other returned real(10) if
1099 # both real(10) and real(16) are available.
1100 #
1101 # When the target name changes, replace the cached result.
1102
1103 proc check_effective_target_fortran_real_16 { } {
1104     return [check_no_compiler_messages fortran_real_16 executable {
1105         ! Fortran
1106         real(kind=16) :: x
1107         x = cos (x)
1108         end
1109     }]
1110 }
1111
1112
1113 # Return 1 if the target supports SQRT for the largest floating-point
1114 # type. (Some targets lack the libm support for this FP type.)
1115 # On most targets, this check effectively checks either whether sqrtl is
1116 # available or on __float128 systems whether libquadmath is installed,
1117 # which provides sqrtq.
1118 #
1119 # When the target name changes, replace the cached result.
1120
1121 proc check_effective_target_fortran_largest_fp_has_sqrt { } {
1122     return [check_no_compiler_messages fortran_largest_fp_has_sqrt executable {
1123         ! Fortran
1124         use iso_fortran_env, only: real_kinds
1125         integer,parameter:: maxFP = real_kinds(ubound(real_kinds,dim=1))
1126         real(kind=maxFP), volatile :: x
1127         x = 2.0_maxFP
1128         x = sqrt (x)
1129         end
1130     }]
1131 }
1132
1133
1134 # Return 1 if the target supports Fortran integer kinds larger than
1135 # integer(8), 0 otherwise.
1136 #
1137 # When the target name changes, replace the cached result.
1138
1139 proc check_effective_target_fortran_large_int { } {
1140     return [check_no_compiler_messages fortran_large_int executable {
1141         ! Fortran
1142         integer,parameter :: k = selected_int_kind (range (0_8) + 1)
1143         integer(kind=k) :: i
1144         end
1145     }]
1146 }
1147
1148 # Return 1 if the target supports Fortran integer(16), 0 otherwise.
1149 #
1150 # When the target name changes, replace the cached result.
1151
1152 proc check_effective_target_fortran_integer_16 { } {
1153     return [check_no_compiler_messages fortran_integer_16 executable {
1154         ! Fortran
1155         integer(16) :: i
1156         end
1157     }]
1158 }
1159
1160 # Return 1 if we can statically link libgfortran, 0 otherwise.
1161 #
1162 # When the target name changes, replace the cached result.
1163
1164 proc check_effective_target_static_libgfortran { } {
1165     return [check_no_compiler_messages static_libgfortran executable {
1166         ! Fortran
1167         print *, 'test'
1168         end
1169     } "-static"]
1170 }
1171
1172 # Return 1 if cilk-plus is supported by the target, 0 otherwise.
1173  
1174 proc check_effective_target_cilkplus { } {
1175     # Skip cilk-plus tests on int16 and size16 targets for now.
1176     # The cilk-plus tests are not generic enough to cover these
1177     # cases and would throw hundreds of FAILs.
1178     if { [check_effective_target_int16]
1179          || ![check_effective_target_size32plus] } {
1180         return 0;
1181     }
1182
1183     # Skip AVR, its RAM is too small and too many tests would fail.
1184     if { [istarget avr-*-*] } {
1185         return 0;
1186     }
1187     return 1
1188 }
1189
1190 proc check_linker_plugin_available { } {
1191   return [check_no_compiler_messages_nocache linker_plugin executable {
1192      int main() { return 0; }
1193   } "-flto -fuse-linker-plugin"]
1194 }
1195
1196 # Return 1 if the target supports executing 750CL paired-single instructions, 0
1197 # otherwise.  Cache the result.
1198
1199 proc check_750cl_hw_available { } {
1200     return [check_cached_effective_target 750cl_hw_available {
1201         # If this is not the right target then we can skip the test.
1202         if { ![istarget powerpc-*paired*] } {
1203             expr 0
1204         } else {
1205             check_runtime_nocache 750cl_hw_available {
1206                  int main()
1207                  {
1208                  #ifdef __MACH__
1209                    asm volatile ("ps_mul v0,v0,v0");
1210                  #else
1211                    asm volatile ("ps_mul 0,0,0");
1212                  #endif
1213                    return 0;
1214                  }
1215             } "-mpaired"
1216         }
1217     }]
1218 }
1219
1220 # Return 1 if the target OS supports running SSE executables, 0
1221 # otherwise.  Cache the result.
1222
1223 proc check_sse_os_support_available { } {
1224     return [check_cached_effective_target sse_os_support_available {
1225         # If this is not the right target then we can skip the test.
1226         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1227             expr 0
1228         } elseif { [istarget i?86-*-solaris2*] } {
1229             # The Solaris 2 kernel doesn't save and restore SSE registers
1230             # before Solaris 9 4/04.  Before that, executables die with SIGILL.
1231             check_runtime_nocache sse_os_support_available {
1232                 int main ()
1233                 {
1234                   asm volatile ("movaps %xmm0,%xmm0");
1235                   return 0;
1236                 }
1237             } "-msse"
1238         } else {
1239             expr 1
1240         }
1241     }]
1242 }
1243
1244 # Return 1 if the target OS supports running AVX executables, 0
1245 # otherwise.  Cache the result.
1246
1247 proc check_avx_os_support_available { } {
1248     return [check_cached_effective_target avx_os_support_available {
1249         # If this is not the right target then we can skip the test.
1250         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1251             expr 0
1252         } else {
1253             # Check that OS has AVX and SSE saving enabled.
1254             check_runtime_nocache avx_os_support_available {
1255                 int main ()
1256                 {
1257                   unsigned int eax, edx;
1258
1259                   asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
1260                   return (eax & 6) != 6;
1261                 }
1262             } ""
1263         }
1264     }]
1265 }
1266
1267 # Return 1 if the target supports executing SSE instructions, 0
1268 # otherwise.  Cache the result.
1269
1270 proc check_sse_hw_available { } {
1271     return [check_cached_effective_target sse_hw_available {
1272         # If this is not the right target then we can skip the test.
1273         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1274             expr 0
1275         } else {
1276             check_runtime_nocache sse_hw_available {
1277                 #include "cpuid.h"
1278                 int main ()
1279                 {
1280                   unsigned int eax, ebx, ecx, edx;
1281                   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1282                     return !(edx & bit_SSE);
1283                   return 1;
1284                 }
1285             } ""
1286         }
1287     }]
1288 }
1289
1290 # Return 1 if the target supports executing SSE2 instructions, 0
1291 # otherwise.  Cache the result.
1292
1293 proc check_sse2_hw_available { } {
1294     return [check_cached_effective_target sse2_hw_available {
1295         # If this is not the right target then we can skip the test.
1296         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1297             expr 0
1298         } else {
1299             check_runtime_nocache sse2_hw_available {
1300                 #include "cpuid.h"
1301                 int main ()
1302                 {
1303                   unsigned int eax, ebx, ecx, edx;
1304                   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1305                     return !(edx & bit_SSE2);
1306                   return 1;
1307                 }
1308             } ""
1309         }
1310     }]
1311 }
1312
1313 # Return 1 if the target supports executing AVX instructions, 0
1314 # otherwise.  Cache the result.
1315
1316 proc check_avx_hw_available { } {
1317     return [check_cached_effective_target avx_hw_available {
1318         # If this is not the right target then we can skip the test.
1319         if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1320             expr 0
1321         } else {
1322             check_runtime_nocache avx_hw_available {
1323                 #include "cpuid.h"
1324                 int main ()
1325                 {
1326                   unsigned int eax, ebx, ecx, edx;
1327                   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1328                     return ((ecx & (bit_AVX | bit_OSXSAVE))
1329                             != (bit_AVX | bit_OSXSAVE));
1330                   return 1;
1331                 }
1332             } ""
1333         }
1334     }]
1335 }
1336
1337 # Return 1 if the target supports running SSE executables, 0 otherwise.
1338
1339 proc check_effective_target_sse_runtime { } {
1340     if { [check_effective_target_sse]
1341          && [check_sse_hw_available]
1342          && [check_sse_os_support_available] } {
1343         return 1
1344     }
1345     return 0
1346 }
1347
1348 # Return 1 if the target supports running SSE2 executables, 0 otherwise.
1349
1350 proc check_effective_target_sse2_runtime { } {
1351     if { [check_effective_target_sse2]
1352          && [check_sse2_hw_available]
1353          && [check_sse_os_support_available] } {
1354         return 1
1355     }
1356     return 0
1357 }
1358
1359 # Return 1 if the target supports running AVX executables, 0 otherwise.
1360
1361 proc check_effective_target_avx_runtime { } {
1362     if { [check_effective_target_avx]
1363          && [check_avx_hw_available]
1364          && [check_avx_os_support_available] } {
1365         return 1
1366     }
1367     return 0
1368 }
1369
1370 # Return 1 if the target supports executing power8 vector instructions, 0
1371 # otherwise.  Cache the result.
1372
1373 proc check_p8vector_hw_available { } {
1374     return [check_cached_effective_target p8vector_hw_available {
1375         # Some simulators are known to not support VSX/power8 instructions.
1376         # For now, disable on Darwin
1377         if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
1378             expr 0
1379         } else {
1380             set options "-mpower8-vector"
1381             check_runtime_nocache p8vector_hw_available {
1382                 int main()
1383                 {
1384                 #ifdef __MACH__
1385                   asm volatile ("xxlorc vs0,vs0,vs0");
1386                 #else
1387                   asm volatile ("xxlorc 0,0,0");
1388                 #endif
1389                   return 0;
1390                 }
1391             } $options
1392         }
1393     }]
1394 }
1395
1396 # Return 1 if the target supports executing VSX instructions, 0
1397 # otherwise.  Cache the result.
1398
1399 proc check_vsx_hw_available { } {
1400     return [check_cached_effective_target vsx_hw_available {
1401         # Some simulators are known to not support VSX instructions.
1402         # For now, disable on Darwin
1403         if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
1404             expr 0
1405         } else {
1406             set options "-mvsx"
1407             check_runtime_nocache vsx_hw_available {
1408                 int main()
1409                 {
1410                 #ifdef __MACH__
1411                   asm volatile ("xxlor vs0,vs0,vs0");
1412                 #else
1413                   asm volatile ("xxlor 0,0,0");
1414                 #endif
1415                   return 0;
1416                 }
1417             } $options
1418         }
1419     }]
1420 }
1421
1422 # Return 1 if the target supports executing AltiVec instructions, 0
1423 # otherwise.  Cache the result.
1424
1425 proc check_vmx_hw_available { } {
1426     return [check_cached_effective_target vmx_hw_available {
1427         # Some simulators are known to not support VMX instructions.
1428         if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } {
1429             expr 0
1430         } else {
1431             # Most targets don't require special flags for this test case, but
1432             # Darwin does.  Just to be sure, make sure VSX is not enabled for
1433             # the altivec tests.
1434             if { [istarget *-*-darwin*]
1435                  || [istarget *-*-aix*] } {
1436                 set options "-maltivec -mno-vsx"
1437             } else {
1438                 set options "-mno-vsx"
1439             }
1440             check_runtime_nocache vmx_hw_available {
1441                 int main()
1442                 {
1443                 #ifdef __MACH__
1444                   asm volatile ("vor v0,v0,v0");
1445                 #else
1446                   asm volatile ("vor 0,0,0");
1447                 #endif
1448                   return 0;
1449                 }
1450             } $options
1451         }
1452     }]
1453 }
1454
1455 proc check_ppc_recip_hw_available { } {
1456     return [check_cached_effective_target ppc_recip_hw_available {
1457         # Some simulators may not support FRE/FRES/FRSQRTE/FRSQRTES
1458         # For now, disable on Darwin
1459         if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
1460             expr 0
1461         } else {
1462             set options "-mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb"
1463             check_runtime_nocache ppc_recip_hw_available {
1464                 volatile double d_recip, d_rsqrt, d_four = 4.0;
1465                 volatile float f_recip, f_rsqrt, f_four = 4.0f;
1466                 int main()
1467                 {
1468                   asm volatile ("fres %0,%1" : "=f" (f_recip) : "f" (f_four));
1469                   asm volatile ("fre %0,%1" : "=d" (d_recip) : "d" (d_four));
1470                   asm volatile ("frsqrtes %0,%1" : "=f" (f_rsqrt) : "f" (f_four));
1471                   asm volatile ("frsqrte %0,%1" : "=f" (d_rsqrt) : "d" (d_four));
1472                   return 0;
1473                 }
1474             } $options
1475         }
1476     }]
1477 }
1478
1479 # Return 1 if the target supports executing AltiVec and Cell PPU
1480 # instructions, 0 otherwise.  Cache the result.
1481
1482 proc check_effective_target_cell_hw { } {
1483     return [check_cached_effective_target cell_hw_available {
1484         # Some simulators are known to not support VMX and PPU instructions.
1485         if { [istarget powerpc-*-eabi*] } {
1486             expr 0
1487         } else {
1488             # Most targets don't require special flags for this test
1489             # case, but Darwin and AIX do.
1490             if { [istarget *-*-darwin*]
1491                  || [istarget *-*-aix*] } {
1492                 set options "-maltivec -mcpu=cell"
1493             } else {
1494                 set options "-mcpu=cell"
1495             }
1496             check_runtime_nocache cell_hw_available {
1497                 int main()
1498                 {
1499                 #ifdef __MACH__
1500                   asm volatile ("vor v0,v0,v0");
1501                   asm volatile ("lvlx v0,r0,r0");
1502                 #else
1503                   asm volatile ("vor 0,0,0");
1504                   asm volatile ("lvlx 0,0,0");
1505                 #endif
1506                   return 0;
1507                 }
1508             } $options
1509         }
1510     }]
1511 }
1512
1513 # Return 1 if the target supports executing 64-bit instructions, 0
1514 # otherwise.  Cache the result.
1515
1516 proc check_effective_target_powerpc64 { } {
1517     global powerpc64_available_saved
1518     global tool
1519
1520     if [info exists powerpc64_available_saved] {
1521         verbose "check_effective_target_powerpc64 returning saved $powerpc64_available_saved" 2
1522     } else {
1523         set powerpc64_available_saved 0
1524
1525         # Some simulators are known to not support powerpc64 instructions.
1526         if { [istarget powerpc-*-eabi*] || [istarget powerpc-ibm-aix*] } {
1527             verbose "check_effective_target_powerpc64 returning 0" 2
1528             return $powerpc64_available_saved
1529         }
1530
1531         # Set up, compile, and execute a test program containing a 64-bit
1532         # instruction.  Include the current process ID in the file
1533         # names to prevent conflicts with invocations for multiple
1534         # testsuites.
1535         set src ppc[pid].c
1536         set exe ppc[pid].x
1537
1538         set f [open $src "w"]
1539         puts $f "int main() {"
1540         puts $f "#ifdef __MACH__"
1541         puts $f "  asm volatile (\"extsw r0,r0\");"
1542         puts $f "#else"
1543         puts $f "  asm volatile (\"extsw 0,0\");"
1544         puts $f "#endif"
1545         puts $f "  return 0; }"
1546         close $f
1547
1548         set opts "additional_flags=-mcpu=G5"
1549
1550         verbose "check_effective_target_powerpc64 compiling testfile $src" 2
1551         set lines [${tool}_target_compile $src $exe executable "$opts"]
1552         file delete $src
1553
1554         if [string match "" $lines] then {
1555             # No error message, compilation succeeded.
1556             set result [${tool}_load "./$exe" "" ""]
1557             set status [lindex $result 0]
1558             remote_file build delete $exe
1559             verbose "check_effective_target_powerpc64 testfile status is <$status>" 2
1560
1561             if { $status == "pass" } then {
1562                 set powerpc64_available_saved 1
1563             }
1564         } else {
1565             verbose "check_effective_target_powerpc64 testfile compilation failed" 2
1566         }
1567     }
1568
1569     return $powerpc64_available_saved
1570 }
1571
1572 # GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing
1573 # complex float arguments.  This affects gfortran tests that call cabsf
1574 # in libm built by an earlier compiler.  Return 1 if libm uses the same
1575 # argument passing as the compiler under test, 0 otherwise.
1576 #
1577 # When the target name changes, replace the cached result.
1578
1579 proc check_effective_target_broken_cplxf_arg { } {
1580     return [check_cached_effective_target broken_cplxf_arg {
1581         # Skip the work for targets known not to be affected.
1582         if { ![istarget powerpc64-*-linux*] } {
1583             expr 0
1584         } elseif { ![is-effective-target lp64] } {
1585             expr 0
1586         } else {
1587             check_runtime_nocache broken_cplxf_arg {
1588                 #include <complex.h>
1589                 extern void abort (void);
1590                 float fabsf (float);
1591                 float cabsf (_Complex float);
1592                 int main ()
1593                 {
1594                   _Complex float cf;
1595                   float f;
1596                   cf = 3 + 4.0fi;
1597                   f = cabsf (cf);
1598                   if (fabsf (f - 5.0) > 0.0001)
1599                     abort ();
1600                   return 0;
1601                 }
1602             } "-lm"
1603         }
1604     }]
1605 }
1606
1607 # Return 1 is this is a TI C6X target supporting C67X instructions
1608 proc check_effective_target_ti_c67x { } {
1609     return [check_no_compiler_messages ti_c67x assembly {
1610         #if !defined(_TMS320C6700)
1611         #error FOO
1612         #endif
1613     }]
1614 }
1615
1616 # Return 1 is this is a TI C6X target supporting C64X+ instructions
1617 proc check_effective_target_ti_c64xp { } {
1618     return [check_no_compiler_messages ti_c64xp assembly {
1619         #if !defined(_TMS320C6400_PLUS)
1620         #error FOO
1621         #endif
1622     }]
1623 }
1624
1625
1626 proc check_alpha_max_hw_available { } {
1627     return [check_runtime alpha_max_hw_available {
1628         int main() { return __builtin_alpha_amask(1<<8) != 0; }
1629     }]
1630 }
1631
1632 # Returns true iff the FUNCTION is available on the target system.
1633 # (This is essentially a Tcl implementation of Autoconf's
1634 # AC_CHECK_FUNC.)
1635
1636 proc check_function_available { function } {
1637     return [check_no_compiler_messages ${function}_available \
1638                 executable [subst {
1639         #ifdef __cplusplus
1640         extern "C"
1641         #endif
1642         char $function ();
1643         int main () { $function (); }
1644     }] "-fno-builtin" ]
1645 }
1646
1647 # Returns true iff "fork" is available on the target system.
1648
1649 proc check_fork_available {} {
1650     return [check_function_available "fork"]
1651 }
1652
1653 # Returns true iff "mkfifo" is available on the target system.
1654
1655 proc check_mkfifo_available {} {
1656     if { [istarget *-*-cygwin*] } {
1657        # Cygwin has mkfifo, but support is incomplete.
1658        return 0
1659      }
1660
1661     return [check_function_available "mkfifo"]
1662 }
1663
1664 # Returns true iff "__cxa_atexit" is used on the target system.
1665
1666 proc check_cxa_atexit_available { } {
1667     return [check_cached_effective_target cxa_atexit_available {
1668         if { [istarget hppa*-*-hpux10*] } {
1669             # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes.
1670             expr 0
1671         } elseif { [istarget *-*-vxworks] } {
1672             # vxworks doesn't have __cxa_atexit but subsequent test passes.
1673             expr 0
1674         } else {
1675             check_runtime_nocache cxa_atexit_available {
1676                 // C++
1677                 #include <stdlib.h>
1678                 static unsigned int count;
1679                 struct X
1680                 {
1681                   X() { count = 1; }
1682                   ~X()
1683                   {
1684                     if (count != 3)
1685                       exit(1);
1686                     count = 4;
1687                   }
1688                 };
1689                 void f()
1690                 {
1691                   static X x;
1692                 }
1693                 struct Y
1694                 {
1695                   Y() { f(); count = 2; }
1696                   ~Y()
1697                   {
1698                     if (count != 2)
1699                       exit(1);
1700                     count = 3;
1701                   }
1702                 };
1703                 Y y;
1704                 int main() { return 0; }
1705             }
1706         }
1707     }]
1708 }
1709
1710 proc check_effective_target_objc2 { } {
1711     return [check_no_compiler_messages objc2 object {
1712         #ifdef __OBJC2__
1713         int dummy[1];
1714         #else
1715         #error
1716         #endif 
1717     }]
1718 }
1719
1720 proc check_effective_target_next_runtime { } {
1721     return [check_no_compiler_messages objc2 object {
1722         #ifdef __NEXT_RUNTIME__
1723         int dummy[1];
1724         #else
1725         #error
1726         #endif 
1727     }]
1728 }
1729
1730 # Return 1 if we're generating 32-bit code using default options, 0
1731 # otherwise.
1732
1733 proc check_effective_target_ilp32 { } {
1734     return [check_no_compiler_messages ilp32 object {
1735         int dummy[sizeof (int) == 4
1736                   && sizeof (void *) == 4
1737                   && sizeof (long) == 4 ? 1 : -1];
1738     }]
1739 }
1740
1741 # Return 1 if we're generating ia32 code using default options, 0
1742 # otherwise.
1743
1744 proc check_effective_target_ia32 { } {
1745     return [check_no_compiler_messages ia32 object {
1746         int dummy[sizeof (int) == 4
1747                   && sizeof (void *) == 4
1748                   && sizeof (long) == 4 ? 1 : -1] = { __i386__ };
1749     }]
1750 }
1751
1752 # Return 1 if we're generating x32 code using default options, 0
1753 # otherwise.
1754
1755 proc check_effective_target_x32 { } {
1756     return [check_no_compiler_messages x32 object {
1757         int dummy[sizeof (int) == 4
1758                   && sizeof (void *) == 4
1759                   && sizeof (long) == 4 ? 1 : -1] = { __x86_64__ };
1760     }]
1761 }
1762
1763 # Return 1 if we're generating 32-bit integers using default
1764 # options, 0 otherwise.
1765
1766 proc check_effective_target_int32 { } {
1767     return [check_no_compiler_messages int32 object {
1768         int dummy[sizeof (int) == 4 ? 1 : -1];
1769     }]
1770 }
1771
1772 # Return 1 if we're generating 32-bit or larger integers using default
1773 # options, 0 otherwise.
1774
1775 proc check_effective_target_int32plus { } {
1776     return [check_no_compiler_messages int32plus object {
1777         int dummy[sizeof (int) >= 4 ? 1 : -1];
1778     }]
1779 }
1780
1781 # Return 1 if we're generating 32-bit or larger pointers using default
1782 # options, 0 otherwise.
1783
1784 proc check_effective_target_ptr32plus { } {
1785     # The msp430 has 16-bit or 20-bit pointers.  The 20-bit pointer is stored
1786     # in a 32-bit slot when in memory, so sizeof(void *) returns 4, but it
1787     # cannot really hold a 32-bit address, so we always return false here.
1788     if { [istarget msp430-*-*] } {
1789         return 0
1790     }
1791  
1792     return [check_no_compiler_messages ptr32plus object {
1793         int dummy[sizeof (void *) >= 4 ? 1 : -1];
1794     }]
1795 }
1796
1797 # Return 1 if we support 32-bit or larger array and structure sizes
1798 # using default options, 0 otherwise.
1799
1800 proc check_effective_target_size32plus { } {
1801     return [check_no_compiler_messages size32plus object {
1802         char dummy[65537];
1803     }]
1804 }
1805
1806 # Returns 1 if we're generating 16-bit or smaller integers with the
1807 # default options, 0 otherwise.
1808
1809 proc check_effective_target_int16 { } {
1810     return [check_no_compiler_messages int16 object {
1811         int dummy[sizeof (int) < 4 ? 1 : -1];
1812     }]
1813 }
1814
1815 # Return 1 if we're generating 64-bit code using default options, 0
1816 # otherwise.
1817
1818 proc check_effective_target_lp64 { } {
1819     return [check_no_compiler_messages lp64 object {
1820         int dummy[sizeof (int) == 4
1821                   && sizeof (void *) == 8
1822                   && sizeof (long) == 8 ? 1 : -1];
1823     }]
1824 }
1825
1826 # Return 1 if we're generating 64-bit code using default llp64 options,
1827 # 0 otherwise.
1828
1829 proc check_effective_target_llp64 { } {
1830     return [check_no_compiler_messages llp64 object {
1831         int dummy[sizeof (int) == 4
1832                   && sizeof (void *) == 8
1833                   && sizeof (long long) == 8
1834                   && sizeof (long) == 4 ? 1 : -1];
1835     }]
1836 }
1837
1838 # Return 1 if long and int have different sizes,
1839 # 0 otherwise.
1840
1841 proc check_effective_target_long_neq_int { } {
1842     return [check_no_compiler_messages long_ne_int object {
1843         int dummy[sizeof (int) != sizeof (long) ? 1 : -1];
1844     }]
1845 }
1846
1847 # Return 1 if the target supports long double larger than double,
1848 # 0 otherwise.
1849
1850 proc check_effective_target_large_long_double { } {
1851     return [check_no_compiler_messages large_long_double object {
1852         int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
1853     }]
1854 }
1855
1856 # Return 1 if the target supports double larger than float,
1857 # 0 otherwise.
1858
1859 proc check_effective_target_large_double { } {
1860     return [check_no_compiler_messages large_double object {
1861         int dummy[sizeof(double) > sizeof(float) ? 1 : -1];
1862     }]
1863 }
1864
1865 # Return 1 if the target supports double of 64 bits,
1866 # 0 otherwise.
1867
1868 proc check_effective_target_double64 { } {
1869     return [check_no_compiler_messages double64 object {
1870         int dummy[sizeof(double) == 8 ? 1 : -1];
1871     }]
1872 }
1873
1874 # Return 1 if the target supports double of at least 64 bits,
1875 # 0 otherwise.
1876
1877 proc check_effective_target_double64plus { } {
1878     return [check_no_compiler_messages double64plus object {
1879         int dummy[sizeof(double) >= 8 ? 1 : -1];
1880     }]
1881 }
1882
1883 # Return 1 if the target supports 'w' suffix on floating constant
1884 # 0 otherwise.
1885
1886 proc check_effective_target_has_w_floating_suffix { } {
1887     set opts ""
1888     if [check_effective_target_c++] {
1889         append opts "-std=gnu++03"
1890     }
1891     return [check_no_compiler_messages w_fp_suffix object {
1892         float dummy = 1.0w;
1893     } "$opts"]
1894 }
1895
1896 # Return 1 if the target supports 'q' suffix on floating constant
1897 # 0 otherwise.
1898
1899 proc check_effective_target_has_q_floating_suffix { } {
1900     set opts ""
1901     if [check_effective_target_c++] {
1902         append opts "-std=gnu++03"
1903     }
1904     return [check_no_compiler_messages q_fp_suffix object {
1905         float dummy = 1.0q;
1906     } "$opts"]
1907 }
1908 # Return 1 if the target supports compiling fixed-point,
1909 # 0 otherwise.
1910
1911 proc check_effective_target_fixed_point { } {
1912     return [check_no_compiler_messages fixed_point object {
1913         _Sat _Fract x; _Sat _Accum y;
1914     }]
1915 }
1916
1917 # Return 1 if the target supports compiling decimal floating point,
1918 # 0 otherwise.
1919
1920 proc check_effective_target_dfp_nocache { } {
1921     verbose "check_effective_target_dfp_nocache: compiling source" 2
1922     set ret [check_no_compiler_messages_nocache dfp object {
1923         float x __attribute__((mode(DD)));
1924     }]
1925     verbose "check_effective_target_dfp_nocache: returning $ret" 2
1926     return $ret
1927 }
1928
1929 proc check_effective_target_dfprt_nocache { } {
1930     return [check_runtime_nocache dfprt {
1931         typedef float d64 __attribute__((mode(DD)));
1932         d64 x = 1.2df, y = 2.3dd, z;
1933         int main () { z = x + y; return 0; }
1934     }]
1935 }
1936
1937 # Return 1 if the target supports compiling Decimal Floating Point,
1938 # 0 otherwise.
1939 #
1940 # This won't change for different subtargets so cache the result.
1941
1942 proc check_effective_target_dfp { } {
1943     return [check_cached_effective_target dfp {
1944         check_effective_target_dfp_nocache
1945     }]
1946 }
1947
1948 # Return 1 if the target supports linking and executing Decimal Floating
1949 # Point, 0 otherwise.
1950 #
1951 # This won't change for different subtargets so cache the result.
1952
1953 proc check_effective_target_dfprt { } {
1954     return [check_cached_effective_target dfprt {
1955         check_effective_target_dfprt_nocache
1956     }]
1957 }
1958
1959 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
1960
1961 proc check_effective_target_ucn_nocache { } {
1962     # -std=c99 is only valid for C
1963     if [check_effective_target_c] {
1964         set ucnopts "-std=c99"
1965     }
1966     append ucnopts " -fextended-identifiers"
1967     verbose "check_effective_target_ucn_nocache: compiling source" 2
1968     set ret [check_no_compiler_messages_nocache ucn object {
1969         int \u00C0;
1970     } $ucnopts]
1971     verbose "check_effective_target_ucn_nocache: returning $ret" 2
1972     return $ret
1973 }
1974
1975 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
1976 #
1977 # This won't change for different subtargets, so cache the result.
1978
1979 proc check_effective_target_ucn { } {
1980     return [check_cached_effective_target ucn {
1981         check_effective_target_ucn_nocache
1982     }]
1983 }
1984
1985 # Return 1 if the target needs a command line argument to enable a SIMD
1986 # instruction set.
1987
1988 proc check_effective_target_vect_cmdline_needed { } {
1989     global et_vect_cmdline_needed_saved
1990     global et_vect_cmdline_needed_target_name
1991
1992     if { ![info exists et_vect_cmdline_needed_target_name] } {
1993         set et_vect_cmdline_needed_target_name ""
1994     }
1995
1996     # If the target has changed since we set the cached value, clear it.
1997     set current_target [current_target_name]
1998     if { $current_target != $et_vect_cmdline_needed_target_name } {
1999         verbose "check_effective_target_vect_cmdline_needed: `$et_vect_cmdline_needed_target_name' `$current_target'" 2
2000         set et_vect_cmdline_needed_target_name $current_target
2001         if { [info exists et_vect_cmdline_needed_saved] } {
2002             verbose "check_effective_target_vect_cmdline_needed: removing cached result" 2
2003             unset et_vect_cmdline_needed_saved
2004         }
2005     }
2006
2007     if [info exists et_vect_cmdline_needed_saved] {
2008         verbose "check_effective_target_vect_cmdline_needed: using cached result" 2
2009     } else {
2010         set et_vect_cmdline_needed_saved 1
2011         if { [istarget alpha*-*-*]
2012              || [istarget ia64-*-*]
2013              || (([istarget x86_64-*-*] || [istarget i?86-*-*])
2014                  && ([check_effective_target_x32]
2015                      || [check_effective_target_lp64]))
2016              || ([istarget powerpc*-*-*]
2017                  && ([check_effective_target_powerpc_spe]
2018                      || [check_effective_target_powerpc_altivec]))
2019              || ([istarget sparc*-*-*] && [check_effective_target_sparc_vis])
2020              || [istarget spu-*-*]
2021              || ([istarget arm*-*-*] && [check_effective_target_arm_neon])
2022              || [istarget aarch64*-*-*] } {
2023            set et_vect_cmdline_needed_saved 0
2024         }
2025     }
2026
2027     verbose "check_effective_target_vect_cmdline_needed: returning $et_vect_cmdline_needed_saved" 2
2028     return $et_vect_cmdline_needed_saved
2029 }
2030
2031 # Return 1 if the target supports hardware vectors of int, 0 otherwise.
2032 #
2033 # This won't change for different subtargets so cache the result.
2034
2035 proc check_effective_target_vect_int { } {
2036     global et_vect_int_saved
2037
2038     if [info exists et_vect_int_saved] {
2039         verbose "check_effective_target_vect_int: using cached result" 2
2040     } else {
2041         set et_vect_int_saved 0
2042         if { [istarget i?86-*-*]
2043              || ([istarget powerpc*-*-*]
2044                   && ![istarget powerpc-*-linux*paired*])
2045               || [istarget spu-*-*]
2046               || [istarget x86_64-*-*]
2047               || [istarget sparc*-*-*]
2048               || [istarget alpha*-*-*]
2049               || [istarget ia64-*-*] 
2050               || [istarget aarch64*-*-*]
2051               || [check_effective_target_arm32]
2052               || ([istarget mips*-*-*]
2053                   && [check_effective_target_mips_loongson]) } {
2054            set et_vect_int_saved 1
2055         }
2056     }
2057
2058     verbose "check_effective_target_vect_int: returning $et_vect_int_saved" 2
2059     return $et_vect_int_saved
2060 }
2061
2062 # Return 1 if the target supports signed int->float conversion 
2063 #
2064
2065 proc check_effective_target_vect_intfloat_cvt { } {
2066     global et_vect_intfloat_cvt_saved
2067
2068     if [info exists et_vect_intfloat_cvt_saved] {
2069         verbose "check_effective_target_vect_intfloat_cvt: using cached result" 2
2070     } else {
2071         set et_vect_intfloat_cvt_saved 0
2072         if { [istarget i?86-*-*]
2073               || ([istarget powerpc*-*-*]
2074                    && ![istarget powerpc-*-linux*paired*])
2075               || [istarget x86_64-*-*] 
2076               || ([istarget arm*-*-*]
2077                   && [check_effective_target_arm_neon_ok])} {
2078            set et_vect_intfloat_cvt_saved 1
2079         }
2080     }
2081
2082     verbose "check_effective_target_vect_intfloat_cvt: returning $et_vect_intfloat_cvt_saved" 2
2083     return $et_vect_intfloat_cvt_saved
2084 }
2085
2086 #Return 1 if we're supporting __int128 for target, 0 otherwise.
2087
2088 proc check_effective_target_int128 { } {
2089     return [check_no_compiler_messages int128 object {
2090         int dummy[
2091         #ifndef __SIZEOF_INT128__
2092         -1
2093         #else
2094         1
2095         #endif
2096         ];
2097     }]
2098 }
2099
2100 # Return 1 if the target supports unsigned int->float conversion 
2101 #
2102
2103 proc check_effective_target_vect_uintfloat_cvt { } {
2104     global et_vect_uintfloat_cvt_saved
2105
2106     if [info exists et_vect_uintfloat_cvt_saved] {
2107         verbose "check_effective_target_vect_uintfloat_cvt: using cached result" 2
2108     } else {
2109         set et_vect_uintfloat_cvt_saved 0
2110         if { [istarget i?86-*-*]
2111               || ([istarget powerpc*-*-*]
2112                   && ![istarget powerpc-*-linux*paired*])
2113               || [istarget x86_64-*-*] 
2114               || [istarget aarch64*-*-*]
2115               || ([istarget arm*-*-*]
2116                   && [check_effective_target_arm_neon_ok])} {
2117            set et_vect_uintfloat_cvt_saved 1
2118         }
2119     }
2120
2121     verbose "check_effective_target_vect_uintfloat_cvt: returning $et_vect_uintfloat_cvt_saved" 2
2122     return $et_vect_uintfloat_cvt_saved
2123 }
2124
2125
2126 # Return 1 if the target supports signed float->int conversion
2127 #
2128
2129 proc check_effective_target_vect_floatint_cvt { } {
2130     global et_vect_floatint_cvt_saved
2131
2132     if [info exists et_vect_floatint_cvt_saved] {
2133         verbose "check_effective_target_vect_floatint_cvt: using cached result" 2
2134     } else {
2135         set et_vect_floatint_cvt_saved 0
2136         if { [istarget i?86-*-*]
2137               || ([istarget powerpc*-*-*]
2138                    && ![istarget powerpc-*-linux*paired*])
2139               || [istarget x86_64-*-*]
2140               || ([istarget arm*-*-*]
2141                   && [check_effective_target_arm_neon_ok])} {
2142            set et_vect_floatint_cvt_saved 1
2143         }
2144     }
2145
2146     verbose "check_effective_target_vect_floatint_cvt: returning $et_vect_floatint_cvt_saved" 2
2147     return $et_vect_floatint_cvt_saved
2148 }
2149
2150 # Return 1 if the target supports unsigned float->int conversion
2151 #
2152
2153 proc check_effective_target_vect_floatuint_cvt { } {
2154     global et_vect_floatuint_cvt_saved
2155
2156     if [info exists et_vect_floatuint_cvt_saved] {
2157         verbose "check_effective_target_vect_floatuint_cvt: using cached result" 2
2158     } else {
2159         set et_vect_floatuint_cvt_saved 0
2160         if { ([istarget powerpc*-*-*]
2161               && ![istarget powerpc-*-linux*paired*])
2162             || ([istarget arm*-*-*]
2163                 && [check_effective_target_arm_neon_ok])} {
2164            set et_vect_floatuint_cvt_saved 1
2165         }
2166     }
2167
2168     verbose "check_effective_target_vect_floatuint_cvt: returning $et_vect_floatuint_cvt_saved" 2
2169     return $et_vect_floatuint_cvt_saved
2170 }
2171
2172 # Return 1 if the target supports #pragma omp declare simd, 0 otherwise.
2173 #
2174 # This won't change for different subtargets so cache the result.
2175
2176 proc check_effective_target_vect_simd_clones { } {
2177     global et_vect_simd_clones_saved
2178
2179     if [info exists et_vect_simd_clones_saved] {
2180         verbose "check_effective_target_vect_simd_clones: using cached result" 2
2181     } else {
2182         set et_vect_simd_clones_saved 0
2183         if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
2184             # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx and
2185             # avx2 clone.  Only the right clone for the specified arch will be
2186             # chosen, but still we need to at least be able to assemble
2187             # avx2.
2188             if { [check_effective_target_avx2] } {
2189                 set et_vect_simd_clones_saved 1
2190             }
2191         }
2192     }
2193
2194     verbose "check_effective_target_vect_simd_clones: returning $et_vect_simd_clones_saved" 2
2195     return $et_vect_simd_clones_saved
2196 }
2197
2198 # Return 1 if this is a AArch64 target supporting big endian
2199 proc check_effective_target_aarch64_big_endian { } {
2200     return [check_no_compiler_messages aarch64_big_endian assembly {
2201         #if !defined(__aarch64__) || !defined(__AARCH64EB__)
2202         #error FOO
2203         #endif
2204     }]
2205 }
2206
2207 # Return 1 if this is a AArch64 target supporting little endian
2208 proc check_effective_target_aarch64_little_endian { } {
2209     return [check_no_compiler_messages aarch64_little_endian assembly {
2210         #if !defined(__aarch64__) || defined(__AARCH64EB__)
2211         #error FOO
2212         #endif
2213     }]
2214 }
2215
2216 # Return 1 is this is an arm target using 32-bit instructions
2217 proc check_effective_target_arm32 { } {
2218     return [check_no_compiler_messages arm32 assembly {
2219         #if !defined(__arm__) || (defined(__thumb__) && !defined(__thumb2__))
2220         #error FOO
2221         #endif
2222     }]
2223 }
2224
2225 # Return 1 is this is an arm target not using Thumb
2226 proc check_effective_target_arm_nothumb { } {
2227     return [check_no_compiler_messages arm_nothumb assembly {
2228         #if (defined(__thumb__) || defined(__thumb2__))
2229         #error FOO
2230         #endif
2231     }]
2232 }
2233
2234 # Return 1 if this is a little-endian ARM target
2235 proc check_effective_target_arm_little_endian { } {
2236     return [check_no_compiler_messages arm_little_endian assembly {
2237         #if !defined(__arm__) || !defined(__ARMEL__)
2238         #error FOO
2239         #endif
2240     }]
2241 }
2242
2243 # Return 1 if this is an ARM target that only supports aligned vector accesses
2244 proc check_effective_target_arm_vect_no_misalign { } {
2245     return [check_no_compiler_messages arm_vect_no_misalign assembly {
2246         #if !defined(__arm__) \
2247             || (defined(__ARMEL__) \
2248                 && (!defined(__thumb__) || defined(__thumb2__)))
2249         #error FOO
2250         #endif
2251     }]
2252 }
2253
2254
2255 # Return 1 if this is an ARM target supporting -mfpu=vfp
2256 # -mfloat-abi=softfp.  Some multilibs may be incompatible with these
2257 # options.
2258
2259 proc check_effective_target_arm_vfp_ok { } {
2260     if { [check_effective_target_arm32] } {
2261         return [check_no_compiler_messages arm_vfp_ok object {
2262             int dummy;
2263         } "-mfpu=vfp -mfloat-abi=softfp"]
2264     } else {
2265         return 0
2266     }
2267 }
2268
2269 # Return 1 if this is an ARM target supporting -mfpu=vfp3
2270 # -mfloat-abi=softfp.
2271
2272 proc check_effective_target_arm_vfp3_ok { } {
2273     if { [check_effective_target_arm32] } {
2274         return [check_no_compiler_messages arm_vfp3_ok object {
2275             int dummy;
2276         } "-mfpu=vfp3 -mfloat-abi=softfp"]
2277     } else {
2278         return 0
2279     }
2280 }
2281
2282 # Return 1 if this is an ARM target supporting -mfpu=fp-armv8
2283 # -mfloat-abi=softfp.
2284 proc check_effective_target_arm_v8_vfp_ok {} {
2285     if { [check_effective_target_arm32] } {
2286         return [check_no_compiler_messages arm_v8_vfp_ok object {
2287           int foo (void)
2288           {
2289              __asm__ volatile ("vrinta.f32.f32 s0, s0");
2290              return 0;
2291           }
2292         } "-mfpu=fp-armv8 -mfloat-abi=softfp"]
2293     } else {
2294         return 0
2295     }
2296 }
2297
2298 # Return 1 if this is an ARM target supporting -mfpu=vfp
2299 # -mfloat-abi=hard.  Some multilibs may be incompatible with these
2300 # options.
2301
2302 proc check_effective_target_arm_hard_vfp_ok { } {
2303     if { [check_effective_target_arm32]
2304          && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } {
2305         return [check_no_compiler_messages arm_hard_vfp_ok executable {
2306             int main() { return 0;}
2307         } "-mfpu=vfp -mfloat-abi=hard"]
2308     } else {
2309         return 0
2310     }
2311 }
2312
2313 # Return 1 if this is an ARM target that supports DSP multiply with
2314 # current multilib flags.
2315
2316 proc check_effective_target_arm_dsp { } {
2317     return [check_no_compiler_messages arm_dsp assembly {
2318         #ifndef __ARM_FEATURE_DSP
2319         #error not DSP
2320         #endif
2321         int i;
2322     }]
2323 }
2324
2325 # Return 1 if this is an ARM target that supports unaligned word/halfword
2326 # load/store instructions.
2327
2328 proc check_effective_target_arm_unaligned { } {
2329     return [check_no_compiler_messages arm_unaligned assembly {
2330         #ifndef __ARM_FEATURE_UNALIGNED
2331         #error no unaligned support
2332         #endif
2333         int i;
2334     }]
2335 }
2336
2337 # Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
2338 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
2339 # incompatible with these options.  Also set et_arm_crypto_flags to the
2340 # best options to add.
2341
2342 proc check_effective_target_arm_crypto_ok_nocache { } {
2343     global et_arm_crypto_flags
2344     set et_arm_crypto_flags ""
2345     if { [check_effective_target_arm32] } {
2346         foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} {
2347             if { [check_no_compiler_messages_nocache arm_crypto_ok object {
2348                 #include "arm_neon.h"
2349                 uint8x16_t
2350                 foo (uint8x16_t a, uint8x16_t b)
2351                 {
2352                   return vaeseq_u8 (a, b);
2353                 }
2354             } "$flags"] } {
2355                 set et_arm_crypto_flags $flags
2356                 return 1
2357             }
2358         }
2359     }
2360
2361     return 0
2362 }
2363
2364 # Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
2365
2366 proc check_effective_target_arm_crypto_ok { } {
2367     return [check_cached_effective_target arm_crypto_ok \
2368                 check_effective_target_arm_crypto_ok_nocache]
2369 }
2370
2371 # Add options for crypto extensions.
2372 proc add_options_for_arm_crypto { flags } {
2373     if { ! [check_effective_target_arm_crypto_ok] } {
2374         return "$flags"
2375     }
2376     global et_arm_crypto_flags
2377     return "$flags $et_arm_crypto_flags"
2378 }
2379
2380 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
2381 # or -mfloat-abi=hard, but if one is already specified by the
2382 # multilib, use it.  Similarly, if a -mfpu option already enables
2383 # NEON, do not add -mfpu=neon.
2384
2385 proc add_options_for_arm_neon { flags } {
2386     if { ! [check_effective_target_arm_neon_ok] } {
2387         return "$flags"
2388     }
2389     global et_arm_neon_flags
2390     return "$flags $et_arm_neon_flags"
2391 }
2392
2393 proc add_options_for_arm_v8_vfp { flags } {
2394     if { ! [check_effective_target_arm_v8_vfp_ok] } {
2395         return "$flags"
2396     }
2397     return "$flags -mfpu=fp-armv8 -mfloat-abi=softfp"
2398 }
2399
2400 proc add_options_for_arm_v8_neon { flags } {
2401     if { ! [check_effective_target_arm_v8_neon_ok] } {
2402         return "$flags"
2403     }
2404     global et_arm_v8_neon_flags
2405     return "$flags $et_arm_v8_neon_flags -march=armv8-a"
2406 }
2407
2408 proc add_options_for_arm_crc { flags } {
2409     if { ! [check_effective_target_arm_crc_ok] } {
2410         return "$flags"
2411     }
2412     global et_arm_crc_flags
2413     return "$flags $et_arm_crc_flags"
2414 }
2415
2416 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
2417 # or -mfloat-abi=hard, but if one is already specified by the
2418 # multilib, use it.  Similarly, if a -mfpu option already enables
2419 # NEON, do not add -mfpu=neon.
2420
2421 proc add_options_for_arm_neonv2 { flags } {
2422     if { ! [check_effective_target_arm_neonv2_ok] } {
2423         return "$flags"
2424     }
2425     global et_arm_neonv2_flags
2426     return "$flags $et_arm_neonv2_flags"
2427 }
2428
2429 # Add the options needed for vfp3.
2430 proc add_options_for_arm_vfp3 { flags } {
2431     if { ! [check_effective_target_arm_vfp3_ok] } {
2432         return "$flags"
2433     }
2434     return "$flags -mfpu=vfp3 -mfloat-abi=softfp"
2435 }
2436
2437 # Return 1 if this is an ARM target supporting -mfpu=neon
2438 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
2439 # incompatible with these options.  Also set et_arm_neon_flags to the
2440 # best options to add.
2441
2442 proc check_effective_target_arm_neon_ok_nocache { } {
2443     global et_arm_neon_flags
2444     set et_arm_neon_flags ""
2445     if { [check_effective_target_arm32] } {
2446         foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp"} {
2447             if { [check_no_compiler_messages_nocache arm_neon_ok object {
2448                 #include "arm_neon.h"
2449                 int dummy;
2450             } "$flags"] } {
2451                 set et_arm_neon_flags $flags
2452                 return 1
2453             }
2454         }
2455     }
2456
2457     return 0
2458 }
2459
2460 proc check_effective_target_arm_neon_ok { } {
2461     return [check_cached_effective_target arm_neon_ok \
2462                 check_effective_target_arm_neon_ok_nocache]
2463 }
2464
2465 proc check_effective_target_arm_crc_ok_nocache { } {
2466     global et_arm_crc_flags
2467     set et_arm_crc_flags "-march=armv8-a+crc"
2468     return [check_no_compiler_messages_nocache arm_crc_ok object {
2469         #if !defined (__ARM_FEATURE_CRC32)
2470         #error FOO
2471         #endif
2472     } "$et_arm_crc_flags"]
2473 }
2474
2475 proc check_effective_target_arm_crc_ok { } {
2476     return [check_cached_effective_target arm_crc_ok \
2477                 check_effective_target_arm_crc_ok_nocache]
2478 }
2479
2480 # Return 1 if this is an ARM target supporting -mfpu=neon-fp16
2481 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
2482 # incompatible with these options.  Also set et_arm_neon_flags to the
2483 # best options to add.
2484
2485 proc check_effective_target_arm_neon_fp16_ok_nocache { } {
2486     global et_arm_neon_fp16_flags
2487     set et_arm_neon_fp16_flags ""
2488     if { [check_effective_target_arm32] } {
2489         foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
2490                        "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
2491             if { [check_no_compiler_messages_nocache arm_neon_fp_16_ok object {
2492                 #include "arm_neon.h"
2493                 float16x4_t
2494                 foo (float32x4_t arg)
2495                 {
2496                   return vcvt_f16_f32 (arg);
2497                 }
2498             } "$flags"] } {
2499                 set et_arm_neon_fp16_flags $flags
2500                 return 1
2501             }
2502         }
2503     }
2504
2505     return 0
2506 }
2507
2508 proc check_effective_target_arm_neon_fp16_ok { } {
2509     return [check_cached_effective_target arm_neon_fp16_ok \
2510                 check_effective_target_arm_neon_fp16_ok_nocache]
2511 }
2512
2513 proc add_options_for_arm_neon_fp16 { flags } {
2514     if { ! [check_effective_target_arm_neon_fp16_ok] } {
2515         return "$flags"
2516     }
2517     global et_arm_neon_fp16_flags
2518     return "$flags $et_arm_neon_fp16_flags"
2519 }
2520
2521 # Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8
2522 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
2523 # incompatible with these options.  Also set et_arm_v8_neon_flags to the
2524 # best options to add.
2525
2526 proc check_effective_target_arm_v8_neon_ok_nocache { } {
2527     global et_arm_v8_neon_flags
2528     set et_arm_v8_neon_flags ""
2529     if { [check_effective_target_arm32] } {
2530         foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
2531             if { [check_no_compiler_messages_nocache arm_v8_neon_ok object {
2532                 #include "arm_neon.h"
2533                 void
2534                 foo ()
2535                 {
2536                   __asm__ volatile ("vrintn.f32 q0, q0");
2537                 }
2538             } "$flags"] } {
2539                 set et_arm_v8_neon_flags $flags
2540                 return 1
2541             }
2542         }
2543     }
2544
2545     return 0
2546 }
2547
2548 proc check_effective_target_arm_v8_neon_ok { } {
2549     return [check_cached_effective_target arm_v8_neon_ok \
2550                 check_effective_target_arm_v8_neon_ok_nocache]
2551 }
2552
2553 # Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4
2554 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
2555 # incompatible with these options.  Also set et_arm_neonv2_flags to the
2556 # best options to add.
2557
2558 proc check_effective_target_arm_neonv2_ok_nocache { } {
2559     global et_arm_neonv2_flags
2560     set et_arm_neonv2_flags ""
2561     if { [check_effective_target_arm32] } {
2562         foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-vfpv4" "-mfpu=neon-vfpv4 -mfloat-abi=softfp"} {
2563             if { [check_no_compiler_messages_nocache arm_neonv2_ok object {
2564                 #include "arm_neon.h"
2565                 float32x2_t 
2566                 foo (float32x2_t a, float32x2_t b, float32x2_t c)
2567                 {
2568                   return vfma_f32 (a, b, c);
2569                 }
2570             } "$flags"] } {
2571                 set et_arm_neonv2_flags $flags
2572                 return 1
2573             }
2574         }
2575     }
2576
2577     return 0
2578 }
2579
2580 proc check_effective_target_arm_neonv2_ok { } {
2581     return [check_cached_effective_target arm_neonv2_ok \
2582                 check_effective_target_arm_neonv2_ok_nocache]
2583 }
2584
2585 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
2586 # or -mfloat-abi=hard, but if one is already specified by the
2587 # multilib, use it.
2588
2589 proc add_options_for_arm_fp16 { flags } {
2590     if { ! [check_effective_target_arm_fp16_ok] } {
2591         return "$flags"
2592     }
2593     global et_arm_fp16_flags
2594     return "$flags $et_arm_fp16_flags"
2595 }
2596
2597 # Return 1 if this is an ARM target that can support a VFP fp16 variant.
2598 # Skip multilibs that are incompatible with these options and set
2599 # et_arm_fp16_flags to the best options to add.
2600
2601 proc check_effective_target_arm_fp16_ok_nocache { } {
2602     global et_arm_fp16_flags
2603     set et_arm_fp16_flags ""
2604     if { ! [check_effective_target_arm32] } {
2605         return 0;
2606     }
2607     if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" "-mfpu=*fpv[1-9][0-9]*" } ]] {
2608         # Multilib flags would override -mfpu.
2609         return 0
2610     }
2611     if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] {
2612         # Must generate floating-point instructions.
2613         return 0
2614     }
2615     if [check_effective_target_arm_hf_eabi] {
2616         # Use existing float-abi and force an fpu which supports fp16
2617         set et_arm_fp16_flags "-mfpu=vfpv4"
2618         return 1;
2619     }
2620     if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] {
2621         # The existing -mfpu value is OK; use it, but add softfp.
2622         set et_arm_fp16_flags "-mfloat-abi=softfp"
2623         return 1;
2624     }
2625     # Add -mfpu for a VFP fp16 variant since there is no preprocessor
2626     # macro to check for this support.
2627     set flags "-mfpu=vfpv4 -mfloat-abi=softfp"
2628     if { [check_no_compiler_messages_nocache arm_fp16_ok assembly {
2629         int dummy;
2630     } "$flags"] } {
2631         set et_arm_fp16_flags "$flags"
2632         return 1
2633     }
2634
2635     return 0
2636 }
2637
2638 proc check_effective_target_arm_fp16_ok { } {
2639     return [check_cached_effective_target arm_fp16_ok \
2640                 check_effective_target_arm_fp16_ok_nocache]
2641 }
2642
2643 # Creates a series of routines that return 1 if the given architecture
2644 # can be selected and a routine to give the flags to select that architecture
2645 # Note: Extra flags may be added to disable options from newer compilers
2646 # (Thumb in particular - but others may be added in the future)
2647 # Usage: /* { dg-require-effective-target arm_arch_v5_ok } */
2648 #        /* { dg-add-options arm_arch_v5 } */
2649 #        /* { dg-require-effective-target arm_arch_v5_multilib } */
2650 foreach { armfunc armflag armdef } { v4 "-march=armv4 -marm" __ARM_ARCH_4__
2651                                      v4t "-march=armv4t" __ARM_ARCH_4T__
2652                                      v5 "-march=armv5 -marm" __ARM_ARCH_5__
2653                                      v5t "-march=armv5t" __ARM_ARCH_5T__
2654                                      v5te "-march=armv5te" __ARM_ARCH_5TE__
2655                                      v6 "-march=armv6" __ARM_ARCH_6__
2656                                      v6k "-march=armv6k" __ARM_ARCH_6K__
2657                                      v6t2 "-march=armv6t2" __ARM_ARCH_6T2__
2658                                      v6z "-march=armv6z" __ARM_ARCH_6Z__
2659                                      v6m "-march=armv6-m -mthumb" __ARM_ARCH_6M__
2660                                      v7a "-march=armv7-a" __ARM_ARCH_7A__
2661                                      v7ve "-march=armv7ve" __ARM_ARCH_7A__
2662                                      v7r "-march=armv7-r" __ARM_ARCH_7R__
2663                                      v7m "-march=armv7-m -mthumb" __ARM_ARCH_7M__
2664                                      v7em "-march=armv7e-m -mthumb" __ARM_ARCH_7EM__
2665                                      v8a "-march=armv8-a" __ARM_ARCH_8A__ } {
2666     eval [string map [list FUNC $armfunc FLAG $armflag DEF $armdef ] {
2667         proc check_effective_target_arm_arch_FUNC_ok { } {
2668             if { [ string match "*-marm*" "FLAG" ] &&
2669                 ![check_effective_target_arm_arm_ok] } {
2670                 return 0
2671             }
2672             return [check_no_compiler_messages arm_arch_FUNC_ok assembly {
2673                 #if !defined (DEF)
2674                 #error FOO
2675                 #endif
2676             } "FLAG" ]
2677         }
2678
2679         proc add_options_for_arm_arch_FUNC { flags } {
2680             return "$flags FLAG"
2681         }
2682
2683         proc check_effective_target_arm_arch_FUNC_multilib { } {
2684             return [check_runtime arm_arch_FUNC_multilib {
2685                 int
2686                 main (void)
2687                 {
2688                     return 0;
2689                 }
2690             } [add_options_for_arm_arch_FUNC ""]]
2691         }
2692     }]
2693 }
2694
2695 # Return 1 if this is an ARM target where -marm causes ARM to be
2696 # used (not Thumb)
2697
2698 proc check_effective_target_arm_arm_ok { } {
2699     return [check_no_compiler_messages arm_arm_ok assembly {
2700         #if !defined (__arm__) || defined (__thumb__) || defined (__thumb2__)
2701         #error FOO
2702         #endif
2703     } "-marm"]
2704 }
2705
2706
2707 # Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
2708 # used.
2709
2710 proc check_effective_target_arm_thumb1_ok { } {
2711     return [check_no_compiler_messages arm_thumb1_ok assembly {
2712         #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
2713         #error FOO
2714         #endif
2715     } "-mthumb"]
2716 }
2717
2718 # Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
2719 # used.
2720
2721 proc check_effective_target_arm_thumb2_ok { } {
2722     return [check_no_compiler_messages arm_thumb2_ok assembly {
2723         #if !defined(__thumb2__)
2724         #error FOO
2725         #endif
2726     } "-mthumb"]
2727 }
2728
2729 # Return 1 if this is an ARM target where Thumb-1 is used without options
2730 # added by the test.
2731
2732 proc check_effective_target_arm_thumb1 { } {
2733     return [check_no_compiler_messages arm_thumb1 assembly {
2734         #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
2735         #error not thumb1
2736         #endif
2737         int i;
2738     } ""]
2739 }
2740
2741 # Return 1 if this is an ARM target where Thumb-2 is used without options
2742 # added by the test.
2743
2744 proc check_effective_target_arm_thumb2 { } {
2745     return [check_no_compiler_messages arm_thumb2 assembly {
2746         #if !defined(__thumb2__)
2747         #error FOO
2748         #endif
2749         int i;
2750     } ""]
2751 }
2752
2753 # Return 1 if this is an ARM target where conditional execution is available.
2754
2755 proc check_effective_target_arm_cond_exec { } {
2756     return [check_no_compiler_messages arm_cond_exec assembly {
2757         #if defined(__arm__) && defined(__thumb__) && !defined(__thumb2__)
2758         #error FOO
2759         #endif
2760         int i;
2761     } ""]
2762 }
2763
2764 # Return 1 if this is an ARM cortex-M profile cpu
2765
2766 proc check_effective_target_arm_cortex_m { } {
2767     return [check_no_compiler_messages arm_cortex_m assembly {
2768         #if !defined(__ARM_ARCH_7M__) \
2769             && !defined (__ARM_ARCH_7EM__) \
2770             && !defined (__ARM_ARCH_6M__)
2771         #error FOO
2772         #endif
2773         int i;
2774     } "-mthumb"]
2775 }
2776
2777 # Return 1 if the target supports executing NEON instructions, 0
2778 # otherwise.  Cache the result.
2779
2780 proc check_effective_target_arm_neon_hw { } {
2781     return [check_runtime arm_neon_hw_available {
2782         int
2783         main (void)
2784         {
2785           long long a = 0, b = 1;
2786           asm ("vorr %P0, %P1, %P2"
2787                : "=w" (a)
2788                : "0" (a), "w" (b));
2789           return (a != 1);
2790         }
2791     } [add_options_for_arm_neon ""]]
2792 }
2793
2794 proc check_effective_target_arm_neonv2_hw { } {
2795     return [check_runtime arm_neon_hwv2_available {
2796         #include "arm_neon.h"
2797         int
2798         main (void)
2799         {
2800           float32x2_t a, b, c;
2801           asm ("vfma.f32 %P0, %P1, %P2"
2802                : "=w" (a)
2803                : "w" (b), "w" (c));
2804           return 0;
2805         }
2806     } [add_options_for_arm_neonv2 ""]]
2807 }
2808
2809 # Return 1 if the target supports executing ARMv8 NEON instructions, 0
2810 # otherwise.
2811
2812 proc check_effective_target_arm_v8_neon_hw { } {
2813     return [check_runtime arm_v8_neon_hw_available {
2814         #include "arm_neon.h"
2815         int
2816         main (void)
2817         {
2818           float32x2_t a;
2819           asm ("vrinta.f32 %P0, %P1"
2820                : "=w" (a)
2821                : "0" (a));
2822           return 0;
2823         }
2824     } [add_options_for_arm_v8_neon ""]]
2825 }
2826
2827 # Return 1 if this is a ARM target with NEON enabled.
2828
2829 proc check_effective_target_arm_neon { } {
2830     if { [check_effective_target_arm32] } {
2831         return [check_no_compiler_messages arm_neon object {
2832             #ifndef __ARM_NEON__
2833             #error not NEON
2834             #else
2835             int dummy;
2836             #endif
2837         }]
2838     } else {
2839         return 0
2840     }
2841 }
2842
2843 proc check_effective_target_arm_neonv2 { } {
2844     if { [check_effective_target_arm32] } {
2845         return [check_no_compiler_messages arm_neon object {
2846             #ifndef __ARM_NEON__
2847             #error not NEON
2848             #else
2849             #ifndef __ARM_FEATURE_FMA
2850             #error not NEONv2
2851             #else
2852             int dummy;
2853             #endif
2854             #endif
2855         }]
2856     } else {
2857         return 0
2858     }
2859 }
2860
2861 # Return 1 if this a Loongson-2E or -2F target using an ABI that supports
2862 # the Loongson vector modes.
2863
2864 proc check_effective_target_mips_loongson { } {
2865     return [check_no_compiler_messages loongson assembly {
2866         #if !defined(__mips_loongson_vector_rev)
2867         #error FOO
2868         #endif
2869     }]
2870 }
2871
2872 # Return 1 if this is an ARM target that adheres to the ABI for the ARM
2873 # Architecture.
2874
2875 proc check_effective_target_arm_eabi { } {
2876     return [check_no_compiler_messages arm_eabi object {
2877         #ifndef __ARM_EABI__
2878         #error not EABI
2879         #else
2880         int dummy;
2881         #endif
2882     }]
2883 }
2884
2885 # Return 1 if this is an ARM target that adheres to the hard-float variant of
2886 # the ABI for the ARM Architecture (e.g. -mfloat-abi=hard).
2887
2888 proc check_effective_target_arm_hf_eabi { } {
2889     return [check_no_compiler_messages arm_hf_eabi object {
2890         #if !defined(__ARM_EABI__) || !defined(__ARM_PCS_VFP)
2891         #error not hard-float EABI
2892         #else
2893         int dummy;
2894         #endif
2895     }]
2896 }
2897
2898 # Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
2899 # Some multilibs may be incompatible with this option.
2900
2901 proc check_effective_target_arm_iwmmxt_ok { } {
2902     if { [check_effective_target_arm32] } {
2903         return [check_no_compiler_messages arm_iwmmxt_ok object {
2904             int dummy;
2905         } "-mcpu=iwmmxt"]
2906     } else {
2907         return 0
2908     }
2909 }
2910
2911 # Return true if LDRD/STRD instructions are prefered over LDM/STM instructions
2912 # for an ARM target.
2913 proc check_effective_target_arm_prefer_ldrd_strd { } {
2914     if { ![check_effective_target_arm32] } {
2915       return 0;
2916     }
2917
2918     return [check_no_messages_and_pattern arm_prefer_ldrd_strd "strd\tr" assembly {
2919         void foo (int *p) { p[0] = 1; p[1] = 0;}
2920     }  "-O2 -mthumb" ]
2921 }
2922
2923 # Return 1 if this is a PowerPC target supporting -meabi.
2924
2925 proc check_effective_target_powerpc_eabi_ok { } {
2926     if { [istarget powerpc*-*-*] } {
2927         return [check_no_compiler_messages powerpc_eabi_ok object {
2928             int dummy;
2929         } "-meabi"]
2930     } else {
2931         return 0
2932     }
2933 }
2934
2935 # Return 1 if this is a PowerPC target with floating-point registers.
2936
2937 proc check_effective_target_powerpc_fprs { } {
2938     if { [istarget powerpc*-*-*]
2939          || [istarget rs6000-*-*] } {
2940         return [check_no_compiler_messages powerpc_fprs object {
2941             #ifdef __NO_FPRS__
2942             #error no FPRs
2943             #else
2944             int dummy;
2945             #endif
2946         }]
2947     } else {
2948         return 0
2949     }
2950 }
2951
2952 # Return 1 if this is a PowerPC target with hardware double-precision
2953 # floating point.
2954
2955 proc check_effective_target_powerpc_hard_double { } {
2956     if { [istarget powerpc*-*-*]
2957          || [istarget rs6000-*-*] } {
2958         return [check_no_compiler_messages powerpc_hard_double object {
2959             #ifdef _SOFT_DOUBLE
2960             #error soft double
2961             #else
2962             int dummy;
2963             #endif
2964         }]
2965     } else {
2966         return 0
2967     }
2968 }
2969
2970 # Return 1 if this is a PowerPC target supporting -maltivec.
2971
2972 proc check_effective_target_powerpc_altivec_ok { } {
2973     if { ([istarget powerpc*-*-*]
2974          && ![istarget powerpc-*-linux*paired*])
2975          || [istarget rs6000-*-*] } {
2976         # AltiVec is not supported on AIX before 5.3.
2977         if { [istarget powerpc*-*-aix4*]
2978              || [istarget powerpc*-*-aix5.1*] 
2979              || [istarget powerpc*-*-aix5.2*] } {
2980             return 0
2981         }
2982         return [check_no_compiler_messages powerpc_altivec_ok object {
2983             int dummy;
2984         } "-maltivec"]
2985     } else {
2986         return 0
2987     }
2988 }
2989
2990 # Return 1 if this is a PowerPC target supporting -mpower8-vector
2991
2992 proc check_effective_target_powerpc_p8vector_ok { } {
2993     if { ([istarget powerpc*-*-*]
2994          && ![istarget powerpc-*-linux*paired*])
2995          || [istarget rs6000-*-*] } {
2996         # AltiVec is not supported on AIX before 5.3.
2997         if { [istarget powerpc*-*-aix4*]
2998              || [istarget powerpc*-*-aix5.1*] 
2999              || [istarget powerpc*-*-aix5.2*] } {
3000             return 0
3001         }
3002         return [check_no_compiler_messages powerpc_p8vector_ok object {
3003             int main (void) {
3004 #ifdef __MACH__
3005                 asm volatile ("xxlorc vs0,vs0,vs0");
3006 #else
3007                 asm volatile ("xxlorc 0,0,0");
3008 #endif
3009                 return 0;
3010             }
3011         } "-mpower8-vector"]
3012     } else {
3013         return 0
3014     }
3015 }
3016
3017 # Return 1 if this is a PowerPC target supporting -mvsx
3018
3019 proc check_effective_target_powerpc_vsx_ok { } {
3020     if { ([istarget powerpc*-*-*]
3021          && ![istarget powerpc-*-linux*paired*])
3022          || [istarget rs6000-*-*] } {
3023         # VSX is not supported on AIX before 7.1.
3024         if { [istarget powerpc*-*-aix4*]
3025              || [istarget powerpc*-*-aix5*]
3026              || [istarget powerpc*-*-aix6*] } {
3027             return 0
3028         }
3029         return [check_no_compiler_messages powerpc_vsx_ok object {
3030             int main (void) {
3031 #ifdef __MACH__
3032                 asm volatile ("xxlor vs0,vs0,vs0");
3033 #else
3034                 asm volatile ("xxlor 0,0,0");
3035 #endif
3036                 return 0;
3037             }
3038         } "-mvsx"]
3039     } else {
3040         return 0
3041     }
3042 }
3043
3044 # Return 1 if this is a PowerPC target supporting -mhtm
3045
3046 proc check_effective_target_powerpc_htm_ok { } {
3047     if { ([istarget powerpc*-*-*]
3048          && ![istarget powerpc-*-linux*paired*])
3049          || [istarget rs6000-*-*] } {
3050         # HTM is not supported on AIX yet.
3051         if { [istarget powerpc*-*-aix*] } {
3052             return 0
3053         }
3054         return [check_no_compiler_messages powerpc_htm_ok object {
3055             int main (void) {
3056                 asm volatile ("tbegin. 0");
3057                 return 0;
3058             }
3059         } "-mhtm"]
3060     } else {
3061         return 0
3062     }
3063 }
3064
3065 # Return 1 if this is a PowerPC target supporting -mcpu=cell.
3066
3067 proc check_effective_target_powerpc_ppu_ok { } {
3068     if [check_effective_target_powerpc_altivec_ok] {
3069         return [check_no_compiler_messages cell_asm_available object {
3070             int main (void) {
3071 #ifdef __MACH__
3072                 asm volatile ("lvlx v0,v0,v0");
3073 #else
3074                 asm volatile ("lvlx 0,0,0");
3075 #endif
3076                 return 0;
3077             }
3078         }]
3079     } else {
3080         return 0
3081     }
3082 }
3083
3084 # Return 1 if this is a PowerPC target that supports SPU.
3085
3086 proc check_effective_target_powerpc_spu { } {
3087     if { [istarget powerpc*-*-linux*] } {
3088         return [check_effective_target_powerpc_altivec_ok]
3089     } else {
3090         return 0
3091     }
3092 }
3093
3094 # Return 1 if this is a PowerPC SPE target.  The check includes options
3095 # specified by dg-options for this test, so don't cache the result.
3096
3097 proc check_effective_target_powerpc_spe_nocache { } {
3098     if { [istarget powerpc*-*-*] } {
3099         return [check_no_compiler_messages_nocache powerpc_spe object {
3100             #ifndef __SPE__
3101             #error not SPE
3102             #else
3103             int dummy;
3104             #endif
3105         } [current_compiler_flags]]
3106     } else {
3107         return 0
3108     }
3109 }
3110
3111 # Return 1 if this is a PowerPC target with SPE enabled.
3112
3113 proc check_effective_target_powerpc_spe { } {
3114     if { [istarget powerpc*-*-*] } {
3115         return [check_no_compiler_messages powerpc_spe object {
3116             #ifndef __SPE__
3117             #error not SPE
3118             #else
3119             int dummy;
3120             #endif
3121         }]
3122     } else {
3123         return 0
3124     }
3125 }
3126
3127 # Return 1 if this is a PowerPC target with Altivec enabled.
3128
3129 proc check_effective_target_powerpc_altivec { } {
3130     if { [istarget powerpc*-*-*] } {
3131         return [check_no_compiler_messages powerpc_altivec object {
3132             #ifndef __ALTIVEC__
3133             #error not Altivec
3134             #else
3135             int dummy;
3136             #endif
3137         }]
3138     } else {
3139         return 0
3140     }
3141 }
3142
3143 # Return 1 if this is a PowerPC 405 target.  The check includes options
3144 # specified by dg-options for this test, so don't cache the result.
3145
3146 proc check_effective_target_powerpc_405_nocache { } {
3147     if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } {
3148         return [check_no_compiler_messages_nocache powerpc_405 object {
3149             #ifdef __PPC405__
3150             int dummy;
3151             #else
3152             #error not a PPC405
3153             #endif
3154         } [current_compiler_flags]]
3155     } else {
3156         return 0
3157     }
3158 }
3159
3160 # Return 1 if this is a PowerPC target using the ELFv2 ABI.
3161
3162 proc check_effective_target_powerpc_elfv2 { } {
3163     if { [istarget powerpc*-*-*] } {
3164         return [check_no_compiler_messages powerpc_elfv2 object {
3165             #if _CALL_ELF != 2
3166             #error not ELF v2 ABI
3167             #else
3168             int dummy;
3169             #endif
3170         }]
3171     } else {
3172         return 0
3173     }
3174 }
3175
3176 # Return 1 if this is a SPU target with a toolchain that
3177 # supports automatic overlay generation.
3178
3179 proc check_effective_target_spu_auto_overlay { } {
3180     if { [istarget spu*-*-elf*] } {
3181         return [check_no_compiler_messages spu_auto_overlay executable {
3182                 int main (void) { }
3183                 } "-Wl,--auto-overlay" ]
3184     } else {
3185         return 0
3186     }
3187 }
3188
3189 # The VxWorks SPARC simulator accepts only EM_SPARC executables and
3190 # chokes on EM_SPARC32PLUS or EM_SPARCV9 executables.  Return 1 if the
3191 # test environment appears to run executables on such a simulator.
3192
3193 proc check_effective_target_ultrasparc_hw { } {
3194     return [check_runtime ultrasparc_hw {
3195         int main() { return 0; }
3196     } "-mcpu=ultrasparc"]
3197 }
3198
3199 # Return 1 if the test environment supports executing UltraSPARC VIS2
3200 # instructions.  We check this by attempting: "bmask %g0, %g0, %g0"
3201
3202 proc check_effective_target_ultrasparc_vis2_hw { } {
3203     return [check_runtime ultrasparc_vis2_hw {
3204         int main() { __asm__(".word 0x81b00320"); return 0; }
3205     } "-mcpu=ultrasparc3"]
3206 }
3207
3208 # Return 1 if the test environment supports executing UltraSPARC VIS3
3209 # instructions.  We check this by attempting: "addxc %g0, %g0, %g0"
3210
3211 proc check_effective_target_ultrasparc_vis3_hw { } {
3212     return [check_runtime ultrasparc_vis3_hw {
3213         int main() { __asm__(".word 0x81b00220"); return 0; }
3214     } "-mcpu=niagara3"]
3215 }
3216
3217 # Return 1 if this is a SPARC-V9 target.
3218
3219 proc check_effective_target_sparc_v9 { } {
3220     if { [istarget sparc*-*-*] } {
3221         return [check_no_compiler_messages sparc_v9 object {
3222             int main (void) {
3223                 asm volatile ("return %i7+8");
3224                 return 0;
3225             }
3226         }]
3227     } else {
3228         return 0
3229     }
3230 }
3231
3232 # Return 1 if this is a SPARC target with VIS enabled.
3233
3234 proc check_effective_target_sparc_vis { } {
3235     if { [istarget sparc*-*-*] } {
3236         return [check_no_compiler_messages sparc_vis object {
3237             #ifndef __VIS__
3238             #error not VIS
3239             #else
3240             int dummy;
3241             #endif
3242         }]
3243     } else {
3244         return 0
3245     }
3246 }
3247
3248 # Return 1 if the target supports hardware vector shift operation.
3249
3250 proc check_effective_target_vect_shift { } {
3251     global et_vect_shift_saved
3252
3253     if [info exists et_vect_shift_saved] {
3254         verbose "check_effective_target_vect_shift: using cached result" 2
3255     } else {
3256         set et_vect_shift_saved 0
3257         if { ([istarget powerpc*-*-*]
3258              && ![istarget powerpc-*-linux*paired*])
3259              || [istarget ia64-*-*]
3260              || [istarget i?86-*-*]
3261              || [istarget x86_64-*-*]
3262              || [istarget aarch64*-*-*]
3263              || [check_effective_target_arm32]
3264              || ([istarget mips*-*-*]
3265                  && [check_effective_target_mips_loongson]) } {
3266            set et_vect_shift_saved 1
3267         }
3268     }
3269
3270     verbose "check_effective_target_vect_shift: returning $et_vect_shift_saved" 2
3271     return $et_vect_shift_saved
3272 }
3273
3274 # Return 1 if the target supports hardware vector shift operation for char.
3275
3276 proc check_effective_target_vect_shift_char { } {
3277     global et_vect_shift_char_saved
3278
3279     if [info exists et_vect_shift_char_saved] {
3280         verbose "check_effective_target_vect_shift_char: using cached result" 2
3281     } else {
3282         set et_vect_shift_char_saved 0
3283         if { ([istarget powerpc*-*-*]
3284              && ![istarget powerpc-*-linux*paired*])
3285              || [check_effective_target_arm32] } {
3286            set et_vect_shift_char_saved 1
3287         }
3288     }
3289
3290     verbose "check_effective_target_vect_shift_char: returning $et_vect_shift_char_saved" 2
3291     return $et_vect_shift_char_saved
3292 }
3293
3294 # Return 1 if the target supports hardware vectors of long, 0 otherwise.
3295 #
3296 # This can change for different subtargets so do not cache the result.
3297
3298 proc check_effective_target_vect_long { } {
3299     if { [istarget i?86-*-*]
3300          || (([istarget powerpc*-*-*] 
3301               && ![istarget powerpc-*-linux*paired*]) 
3302               && [check_effective_target_ilp32])
3303          || [istarget x86_64-*-*]
3304          || [check_effective_target_arm32]
3305          || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) } {
3306         set answer 1
3307     } else {
3308         set answer 0
3309     }
3310
3311     verbose "check_effective_target_vect_long: returning $answer" 2
3312     return $answer
3313 }
3314
3315 # Return 1 if the target supports hardware vectors of float, 0 otherwise.
3316 #
3317 # This won't change for different subtargets so cache the result.
3318
3319 proc check_effective_target_vect_float { } {
3320     global et_vect_float_saved
3321
3322     if [info exists et_vect_float_saved] {
3323         verbose "check_effective_target_vect_float: using cached result" 2
3324     } else {
3325         set et_vect_float_saved 0
3326         if { [istarget i?86-*-*]
3327               || [istarget powerpc*-*-*]
3328               || [istarget spu-*-*]
3329               || [istarget mips-sde-elf]
3330               || [istarget mipsisa64*-*-*]
3331               || [istarget x86_64-*-*]
3332               || [istarget ia64-*-*]
3333               || [istarget aarch64*-*-*]
3334               || [check_effective_target_arm32] } {
3335            set et_vect_float_saved 1
3336         }
3337     }
3338
3339     verbose "check_effective_target_vect_float: returning $et_vect_float_saved" 2
3340     return $et_vect_float_saved
3341 }
3342
3343 # Return 1 if the target supports hardware vectors of double, 0 otherwise.
3344 #
3345 # This won't change for different subtargets so cache the result.
3346
3347 proc check_effective_target_vect_double { } {
3348     global et_vect_double_saved
3349
3350     if [info exists et_vect_double_saved] {
3351         verbose "check_effective_target_vect_double: using cached result" 2
3352     } else {
3353         set et_vect_double_saved 0
3354         if { [istarget i?86-*-*]
3355               || [istarget aarch64*-*-*]
3356               || [istarget x86_64-*-*] } {
3357            if { [check_no_compiler_messages vect_double assembly {
3358                  #ifdef __tune_atom__
3359                  # error No double vectorizer support.
3360                  #endif
3361                 }] } {
3362                 set et_vect_double_saved 1
3363             } else {
3364                 set et_vect_double_saved 0
3365             }
3366         } elseif { [istarget spu-*-*] } {
3367            set et_vect_double_saved 1
3368         }
3369     }
3370
3371     verbose "check_effective_target_vect_double: returning $et_vect_double_saved" 2
3372     return $et_vect_double_saved
3373 }
3374
3375 # Return 1 if the target supports hardware vectors of long long, 0 otherwise.
3376 #
3377 # This won't change for different subtargets so cache the result.
3378
3379 proc check_effective_target_vect_long_long { } {
3380     global et_vect_long_long_saved
3381
3382     if [info exists et_vect_long_long_saved] {
3383         verbose "check_effective_target_vect_long_long: using cached result" 2
3384     } else {
3385         set et_vect_long_long_saved 0
3386         if { [istarget i?86-*-*]
3387               || [istarget x86_64-*-*] } {
3388            set et_vect_long_long_saved 1
3389         }
3390     }
3391
3392     verbose "check_effective_target_vect_long_long: returning $et_vect_long_long_saved" 2
3393     return $et_vect_long_long_saved
3394 }
3395
3396
3397 # Return 1 if the target plus current options does not support a vector
3398 # max instruction on "int", 0 otherwise.
3399 #
3400 # This won't change for different subtargets so cache the result.
3401
3402 proc check_effective_target_vect_no_int_max { } {
3403     global et_vect_no_int_max_saved
3404
3405     if [info exists et_vect_no_int_max_saved] {
3406         verbose "check_effective_target_vect_no_int_max: using cached result" 2
3407     } else {
3408         set et_vect_no_int_max_saved 0
3409         if { [istarget sparc*-*-*]
3410              || [istarget spu-*-*]
3411              || [istarget alpha*-*-*]
3412              || ([istarget mips*-*-*]
3413                  && [check_effective_target_mips_loongson]) } {
3414             set et_vect_no_int_max_saved 1
3415         }
3416     }
3417     verbose "check_effective_target_vect_no_int_max: returning $et_vect_no_int_max_saved" 2
3418     return $et_vect_no_int_max_saved
3419 }
3420
3421 # Return 1 if the target plus current options does not support a vector
3422 # add instruction on "int", 0 otherwise.
3423 #
3424 # This won't change for different subtargets so cache the result.
3425
3426 proc check_effective_target_vect_no_int_add { } {
3427     global et_vect_no_int_add_saved
3428
3429     if [info exists et_vect_no_int_add_saved] {
3430         verbose "check_effective_target_vect_no_int_add: using cached result" 2
3431     } else {
3432         set et_vect_no_int_add_saved 0
3433         # Alpha only supports vector add on V8QI and V4HI.
3434         if { [istarget alpha*-*-*] } {
3435             set et_vect_no_int_add_saved 1
3436         }
3437     }
3438     verbose "check_effective_target_vect_no_int_add: returning $et_vect_no_int_add_saved" 2
3439     return $et_vect_no_int_add_saved
3440 }
3441
3442 # Return 1 if the target plus current options does not support vector
3443 # bitwise instructions, 0 otherwise.
3444 #
3445 # This won't change for different subtargets so cache the result.
3446
3447 proc check_effective_target_vect_no_bitwise { } {
3448     global et_vect_no_bitwise_saved
3449
3450     if [info exists et_vect_no_bitwise_saved] {
3451         verbose "check_effective_target_vect_no_bitwise: using cached result" 2
3452     } else {
3453         set et_vect_no_bitwise_saved 0
3454     }
3455     verbose "check_effective_target_vect_no_bitwise: returning $et_vect_no_bitwise_saved" 2
3456     return $et_vect_no_bitwise_saved
3457 }
3458
3459 # Return 1 if the target plus current options supports vector permutation,
3460 # 0 otherwise.
3461 #
3462 # This won't change for different subtargets so cache the result.
3463
3464 proc check_effective_target_vect_perm { } {
3465     global et_vect_perm
3466
3467     if [info exists et_vect_perm_saved] {
3468         verbose "check_effective_target_vect_perm: using cached result" 2
3469     } else {
3470         set et_vect_perm_saved 0
3471         if { [is-effective-target arm_neon_ok]
3472              || ([istarget aarch64*-*-*]
3473                  && [is-effective-target aarch64_little_endian])
3474              || [istarget powerpc*-*-*]
3475              || [istarget spu-*-*]
3476              || [istarget i?86-*-*]
3477              || [istarget x86_64-*-*]
3478              || ([istarget mips*-*-*]
3479                  && [check_effective_target_mpaired_single]) } {
3480             set et_vect_perm_saved 1
3481         }
3482     }
3483     verbose "check_effective_target_vect_perm: returning $et_vect_perm_saved" 2
3484     return $et_vect_perm_saved
3485 }
3486
3487 # Return 1 if the target plus current options supports vector permutation
3488 # on byte-sized elements, 0 otherwise.
3489 #
3490 # This won't change for different subtargets so cache the result.
3491
3492 proc check_effective_target_vect_perm_byte { } {
3493     global et_vect_perm_byte
3494
3495     if [info exists et_vect_perm_byte_saved] {
3496         verbose "check_effective_target_vect_perm_byte: using cached result" 2
3497     } else {
3498         set et_vect_perm_byte_saved 0
3499         if { ([is-effective-target arm_neon_ok]
3500               && [is-effective-target arm_little_endian])
3501              || ([istarget aarch64*-*-*]
3502                  && [is-effective-target aarch64_little_endian])
3503              || [istarget powerpc*-*-*]
3504              || [istarget spu-*-*] } {
3505             set et_vect_perm_byte_saved 1
3506         }
3507     }
3508     verbose "check_effective_target_vect_perm_byte: returning $et_vect_perm_byte_saved" 2
3509     return $et_vect_perm_byte_saved
3510 }
3511
3512 # Return 1 if the target plus current options supports vector permutation
3513 # on short-sized elements, 0 otherwise.
3514 #
3515 # This won't change for different subtargets so cache the result.
3516
3517 proc check_effective_target_vect_perm_short { } {
3518     global et_vect_perm_short
3519
3520     if [info exists et_vect_perm_short_saved] {
3521         verbose "check_effective_target_vect_perm_short: using cached result" 2
3522     } else {
3523         set et_vect_perm_short_saved 0
3524         if { ([is-effective-target arm_neon_ok]
3525               && [is-effective-target arm_little_endian])
3526              || ([istarget aarch64*-*-*]
3527                  && [is-effective-target aarch64_little_endian])
3528              || [istarget powerpc*-*-*]
3529              || [istarget spu-*-*] } {
3530             set et_vect_perm_short_saved 1
3531         }
3532     }
3533     verbose "check_effective_target_vect_perm_short: returning $et_vect_perm_short_saved" 2
3534     return $et_vect_perm_short_saved
3535 }
3536
3537 # Return 1 if the target plus current options supports a vector
3538 # widening summation of *short* args into *int* result, 0 otherwise.
3539 #
3540 # This won't change for different subtargets so cache the result.
3541
3542 proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
3543     global et_vect_widen_sum_hi_to_si_pattern
3544
3545     if [info exists et_vect_widen_sum_hi_to_si_pattern_saved] {
3546         verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: using cached result" 2
3547     } else {
3548         set et_vect_widen_sum_hi_to_si_pattern_saved 0
3549         if { [istarget powerpc*-*-*]
3550              || [istarget ia64-*-*] } {
3551             set et_vect_widen_sum_hi_to_si_pattern_saved 1
3552         }
3553     }
3554     verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern: returning $et_vect_widen_sum_hi_to_si_pattern_saved" 2
3555     return $et_vect_widen_sum_hi_to_si_pattern_saved
3556 }
3557
3558 # Return 1 if the target plus current options supports a vector
3559 # widening summation of *short* args into *int* result, 0 otherwise.
3560 # A target can also support this widening summation if it can support
3561 # promotion (unpacking) from shorts to ints.
3562 #
3563 # This won't change for different subtargets so cache the result.
3564                                                                                                 
3565 proc check_effective_target_vect_widen_sum_hi_to_si { } {
3566     global et_vect_widen_sum_hi_to_si
3567
3568     if [info exists et_vect_widen_sum_hi_to_si_saved] {
3569         verbose "check_effective_target_vect_widen_sum_hi_to_si: using cached result" 2
3570     } else {
3571         set et_vect_widen_sum_hi_to_si_saved [check_effective_target_vect_unpack]
3572         if { [istarget powerpc*-*-*] 
3573              || [istarget ia64-*-*] } {
3574             set et_vect_widen_sum_hi_to_si_saved 1
3575         }
3576     }
3577     verbose "check_effective_target_vect_widen_sum_hi_to_si: returning $et_vect_widen_sum_hi_to_si_saved" 2
3578     return $et_vect_widen_sum_hi_to_si_saved
3579 }
3580
3581 # Return 1 if the target plus current options supports a vector
3582 # widening summation of *char* args into *short* result, 0 otherwise.
3583 # A target can also support this widening summation if it can support
3584 # promotion (unpacking) from chars to shorts.
3585 #
3586 # This won't change for different subtargets so cache the result.
3587                                                                                                 
3588 proc check_effective_target_vect_widen_sum_qi_to_hi { } {
3589     global et_vect_widen_sum_qi_to_hi
3590
3591     if [info exists et_vect_widen_sum_qi_to_hi_saved] {
3592         verbose "check_effective_target_vect_widen_sum_qi_to_hi: using cached result" 2
3593     } else {
3594         set et_vect_widen_sum_qi_to_hi_saved 0
3595         if { [check_effective_target_vect_unpack] 
3596              || [check_effective_target_arm_neon_ok]
3597              || [istarget ia64-*-*] } {
3598             set et_vect_widen_sum_qi_to_hi_saved 1
3599         }
3600     }
3601     verbose "check_effective_target_vect_widen_sum_qi_to_hi: returning $et_vect_widen_sum_qi_to_hi_saved" 2
3602     return $et_vect_widen_sum_qi_to_hi_saved
3603 }
3604
3605 # Return 1 if the target plus current options supports a vector
3606 # widening summation of *char* args into *int* result, 0 otherwise.
3607 #
3608 # This won't change for different subtargets so cache the result.
3609                                                                                                 
3610 proc check_effective_target_vect_widen_sum_qi_to_si { } {
3611     global et_vect_widen_sum_qi_to_si
3612
3613     if [info exists et_vect_widen_sum_qi_to_si_saved] {
3614         verbose "check_effective_target_vect_widen_sum_qi_to_si: using cached result" 2
3615     } else {
3616         set et_vect_widen_sum_qi_to_si_saved 0
3617         if { [istarget powerpc*-*-*] } {
3618             set et_vect_widen_sum_qi_to_si_saved 1
3619         }
3620     }
3621     verbose "check_effective_target_vect_widen_sum_qi_to_si: returning $et_vect_widen_sum_qi_to_si_saved" 2
3622     return $et_vect_widen_sum_qi_to_si_saved
3623 }
3624
3625 # Return 1 if the target plus current options supports a vector
3626 # widening multiplication of *char* args into *short* result, 0 otherwise.
3627 # A target can also support this widening multplication if it can support
3628 # promotion (unpacking) from chars to shorts, and vect_short_mult (non-widening
3629 # multiplication of shorts).
3630 #
3631 # This won't change for different subtargets so cache the result.
3632
3633
3634 proc check_effective_target_vect_widen_mult_qi_to_hi { } {
3635     global et_vect_widen_mult_qi_to_hi
3636
3637     if [info exists et_vect_widen_mult_qi_to_hi_saved] {
3638         verbose "check_effective_target_vect_widen_mult_qi_to_hi: using cached result" 2
3639     } else {
3640         if { [check_effective_target_vect_unpack]
3641              && [check_effective_target_vect_short_mult] } {
3642             set et_vect_widen_mult_qi_to_hi_saved 1
3643         } else {
3644             set et_vect_widen_mult_qi_to_hi_saved 0
3645         }
3646         if { [istarget powerpc*-*-*]
3647               || [istarget aarch64*-*-*]
3648               || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
3649             set et_vect_widen_mult_qi_to_hi_saved 1
3650         }
3651     }
3652     verbose "check_effective_target_vect_widen_mult_qi_to_hi: returning $et_vect_widen_mult_qi_to_hi_saved" 2
3653     return $et_vect_widen_mult_qi_to_hi_saved
3654 }
3655
3656 # Return 1 if the target plus current options supports a vector
3657 # widening multiplication of *short* args into *int* result, 0 otherwise.
3658 # A target can also support this widening multplication if it can support
3659 # promotion (unpacking) from shorts to ints, and vect_int_mult (non-widening
3660 # multiplication of ints).
3661 #
3662 # This won't change for different subtargets so cache the result.
3663
3664
3665 proc check_effective_target_vect_widen_mult_hi_to_si { } {
3666     global et_vect_widen_mult_hi_to_si
3667
3668     if [info exists et_vect_widen_mult_hi_to_si_saved] {
3669         verbose "check_effective_target_vect_widen_mult_hi_to_si: using cached result" 2
3670     } else {
3671         if { [check_effective_target_vect_unpack]
3672              && [check_effective_target_vect_int_mult] } {
3673           set et_vect_widen_mult_hi_to_si_saved 1
3674         } else {
3675           set et_vect_widen_mult_hi_to_si_saved 0
3676         }
3677         if { [istarget powerpc*-*-*]
3678               || [istarget spu-*-*]
3679               || [istarget ia64-*-*]
3680               || [istarget aarch64*-*-*]
3681               || [istarget i?86-*-*]
3682               || [istarget x86_64-*-*]
3683               || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
3684             set et_vect_widen_mult_hi_to_si_saved 1
3685         }
3686     }
3687     verbose "check_effective_target_vect_widen_mult_hi_to_si: returning $et_vect_widen_mult_hi_to_si_saved" 2
3688     return $et_vect_widen_mult_hi_to_si_saved
3689 }
3690
3691 # Return 1 if the target plus current options supports a vector
3692 # widening multiplication of *char* args into *short* result, 0 otherwise.
3693 #
3694 # This won't change for different subtargets so cache the result.
3695
3696 proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
3697     global et_vect_widen_mult_qi_to_hi_pattern
3698
3699     if [info exists et_vect_widen_mult_qi_to_hi_pattern_saved] {
3700         verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: using cached result" 2
3701     } else {
3702         set et_vect_widen_mult_qi_to_hi_pattern_saved 0
3703         if { [istarget powerpc*-*-*]
3704               || ([istarget arm*-*-*]
3705                   && [check_effective_target_arm_neon_ok]
3706                   && [check_effective_target_arm_little_endian]) } {
3707             set et_vect_widen_mult_qi_to_hi_pattern_saved 1
3708         }
3709     }
3710     verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: returning $et_vect_widen_mult_qi_to_hi_pattern_saved" 2
3711     return $et_vect_widen_mult_qi_to_hi_pattern_saved
3712 }
3713
3714 # Return 1 if the target plus current options supports a vector
3715 # widening multiplication of *short* args into *int* result, 0 otherwise.
3716 #
3717 # This won't change for different subtargets so cache the result.
3718
3719 proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
3720     global et_vect_widen_mult_hi_to_si_pattern
3721
3722     if [info exists et_vect_widen_mult_hi_to_si_pattern_saved] {
3723         verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: using cached result" 2
3724     } else {
3725         set et_vect_widen_mult_hi_to_si_pattern_saved 0
3726         if { [istarget powerpc*-*-*]
3727               || [istarget spu-*-*]
3728               || [istarget ia64-*-*]
3729               || [istarget i?86-*-*]
3730               || [istarget x86_64-*-*]
3731               || ([istarget arm*-*-*]
3732                   && [check_effective_target_arm_neon_ok]
3733                   && [check_effective_target_arm_little_endian]) } {
3734             set et_vect_widen_mult_hi_to_si_pattern_saved 1
3735         }
3736     }
3737     verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: returning $et_vect_widen_mult_hi_to_si_pattern_saved" 2
3738     return $et_vect_widen_mult_hi_to_si_pattern_saved
3739 }
3740
3741 # Return 1 if the target plus current options supports a vector
3742 # widening multiplication of *int* args into *long* result, 0 otherwise.
3743 #
3744 # This won't change for different subtargets so cache the result.
3745
3746 proc check_effective_target_vect_widen_mult_si_to_di_pattern { } {
3747     global et_vect_widen_mult_si_to_di_pattern
3748
3749     if [info exists et_vect_widen_mult_si_to_di_pattern_saved] {
3750         verbose "check_effective_target_vect_widen_mult_si_to_di_pattern: using cached result" 2
3751     } else {
3752         if {[istarget ia64-*-*]
3753               || [istarget i?86-*-*]
3754               || [istarget x86_64-*-*] } {
3755             set et_vect_widen_mult_si_to_di_pattern_saved 1
3756         }
3757     }
3758     verbose "check_effective_target_vect_widen_mult_si_to_di_pattern: returning $et_vect_widen_mult_si_to_di_pattern_saved" 2
3759     return $et_vect_widen_mult_si_to_di_pattern_saved
3760 }
3761
3762 # Return 1 if the target plus current options supports a vector
3763 # widening shift, 0 otherwise.
3764 #
3765 # This won't change for different subtargets so cache the result.
3766
3767 proc check_effective_target_vect_widen_shift { } {
3768     global et_vect_widen_shift_saved
3769
3770     if [info exists et_vect_shift_saved] {
3771         verbose "check_effective_target_vect_widen_shift: using cached result" 2
3772     } else {
3773         set et_vect_widen_shift_saved 0
3774         if { ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
3775             set et_vect_widen_shift_saved 1
3776         }
3777     }
3778     verbose "check_effective_target_vect_widen_shift: returning $et_vect_widen_shift_saved" 2
3779     return $et_vect_widen_shift_saved
3780 }
3781
3782 # Return 1 if the target plus current options supports a vector
3783 # dot-product of signed chars, 0 otherwise.
3784 #
3785 # This won't change for different subtargets so cache the result.
3786
3787 proc check_effective_target_vect_sdot_qi { } {
3788     global et_vect_sdot_qi
3789
3790     if [info exists et_vect_sdot_qi_saved] {
3791         verbose "check_effective_target_vect_sdot_qi: using cached result" 2
3792     } else {
3793         set et_vect_sdot_qi_saved 0
3794         if { [istarget ia64-*-*] } {
3795             set et_vect_udot_qi_saved 1
3796         }
3797     }
3798     verbose "check_effective_target_vect_sdot_qi: returning $et_vect_sdot_qi_saved" 2
3799     return $et_vect_sdot_qi_saved
3800 }
3801
3802 # Return 1 if the target plus current options supports a vector
3803 # dot-product of unsigned chars, 0 otherwise.
3804 #
3805 # This won't change for different subtargets so cache the result.
3806
3807 proc check_effective_target_vect_udot_qi { } {
3808     global et_vect_udot_qi
3809
3810     if [info exists et_vect_udot_qi_saved] {
3811         verbose "check_effective_target_vect_udot_qi: using cached result" 2
3812     } else {
3813         set et_vect_udot_qi_saved 0
3814         if { [istarget powerpc*-*-*]
3815              || [istarget ia64-*-*] } {
3816             set et_vect_udot_qi_saved 1
3817         }
3818     }
3819     verbose "check_effective_target_vect_udot_qi: returning $et_vect_udot_qi_saved" 2
3820     return $et_vect_udot_qi_saved
3821 }
3822
3823 # Return 1 if the target plus current options supports a vector
3824 # dot-product of signed shorts, 0 otherwise.
3825 #
3826 # This won't change for different subtargets so cache the result.
3827
3828 proc check_effective_target_vect_sdot_hi { } {
3829     global et_vect_sdot_hi
3830
3831     if [info exists et_vect_sdot_hi_saved] {
3832         verbose "check_effective_target_vect_sdot_hi: using cached result" 2
3833     } else {
3834         set et_vect_sdot_hi_saved 0
3835         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
3836              || [istarget ia64-*-*]
3837              || [istarget i?86-*-*]
3838              || [istarget x86_64-*-*] } {
3839             set et_vect_sdot_hi_saved 1
3840         }
3841     }
3842     verbose "check_effective_target_vect_sdot_hi: returning $et_vect_sdot_hi_saved" 2
3843     return $et_vect_sdot_hi_saved
3844 }
3845
3846 # Return 1 if the target plus current options supports a vector
3847 # dot-product of unsigned shorts, 0 otherwise.
3848 #
3849 # This won't change for different subtargets so cache the result.
3850
3851 proc check_effective_target_vect_udot_hi { } {
3852     global et_vect_udot_hi
3853
3854     if [info exists et_vect_udot_hi_saved] {
3855         verbose "check_effective_target_vect_udot_hi: using cached result" 2
3856     } else {
3857         set et_vect_udot_hi_saved 0
3858         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) } {
3859             set et_vect_udot_hi_saved 1
3860         }
3861     }
3862     verbose "check_effective_target_vect_udot_hi: returning $et_vect_udot_hi_saved" 2
3863     return $et_vect_udot_hi_saved
3864 }
3865
3866
3867 # Return 1 if the target plus current options supports a vector
3868 # demotion (packing) of shorts (to chars) and ints (to shorts) 
3869 # using modulo arithmetic, 0 otherwise.
3870 #
3871 # This won't change for different subtargets so cache the result.
3872                                                                                 
3873 proc check_effective_target_vect_pack_trunc { } {
3874     global et_vect_pack_trunc
3875                                                                                 
3876     if [info exists et_vect_pack_trunc_saved] {
3877         verbose "check_effective_target_vect_pack_trunc: using cached result" 2
3878     } else {
3879         set et_vect_pack_trunc_saved 0
3880         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
3881              || [istarget i?86-*-*]
3882              || [istarget x86_64-*-*]
3883              || [istarget aarch64*-*-*]
3884              || [istarget spu-*-*]
3885              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
3886                  && [check_effective_target_arm_little_endian]) } {
3887             set et_vect_pack_trunc_saved 1
3888         }
3889     }
3890     verbose "check_effective_target_vect_pack_trunc: returning $et_vect_pack_trunc_saved" 2
3891     return $et_vect_pack_trunc_saved
3892 }
3893
3894 # Return 1 if the target plus current options supports a vector
3895 # promotion (unpacking) of chars (to shorts) and shorts (to ints), 0 otherwise.
3896 #
3897 # This won't change for different subtargets so cache the result.
3898                                    
3899 proc check_effective_target_vect_unpack { } {
3900     global et_vect_unpack
3901                                         
3902     if [info exists et_vect_unpack_saved] {
3903         verbose "check_effective_target_vect_unpack: using cached result" 2
3904     } else {
3905         set et_vect_unpack_saved 0
3906         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
3907              || [istarget i?86-*-*]
3908              || [istarget x86_64-*-*] 
3909              || [istarget spu-*-*]
3910              || [istarget ia64-*-*]
3911              || [istarget aarch64*-*-*]
3912              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
3913                  && [check_effective_target_arm_little_endian]) } {
3914             set et_vect_unpack_saved 1
3915         }
3916     }
3917     verbose "check_effective_target_vect_unpack: returning $et_vect_unpack_saved" 2  
3918     return $et_vect_unpack_saved
3919 }
3920
3921 # Return 1 if the target plus current options does not guarantee
3922 # that its STACK_BOUNDARY is >= the reguired vector alignment.
3923 #
3924 # This won't change for different subtargets so cache the result.
3925
3926 proc check_effective_target_unaligned_stack { } {
3927     global et_unaligned_stack_saved
3928
3929     if [info exists et_unaligned_stack_saved] {
3930         verbose "check_effective_target_unaligned_stack: using cached result" 2
3931     } else {
3932         set et_unaligned_stack_saved 0
3933     }
3934     verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2
3935     return $et_unaligned_stack_saved
3936 }
3937
3938 # Return 1 if the target plus current options does not support a vector
3939 # alignment mechanism, 0 otherwise.
3940 #
3941 # This won't change for different subtargets so cache the result.
3942
3943 proc check_effective_target_vect_no_align { } {
3944     global et_vect_no_align_saved
3945
3946     if [info exists et_vect_no_align_saved] {
3947         verbose "check_effective_target_vect_no_align: using cached result" 2
3948     } else {
3949         set et_vect_no_align_saved 0
3950         if { [istarget mipsisa64*-*-*]
3951              || [istarget mips-sde-elf]
3952              || [istarget sparc*-*-*]
3953              || [istarget ia64-*-*]
3954              || [check_effective_target_arm_vect_no_misalign]
3955              || ([istarget mips*-*-*]
3956                  && [check_effective_target_mips_loongson]) } {
3957             set et_vect_no_align_saved 1
3958         }
3959     }
3960     verbose "check_effective_target_vect_no_align: returning $et_vect_no_align_saved" 2
3961     return $et_vect_no_align_saved
3962 }
3963
3964 # Return 1 if the target supports a vector misalign access, 0 otherwise.
3965 #
3966 # This won't change for different subtargets so cache the result.
3967
3968 proc check_effective_target_vect_hw_misalign { } {
3969     global et_vect_hw_misalign_saved
3970
3971     if [info exists et_vect_hw_misalign_saved] {
3972         verbose "check_effective_target_vect_hw_misalign: using cached result" 2
3973     } else {
3974         set et_vect_hw_misalign_saved 0
3975        if { ([istarget x86_64-*-*] 
3976             || [istarget aarch64*-*-*]
3977             || [istarget i?86-*-*]) } {
3978           set et_vect_hw_misalign_saved 1
3979        }
3980     }
3981     verbose "check_effective_target_vect_hw_misalign: returning $et_vect_hw_misalign_saved" 2
3982     return $et_vect_hw_misalign_saved
3983 }
3984
3985
3986 # Return 1 if arrays are aligned to the vector alignment
3987 # boundary, 0 otherwise.
3988 #
3989 # This won't change for different subtargets so cache the result.
3990
3991 proc check_effective_target_vect_aligned_arrays { } {
3992     global et_vect_aligned_arrays
3993
3994     if [info exists et_vect_aligned_arrays_saved] {
3995         verbose "check_effective_target_vect_aligned_arrays: using cached result" 2
3996     } else {
3997         set et_vect_aligned_arrays_saved 0
3998         if { ([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
3999             if { ([is-effective-target lp64]
4000                   && ( ![check_avx_available]
4001                      || [check_prefer_avx128])) } {
4002                  set et_vect_aligned_arrays_saved 1
4003             }
4004         }
4005         if [istarget spu-*-*] {
4006             set et_vect_aligned_arrays_saved 1
4007         }
4008     }
4009     verbose "check_effective_target_vect_aligned_arrays: returning $et_vect_aligned_arrays_saved" 2
4010     return $et_vect_aligned_arrays_saved
4011 }
4012
4013 # Return 1 if types of size 32 bit or less are naturally aligned
4014 # (aligned to their type-size), 0 otherwise.
4015 #
4016 # This won't change for different subtargets so cache the result.
4017
4018 proc check_effective_target_natural_alignment_32 { } {
4019     global et_natural_alignment_32
4020
4021     if [info exists et_natural_alignment_32_saved] {
4022         verbose "check_effective_target_natural_alignment_32: using cached result" 2
4023     } else {
4024         # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
4025         set et_natural_alignment_32_saved 1
4026         if { ([istarget *-*-darwin*] && [is-effective-target lp64]) } {
4027             set et_natural_alignment_32_saved 0
4028         }
4029     }
4030     verbose "check_effective_target_natural_alignment_32: returning $et_natural_alignment_32_saved" 2
4031     return $et_natural_alignment_32_saved
4032 }
4033
4034 # Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
4035 # type-size), 0 otherwise.
4036 #
4037 # This won't change for different subtargets so cache the result.
4038
4039 proc check_effective_target_natural_alignment_64 { } {
4040     global et_natural_alignment_64
4041
4042     if [info exists et_natural_alignment_64_saved] {
4043         verbose "check_effective_target_natural_alignment_64: using cached result" 2
4044     } else {
4045         set et_natural_alignment_64_saved 0
4046         if { ([is-effective-target lp64] && ![istarget *-*-darwin*])
4047              || [istarget spu-*-*] } {
4048             set et_natural_alignment_64_saved 1
4049         }
4050     }
4051     verbose "check_effective_target_natural_alignment_64: returning $et_natural_alignment_64_saved" 2
4052     return $et_natural_alignment_64_saved
4053 }
4054
4055 # Return 1 if all vector types are naturally aligned (aligned to their
4056 # type-size), 0 otherwise.
4057 #
4058 # This won't change for different subtargets so cache the result.
4059
4060 proc check_effective_target_vect_natural_alignment { } {
4061     global et_vect_natural_alignment
4062
4063     if [info exists et_vect_natural_alignment_saved] {
4064         verbose "check_effective_target_vect_natural_alignment: using cached result" 2
4065     } else {
4066         set et_vect_natural_alignment_saved 1
4067         if { [check_effective_target_arm_eabi] } {
4068             set et_vect_natural_alignment_saved 0
4069         }
4070     }
4071     verbose "check_effective_target_vect_natural_alignment: returning $et_vect_natural_alignment_saved" 2
4072     return $et_vect_natural_alignment_saved
4073 }
4074
4075 # Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise.
4076 #
4077 # This won't change for different subtargets so cache the result.
4078
4079 proc check_effective_target_vector_alignment_reachable { } {
4080     global et_vector_alignment_reachable
4081
4082     if [info exists et_vector_alignment_reachable_saved] {
4083         verbose "check_effective_target_vector_alignment_reachable: using cached result" 2
4084     } else {
4085         if { [check_effective_target_vect_aligned_arrays]
4086              || [check_effective_target_natural_alignment_32] } {
4087             set et_vector_alignment_reachable_saved 1
4088         } else {
4089             set et_vector_alignment_reachable_saved 0
4090         }
4091     }
4092     verbose "check_effective_target_vector_alignment_reachable: returning $et_vector_alignment_reachable_saved" 2
4093     return $et_vector_alignment_reachable_saved
4094 }
4095
4096 # Return 1 if vector alignment for 64 bit is reachable, 0 otherwise.
4097 #
4098 # This won't change for different subtargets so cache the result.
4099
4100 proc check_effective_target_vector_alignment_reachable_for_64bit { } {
4101     global et_vector_alignment_reachable_for_64bit
4102
4103     if [info exists et_vector_alignment_reachable_for_64bit_saved] {
4104         verbose "check_effective_target_vector_alignment_reachable_for_64bit: using cached result" 2
4105     } else {
4106         if { [check_effective_target_vect_aligned_arrays] 
4107              || [check_effective_target_natural_alignment_64] } {
4108             set et_vector_alignment_reachable_for_64bit_saved 1
4109         } else {
4110             set et_vector_alignment_reachable_for_64bit_saved 0
4111         }
4112     }
4113     verbose "check_effective_target_vector_alignment_reachable_for_64bit: returning $et_vector_alignment_reachable_for_64bit_saved" 2
4114     return $et_vector_alignment_reachable_for_64bit_saved
4115 }
4116
4117 # Return 1 if the target only requires element alignment for vector accesses
4118
4119 proc check_effective_target_vect_element_align { } {
4120     global et_vect_element_align
4121
4122     if [info exists et_vect_element_align] {
4123         verbose "check_effective_target_vect_element_align: using cached result" 2
4124     } else {
4125         set et_vect_element_align 0
4126         if { ([istarget arm*-*-*]
4127               && ![check_effective_target_arm_vect_no_misalign])
4128              || [check_effective_target_vect_hw_misalign] } {
4129            set et_vect_element_align 1
4130         }
4131     }
4132
4133     verbose "check_effective_target_vect_element_align: returning $et_vect_element_align" 2
4134     return $et_vect_element_align
4135 }
4136
4137 # Return 1 if the target supports vector conditional operations, 0 otherwise.
4138
4139 proc check_effective_target_vect_condition { } {
4140     global et_vect_cond_saved
4141
4142     if [info exists et_vect_cond_saved] {
4143         verbose "check_effective_target_vect_cond: using cached result" 2
4144     } else {
4145         set et_vect_cond_saved 0
4146         if { [istarget aarch64*-*-*]
4147              || [istarget powerpc*-*-*]
4148              || [istarget ia64-*-*]
4149              || [istarget i?86-*-*]
4150              || [istarget spu-*-*]
4151              || [istarget x86_64-*-*]
4152              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
4153            set et_vect_cond_saved 1
4154         }
4155     }
4156
4157     verbose "check_effective_target_vect_cond: returning $et_vect_cond_saved" 2
4158     return $et_vect_cond_saved
4159 }
4160
4161 # Return 1 if the target supports vector conditional operations where
4162 # the comparison has different type from the lhs, 0 otherwise.
4163
4164 proc check_effective_target_vect_cond_mixed { } {
4165     global et_vect_cond_mixed_saved
4166
4167     if [info exists et_vect_cond_mixed_saved] {
4168         verbose "check_effective_target_vect_cond_mixed: using cached result" 2
4169     } else {
4170         set et_vect_cond_mixed_saved 0
4171         if { [istarget i?86-*-*]
4172              || [istarget x86_64-*-*]
4173              || [istarget powerpc*-*-*] } {
4174            set et_vect_cond_mixed_saved 1
4175         }
4176     }
4177
4178     verbose "check_effective_target_vect_cond_mixed: returning $et_vect_cond_mixed_saved" 2
4179     return $et_vect_cond_mixed_saved
4180 }
4181
4182 # Return 1 if the target supports vector char multiplication, 0 otherwise.
4183
4184 proc check_effective_target_vect_char_mult { } {
4185     global et_vect_char_mult_saved
4186
4187     if [info exists et_vect_char_mult_saved] {
4188         verbose "check_effective_target_vect_char_mult: using cached result" 2
4189     } else {
4190         set et_vect_char_mult_saved 0
4191         if { [istarget aarch64*-*-*]
4192              || [istarget ia64-*-*]
4193              || [istarget i?86-*-*]
4194              || [istarget x86_64-*-*]
4195             || [check_effective_target_arm32] } {
4196            set et_vect_char_mult_saved 1
4197         }
4198     }
4199
4200     verbose "check_effective_target_vect_char_mult: returning $et_vect_char_mult_saved" 2
4201     return $et_vect_char_mult_saved
4202 }
4203
4204 # Return 1 if the target supports vector short multiplication, 0 otherwise.
4205
4206 proc check_effective_target_vect_short_mult { } {
4207     global et_vect_short_mult_saved
4208
4209     if [info exists et_vect_short_mult_saved] {
4210         verbose "check_effective_target_vect_short_mult: using cached result" 2
4211     } else {
4212         set et_vect_short_mult_saved 0
4213         if { [istarget ia64-*-*]
4214              || [istarget spu-*-*]
4215              || [istarget i?86-*-*]
4216              || [istarget x86_64-*-*]
4217              || [istarget powerpc*-*-*]
4218              || [istarget aarch64*-*-*]
4219              || [check_effective_target_arm32]
4220              || ([istarget mips*-*-*]
4221                  && [check_effective_target_mips_loongson]) } {
4222            set et_vect_short_mult_saved 1
4223         }
4224     }
4225
4226     verbose "check_effective_target_vect_short_mult: returning $et_vect_short_mult_saved" 2
4227     return $et_vect_short_mult_saved
4228 }
4229
4230 # Return 1 if the target supports vector int multiplication, 0 otherwise.
4231
4232 proc check_effective_target_vect_int_mult { } {
4233     global et_vect_int_mult_saved
4234
4235     if [info exists et_vect_int_mult_saved] {
4236         verbose "check_effective_target_vect_int_mult: using cached result" 2
4237     } else {
4238         set et_vect_int_mult_saved 0
4239         if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
4240              || [istarget spu-*-*]
4241              || [istarget i?86-*-*]
4242              || [istarget x86_64-*-*]
4243              || [istarget ia64-*-*]
4244              || [istarget aarch64*-*-*]
4245              || [check_effective_target_arm32] } {
4246            set et_vect_int_mult_saved 1
4247         }
4248     }
4249
4250     verbose "check_effective_target_vect_int_mult: returning $et_vect_int_mult_saved" 2
4251     return $et_vect_int_mult_saved
4252 }
4253
4254 # Return 1 if the target supports vector even/odd elements extraction, 0 otherwise.
4255
4256 proc check_effective_target_vect_extract_even_odd { } {
4257     global et_vect_extract_even_odd_saved
4258     
4259     if [info exists et_vect_extract_even_odd_saved] {
4260         verbose "check_effective_target_vect_extract_even_odd: using cached result" 2
4261     } else {
4262         set et_vect_extract_even_odd_saved 0 
4263         if { [istarget aarch64*-*-*]
4264              || [istarget powerpc*-*-*]
4265              || [is-effective-target arm_neon_ok]
4266              || [istarget i?86-*-*]
4267              || [istarget x86_64-*-*]
4268              || [istarget ia64-*-*]
4269              || [istarget spu-*-*]
4270              || ([istarget mips*-*-*]
4271                  && [check_effective_target_mpaired_single]) } {
4272             set et_vect_extract_even_odd_saved 1
4273         }
4274     }
4275
4276     verbose "check_effective_target_vect_extract_even_odd: returning $et_vect_extract_even_odd_saved" 2
4277     return $et_vect_extract_even_odd_saved
4278 }
4279
4280 # Return 1 if the target supports vector interleaving, 0 otherwise.
4281
4282 proc check_effective_target_vect_interleave { } {
4283     global et_vect_interleave_saved
4284     
4285     if [info exists et_vect_interleave_saved] {
4286         verbose "check_effective_target_vect_interleave: using cached result" 2
4287     } else {
4288         set et_vect_interleave_saved 0
4289         if { [istarget aarch64*-*-*]
4290              || [istarget powerpc*-*-*]
4291              || [is-effective-target arm_neon_ok]
4292              || [istarget i?86-*-*]
4293              || [istarget x86_64-*-*]
4294              || [istarget ia64-*-*]
4295              || [istarget spu-*-*]
4296              || ([istarget mips*-*-*]
4297                  && [check_effective_target_mpaired_single]) } {
4298            set et_vect_interleave_saved 1
4299         }
4300     }
4301
4302     verbose "check_effective_target_vect_interleave: returning $et_vect_interleave_saved" 2
4303     return $et_vect_interleave_saved
4304 }
4305
4306 foreach N {2 3 4 8} {
4307     eval [string map [list N $N] {
4308         # Return 1 if the target supports 2-vector interleaving
4309         proc check_effective_target_vect_stridedN { } {
4310             global et_vect_stridedN_saved
4311
4312             if [info exists et_vect_stridedN_saved] {
4313                 verbose "check_effective_target_vect_stridedN: using cached result" 2
4314             } else {
4315                 set et_vect_stridedN_saved 0
4316                 if { (N & -N) == N
4317                      && [check_effective_target_vect_interleave]
4318                      && [check_effective_target_vect_extract_even_odd] } {
4319                     set et_vect_stridedN_saved 1
4320                 }
4321                 if { ([istarget arm*-*-*]
4322                       || [istarget aarch64*-*-*]) && N >= 2 && N <= 4 } {
4323                     set et_vect_stridedN_saved 1
4324                 }
4325             }
4326
4327             verbose "check_effective_target_vect_stridedN: returning $et_vect_stridedN_saved" 2
4328             return $et_vect_stridedN_saved
4329         }
4330     }]
4331 }
4332
4333 # Return 1 if the target supports multiple vector sizes
4334
4335 proc check_effective_target_vect_multiple_sizes { } {
4336     global et_vect_multiple_sizes_saved
4337
4338     set et_vect_multiple_sizes_saved 0
4339     if { ([istarget aarch64*-*-*]
4340           || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok])) } {
4341        set et_vect_multiple_sizes_saved 1
4342     }
4343     if { ([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
4344       if { ([check_avx_available] && ![check_prefer_avx128]) } {
4345         set et_vect_multiple_sizes_saved 1
4346       }
4347     }
4348
4349     verbose "check_effective_target_vect_multiple_sizes: returning $et_vect_multiple_sizes_saved" 2
4350     return $et_vect_multiple_sizes_saved
4351 }
4352
4353 # Return 1 if the target supports vectors of 64 bits.
4354
4355 proc check_effective_target_vect64 { } {
4356     global et_vect64_saved
4357
4358     if [info exists et_vect64_saved] {
4359         verbose "check_effective_target_vect64: using cached result" 2
4360     } else {
4361         set et_vect64_saved 0
4362         if { ([istarget arm*-*-*]
4363               && [check_effective_target_arm_neon_ok]
4364               && [check_effective_target_arm_little_endian]) } {
4365            set et_vect64_saved 1
4366         }
4367     }
4368
4369     verbose "check_effective_target_vect64: returning $et_vect64_saved" 2
4370     return $et_vect64_saved
4371 }
4372
4373 # Return 1 if the target supports vector copysignf calls.
4374
4375 proc check_effective_target_vect_call_copysignf { } {
4376     global et_vect_call_copysignf_saved
4377
4378     if [info exists et_vect_call_copysignf_saved] {
4379         verbose "check_effective_target_vect_call_copysignf: using cached result" 2
4380     } else {
4381         set et_vect_call_copysignf_saved 0
4382         if { [istarget i?86-*-*]
4383              || [istarget x86_64-*-*]
4384              || [istarget powerpc*-*-*] } {
4385            set et_vect_call_copysignf_saved 1
4386         }
4387     }
4388
4389     verbose "check_effective_target_vect_call_copysignf: returning $et_vect_call_copysignf_saved" 2
4390     return $et_vect_call_copysignf_saved
4391 }
4392
4393 # Return 1 if the target supports vector sqrtf calls.
4394
4395 proc check_effective_target_vect_call_sqrtf { } {
4396     global et_vect_call_sqrtf_saved
4397
4398     if [info exists et_vect_call_sqrtf_saved] {
4399         verbose "check_effective_target_vect_call_sqrtf: using cached result" 2
4400     } else {
4401         set et_vect_call_sqrtf_saved 0
4402         if { [istarget aarch64*-*-*]
4403              || [istarget i?86-*-*]
4404              || [istarget x86_64-*-*]
4405              || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) } {
4406             set et_vect_call_sqrtf_saved 1
4407         }
4408     }
4409
4410     verbose "check_effective_target_vect_call_sqrtf: returning $et_vect_call_sqrtf_saved" 2
4411     return $et_vect_call_sqrtf_saved
4412 }
4413
4414 # Return 1 if the target supports vector lrint calls.
4415
4416 proc check_effective_target_vect_call_lrint { } {
4417     set et_vect_call_lrint 0
4418     if { ([istarget i?86-*-*] || [istarget x86_64-*-*]) && [check_effective_target_ilp32] } {
4419         set et_vect_call_lrint 1
4420     }
4421
4422     verbose "check_effective_target_vect_call_lrint: returning $et_vect_call_lrint" 2
4423     return $et_vect_call_lrint
4424 }
4425
4426 # Return 1 if the target supports vector btrunc calls.
4427
4428 proc check_effective_target_vect_call_btrunc { } {
4429     global et_vect_call_btrunc_saved
4430
4431     if [info exists et_vect_call_btrunc_saved] {
4432         verbose "check_effective_target_vect_call_btrunc: using cached result" 2
4433     } else {
4434         set et_vect_call_btrunc_saved 0
4435         if { [istarget aarch64*-*-*] } {
4436           set et_vect_call_btrunc_saved 1
4437         }
4438     }
4439
4440     verbose "check_effective_target_vect_call_btrunc: returning $et_vect_call_btrunc_saved" 2
4441     return $et_vect_call_btrunc_saved
4442 }
4443
4444 # Return 1 if the target supports vector btruncf calls.
4445
4446 proc check_effective_target_vect_call_btruncf { } {
4447     global et_vect_call_btruncf_saved
4448
4449     if [info exists et_vect_call_btruncf_saved] {
4450         verbose "check_effective_target_vect_call_btruncf: using cached result" 2
4451     } else {
4452         set et_vect_call_btruncf_saved 0
4453         if { [istarget aarch64*-*-*] } {
4454           set et_vect_call_btruncf_saved 1
4455         }
4456     }
4457
4458     verbose "check_effective_target_vect_call_btruncf: returning $et_vect_call_btruncf_saved" 2
4459     return $et_vect_call_btruncf_saved
4460 }
4461
4462 # Return 1 if the target supports vector ceil calls.
4463
4464 proc check_effective_target_vect_call_ceil { } {
4465     global et_vect_call_ceil_saved
4466
4467     if [info exists et_vect_call_ceil_saved] {
4468         verbose "check_effective_target_vect_call_ceil: using cached result" 2
4469     } else {
4470         set et_vect_call_ceil_saved 0
4471         if { [istarget aarch64*-*-*] } {
4472           set et_vect_call_ceil_saved 1
4473         }
4474     }
4475
4476     verbose "check_effective_target_vect_call_ceil: returning $et_vect_call_ceil_saved" 2
4477     return $et_vect_call_ceil_saved
4478 }
4479
4480 # Return 1 if the target supports vector ceilf calls.
4481
4482 proc check_effective_target_vect_call_ceilf { } {
4483     global et_vect_call_ceilf_saved
4484
4485     if [info exists et_vect_call_ceilf_saved] {
4486         verbose "check_effective_target_vect_call_ceilf: using cached result" 2
4487     } else {
4488         set et_vect_call_ceilf_saved 0
4489         if { [istarget aarch64*-*-*] } {
4490           set et_vect_call_ceilf_saved 1
4491         }
4492     }
4493
4494     verbose "check_effective_target_vect_call_ceilf: returning $et_vect_call_ceilf_saved" 2
4495     return $et_vect_call_ceilf_saved
4496 }
4497
4498 # Return 1 if the target supports vector floor calls.
4499
4500 proc check_effective_target_vect_call_floor { } {
4501     global et_vect_call_floor_saved
4502
4503     if [info exists et_vect_call_floor_saved] {
4504         verbose "check_effective_target_vect_call_floor: using cached result" 2
4505     } else {
4506         set et_vect_call_floor_saved 0
4507         if { [istarget aarch64*-*-*] } {
4508           set et_vect_call_floor_saved 1
4509         }
4510     }
4511
4512     verbose "check_effective_target_vect_call_floor: returning $et_vect_call_floor_saved" 2
4513     return $et_vect_call_floor_saved
4514 }
4515
4516 # Return 1 if the target supports vector floorf calls.
4517
4518 proc check_effective_target_vect_call_floorf { } {
4519     global et_vect_call_floorf_saved
4520
4521     if [info exists et_vect_call_floorf_saved] {
4522         verbose "check_effective_target_vect_call_floorf: using cached result" 2
4523     } else {
4524         set et_vect_call_floorf_saved 0
4525         if { [istarget aarch64*-*-*] } {
4526           set et_vect_call_floorf_saved 1
4527         }
4528     }
4529
4530     verbose "check_effective_target_vect_call_floorf: returning $et_vect_call_floorf_saved" 2
4531     return $et_vect_call_floorf_saved
4532 }
4533
4534 # Return 1 if the target supports vector lceil calls.
4535
4536 proc check_effective_target_vect_call_lceil { } {
4537     global et_vect_call_lceil_saved
4538
4539     if [info exists et_vect_call_lceil_saved] {
4540         verbose "check_effective_target_vect_call_lceil: using cached result" 2
4541     } else {
4542         set et_vect_call_lceil_saved 0
4543         if { [istarget aarch64*-*-*] } {
4544           set et_vect_call_lceil_saved 1
4545         }
4546     }
4547
4548     verbose "check_effective_target_vect_call_lceil: returning $et_vect_call_lceil_saved" 2
4549     return $et_vect_call_lceil_saved
4550 }
4551
4552 # Return 1 if the target supports vector lfloor calls.
4553
4554 proc check_effective_target_vect_call_lfloor { } {
4555     global et_vect_call_lfloor_saved
4556
4557     if [info exists et_vect_call_lfloor_saved] {
4558         verbose "check_effective_target_vect_call_lfloor: using cached result" 2
4559     } else {
4560         set et_vect_call_lfloor_saved 0
4561         if { [istarget aarch64*-*-*] } {
4562           set et_vect_call_lfloor_saved 1
4563         }
4564     }
4565
4566     verbose "check_effective_target_vect_call_lfloor: returning $et_vect_call_lfloor_saved" 2
4567     return $et_vect_call_lfloor_saved
4568 }
4569
4570 # Return 1 if the target supports vector nearbyint calls.
4571
4572 proc check_effective_target_vect_call_nearbyint { } {
4573     global et_vect_call_nearbyint_saved
4574
4575     if [info exists et_vect_call_nearbyint_saved] {
4576         verbose "check_effective_target_vect_call_nearbyint: using cached result" 2
4577     } else {
4578         set et_vect_call_nearbyint_saved 0
4579         if { [istarget aarch64*-*-*] } {
4580           set et_vect_call_nearbyint_saved 1
4581         }
4582     }
4583
4584     verbose "check_effective_target_vect_call_nearbyint: returning $et_vect_call_nearbyint_saved" 2
4585     return $et_vect_call_nearbyint_saved
4586 }
4587
4588 # Return 1 if the target supports vector nearbyintf calls.
4589
4590 proc check_effective_target_vect_call_nearbyintf { } {
4591     global et_vect_call_nearbyintf_saved
4592
4593     if [info exists et_vect_call_nearbyintf_saved] {
4594         verbose "check_effective_target_vect_call_nearbyintf: using cached result" 2
4595     } else {
4596         set et_vect_call_nearbyintf_saved 0
4597         if { [istarget aarch64*-*-*] } {
4598           set et_vect_call_nearbyintf_saved 1
4599         }
4600     }
4601
4602     verbose "check_effective_target_vect_call_nearbyintf: returning $et_vect_call_nearbyintf_saved" 2
4603     return $et_vect_call_nearbyintf_saved
4604 }
4605
4606 # Return 1 if the target supports vector round calls.
4607
4608 proc check_effective_target_vect_call_round { } {
4609     global et_vect_call_round_saved
4610
4611     if [info exists et_vect_call_round_saved] {
4612         verbose "check_effective_target_vect_call_round: using cached result" 2
4613     } else {
4614         set et_vect_call_round_saved 0
4615         if { [istarget aarch64*-*-*] } {
4616           set et_vect_call_round_saved 1
4617         }
4618     }
4619
4620     verbose "check_effective_target_vect_call_round: returning $et_vect_call_round_saved" 2
4621     return $et_vect_call_round_saved
4622 }
4623
4624 # Return 1 if the target supports vector roundf calls.
4625
4626 proc check_effective_target_vect_call_roundf { } {
4627     global et_vect_call_roundf_saved
4628
4629     if [info exists et_vect_call_roundf_saved] {
4630         verbose "check_effective_target_vect_call_roundf: using cached result" 2
4631     } else {
4632         set et_vect_call_roundf_saved 0
4633         if { [istarget aarch64*-*-*] } {
4634           set et_vect_call_roundf_saved 1
4635         }
4636     }
4637
4638     verbose "check_effective_target_vect_call_roundf: returning $et_vect_call_roundf_saved" 2
4639     return $et_vect_call_roundf_saved
4640 }
4641
4642 # Return 1 if the target supports section-anchors
4643
4644 proc check_effective_target_section_anchors { } {
4645     global et_section_anchors_saved
4646
4647     if [info exists et_section_anchors_saved] {
4648         verbose "check_effective_target_section_anchors: using cached result" 2
4649     } else {
4650         set et_section_anchors_saved 0
4651         if { [istarget powerpc*-*-*]
4652               || [istarget arm*-*-*] } {
4653            set et_section_anchors_saved 1
4654         }
4655     }
4656
4657     verbose "check_effective_target_section_anchors: returning $et_section_anchors_saved" 2
4658     return $et_section_anchors_saved
4659 }
4660
4661 # Return 1 if the target supports atomic operations on "int_128" values.
4662
4663 proc check_effective_target_sync_int_128 { } {
4664     if { ([istarget x86_64-*-*] || [istarget i?86-*-*])
4665          && ![is-effective-target ia32] } {
4666         return 1
4667     } else {
4668         return 0
4669     }
4670 }
4671
4672 # Return 1 if the target supports atomic operations on "int_128" values
4673 # and can execute them.
4674
4675 proc check_effective_target_sync_int_128_runtime { } {
4676     if { ([istarget x86_64-*-*] || [istarget i?86-*-*])
4677          && ![is-effective-target ia32] } {
4678         return [check_cached_effective_target sync_int_128_available {
4679             check_runtime_nocache sync_int_128_available {
4680                 #include "cpuid.h"
4681                 int main ()
4682                 {
4683                   unsigned int eax, ebx, ecx, edx;
4684                   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
4685                     return !(ecx & bit_CMPXCHG16B);
4686                   return 1;
4687                 }
4688             } ""
4689         }]
4690     } else {
4691         return 0
4692     }
4693 }
4694
4695 # Return 1 if the target supports atomic operations on "long long".
4696 #
4697 # Note: 32bit x86 targets require -march=pentium in dg-options.
4698
4699 proc check_effective_target_sync_long_long { } {
4700     if { [istarget x86_64-*-*]
4701          || [istarget i?86-*-*])
4702          || [istarget aarch64*-*-*]
4703          || [istarget arm*-*-*]
4704          || [istarget alpha*-*-*]
4705          || ([istarget sparc*-*-*] && [check_effective_target_lp64]) } {
4706         return 1
4707     } else {
4708         return 0
4709     }
4710 }
4711
4712 # Return 1 if the target supports atomic operations on "long long"
4713 # and can execute them.
4714 #
4715 # Note: 32bit x86 targets require -march=pentium in dg-options.
4716
4717 proc check_effective_target_sync_long_long_runtime { } {
4718     if { [istarget x86_64-*-*]
4719          || [istarget i?86-*-*] } {
4720         return [check_cached_effective_target sync_long_long_available {
4721             check_runtime_nocache sync_long_long_available {
4722                 #include "cpuid.h"
4723                 int main ()
4724                 {
4725                   unsigned int eax, ebx, ecx, edx;
4726                   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
4727                     return !(edx & bit_CMPXCHG8B);
4728                   return 1;
4729                 }
4730             } ""
4731         }]
4732     } elseif { [istarget aarch64*-*-*] } {
4733         return 1
4734     } elseif { [istarget arm*-*-linux-*] } {
4735         return [check_runtime sync_longlong_runtime {
4736             #include <stdlib.h>
4737             int main ()
4738             {
4739               long long l1;
4740
4741               if (sizeof (long long) != 8)
4742                 exit (1);
4743
4744               /* Just check for native; checking for kernel fallback is tricky.  */
4745               asm volatile ("ldrexd r0,r1, [%0]" : : "r" (&l1) : "r0", "r1");
4746
4747               exit (0);
4748             }
4749         } "" ]
4750     } elseif { [istarget alpha*-*-*] } {
4751         return 1
4752     } elseif { ([istarget sparc*-*-*]
4753                  && [check_effective_target_lp64]
4754                  && [check_effective_target_ultrasparc_hw]) } {
4755         return 1
4756     } elseif { [istarget powerpc*-*-*] && [check_effective_target_lp64] } {
4757         return 1
4758     } else {
4759         return 0
4760     }
4761 }
4762
4763 # Return 1 if the target supports atomic operations on "int" and "long".
4764
4765 proc check_effective_target_sync_int_long { } {
4766     global et_sync_int_long_saved
4767
4768     if [info exists et_sync_int_long_saved] {
4769         verbose "check_effective_target_sync_int_long: using cached result" 2
4770     } else {
4771         set et_sync_int_long_saved 0
4772 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
4773 # load-reserved/store-conditional instructions.
4774         if { [istarget ia64-*-*]
4775              || [istarget i?86-*-*]
4776              || [istarget x86_64-*-*]
4777              || [istarget aarch64*-*-*]
4778              || [istarget alpha*-*-*] 
4779              || [istarget arm*-*-linux-*] 
4780              || [istarget bfin*-*linux*]
4781              || [istarget hppa*-*linux*]
4782              || [istarget s390*-*-*] 
4783              || [istarget powerpc*-*-*]
4784              || [istarget crisv32-*-*] || [istarget cris-*-*]
4785              || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
4786              || [check_effective_target_mips_llsc] } {
4787            set et_sync_int_long_saved 1
4788         }
4789     }
4790
4791     verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
4792     return $et_sync_int_long_saved
4793 }
4794
4795 # Return 1 if the target supports atomic operations on "char" and "short".
4796
4797 proc check_effective_target_sync_char_short { } {
4798     global et_sync_char_short_saved
4799
4800     if [info exists et_sync_char_short_saved] {
4801         verbose "check_effective_target_sync_char_short: using cached result" 2
4802     } else {
4803         set et_sync_char_short_saved 0
4804 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
4805 # load-reserved/store-conditional instructions.
4806         if { [istarget aarch64*-*-*]
4807              || [istarget ia64-*-*]
4808              || [istarget i?86-*-*]
4809              || [istarget x86_64-*-*]
4810              || [istarget alpha*-*-*] 
4811              || [istarget arm*-*-linux-*] 
4812              || [istarget hppa*-*linux*]
4813              || [istarget s390*-*-*] 
4814              || [istarget powerpc*-*-*]
4815              || [istarget crisv32-*-*] || [istarget cris-*-*]
4816              || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
4817              || [check_effective_target_mips_llsc] } {
4818            set et_sync_char_short_saved 1
4819         }
4820     }
4821
4822     verbose "check_effective_target_sync_char_short: returning $et_sync_char_short_saved" 2
4823     return $et_sync_char_short_saved
4824 }
4825
4826 # Return 1 if the target uses a ColdFire FPU.
4827
4828 proc check_effective_target_coldfire_fpu { } {
4829     return [check_no_compiler_messages coldfire_fpu assembly {
4830         #ifndef __mcffpu__
4831         #error FOO
4832         #endif
4833     }]
4834 }
4835
4836 # Return true if this is a uClibc target.
4837
4838 proc check_effective_target_uclibc {} {
4839     return [check_no_compiler_messages uclibc object {
4840         #include <features.h>
4841         #if !defined (__UCLIBC__)
4842         #error FOO
4843         #endif
4844     }]
4845 }
4846
4847 # Return true if this is a uclibc target and if the uclibc feature
4848 # described by __$feature__ is not present.
4849
4850 proc check_missing_uclibc_feature {feature} {
4851     return [check_no_compiler_messages $feature object "
4852         #include <features.h>
4853         #if !defined (__UCLIBC) || defined (__${feature}__)
4854         #error FOO
4855         #endif
4856     "]
4857 }
4858
4859 # Return true if this is a Newlib target.
4860
4861 proc check_effective_target_newlib {} {
4862     return [check_no_compiler_messages newlib object {
4863         #include <newlib.h>
4864     }]
4865 }
4866
4867 # Return true if this is NOT a Bionic target.
4868
4869 proc check_effective_target_non_bionic {} {
4870     return [check_no_compiler_messages non_bionic object {
4871         #include <ctype.h>
4872         #if defined (__BIONIC__)
4873         #error FOO
4874         #endif
4875     }]
4876 }
4877
4878 # Return 1 if
4879 #   (a) an error of a few ULP is expected in string to floating-point
4880 #       conversion functions; and
4881 #   (b) overflow is not always detected correctly by those functions.
4882
4883 proc check_effective_target_lax_strtofp {} {
4884     # By default, assume that all uClibc targets suffer from this.
4885     return [check_effective_target_uclibc]
4886 }
4887
4888 # Return 1 if this is a target for which wcsftime is a dummy
4889 # function that always returns 0.
4890
4891 proc check_effective_target_dummy_wcsftime {} {
4892     # By default, assume that all uClibc targets suffer from this.
4893     return [check_effective_target_uclibc]
4894 }
4895
4896 # Return 1 if constructors with initialization priority arguments are
4897 # supposed on this target.
4898
4899 proc check_effective_target_init_priority {} {
4900     return [check_no_compiler_messages init_priority assembly "
4901         void f() __attribute__((constructor (1000)));
4902         void f() \{\}
4903     "]
4904 }
4905
4906 # Return 1 if the target matches the effective target 'arg', 0 otherwise.
4907 # This can be used with any check_* proc that takes no argument and
4908 # returns only 1 or 0.  It could be used with check_* procs that take
4909 # arguments with keywords that pass particular arguments.
4910
4911 proc is-effective-target { arg } {
4912     set selected 0
4913     if { [info procs check_effective_target_${arg}] != [list] } {
4914         set selected [check_effective_target_${arg}]
4915     } else {
4916         switch $arg {
4917           "vmx_hw"         { set selected [check_vmx_hw_available] }
4918           "vsx_hw"         { set selected [check_vsx_hw_available] }
4919           "p8vector_hw"    { set selected [check_p8vector_hw_available] }
4920           "ppc_recip_hw"   { set selected [check_ppc_recip_hw_available] }
4921           "named_sections" { set selected [check_named_sections_available] }
4922           "gc_sections"    { set selected [check_gc_sections_available] }
4923           "cxa_atexit"     { set selected [check_cxa_atexit_available] }
4924           default          { error "unknown effective target keyword `$arg'" }
4925         }
4926     }
4927     verbose "is-effective-target: $arg $selected" 2
4928     return $selected
4929 }
4930
4931 # Return 1 if the argument is an effective-target keyword, 0 otherwise.
4932
4933 proc is-effective-target-keyword { arg } {
4934     if { [info procs check_effective_target_${arg}] != [list] } {
4935         return 1
4936     } else {
4937         # These have different names for their check_* procs.
4938         switch $arg {
4939           "vmx_hw"         { return 1 }
4940           "vsx_hw"         { return 1 }
4941           "p8vector_hw"    { return 1 }
4942           "ppc_recip_hw"   { return 1 }
4943           "named_sections" { return 1 }
4944           "gc_sections"    { return 1 }
4945           "cxa_atexit"     { return 1 }
4946           default          { return 0 }
4947         }
4948     }
4949 }
4950
4951 # Return 1 if target default to short enums
4952
4953 proc check_effective_target_short_enums { } {
4954     return [check_no_compiler_messages short_enums assembly {
4955         enum foo { bar };
4956         int s[sizeof (enum foo) == 1 ? 1 : -1];
4957     }]
4958 }
4959
4960 # Return 1 if target supports merging string constants at link time.
4961
4962 proc check_effective_target_string_merging { } {
4963     return [check_no_messages_and_pattern string_merging \
4964                 "rodata\\.str" assembly {
4965                     const char *var = "String";
4966                 } {-O2}]
4967 }
4968
4969 # Return 1 if target has the basic signed and unsigned types in
4970 # <stdint.h>, 0 otherwise.  This will be obsolete when GCC ensures a
4971 # working <stdint.h> for all targets.
4972
4973 proc check_effective_target_stdint_types { } {
4974     return [check_no_compiler_messages stdint_types assembly {
4975         #include <stdint.h>
4976         int8_t a; int16_t b; int32_t c; int64_t d;
4977         uint8_t e; uint16_t f; uint32_t g; uint64_t h;
4978     }]
4979 }
4980
4981 # Return 1 if target has the basic signed and unsigned types in
4982 # <inttypes.h>, 0 otherwise.  This is for tests that GCC's notions of
4983 # these types agree with those in the header, as some systems have
4984 # only <inttypes.h>.
4985
4986 proc check_effective_target_inttypes_types { } {
4987     return [check_no_compiler_messages inttypes_types assembly {
4988         #include <inttypes.h>
4989         int8_t a; int16_t b; int32_t c; int64_t d;
4990         uint8_t e; uint16_t f; uint32_t g; uint64_t h;
4991     }]
4992 }
4993
4994 # Return 1 if programs are intended to be run on a simulator
4995 # (i.e. slowly) rather than hardware (i.e. fast).
4996
4997 proc check_effective_target_simulator { } {
4998
4999     # All "src/sim" simulators set this one.
5000     if [board_info target exists is_simulator] {
5001         return [board_info target is_simulator]
5002     }
5003
5004     # The "sid" simulators don't set that one, but at least they set
5005     # this one.
5006     if [board_info target exists slow_simulator] {
5007         return [board_info target slow_simulator]
5008     }
5009
5010     return 0
5011 }
5012
5013 # Return 1 if programs are intended to be run on hardware rather than
5014 # on a simulator
5015
5016 proc check_effective_target_hw { } {
5017
5018     # All "src/sim" simulators set this one.
5019     if [board_info target exists is_simulator] {
5020         if [board_info target is_simulator] {
5021           return 0
5022         } else {
5023           return 1
5024         }
5025     }
5026
5027     # The "sid" simulators don't set that one, but at least they set
5028     # this one.
5029     if [board_info target exists slow_simulator] {
5030         if [board_info target slow_simulator] {
5031           return 0
5032         } else {
5033           return 1
5034         }
5035     }
5036
5037     return 1
5038 }
5039
5040 # Return 1 if the target is a VxWorks kernel.
5041
5042 proc check_effective_target_vxworks_kernel { } {
5043     return [check_no_compiler_messages vxworks_kernel assembly {
5044         #if !defined __vxworks || defined __RTP__
5045         #error NO
5046         #endif
5047     }]
5048 }
5049
5050 # Return 1 if the target is a VxWorks RTP.
5051
5052 proc check_effective_target_vxworks_rtp { } {
5053     return [check_no_compiler_messages vxworks_rtp assembly {
5054         #if !defined __vxworks || !defined __RTP__
5055         #error NO
5056         #endif
5057     }]
5058 }
5059
5060 # Return 1 if the target is expected to provide wide character support.
5061
5062 proc check_effective_target_wchar { } {
5063     if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} {
5064         return 0
5065     }
5066     return [check_no_compiler_messages wchar assembly {
5067         #include <wchar.h>
5068     }]
5069 }
5070
5071 # Return 1 if the target has <pthread.h>.
5072
5073 proc check_effective_target_pthread_h { } {
5074     return [check_no_compiler_messages pthread_h assembly {
5075         #include <pthread.h>
5076     }]
5077 }
5078
5079 # Return 1 if the target can truncate a file from a file-descriptor,
5080 # as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or
5081 # chsize.  We test for a trivially functional truncation; no stubs.
5082 # As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a
5083 # different function to be used.
5084
5085 proc check_effective_target_fd_truncate { } {
5086     set prog {
5087         #define _FILE_OFFSET_BITS 64
5088         #include <unistd.h>
5089         #include <stdio.h>
5090         #include <stdlib.h>
5091         int main ()
5092         {
5093           FILE *f = fopen ("tst.tmp", "wb");
5094           int fd;
5095           const char t[] = "test writing more than ten characters";
5096           char s[11];
5097           int status = 0;
5098           fd = fileno (f);
5099           write (fd, t, sizeof (t) - 1);
5100           lseek (fd, 0, 0);
5101           if (ftruncate (fd, 10) != 0)
5102             status = 1;
5103           close (fd);
5104           fclose (f);
5105           if (status)
5106             {
5107               unlink ("tst.tmp");
5108               exit (status);
5109             }
5110           f = fopen ("tst.tmp", "rb");
5111           if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0)
5112             status = 1;
5113           fclose (f);
5114           unlink ("tst.tmp");
5115           exit (status);
5116         }
5117     }
5118
5119     if { [check_runtime ftruncate $prog] } {
5120       return 1;
5121     }
5122
5123     regsub "ftruncate" $prog "chsize" prog
5124     return [check_runtime chsize $prog]
5125 }
5126
5127 # Add to FLAGS all the target-specific flags needed to access the c99 runtime.
5128
5129 proc add_options_for_c99_runtime { flags } {
5130     if { [istarget *-*-solaris2*] } {
5131         return "$flags -std=c99"
5132     }
5133     if { [istarget powerpc-*-darwin*] } {
5134         return "$flags -mmacosx-version-min=10.3"
5135     }
5136     return $flags
5137 }
5138
5139 # Add to FLAGS all the target-specific flags needed to enable
5140 # full IEEE compliance mode.
5141
5142 proc add_options_for_ieee { flags } {
5143     if { [istarget alpha*-*-*]
5144          || [istarget sh*-*-*] } {
5145        return "$flags -mieee"
5146     }
5147     if { [istarget rx-*-*] } {
5148        return "$flags -mnofpu"
5149     }
5150     return $flags
5151 }
5152
5153 # Add to FLAGS the flags needed to enable functions to bind locally
5154 # when using pic/PIC passes in the testsuite.
5155
5156 proc add_options_for_bind_pic_locally { flags } {
5157     if {[check_no_compiler_messages using_pic2 assembly {
5158         #if __PIC__ != 2
5159         #error FOO
5160         #endif
5161     }]} {
5162         return "$flags -fPIE"
5163     }
5164     if {[check_no_compiler_messages using_pic1 assembly {
5165         #if __PIC__ != 1
5166         #error FOO
5167         #endif
5168     }]} {
5169         return "$flags -fpie"
5170     }
5171
5172     return $flags
5173 }
5174
5175 # Add to FLAGS the flags needed to enable 64-bit vectors.
5176
5177 proc add_options_for_double_vectors { flags } {
5178     if [is-effective-target arm_neon_ok] {
5179         return "$flags -mvectorize-with-neon-double"
5180     }
5181
5182     return $flags
5183 }
5184
5185 # Return 1 if the target provides a full C99 runtime.
5186
5187 proc check_effective_target_c99_runtime { } {
5188     return [check_cached_effective_target c99_runtime {
5189         global srcdir
5190
5191         set file [open "$srcdir/gcc.dg/builtins-config.h"]
5192         set contents [read $file]
5193         close $file
5194         append contents {
5195             #ifndef HAVE_C99_RUNTIME
5196             #error FOO
5197             #endif
5198         }
5199         check_no_compiler_messages_nocache c99_runtime assembly \
5200             $contents [add_options_for_c99_runtime ""]
5201     }]
5202 }
5203
5204 # Return 1 if  target wchar_t is at least 4 bytes.
5205
5206 proc check_effective_target_4byte_wchar_t { } {
5207     return [check_no_compiler_messages 4byte_wchar_t object {
5208         int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1];
5209     }]
5210 }
5211
5212 # Return 1 if the target supports automatic stack alignment.
5213
5214 proc check_effective_target_automatic_stack_alignment  { } {
5215     # Ordinarily x86 supports automatic stack alignment ...
5216     if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
5217         if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
5218             # ... except Win64 SEH doesn't.  Succeed for Win32 though.
5219             return [check_effective_target_ilp32];
5220         }
5221         return 1;
5222     }
5223     return 0;
5224 }
5225
5226 # Return true if we are compiling for AVX target.
5227
5228 proc check_avx_available { } {
5229   if { [check_no_compiler_messages avx_available assembly {
5230     #ifndef __AVX__
5231     #error unsupported
5232     #endif
5233   } ""] } {
5234     return 1;
5235   }
5236   return 0;
5237 }
5238
5239 # Return true if 32- and 16-bytes vectors are available.
5240
5241 proc check_effective_target_vect_sizes_32B_16B { } {
5242   return [check_avx_available];
5243 }
5244
5245 # Return true if 128-bits vectors are preferred even if 256-bits vectors
5246 # are available.
5247
5248 proc check_prefer_avx128 { } {
5249     if ![check_avx_available] {
5250       return 0;
5251     }
5252     return [check_no_messages_and_pattern avx_explicit "xmm" assembly {
5253       float a[1024],b[1024],c[1024];
5254       void foo (void) { int i; for (i = 0; i < 1024; i++) a[i]=b[i]+c[i];}
5255     } "-O2 -ftree-vectorize"]
5256 }
5257
5258
5259 # Return 1 if avx512f instructions can be compiled.
5260
5261 proc check_effective_target_avx512f { } {
5262     return [check_no_compiler_messages avx512f object {
5263         typedef double __m512d __attribute__ ((__vector_size__ (64)));
5264
5265         __m512d _mm512_add (__m512d a)
5266         {
5267           return __builtin_ia32_addpd512_mask (a, a, a, 1, 4);
5268         }
5269     } "-O2 -mavx512f" ]
5270 }
5271
5272 # Return 1 if avx instructions can be compiled.
5273
5274 proc check_effective_target_avx { } {
5275     return [check_no_compiler_messages avx object {
5276         void _mm256_zeroall (void)
5277         {
5278            __builtin_ia32_vzeroall ();
5279         }
5280     } "-O2 -mavx" ]
5281 }
5282
5283 # Return 1 if avx2 instructions can be compiled.
5284 proc check_effective_target_avx2 { } {
5285     return [check_no_compiler_messages avx2 object {
5286         typedef long long __v4di __attribute__ ((__vector_size__ (32)));
5287         __v4di
5288         mm256_is32_andnotsi256  (__v4di __X, __v4di __Y)
5289         {
5290            return __builtin_ia32_andnotsi256 (__X, __Y);
5291         }
5292     } "-O0 -mavx2" ]
5293 }
5294
5295 # Return 1 if sse instructions can be compiled.
5296 proc check_effective_target_sse { } {
5297     return [check_no_compiler_messages sse object {
5298         int main ()
5299         {
5300             __builtin_ia32_stmxcsr ();
5301             return 0;
5302         }
5303     } "-O2 -msse" ]
5304 }
5305
5306 # Return 1 if sse2 instructions can be compiled.
5307 proc check_effective_target_sse2 { } {
5308     return [check_no_compiler_messages sse2 object {
5309         typedef long long __m128i __attribute__ ((__vector_size__ (16)));
5310         
5311         __m128i _mm_srli_si128 (__m128i __A, int __N)
5312         {
5313             return (__m128i)__builtin_ia32_psrldqi128 (__A, 8);
5314         }
5315     } "-O2 -msse2" ]
5316 }
5317
5318 # Return 1 if F16C instructions can be compiled.
5319
5320 proc check_effective_target_f16c { } {
5321     return [check_no_compiler_messages f16c object {
5322         #include "immintrin.h"
5323         float
5324         foo (unsigned short val)
5325         {
5326           return _cvtsh_ss (val);
5327         }
5328     } "-O2 -mf16c" ]
5329 }
5330
5331 # Return 1 if C wchar_t type is compatible with char16_t.
5332
5333 proc check_effective_target_wchar_t_char16_t_compatible { } {
5334     return [check_no_compiler_messages wchar_t_char16_t object {
5335         __WCHAR_TYPE__ wc;
5336         __CHAR16_TYPE__ *p16 = &wc;
5337         char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
5338     }]
5339 }
5340
5341 # Return 1 if C wchar_t type is compatible with char32_t.
5342
5343 proc check_effective_target_wchar_t_char32_t_compatible { } {
5344     return [check_no_compiler_messages wchar_t_char32_t object {
5345         __WCHAR_TYPE__ wc;
5346         __CHAR32_TYPE__ *p32 = &wc;
5347         char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
5348     }]
5349 }
5350
5351 # Return 1 if pow10 function exists.
5352
5353 proc check_effective_target_pow10 { } {
5354     return [check_runtime pow10 {
5355         #include <math.h>
5356         int main () {
5357         double x;
5358         x = pow10 (1);
5359         return 0;
5360         }
5361     } "-lm" ]
5362 }
5363
5364 # Return 1 if current options generate DFP instructions, 0 otherwise.
5365
5366 proc check_effective_target_hard_dfp {} {
5367     return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly {
5368         typedef float d64 __attribute__((mode(DD)));
5369         d64 x, y, z;
5370         void foo (void) { z = x + y; }
5371     }]
5372 }
5373
5374 # Return 1 if string.h and wchar.h headers provide C++ requires overloads
5375 # for strchr etc. functions.
5376
5377 proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
5378     return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly {
5379         #include <string.h>
5380         #include <wchar.h>
5381         #if !defined(__cplusplus) \
5382             || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \
5383             || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO)
5384         ISO C++ correct string.h and wchar.h protos not supported.
5385         #else
5386         int i;
5387         #endif
5388     }]
5389 }
5390
5391 # Return 1 if GNU as is used.
5392
5393 proc check_effective_target_gas { } {
5394     global use_gas_saved
5395     global tool
5396
5397     if {![info exists use_gas_saved]} {
5398         # Check if the as used by gcc is GNU as.
5399         set gcc_as [lindex [${tool}_target_compile "-print-prog-name=as" "" "none" ""] 0]
5400         # Provide /dev/null as input, otherwise gas times out reading from
5401         # stdin.
5402         set status [remote_exec host "$gcc_as" "-v /dev/null"]
5403         set as_output [lindex $status 1]
5404         if { [ string first "GNU" $as_output ] >= 0 } {
5405             set use_gas_saved 1
5406         } else {
5407             set use_gas_saved 0
5408         }
5409     }
5410     return $use_gas_saved
5411 }
5412
5413 # Return 1 if GNU ld is used.
5414
5415 proc check_effective_target_gld { } {
5416     global use_gld_saved
5417     global tool
5418
5419     if {![info exists use_gld_saved]} {
5420         # Check if the ld used by gcc is GNU ld.
5421         set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=ld" "" "none" ""] 0]
5422         set status [remote_exec host "$gcc_ld" "--version"]
5423         set ld_output [lindex $status 1]
5424         if { [ string first "GNU" $ld_output ] >= 0 } {
5425             set use_gld_saved 1
5426         } else {
5427             set use_gld_saved 0
5428         }
5429     }
5430     return $use_gld_saved
5431 }
5432
5433 # Return 1 if the compiler has been configure with link-time optimization
5434 # (LTO) support.
5435
5436 proc check_effective_target_lto { } {
5437     global ENABLE_LTO
5438     return [info exists ENABLE_LTO]
5439 }
5440
5441 # Return 1 if -mx32 -maddress-mode=short can compile, 0 otherwise.
5442
5443 proc check_effective_target_maybe_x32 { } {
5444     return [check_no_compiler_messages maybe_x32 object {
5445         void foo (void) {}
5446     } "-mx32 -maddress-mode=short"]
5447 }
5448
5449 # Return 1 if this target supports the -fsplit-stack option, 0
5450 # otherwise.
5451
5452 proc check_effective_target_split_stack {} {
5453     return [check_no_compiler_messages split_stack object {
5454         void foo (void) { }
5455     } "-fsplit-stack"]
5456 }
5457
5458 # Return 1 if this target supports the -masm=intel option, 0
5459 # otherwise
5460
5461 proc check_effective_target_masm_intel  {} {
5462     return [check_no_compiler_messages masm_intel object {
5463         extern void abort (void);
5464     } "-masm=intel"]
5465 }
5466
5467 # Return 1 if the language for the compiler under test is C.
5468
5469 proc check_effective_target_c { } {
5470  global tool
5471     if [string match $tool "gcc"] {
5472    return 1
5473     }
5474  return 0
5475 }
5476
5477 # Return 1 if the language for the compiler under test is C++.
5478
5479 proc check_effective_target_c++ { } {
5480  global tool
5481     if [string match $tool "g++"] {
5482    return 1
5483     }
5484  return 0
5485 }
5486
5487 # Check whether the current active language standard supports the features
5488 # of C++11/C++1y by checking for the presence of one of the -std
5489 # flags.  This assumes that the default for the compiler is C++98, and that
5490 # there will never be multiple -std= arguments on the command line.
5491 proc check_effective_target_c++11_only { } {
5492     if ![check_effective_target_c++] {
5493         return 0
5494     }
5495     return [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }]
5496 }
5497 proc check_effective_target_c++11 { } {
5498     if [check_effective_target_c++11_only] {
5499         return 1
5500     }
5501     return [check_effective_target_c++1y]
5502 }
5503 proc check_effective_target_c++11_down { } {
5504     if ![check_effective_target_c++] {
5505         return 0
5506     }
5507     return ![check_effective_target_c++1y]
5508 }
5509
5510 proc check_effective_target_c++1y_only { } {
5511     if ![check_effective_target_c++] {
5512         return 0
5513     }
5514     return [check-flags { { } { } { -std=c++1y -std=gnu++1y -std=c++14 -std=gnu++14 } }]
5515 }
5516 proc check_effective_target_c++1y { } {
5517     return [check_effective_target_c++1y_only]
5518 }
5519
5520 proc check_effective_target_c++98_only { } {
5521     if ![check_effective_target_c++] {
5522         return 0
5523     }
5524     return ![check_effective_target_c++11]
5525 }
5526
5527 # Return 1 if expensive testcases should be run.
5528
5529 proc check_effective_target_run_expensive_tests { } {
5530     if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } {
5531         return 1
5532     }
5533     return 0
5534 }
5535
5536 # Returns 1 if "mempcpy" is available on the target system.
5537
5538 proc check_effective_target_mempcpy {} {
5539     return [check_function_available "mempcpy"]
5540 }
5541
5542 # Check whether the vectorizer tests are supported by the target and
5543 # append additional target-dependent compile flags to DEFAULT_VECTCFLAGS.
5544 # Set dg-do-what-default to either compile or run, depending on target
5545 # capabilities.  Return 1 if vectorizer tests are supported by
5546 # target, 0 otherwise.
5547
5548 proc check_vect_support_and_set_flags { } {
5549     global DEFAULT_VECTCFLAGS
5550     global dg-do-what-default
5551
5552     if  [istarget powerpc-*paired*]  {
5553         lappend DEFAULT_VECTCFLAGS "-mpaired"
5554         if [check_750cl_hw_available] {
5555             set dg-do-what-default run
5556         } else {
5557             set dg-do-what-default compile
5558         }
5559     } elseif [istarget powerpc*-*-*] {
5560         # Skip targets not supporting -maltivec.
5561         if ![is-effective-target powerpc_altivec_ok] {
5562             return 0
5563         }
5564
5565         lappend DEFAULT_VECTCFLAGS "-maltivec"
5566         if [check_p8vector_hw_available] {
5567             lappend DEFAULT_VECTCFLAGS "-mpower8-vector" "-mno-allow-movmisalign"
5568         } elseif [check_vsx_hw_available] {
5569             lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
5570         }
5571
5572         if [check_vmx_hw_available] {
5573             set dg-do-what-default run
5574         } else {
5575             if [is-effective-target ilp32] {
5576                 # Specify a cpu that supports VMX for compile-only tests.
5577                 lappend DEFAULT_VECTCFLAGS "-mcpu=970"
5578             }
5579             set dg-do-what-default compile
5580         }
5581     } elseif { [istarget spu-*-*] } {
5582         set dg-do-what-default run
5583     } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
5584         lappend DEFAULT_VECTCFLAGS "-msse2"
5585         if { [check_effective_target_sse2_runtime] } {
5586             set dg-do-what-default run
5587         } else {
5588             set dg-do-what-default compile
5589         }
5590     } elseif { [istarget mips*-*-*]
5591                && ([check_effective_target_mpaired_single]
5592                     || [check_effective_target_mips_loongson])
5593                && [check_effective_target_nomips16] } {
5594         if { [check_effective_target_mpaired_single] } {
5595             lappend DEFAULT_VECTCFLAGS "-mpaired-single"
5596         }
5597         set dg-do-what-default run
5598     } elseif [istarget sparc*-*-*] {
5599         lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
5600         if [check_effective_target_ultrasparc_hw] {
5601             set dg-do-what-default run
5602         } else {
5603             set dg-do-what-default compile
5604         }
5605     } elseif [istarget alpha*-*-*] {
5606         # Alpha's vectorization capabilities are extremely limited.
5607         # It's more effort than its worth disabling all of the tests
5608         # that it cannot pass.  But if you actually want to see what
5609         # does work, command out the return.
5610         return 0
5611
5612         lappend DEFAULT_VECTCFLAGS "-mmax"
5613         if [check_alpha_max_hw_available] {
5614             set dg-do-what-default run
5615         } else {
5616             set dg-do-what-default compile
5617         }
5618     } elseif [istarget ia64-*-*] {
5619         set dg-do-what-default run
5620     } elseif [is-effective-target arm_neon_ok] {
5621         eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
5622         # NEON does not support denormals, so is not used for vectorization by
5623         # default to avoid loss of precision.  We must pass -ffast-math to test
5624         # vectorization of float operations.
5625         lappend DEFAULT_VECTCFLAGS "-ffast-math"
5626         if [is-effective-target arm_neon_hw] {
5627             set dg-do-what-default run
5628         } else {
5629             set dg-do-what-default compile
5630         }
5631     } elseif [istarget "aarch64*-*-*"] {
5632         set dg-do-what-default run
5633     } else {
5634         return 0
5635     }
5636
5637     return 1
5638 }
5639
5640 proc check_effective_target_non_strict_align {} {
5641     return [check_no_compiler_messages non_strict_align assembly {
5642         char *y;
5643         typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c;
5644         c *z;
5645         void foo(void) { z = (c *) y; }
5646     } "-Wcast-align"]
5647 }
5648
5649 # Return 1 if the target has <ucontext.h>.
5650
5651 proc check_effective_target_ucontext_h { } {
5652     return [check_no_compiler_messages ucontext_h assembly {
5653         #include <ucontext.h>
5654     }]
5655 }
5656
5657 proc check_effective_target_aarch64_tiny { } {
5658     if { [istarget aarch64*-*-*] } {
5659         return [check_no_compiler_messages aarch64_tiny object {
5660             #ifdef __AARCH64_CMODEL_TINY__
5661             int dummy;
5662             #else
5663             #error target not AArch64 tiny code model
5664             #endif
5665         }]
5666     } else {
5667         return 0
5668     }
5669 }
5670
5671 proc check_effective_target_aarch64_small { } {
5672     if { [istarget aarch64*-*-*] } {
5673         return [check_no_compiler_messages aarch64_small object {
5674             #ifdef __AARCH64_CMODEL_SMALL__
5675             int dummy;
5676             #else
5677             #error target not AArch64 small code model
5678             #endif
5679         }]
5680     } else {
5681         return 0
5682     }
5683 }
5684
5685 proc check_effective_target_aarch64_large { } {
5686     if { [istarget aarch64*-*-*] } {
5687         return [check_no_compiler_messages aarch64_large object {
5688             #ifdef __AARCH64_CMODEL_LARGE__
5689             int dummy;
5690             #else
5691             #error target not AArch64 large code model
5692             #endif
5693         }]
5694     } else {
5695         return 0
5696     }
5697 }
5698
5699 # Return 1 if <fenv.h> is available with all the standard IEEE
5700 # exceptions and floating-point exceptions are raised by arithmetic
5701 # operations.  (If the target requires special options for "inexact"
5702 # exceptions, those need to be specified in the testcases.)
5703
5704 proc check_effective_target_fenv_exceptions {} {
5705     return [check_runtime fenv_exceptions {
5706         #include <fenv.h>
5707         #include <stdlib.h>
5708         #ifndef FE_DIVBYZERO
5709         # error Missing FE_DIVBYZERO
5710         #endif
5711         #ifndef FE_INEXACT
5712         # error Missing FE_INEXACT
5713         #endif
5714         #ifndef FE_INVALID
5715         # error Missing FE_INVALID
5716         #endif
5717         #ifndef FE_OVERFLOW
5718         # error Missing FE_OVERFLOW
5719         #endif
5720         #ifndef FE_UNDERFLOW
5721         # error Missing FE_UNDERFLOW
5722         #endif
5723         volatile float a = 0.0f, r;
5724         int
5725         main (void)
5726         {
5727           r = a / a;
5728           if (fetestexcept (FE_INVALID))
5729             exit (0);
5730           else
5731             abort ();
5732         }
5733     } "-std=gnu99"]
5734 }
5735
5736 # Return 1 if LOGICAL_OP_NON_SHORT_CIRCUIT is set to 0 for the current target.
5737
5738 proc check_effective_target_logical_op_short_circuit {} {
5739     if { [istarget mips*-*-*]
5740          || [istarget arc*-*-*]
5741          || [istarget avr*-*-*]
5742          || [istarget crisv32-*-*] || [istarget cris-*-*]
5743          || [istarget s390*-*-*]
5744          || [check_effective_target_arm_cortex_m] } {
5745         return 1
5746     }
5747     return 0
5748 }
5749
5750 # Record that dg-final test TEST requires convential compilation.
5751
5752 proc force_conventional_output_for { test } {
5753     if { [info proc $test] == "" } {
5754         perror "$test does not exist"
5755         exit 1
5756     }
5757     proc ${test}_required_options {} {
5758         global gcc_force_conventional_output
5759         return $gcc_force_conventional_output
5760     }
5761 }
5762