OSDN Git Service

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