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