OSDN Git Service

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