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