1#   Copyright (C) 1999-2020 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# "// D" for D,
35# "! Fortran" for Fortran code,
36# "/* ObjC", for ObjC
37# "// ObjC++" for ObjC++
38# and "// Go" for Go
39# If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to
40# allow for ObjC/ObjC++ specific flags.
41
42proc check_compile {basename type contents args} {
43    global tool
44    verbose "check_compile tool: $tool for $basename"
45
46    # Save additional_sources to avoid compiling testsuite's sources
47    # against check_compile's source.
48    global additional_sources
49    if [info exists additional_sources] {
50	set tmp_additional_sources "$additional_sources"
51	set additional_sources ""
52    }
53
54    if { [llength $args] > 0 } {
55	set options [list "additional_flags=[lindex $args 0]"]
56    } else {
57	set options ""
58    }
59    switch -glob -- $contents {
60	"*! Fortran*" { set src ${basename}[pid].f90 }
61	"*// C++*" { set src ${basename}[pid].cc }
62	"*// D*" { set src ${basename}[pid].d }
63	"*// ObjC++*" { set src ${basename}[pid].mm }
64	"*/* ObjC*" { set src ${basename}[pid].m }
65	"*// Go*" { set src ${basename}[pid].go }
66	default {
67	    switch -- $tool {
68		"objc" { set src ${basename}[pid].m }
69		"obj-c++" { set src ${basename}[pid].mm }
70		default { set src ${basename}[pid].c }
71	    }
72	}
73    }
74
75    set compile_type $type
76    switch -glob $type {
77	assembly { set output ${basename}[pid].s }
78	object { set output ${basename}[pid].o }
79	executable { set output ${basename}[pid].exe }
80	"rtl-*" {
81	    set output ${basename}[pid].s
82	    lappend options "additional_flags=-fdump-$type"
83	    set compile_type assembly
84	}
85    }
86    set f [open $src "w"]
87    puts $f $contents
88    close $f
89    set lines [${tool}_target_compile $src $output $compile_type "$options"]
90    file delete $src
91
92    set scan_output $output
93    # Don't try folding this into the switch above; calling "glob" before the
94    # file is created won't work.
95    if [regexp "rtl-(.*)" $type dummy rtl_type] {
96	set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]"
97	file delete $output
98    }
99
100    # Restore additional_sources.
101    if [info exists additional_sources] {
102	set additional_sources "$tmp_additional_sources"
103    }
104
105    return [list $lines $scan_output]
106}
107
108proc current_target_name { } {
109    global target_info
110    if [info exists target_info(target,name)] {
111	set answer $target_info(target,name)
112    } else {
113	set answer ""
114    }
115    return $answer
116}
117
118# Implement an effective-target check for property PROP by invoking
119# the Tcl command ARGS and seeing if it returns true.
120
121proc check_cached_effective_target { prop args } {
122    global et_cache
123
124    set target [current_target_name]
125    if {![info exists et_cache($prop,$target)]} {
126	verbose "check_cached_effective_target $prop: checking $target" 2
127	if {[string is true -strict $args] || [string is false -strict $args]} {
128	    error {check_cached_effective_target condition already evaluated; did you pass [...] instead of the expected {...}?}
129	} else {
130	    set code [catch {uplevel eval $args} result]
131	    if {$code != 0 && $code != 2} {
132		return -code $code $result
133	    }
134	    set et_cache($prop,$target) $result
135	}
136    }
137    set value $et_cache($prop,$target)
138    verbose "check_cached_effective_target $prop: returning $value for $target" 2
139    return $value
140}
141
142# Implements a version of check_cached_effective_target that also takes et_index
143# into account when creating the key for the cache.
144proc check_cached_effective_target_indexed { prop args } {
145    global et_index
146    set key "$et_index $prop"
147    verbose "check_cached_effective_target_index $prop: returning $key" 2
148
149    return [check_cached_effective_target $key [list uplevel eval $args]]
150}
151
152# Clear effective-target cache. This is useful after testing
153# effective-target features and overriding TEST_ALWAYS_FLAGS and/or
154# ALWAYS_CXXFLAGS.
155# If one changes ALWAYS_CXXFLAGS or TEST_ALWAYS_FLAGS then they should
156# do a clear_effective_target_cache at the end as the target cache can
157# make decisions based upon the flags, and those decisions need to be
158# redone when the flags change. An example of this is the
159# asan_init/asan_finish pair.
160
161proc clear_effective_target_cache { } {
162    global et_cache
163    array unset et_cache
164}
165
166# Like check_compile, but delete the output file and return true if the
167# compiler printed no messages.
168proc check_no_compiler_messages_nocache {args} {
169    set result [eval check_compile $args]
170    set lines [lindex $result 0]
171    set output [lindex $result 1]
172    remote_file build delete $output
173    return [string match "" $lines]
174}
175
176# Like check_no_compiler_messages_nocache, but cache the result.
177# PROP is the property we're checking, and doubles as a prefix for
178# temporary filenames.
179proc check_no_compiler_messages {prop args} {
180    return [check_cached_effective_target $prop {
181	eval [list check_no_compiler_messages_nocache $prop] $args
182    }]
183}
184
185# Like check_compile, but return true if the compiler printed no
186# messages and if the contents of the output file satisfy PATTERN.
187# If PATTERN has the form "!REGEXP", the contents satisfy it if they
188# don't match regular expression REGEXP, otherwise they satisfy it
189# if they do match regular expression PATTERN.  (PATTERN can start
190# with something like "[!]" if the regular expression needs to match
191# "!" as the first character.)
192#
193# Delete the output file before returning.  The other arguments are
194# as for check_compile.
195proc check_no_messages_and_pattern_nocache {basename pattern args} {
196    global tool
197
198    set result [eval [list check_compile $basename] $args]
199    set lines [lindex $result 0]
200    set output [lindex $result 1]
201
202    set ok 0
203    if { [string match "" $lines] } {
204	set chan [open "$output"]
205	set invert [regexp {^!(.*)} $pattern dummy pattern]
206	set ok [expr { [regexp $pattern [read $chan]] != $invert }]
207	close $chan
208    }
209
210    remote_file build delete $output
211    return $ok
212}
213
214# Like check_no_messages_and_pattern_nocache, but cache the result.
215# PROP is the property we're checking, and doubles as a prefix for
216# temporary filenames.
217proc check_no_messages_and_pattern {prop pattern args} {
218    return [check_cached_effective_target $prop {
219	eval [list check_no_messages_and_pattern_nocache $prop $pattern] $args
220    }]
221}
222
223# Try to compile and run an executable from code CONTENTS.  Return true
224# if the compiler reports no messages and if execution "passes" in the
225# usual DejaGNU sense.  The arguments are as for check_compile, with
226# TYPE implicitly being "executable".
227proc check_runtime_nocache {basename contents args} {
228    global tool
229
230    set result [eval [list check_compile $basename executable $contents] $args]
231    set lines [lindex $result 0]
232    set output [lindex $result 1]
233
234    set ok 0
235    if { [string match "" $lines] } {
236	# No error messages, everything is OK.
237	set result [remote_load target "./$output" "" ""]
238	set status [lindex $result 0]
239	verbose "check_runtime_nocache $basename: status is <$status>" 2
240	if { $status == "pass" } {
241	    set ok 1
242	}
243    }
244    remote_file build delete $output
245    return $ok
246}
247
248# Like check_runtime_nocache, but cache the result.  PROP is the
249# property we're checking, and doubles as a prefix for temporary
250# filenames.
251proc check_runtime {prop args} {
252    global tool
253
254    return [check_cached_effective_target $prop {
255	eval [list check_runtime_nocache $prop] $args
256    }]
257}
258
259# Return 1 if GCC was configured with $pattern.
260proc check_configured_with { pattern } {
261    global tool
262
263    set options [list "additional_flags=-v"]
264    set gcc_output [${tool}_target_compile "" "" "none" $options]
265    if { [ regexp "Configured with: \[^\n\]*$pattern" $gcc_output ] } {
266        verbose "Matched: $pattern" 2
267        return 1
268    }
269
270    verbose "Failed to match: $pattern" 2
271    return 0
272}
273
274###############################
275# proc check_weak_available { }
276###############################
277
278# weak symbols are only supported in some configs/object formats
279# this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure
280
281proc check_weak_available { } {
282    global target_cpu
283
284    # All mips targets should support it
285
286    if { [ string first "mips" $target_cpu ] >= 0 } {
287        return 1
288    }
289
290    # All AIX targets should support it
291
292    if { [istarget *-*-aix*] } {
293        return 1
294    }
295
296    # All solaris2 targets should support it
297
298    if { [istarget *-*-solaris2*] } {
299        return 1
300    }
301
302    # Windows targets Cygwin and MingW32 support it
303
304    if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
305	return 1
306    }
307
308    # HP-UX 10.X doesn't support it
309
310    if { [istarget hppa*-*-hpux10*] } {
311	return 0
312    }
313
314    # nvptx (nearly) supports it
315
316    if { [istarget nvptx-*-*] } {
317	return 1
318    }
319
320    # pdp11 doesn't support it
321
322    if { [istarget pdp11*-*-*] } {
323	return 0
324    }
325
326    # ELF and ECOFF support it. a.out does with gas/gld but may also with
327    # other linkers, so we should try it
328
329    set objformat [gcc_target_object_format]
330
331    switch $objformat {
332        elf      { return 1 }
333        ecoff    { return 1 }
334        a.out    { return 1 }
335	mach-o	 { return 1 }
336	som	 { return 1 }
337        unknown  { return -1 }
338        default  { return 0 }
339    }
340}
341
342# return 1 if weak undefined symbols are supported.
343
344proc check_effective_target_weak_undefined { } {
345    if { [istarget hppa*-*-hpux*] } {
346	return 0
347    }
348    return [check_runtime weak_undefined {
349	extern void foo () __attribute__((weak));
350	int main (void) { if (foo) return 1; return 0; }
351    } ""]
352}
353
354###############################
355# proc check_weak_override_available { }
356###############################
357
358# Like check_weak_available, but return 0 if weak symbol definitions
359# cannot be overridden.
360
361proc check_weak_override_available { } {
362    if { [istarget *-*-mingw*] } {
363	return 0
364    }
365    return [check_weak_available]
366}
367
368# The noinit attribute is only supported by some targets.
369# This proc returns 1 if it's supported, 0 if it's not.
370
371proc check_effective_target_noinit { } {
372    if { [istarget arm*-*-eabi]
373	 || [istarget msp430-*-*] } {
374	return 1
375    }
376
377    return 0
378}
379
380###############################
381# proc check_visibility_available { what_kind }
382###############################
383
384# The visibility attribute is only support in some object formats
385# This proc returns 1 if it is supported, 0 if not.
386# The argument is the kind of visibility, default/protected/hidden/internal.
387
388proc check_visibility_available { what_kind } {
389    if [string match "" $what_kind] { set what_kind "hidden" }
390
391    return [check_no_compiler_messages visibility_available_$what_kind object "
392	void f() __attribute__((visibility(\"$what_kind\")));
393	void f() {}
394    "]
395}
396
397###############################
398# proc check_alias_available { }
399###############################
400
401# Determine if the target toolchain supports the alias attribute.
402
403# Returns 2 if the target supports aliases.  Returns 1 if the target
404# only supports weak aliased.  Returns 0 if the target does not
405# support aliases at all.  Returns -1 if support for aliases could not
406# be determined.
407
408proc check_alias_available { } {
409    global tool
410
411    return [check_cached_effective_target alias_available {
412	set src alias[pid].c
413	set obj alias[pid].o
414        verbose "check_alias_available  compiling testfile $src" 2
415	set f [open $src "w"]
416	# Compile a small test program.  The definition of "g" is
417	# necessary to keep the Solaris assembler from complaining
418	# about the program.
419	puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
420	puts $f "void g() {} void f() __attribute__((alias(\"g\")));"
421	close $f
422	set lines [${tool}_target_compile $src $obj object ""]
423	file delete $src
424	remote_file build delete $obj
425
426	if [string match "" $lines] then {
427	    # No error messages, everything is OK.
428	    return 2
429	} else {
430	    if [regexp "alias definitions not supported" $lines] {
431		verbose "check_alias_available  target does not support aliases" 2
432
433		set objformat [gcc_target_object_format]
434
435		if { $objformat == "elf" } {
436		    verbose "check_alias_available  but target uses ELF format, so it ought to" 2
437		    return -1
438		} else {
439		    return 0
440		}
441	    } else {
442		if [regexp "only weak aliases are supported" $lines] {
443		verbose "check_alias_available  target supports only weak aliases" 2
444		    return 1
445		} else {
446		    return -1
447		}
448	    }
449	}
450    }]
451}
452
453# Returns 1 if the target toolchain supports strong aliases, 0 otherwise.
454
455proc check_effective_target_alias { } {
456    if { [check_alias_available] < 2 } {
457	return 0
458    } else {
459	return 1
460    }
461}
462
463# Returns 1 if the target toolchain supports ifunc, 0 otherwise.
464
465proc check_ifunc_available { } {
466    return [check_no_compiler_messages ifunc_available object {
467	#ifdef __cplusplus
468	extern "C" {
469	#endif
470	extern void f_ ();
471 	typedef void F (void);
472	F* g (void) { return &f_; }
473	void f () __attribute__ ((ifunc ("g")));
474	#ifdef __cplusplus
475	}
476	#endif
477    }]
478}
479
480# Returns true if --gc-sections is supported on the target.
481
482proc check_gc_sections_available { } {
483    global tool
484
485    return [check_cached_effective_target gc_sections_available {
486	# Some targets don't support gc-sections despite whatever's
487	# advertised by ld's options.
488	if { [istarget alpha*-*-*]
489	     || [istarget ia64-*-*] } {
490	    return 0
491	}
492
493	# elf2flt uses -q (--emit-relocs), which is incompatible with
494	# --gc-sections.
495	if { [board_info target exists ldflags]
496	     && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
497	    return 0
498	}
499
500	# VxWorks kernel modules are relocatable objects linked with -r,
501	# while RTP executables are linked with -q (--emit-relocs).
502	# Both of these options are incompatible with --gc-sections.
503	if { [istarget *-*-vxworks*] } {
504	    return 0
505	}
506
507	# Check if the ld used by gcc supports --gc-sections.
508	set options [list "additional_flags=-print-prog-name=ld"]
509	set gcc_ld [lindex [${tool}_target_compile "" "" "none" $options] 0]
510	set ld_output [remote_exec host "$gcc_ld" "--help"]
511	if { [ string first "--gc-sections" $ld_output ] >= 0 } {
512	    return 1
513	} else {
514	    return 0
515	}
516    }]
517}
518
519# Returns 1 if "dot" is supported on the host.
520
521proc check_dot_available { } {
522    verbose "check_dot_available" 2
523
524    set status [remote_exec host "dot" "-V"]
525    verbose "  status: $status" 2
526    if { [lindex $status 0] != 0 } {
527	return 0
528    }
529    return 1
530}
531
532# Return 1 if according to target_info struct and explicit target list
533# target is supposed to support trampolines.
534
535proc check_effective_target_trampolines { } {
536    if [target_info exists gcc,no_trampolines] {
537      return 0
538    }
539    if { [istarget avr-*-*]
540	 || [istarget msp430-*-*]
541	 || [istarget nvptx-*-*]
542	 || [istarget hppa2.0w-hp-hpux11.23]
543	 || [istarget hppa64-hp-hpux11.23]
544	 || [istarget pru-*-*]
545	 || [istarget bpf-*-*] } {
546	return 0;
547    }
548    return 1
549}
550
551# Return 1 if target has limited stack size.
552
553proc check_effective_target_stack_size { } {
554    if [target_info exists gcc,stack_size] {
555	return 1
556    }
557    return 0
558}
559
560# Return the value attribute of an effective target, otherwise return 0.
561
562proc dg-effective-target-value { effective_target } {
563    if { "$effective_target" == "stack_size" } {
564	if [check_effective_target_stack_size] {
565	    return [target_info gcc,stack_size]
566	}
567    }
568
569    return 0
570}
571
572# Return 1 if signal.h is supported.
573
574proc check_effective_target_signal { } {
575    if [target_info exists gcc,signal_suppress] {
576      return 0
577    }
578    return 1
579}
580
581# Return 1 if according to target_info struct and explicit target list
582# target disables -fdelete-null-pointer-checks.  Targets should return 0
583# if they simply default to -fno-delete-null-pointer-checks but obey
584# -fdelete-null-pointer-checks when passed explicitly (and tests that
585# depend on this option should do that).
586
587proc check_effective_target_keeps_null_pointer_checks { } {
588    if [target_info exists keeps_null_pointer_checks] {
589      return 1
590    }
591    if { [istarget msp430-*-*] || [istarget cr16-*-*] } {
592	return 1;
593    }
594    return 0
595}
596
597# Return the autofdo profile wrapper
598
599# Linux by default allows 516KB of perf event buffers
600# in /proc/sys/kernel/perf_event_mlock_kb
601# Each individual perf tries to grab it
602# This causes problems with parallel test suite runs. Instead
603# limit us to 8 pages (32K), which should be good enough
604# for the small test programs. With the default settings
605# this allows parallelism of 16 and higher of parallel gcc-auto-profile
606proc profopt-perf-wrapper { } {
607    global srcdir
608    return "$srcdir/../config/i386/gcc-auto-profile -o perf.data -m8 "
609}
610
611# Return true if profiling is supported on the target.
612
613proc check_profiling_available { test_what } {
614    verbose "Profiling argument is <$test_what>" 1
615
616    # These conditions depend on the argument so examine them before
617    # looking at the cache variable.
618
619    # Tree profiling requires TLS runtime support.
620    if { $test_what == "-fprofile-generate" } {
621	if { ![check_effective_target_tls_runtime] } {
622	    return 0
623	}
624    }
625
626    if { $test_what == "-fauto-profile" } {
627	if { !([istarget i?86-*-linux*] || [istarget x86_64-*-linux*]) } {
628            verbose "autofdo only supported on linux"
629            return 0
630        }
631	# not cross compiling?
632	if { ![isnative] } {
633	    verbose "autofdo not supported for non native builds"
634	    return 0
635	}
636	set event [profopt-perf-wrapper]
637	if {$event == "" } {
638	    verbose "autofdo not supported"
639	    return 0
640	}
641        global srcdir
642	set status [remote_exec host "$srcdir/../config/i386/gcc-auto-profile" "true -v >/dev/null"]
643	if { [lindex $status 0] != 0 } {
644	    verbose "autofdo not supported because perf does not work"
645	    return 0
646	}
647
648	# no good way to check this in advance -- check later instead.
649	#set status [remote_exec host "create_gcov" "2>/dev/null"]
650	#if { [lindex $status 0] != 255 } {
651        #    verbose "autofdo not supported due to missing create_gcov"
652        #    return 0
653        #}
654    }
655
656    # Support for -p on solaris2 relies on mcrt1.o which comes with the
657    # vendor compiler.  We cannot reliably predict the directory where the
658    # vendor compiler (and thus mcrt1.o) is installed so we can't
659    # necessarily find mcrt1.o even if we have it.
660    if { [istarget *-*-solaris2*] && $test_what == "-p" } {
661	return 0
662    }
663
664    # We don't yet support profiling for MIPS16.
665    if { [istarget mips*-*-*]
666	 && ![check_effective_target_nomips16]
667	 && ($test_what == "-p" || $test_what == "-pg") } {
668	return 0
669    }
670
671    # MinGW does not support -p.
672    if { [istarget *-*-mingw*] && $test_what == "-p" } {
673	return 0
674    }
675
676    # cygwin does not support -p.
677    if { [istarget *-*-cygwin*] && $test_what == "-p" } {
678	return 0
679    }
680
681    # uClibc does not have gcrt1.o.
682    if { [check_effective_target_uclibc]
683	 && ($test_what == "-p" || $test_what == "-pg") } {
684	return 0
685    }
686
687    # Now examine the cache variable.
688    set profiling_working \
689       [check_cached_effective_target profiling_available {
690	# Some targets don't have any implementation of __bb_init_func or are
691	# missing other needed machinery.
692	if {[istarget aarch64*-*-elf]
693	     || [istarget am3*-*-linux*]
694	     || [istarget amdgcn-*-*]
695	     || [istarget arm*-*-eabi*]
696	     || [istarget arm*-*-elf]
697	     || [istarget arm*-*-symbianelf*]
698	     || [istarget avr-*-*]
699	     || [istarget bfin-*-*]
700	     || [istarget cris-*-*]
701	     || [istarget crisv32-*-*]
702	     || [istarget csky-*-elf]
703	     || [istarget fido-*-elf]
704	     || [istarget h8300-*-*]
705	     || [istarget lm32-*-*]
706	     || [istarget m32c-*-elf]
707	     || [istarget m68k-*-elf]
708	     || [istarget m68k-*-uclinux*]
709	     || [istarget mips*-*-elf*]
710	     || [istarget mmix-*-*]
711	     || [istarget mn10300-*-elf*]
712	     || [istarget moxie-*-elf*]
713	     || [istarget msp430-*-*]
714	     || [istarget nds32*-*-elf]
715	     || [istarget nios2-*-elf]
716	     || [istarget nvptx-*-*]
717	     || [istarget powerpc-*-eabi*]
718	     || [istarget powerpc-*-elf]
719	     || [istarget pru-*-*]
720	     || [istarget rx-*-*]
721	     || [istarget tic6x-*-elf]
722	     || [istarget visium-*-*]
723	     || [istarget xstormy16-*]
724	     || [istarget xtensa*-*-elf]
725	     || [istarget *-*-rtems*]
726	     || [istarget *-*-vxworks*] } {
727	    return 0
728	} else {
729	    return 1
730	}
731    }]
732
733    # -pg link test result can't be cached since it may change between
734    # runs.
735    if { $profiling_working == 1
736         && ![check_no_compiler_messages_nocache profiling executable {
737	      int main() { return 0; } } "-pg"] } {
738	set profiling_working 0
739    }
740
741    return $profiling_working
742}
743
744# Check to see if a target is "freestanding". This is as per the definition
745# in Section 4 of C99 standard. Effectively, it is a target which supports no
746# extra headers or libraries other than what is considered essential.
747proc check_effective_target_freestanding { } {
748    if { [istarget nvptx-*-*] } {
749	return 1
750    }
751    return 0
752}
753
754# Check to see that file I/O functions are available.
755proc check_effective_target_fileio { } {
756    return [check_no_compiler_messages fileio_available executable {
757#include <stdio.h>
758int main() {
759    char *n = tmpnam (NULL);
760    FILE *f = fopen (n, "w");
761    fclose (f);
762    remove (n);
763    return 0;
764} } ""]
765}
766
767# Return 1 if target has packed layout of structure members by
768# default, 0 otherwise.  Note that this is slightly different than
769# whether the target has "natural alignment": both attributes may be
770# false.
771
772proc check_effective_target_default_packed { } {
773    return [check_no_compiler_messages default_packed assembly {
774	struct x { char a; long b; } c;
775	int s[sizeof (c) == sizeof (char) + sizeof (long) ? 1 : -1];
776    }]
777}
778
779# Return 1 if target has PCC_BITFIELD_TYPE_MATTERS defined.  See
780# documentation, where the test also comes from.
781
782proc check_effective_target_pcc_bitfield_type_matters { } {
783    # PCC_BITFIELD_TYPE_MATTERS isn't just about unnamed or empty
784    # bitfields, but let's stick to the example code from the docs.
785    return [check_no_compiler_messages pcc_bitfield_type_matters assembly {
786	struct foo1 { char x; char :0; char y; };
787	struct foo2 { char x; int :0; char y; };
788	int s[sizeof (struct foo1) != sizeof (struct foo2) ? 1 : -1];
789    }]
790}
791
792# Add to FLAGS all the target-specific flags needed to use thread-local storage.
793
794proc add_options_for_tls { flags } {
795    # On Solaris 9, __tls_get_addr/___tls_get_addr only lives in
796    # libthread, so always pass -pthread for native TLS. Same for AIX.
797    # Need to duplicate native TLS check from
798    # check_effective_target_tls_native to avoid recursion.
799    if { ([istarget powerpc-ibm-aix*]) &&
800	 [check_no_messages_and_pattern tls_native "!emutls" assembly {
801	     __thread int i;
802	     int f (void) { return i; }
803	     void g (int j) { i = j; }
804	 }] } {
805	return "-pthread [g++_link_flags [get_multilibs "-pthread"] ] $flags "
806    }
807    return $flags
808}
809
810# Return 1 if indirect jumps are supported, 0 otherwise.
811
812proc check_effective_target_indirect_jumps {} {
813    if { [istarget nvptx-*-*] || [istarget bpf-*-*] } {
814	return 0
815    }
816    return 1
817}
818
819# Return 1 if nonlocal goto is supported, 0 otherwise.
820
821proc check_effective_target_nonlocal_goto {} {
822    if { [istarget nvptx-*-*] || [istarget bpf-*-*] } {
823	return 0
824    }
825    return 1
826}
827
828# Return 1 if global constructors are supported, 0 otherwise.
829
830proc check_effective_target_global_constructor {} {
831    if { [istarget nvptx-*-*]
832	 || [istarget amdgcn-*-*]
833	 || [istarget bpf-*-*] } {
834	return 0
835    }
836    return 1
837}
838
839# Return 1 if taking label values is supported, 0 otherwise.
840
841proc check_effective_target_label_values {} {
842    if { [istarget nvptx-*-*] || [target_info exists gcc,no_label_values] } {
843	return 0
844    }
845
846    return 1
847}
848
849# Return 1 if builtin_return_address and builtin_frame_address are
850# supported, 0 otherwise.
851
852proc check_effective_target_return_address {} {
853    if { [istarget nvptx-*-*] } {
854	return 0
855    }
856    # No notion of return address in eBPF.
857    if { [istarget bpf-*-*] } {
858	return 0
859    }
860    # It could be supported on amdgcn, but isn't yet.
861    if { [istarget amdgcn*-*-*] } {
862	return 0
863    }
864    return 1
865}
866
867# Return 1 if the assembler does not verify function types against
868# calls, 0 otherwise.  Such verification will typically show up problems
869# with K&R C function declarations.
870
871proc check_effective_target_untyped_assembly {} {
872    if { [istarget nvptx-*-*] } {
873	return 0
874    }
875    return 1
876}
877
878# Return 1 if alloca is supported, 0 otherwise.
879
880proc check_effective_target_alloca {} {
881    if { [istarget nvptx-*-*] } {
882	return [check_no_compiler_messages alloca assembly {
883	    void f (void*);
884	    void g (int n) { f (__builtin_alloca (n)); }
885	}]
886    }
887    return 1
888}
889
890# Return 1 if thread local storage (TLS) is supported, 0 otherwise.
891
892proc check_effective_target_tls {} {
893    return [check_no_compiler_messages tls assembly {
894	__thread int i;
895	int f (void) { return i; }
896	void g (int j) { i = j; }
897    }]
898}
899
900# Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise.
901
902proc check_effective_target_tls_native {} {
903    # VxWorks uses emulated TLS machinery, but with non-standard helper
904    # functions, so we fail to automatically detect it.
905    if { [istarget *-*-vxworks*] } {
906	return 0
907    }
908
909    return [check_no_messages_and_pattern tls_native "!emutls" assembly {
910	__thread int i;
911	int f (void) { return i; }
912	void g (int j) { i = j; }
913    }]
914}
915
916# Return 1 if *emulated* thread local storage (TLS) is supported, 0 otherwise.
917
918proc check_effective_target_tls_emulated {} {
919    # VxWorks uses emulated TLS machinery, but with non-standard helper
920    # functions, so we fail to automatically detect it.
921    if { [istarget *-*-vxworks*] } {
922	return 1
923    }
924
925    return [check_no_messages_and_pattern tls_emulated "emutls" assembly {
926	__thread int i;
927	int f (void) { return i; }
928	void g (int j) { i = j; }
929    }]
930}
931
932# Return 1 if TLS executables can run correctly, 0 otherwise.
933
934proc check_effective_target_tls_runtime {} {
935    return [check_runtime tls_runtime {
936	__thread int thr __attribute__((tls_model("global-dynamic"))) = 0;
937	int main (void) { return thr; }
938    } [add_options_for_tls ""]]
939}
940
941# Return 1 if atomic compare-and-swap is supported on 'int'
942
943proc check_effective_target_cas_char {} {
944    return [check_no_compiler_messages cas_char assembly {
945	#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
946	#error unsupported
947	#endif
948    } ""]
949}
950
951proc check_effective_target_cas_int {} {
952    return [check_no_compiler_messages cas_int assembly {
953	#if __INT_MAX__ == 0x7fff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
954        /* ok */
955        #elif __INT_MAX__ == 0x7fffffff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
956	/* ok */
957	#else
958	#error unsupported
959	#endif
960    } ""]
961}
962
963# Return 1 if -ffunction-sections is supported, 0 otherwise.
964
965proc check_effective_target_function_sections {} {
966    # Darwin has its own scheme and silently accepts -ffunction-sections.
967    if { [istarget *-*-darwin*] } {
968	return 0
969    }
970
971    return [check_no_compiler_messages functionsections assembly {
972 	void foo (void) { }
973    } "-ffunction-sections"]
974}
975
976# Return 1 if instruction scheduling is available, 0 otherwise.
977
978proc check_effective_target_scheduling {} {
979    return [check_no_compiler_messages scheduling object {
980	void foo (void) { }
981    } "-fschedule-insns"]
982}
983
984# Return 1 if trapping arithmetic is available, 0 otherwise.
985
986proc check_effective_target_trapping {} {
987    return [check_no_compiler_messages trapping object {
988        int add (int a, int b) { return a + b; }
989    } "-ftrapv"]
990}
991
992# Return 1 if compilation with -fgraphite is error-free for trivial
993# code, 0 otherwise.
994
995proc check_effective_target_fgraphite {} {
996    return [check_no_compiler_messages fgraphite object {
997	void foo (void) { }
998    } "-O1 -fgraphite"]
999}
1000
1001# Return 1 if compiled with --enable-offload-targets=
1002# This affects host compilation as ENABLE_OFFLOAD then evaluates to true.
1003proc check_effective_target_offloading_enabled {} {
1004    return [check_configured_with "--enable-offload-targets"]
1005}
1006
1007# Return 1 if compilation with -fopenacc is error-free for trivial
1008# code, 0 otherwise.
1009
1010proc check_effective_target_fopenacc {} {
1011    # nvptx/amdgcn can be built with the device-side bits of openacc, but it
1012    # does not make sense to test it as an openacc host.
1013    if [istarget nvptx-*-*] { return 0 }
1014    if [istarget amdgcn-*-*] { return 0 }
1015
1016    return [check_no_compiler_messages fopenacc object {
1017	void foo (void) { }
1018    } "-fopenacc"]
1019}
1020
1021# Return 1 if compilation with -fopenmp is error-free for trivial
1022# code, 0 otherwise.
1023
1024proc check_effective_target_fopenmp {} {
1025    # nvptx/amdgcn can be built with the device-side bits of libgomp, but it
1026    # does not make sense to test it as an openmp host.
1027    if [istarget nvptx-*-*] { return 0 }
1028    if [istarget amdgcn-*-*] { return 0 }
1029
1030    return [check_no_compiler_messages fopenmp object {
1031	void foo (void) { }
1032    } "-fopenmp"]
1033}
1034
1035# Return 1 if compilation with -fgnu-tm is error-free for trivial
1036# code, 0 otherwise.
1037
1038proc check_effective_target_fgnu_tm {} {
1039    return [check_no_compiler_messages fgnu_tm object {
1040	void foo (void) { }
1041    } "-fgnu-tm"]
1042}
1043
1044# Return 1 if the target supports mmap, 0 otherwise.
1045
1046proc check_effective_target_mmap {} {
1047    return [check_function_available "mmap"]
1048}
1049
1050# Return 1 if the target supports dlopen, 0 otherwise.
1051proc check_effective_target_dlopen {} {
1052    return [check_no_compiler_messages dlopen executable {
1053	#include <dlfcn.h>
1054	int main(void) { dlopen ("dummy.so", RTLD_NOW); }
1055    } [add_options_for_dlopen ""]]
1056}
1057
1058proc add_options_for_dlopen { flags } {
1059    return "$flags -ldl"
1060}
1061
1062# Return 1 if the target supports clone, 0 otherwise.
1063proc check_effective_target_clone {} {
1064    return [check_function_available "clone"]
1065}
1066
1067# Return 1 if the target supports setrlimit, 0 otherwise.
1068proc check_effective_target_setrlimit {} {
1069    # Darwin has non-posix compliant RLIMIT_AS
1070    if { [istarget *-*-darwin*] } {
1071        return 0
1072    }
1073    return [check_function_available "setrlimit"]
1074}
1075
1076# Return 1 if the target supports gettimeofday, 0 otherwise.
1077proc check_effective_target_gettimeofday {} {
1078    return [check_function_available "gettimeofday"]
1079}
1080
1081# Return 1 if the target supports swapcontext, 0 otherwise.
1082proc check_effective_target_swapcontext {} {
1083    return [check_no_compiler_messages swapcontext executable {
1084	#include <ucontext.h>
1085	int main (void)
1086	{
1087	  ucontext_t orig_context,child_context;
1088	  if (swapcontext(&child_context, &orig_context) < 0) { }
1089	}
1090    }]
1091}
1092
1093# Return 1 if the target supports POSIX threads, 0 otherwise.
1094proc check_effective_target_pthread {} {
1095    return [check_no_compiler_messages pthread object {
1096	#include <pthread.h>
1097	void foo (void) { }
1098    } "-pthread"]
1099}
1100
1101# Return 1 if compilation with -gstabs is error-free for trivial
1102# code, 0 otherwise.
1103
1104proc check_effective_target_stabs {} {
1105    return [check_no_compiler_messages stabs object {
1106	void foo (void) { }
1107    } "-gstabs"]
1108}
1109
1110# Return 1 if compilation with -mpe-aligned-commons is error-free
1111# for trivial code, 0 otherwise.
1112
1113proc check_effective_target_pe_aligned_commons {} {
1114    if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
1115	return [check_no_compiler_messages pe_aligned_commons object {
1116	    int foo;
1117	} "-mpe-aligned-commons"]
1118    }
1119    return 0
1120}
1121
1122# Return 1 if the target supports -static
1123proc check_effective_target_static {} {
1124    if { [istarget arm*-*-uclinuxfdpiceabi] } {
1125	return 0;
1126    }
1127    return [check_no_compiler_messages static executable {
1128	int main (void) { return 0; }
1129    } "-static"]
1130}
1131
1132# Return 1 if the target supports -fstack-protector
1133proc check_effective_target_fstack_protector {} {
1134    return [check_runtime fstack_protector {
1135	#include <string.h>
1136	int main (int argc, char *argv[]) {
1137	  char buf[64];
1138	  return !strcpy (buf, strrchr (argv[0], '/'));
1139	}
1140    } "-fstack-protector"]
1141}
1142
1143# Return 1 if the target supports -fstack-check or -fstack-check=$stack_kind
1144proc check_stack_check_available { stack_kind } {
1145    if [string match "" $stack_kind] then {
1146	set stack_opt "-fstack-check"
1147    } else { set stack_opt "-fstack-check=$stack_kind" }
1148
1149    return [check_no_compiler_messages stack_check_$stack_kind executable {
1150	int main (void) { return 0; }
1151    } "$stack_opt"]
1152}
1153
1154# Return 1 if compilation with -freorder-blocks-and-partition is error-free
1155# for trivial code, 0 otherwise.  As some targets (ARM for example) only
1156# warn when -fprofile-use is also supplied we test that combination too.
1157
1158proc check_effective_target_freorder {} {
1159    if { [check_no_compiler_messages freorder object {
1160	void foo (void) { }
1161    } "-freorder-blocks-and-partition"]
1162    && [check_no_compiler_messages fprofile_use_freorder object {
1163	void foo (void) { }
1164    } "-fprofile-use -freorder-blocks-and-partition -Wno-missing-profile"] } {
1165	return 1
1166    }
1167    return 0
1168}
1169
1170# Return 1 if -fpic and -fPIC are supported, as in no warnings or errors
1171# emitted, 0 otherwise.  Whether a shared library can actually be built is
1172# out of scope for this test.
1173
1174proc check_effective_target_fpic { } {
1175    # Note that M68K has a multilib that supports -fpic but not
1176    # -fPIC, so we need to check both.  We test with a program that
1177    # requires GOT references.
1178    foreach arg {fpic fPIC} {
1179	if [check_no_compiler_messages $arg object {
1180	    extern int foo (void); extern int bar;
1181	    int baz (void) { return foo () + bar; }
1182	} "-$arg"] {
1183	    return 1
1184	}
1185    }
1186    return 0
1187}
1188
1189# On AArch64, if -fpic is not supported, then we will fall back to -fPIC
1190# silently.  So, we can't rely on above "check_effective_target_fpic" as it
1191# assumes compiler will give warning if -fpic not supported.  Here we check
1192# whether binutils supports those new -fpic relocation modifiers, and assume
1193# -fpic is supported if there is binutils support.  GCC configuration will
1194# enable -fpic for AArch64 in this case.
1195#
1196# "check_effective_target_aarch64_small_fpic" is dedicated for checking small
1197# memory model -fpic relocation types.
1198
1199proc check_effective_target_aarch64_small_fpic { } {
1200    if { [istarget aarch64*-*-*] } {
1201	return [check_no_compiler_messages aarch64_small_fpic object {
1202	    void foo (void) { asm ("ldr	x0, [x2, #:gotpage_lo15:globalsym]"); }
1203	}]
1204    } else {
1205	return 0
1206    }
1207}
1208
1209# On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize
1210# the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported
1211# in binutils since 2015-03-04 as PR gas/17843.
1212#
1213# This test directive make sure binutils support all features needed by TLS LE
1214# under -mtls-size=32 on AArch64.
1215
1216proc check_effective_target_aarch64_tlsle32 { } {
1217    if { [istarget aarch64*-*-*] } {
1218	return [check_no_compiler_messages aarch64_tlsle32 object {
1219	    void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); }
1220	}]
1221    } else {
1222	return 0
1223    }
1224}
1225
1226# Return 1 if -shared is supported, as in no warnings or errors
1227# emitted, 0 otherwise.
1228
1229proc check_effective_target_shared { } {
1230    # Note that M68K has a multilib that supports -fpic but not
1231    # -fPIC, so we need to check both.  We test with a program that
1232    # requires GOT references.
1233    return [check_no_compiler_messages shared executable {
1234	extern int foo (void); extern int bar;
1235	int baz (void) { return foo () + bar; }
1236    } "-shared -fpic"]
1237}
1238
1239# Return 1 if -pie, -fpie and -fPIE are supported, 0 otherwise.
1240
1241proc check_effective_target_pie { } {
1242    if { [istarget *-*-darwin\[912\]*]
1243	 || [istarget *-*-dragonfly*]
1244	 || [istarget *-*-freebsd*]
1245	 || [istarget *-*-linux*]
1246	 || [istarget arm*-*-uclinuxfdpiceabi]
1247	 || [istarget *-*-gnu*]
1248	 || [istarget *-*-amdhsa]} {
1249	return 1;
1250    }
1251    if { [istarget *-*-solaris2.1\[1-9\]*] } {
1252	# Full PIE support was added in Solaris 11.3, but gcc errors out
1253	# if missing, so check for that.
1254	return [check_no_compiler_messages pie executable {
1255	    int main (void) { return 0; }
1256	} "-pie -fpie"]
1257    }
1258    return 0
1259}
1260
1261# Return true if the target supports -mpaired-single (as used on MIPS).
1262
1263proc check_effective_target_mpaired_single { } {
1264    return [check_no_compiler_messages mpaired_single object {
1265	void foo (void) { }
1266    } "-mpaired-single"]
1267}
1268
1269# Return true if the target has access to FPU instructions.
1270
1271proc check_effective_target_hard_float { } {
1272    if { [istarget mips*-*-*] } {
1273	return [check_no_compiler_messages hard_float assembly {
1274		#if (defined __mips_soft_float || defined __mips16)
1275		#error __mips_soft_float || __mips16
1276		#endif
1277	}]
1278    }
1279
1280    # This proc is actually checking the availabilty of FPU
1281    # support for doubles, so on the RX we must fail if the
1282    # 64-bit double multilib has been selected.
1283    if { [istarget rx-*-*] } {
1284	return 0
1285	# return [check_no_compiler_messages hard_float assembly {
1286		#if defined __RX_64_BIT_DOUBLES__
1287		#error __RX_64_BIT_DOUBLES__
1288		#endif
1289	# }]
1290    }
1291
1292    # The generic test doesn't work for C-SKY because some cores have
1293    # hard float for single precision only.
1294    if { [istarget csky*-*-*] } {
1295       return [check_no_compiler_messages hard_float assembly {
1296               #if defined __csky_soft_float__
1297               #error __csky_soft_float__
1298               #endif
1299       }]
1300    }
1301
1302    # The generic test equates hard_float with "no call for adding doubles".
1303    return [check_no_messages_and_pattern hard_float "!\\(call" rtl-expand {
1304	double a (double b, double c) { return b + c; }
1305    }]
1306}
1307
1308# Return true if the target is a 64-bit MIPS target.
1309
1310proc check_effective_target_mips64 { } {
1311    return [check_no_compiler_messages mips64 assembly {
1312	#ifndef __mips64
1313	#error !__mips64
1314	#endif
1315    }]
1316}
1317
1318# Return true if the target is a MIPS target that does not produce
1319# MIPS16 code.
1320
1321proc check_effective_target_nomips16 { } {
1322    return [check_no_compiler_messages nomips16 object {
1323	#ifndef __mips
1324	#error !__mips
1325	#else
1326	/* A cheap way of testing for -mflip-mips16.  */
1327	void foo (void) { asm ("addiu $20,$20,1"); }
1328	void bar (void) { asm ("addiu $20,$20,1"); }
1329	#endif
1330    }]
1331}
1332
1333# Add the options needed for MIPS16 function attributes.  At the moment,
1334# we don't support MIPS16 PIC.
1335
1336proc add_options_for_mips16_attribute { flags } {
1337    return "$flags -mno-abicalls -fno-pic -DMIPS16=__attribute__((mips16))"
1338}
1339
1340# Return true if we can force a mode that allows MIPS16 code generation.
1341# We don't support MIPS16 PIC, and only support MIPS16 -mhard-float
1342# for o32 and o64.
1343
1344proc check_effective_target_mips16_attribute { } {
1345    return [check_no_compiler_messages mips16_attribute assembly {
1346	#ifdef PIC
1347	#error PIC
1348	#endif
1349	#if defined __mips_hard_float \
1350	    && (!defined _ABIO32 || _MIPS_SIM != _ABIO32) \
1351	    && (!defined _ABIO64 || _MIPS_SIM != _ABIO64)
1352	#error __mips_hard_float && (!_ABIO32 || !_ABIO64)
1353	#endif
1354    } [add_options_for_mips16_attribute ""]]
1355}
1356
1357# Return 1 if the target supports long double larger than double when
1358# using the new ABI, 0 otherwise.
1359
1360proc check_effective_target_mips_newabi_large_long_double { } {
1361    return [check_no_compiler_messages mips_newabi_large_long_double object {
1362	int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
1363    } "-mabi=64"]
1364}
1365
1366# Return true if the target is a MIPS target that has access
1367# to the LL and SC instructions.
1368
1369proc check_effective_target_mips_llsc { } {
1370    if { ![istarget mips*-*-*] } {
1371	return 0
1372    }
1373    # Assume that these instructions are always implemented for
1374    # non-elf* targets, via emulation if necessary.
1375    if { ![istarget *-*-elf*] } {
1376	return 1
1377    }
1378    # Otherwise assume LL/SC support for everything but MIPS I.
1379    return [check_no_compiler_messages mips_llsc assembly {
1380	#if __mips == 1
1381	#error __mips == 1
1382	#endif
1383    }]
1384}
1385
1386# Return true if the target is a MIPS target that uses in-place relocations.
1387
1388proc check_effective_target_mips_rel { } {
1389    if { ![istarget mips*-*-*] } {
1390	return 0
1391    }
1392    return [check_no_compiler_messages mips_rel object {
1393	#if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
1394	    || (defined _ABI64 && _MIPS_SIM == _ABI64)
1395	#error _ABIN32 && (_ABIN32 || _ABI64)
1396	#endif
1397    }]
1398}
1399
1400# Return true if the target is a MIPS target that uses the EABI.
1401
1402proc check_effective_target_mips_eabi { } {
1403    if { ![istarget mips*-*-*] } {
1404	return 0
1405    }
1406    return [check_no_compiler_messages mips_eabi object {
1407	#ifndef __mips_eabi
1408	#error !__mips_eabi
1409	#endif
1410    }]
1411}
1412
1413# Return 1 if the current multilib does not generate PIC by default.
1414
1415proc check_effective_target_nonpic { } {
1416    return [check_no_compiler_messages nonpic assembly {
1417	#if __PIC__
1418	#error __PIC__
1419	#endif
1420    }]
1421}
1422
1423# Return 1 if the current multilib generates PIE by default.
1424
1425proc check_effective_target_pie_enabled { } {
1426    return [check_no_compiler_messages pie_enabled assembly {
1427	#ifndef __PIE__
1428	#error unsupported
1429	#endif
1430    }]
1431}
1432
1433# Return 1 if the target generates -fstack-protector by default.
1434
1435proc check_effective_target_fstack_protector_enabled {} {
1436    return [ check_no_compiler_messages fstack_protector_enabled assembly {
1437    #if !defined(__SSP__) && !defined(__SSP_ALL__) && \
1438      !defined(__SSP_STRONG__) && !defined(__SSP_EXPICIT__)
1439    #error unsupported
1440    #endif
1441    }]
1442}
1443
1444# Return 1 if the target does not use a status wrapper.
1445
1446proc check_effective_target_unwrapped { } {
1447    if { [target_info needs_status_wrapper] != "" \
1448	     && [target_info needs_status_wrapper] != "0" } {
1449	return 0
1450    }
1451    return 1
1452}
1453
1454# Return true if iconv is supported on the target. In particular IBM1047.
1455
1456proc check_iconv_available { test_what } {
1457    global libiconv
1458
1459    # If the tool configuration file has not set libiconv, try "-liconv"
1460    if { ![info exists libiconv] } {
1461	set libiconv "-liconv"
1462    }
1463    set test_what [lindex $test_what 1]
1464    return [check_runtime_nocache $test_what [subst {
1465	#include <iconv.h>
1466	int main (void)
1467	{
1468	  iconv_t cd;
1469
1470	  cd = iconv_open ("$test_what", "UTF-8");
1471	  if (cd == (iconv_t) -1)
1472	    return 1;
1473	  return 0;
1474	}
1475    }] $libiconv]
1476}
1477
1478# Return true if the atomic library is supported on the target.
1479proc check_effective_target_libatomic_available { } {
1480    return [check_no_compiler_messages libatomic_available executable {
1481	int main (void) { return 0; }
1482    } "-latomic"]
1483}
1484
1485# Return 1 if an ASCII locale is supported on this host, 0 otherwise.
1486
1487proc check_ascii_locale_available { } {
1488    return 1
1489}
1490
1491# Return true if named sections are supported on this target.
1492
1493proc check_named_sections_available { } {
1494    return [check_no_compiler_messages named_sections assembly {
1495	int __attribute__ ((section("whatever"))) foo;
1496    }]
1497}
1498
1499# Return true if the "naked" function attribute is supported on this target.
1500
1501proc check_effective_target_naked_functions { } {
1502    return [check_no_compiler_messages naked_functions assembly {
1503	void f() __attribute__((naked));
1504    }]
1505}
1506
1507# Return 1 if the target supports Fortran real kinds larger than real(8),
1508# 0 otherwise.
1509#
1510# When the target name changes, replace the cached result.
1511
1512proc check_effective_target_fortran_large_real { } {
1513    return [check_no_compiler_messages fortran_large_real executable {
1514	! Fortran
1515	integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1)
1516	real(kind=k) :: x
1517	x = cos (x)
1518	end
1519    }]
1520}
1521
1522# Return 1 if the target supports Fortran real kind real(16),
1523# 0 otherwise. Contrary to check_effective_target_fortran_large_real
1524# this checks for Real(16) only; the other returned real(10) if
1525# both real(10) and real(16) are available.
1526#
1527# When the target name changes, replace the cached result.
1528
1529proc check_effective_target_fortran_real_16 { } {
1530    return [check_no_compiler_messages fortran_real_16 executable {
1531	! Fortran
1532	real(kind=16) :: x
1533	x = cos (x)
1534	end
1535    }]
1536}
1537
1538# Return 1 if the target supports Fortran real kind 10,
1539# 0 otherwise. Contrary to check_effective_target_fortran_large_real
1540# this checks for real(10) only.
1541#
1542# When the target name changes, replace the cached result.
1543
1544proc check_effective_target_fortran_real_10 { } {
1545    return [check_no_compiler_messages fortran_real_10 executable {
1546	! Fortran
1547	real(kind=10) :: x
1548	x = cos (x)
1549	end
1550    }]
1551}
1552
1553# Return 1 if the target supports Fortran's IEEE modules,
1554# 0 otherwise.
1555#
1556# When the target name changes, replace the cached result.
1557
1558proc check_effective_target_fortran_ieee { flags } {
1559    return [check_no_compiler_messages fortran_ieee executable {
1560	! Fortran
1561	use, intrinsic :: ieee_features
1562	end
1563    } $flags ]
1564}
1565
1566
1567# Return 1 if the target supports SQRT for the largest floating-point
1568# type. (Some targets lack the libm support for this FP type.)
1569# On most targets, this check effectively checks either whether sqrtl is
1570# available or on __float128 systems whether libquadmath is installed,
1571# which provides sqrtq.
1572#
1573# When the target name changes, replace the cached result.
1574
1575proc check_effective_target_fortran_largest_fp_has_sqrt { } {
1576    return [check_no_compiler_messages fortran_largest_fp_has_sqrt executable {
1577	! Fortran
1578        use iso_fortran_env, only: real_kinds
1579        integer,parameter:: maxFP = real_kinds(ubound(real_kinds,dim=1))
1580	real(kind=maxFP), volatile :: x
1581        x = 2.0_maxFP
1582	x = sqrt (x)
1583	end
1584    }]
1585}
1586
1587
1588# Return 1 if the target supports Fortran integer kinds larger than
1589# integer(8), 0 otherwise.
1590#
1591# When the target name changes, replace the cached result.
1592
1593proc check_effective_target_fortran_large_int { } {
1594    return [check_no_compiler_messages fortran_large_int executable {
1595	! Fortran
1596	integer,parameter :: k = selected_int_kind (range (0_8) + 1)
1597	integer(kind=k) :: i
1598	end
1599    }]
1600}
1601
1602# Return 1 if the target supports Fortran integer(16), 0 otherwise.
1603#
1604# When the target name changes, replace the cached result.
1605
1606proc check_effective_target_fortran_integer_16 { } {
1607    return [check_no_compiler_messages fortran_integer_16 executable {
1608        ! Fortran
1609        integer(16) :: i
1610        end
1611    }]
1612}
1613
1614# Return 1 if we can statically link libgfortran, 0 otherwise.
1615#
1616# When the target name changes, replace the cached result.
1617
1618proc check_effective_target_static_libgfortran { } {
1619    return [check_no_compiler_messages static_libgfortran executable {
1620	! Fortran
1621	print *, 'test'
1622	end
1623    } "-static"]
1624}
1625
1626# Return 1 if we can use the -rdynamic option, 0 otherwise.
1627
1628proc check_effective_target_rdynamic { } {
1629  return [check_no_compiler_messages rdynamic executable {
1630     int main() { return 0; }
1631  } "-rdynamic"]
1632}
1633
1634proc check_linker_plugin_available { } {
1635  return [check_no_compiler_messages_nocache linker_plugin executable {
1636     int main() { return 0; }
1637  } "-flto -fuse-linker-plugin"]
1638}
1639
1640# Return 1 if the target OS supports running SSE executables, 0
1641# otherwise.  Cache the result.
1642
1643proc check_sse_os_support_available { } {
1644    return [check_cached_effective_target sse_os_support_available {
1645	# If this is not the right target then we can skip the test.
1646	if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1647	    expr 0
1648	} else {
1649	    expr 1
1650	}
1651    }]
1652}
1653
1654# Return 1 if the target OS supports running AVX executables, 0
1655# otherwise.  Cache the result.
1656
1657proc check_avx_os_support_available { } {
1658    return [check_cached_effective_target avx_os_support_available {
1659	# If this is not the right target then we can skip the test.
1660	if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1661	    expr 0
1662	} else {
1663	    # Check that OS has AVX and SSE saving enabled.
1664	    check_runtime_nocache avx_os_support_available {
1665		int main ()
1666		{
1667		  unsigned int eax, edx;
1668
1669		  asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
1670		  return (eax & 0x06) != 0x06;
1671		}
1672	    } ""
1673	}
1674    }]
1675}
1676
1677# Return 1 if the target OS supports running AVX executables, 0
1678# otherwise.  Cache the result.
1679
1680proc check_avx512_os_support_available { } {
1681    return [check_cached_effective_target avx512_os_support_available {
1682	# If this is not the right target then we can skip the test.
1683	if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1684	    expr 0
1685	} else {
1686	    # Check that OS has AVX512, AVX and SSE saving enabled.
1687	    check_runtime_nocache avx512_os_support_available {
1688		int main ()
1689		{
1690		  unsigned int eax, edx;
1691
1692		  asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
1693		  return (eax & 0xe6) != 0xe6;
1694		}
1695	    } ""
1696	}
1697    }]
1698}
1699
1700# Return 1 if the target supports executing SSE instructions, 0
1701# otherwise.  Cache the result.
1702
1703proc check_sse_hw_available { } {
1704    return [check_cached_effective_target sse_hw_available {
1705	# If this is not the right target then we can skip the test.
1706	if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1707	    expr 0
1708	} else {
1709	    check_runtime_nocache sse_hw_available {
1710		#include "cpuid.h"
1711		int main ()
1712		{
1713		  unsigned int eax, ebx, ecx, edx;
1714		  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1715		    return 1;
1716
1717		  return !(edx & bit_SSE);
1718		}
1719	    } ""
1720	}
1721    }]
1722}
1723
1724# Return 1 if the target supports executing SSE2 instructions, 0
1725# otherwise.  Cache the result.
1726
1727proc check_sse2_hw_available { } {
1728    return [check_cached_effective_target sse2_hw_available {
1729	# If this is not the right target then we can skip the test.
1730	if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1731	    expr 0
1732	} else {
1733	    check_runtime_nocache sse2_hw_available {
1734		#include "cpuid.h"
1735		int main ()
1736		{
1737		  unsigned int eax, ebx, ecx, edx;
1738		  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1739		    return 1;
1740
1741		  return !(edx & bit_SSE2);
1742		}
1743	    } ""
1744	}
1745    }]
1746}
1747
1748# Return 1 if the target supports executing SSE4 instructions, 0
1749# otherwise.  Cache the result.
1750
1751proc check_sse4_hw_available { } {
1752    return [check_cached_effective_target sse4_hw_available {
1753	# If this is not the right target then we can skip the test.
1754	if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1755	    expr 0
1756	} else {
1757	    check_runtime_nocache sse4_hw_available {
1758		#include "cpuid.h"
1759		int main ()
1760		{
1761		  unsigned int eax, ebx, ecx, edx;
1762		  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1763		    return 1;
1764
1765		  return !(ecx & bit_SSE4_2);
1766		}
1767	    } ""
1768	}
1769    }]
1770}
1771
1772# Return 1 if the target supports executing AVX instructions, 0
1773# otherwise.  Cache the result.
1774
1775proc check_avx_hw_available { } {
1776    return [check_cached_effective_target avx_hw_available {
1777	# If this is not the right target then we can skip the test.
1778	if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1779	    expr 0
1780	} else {
1781	    check_runtime_nocache avx_hw_available {
1782		#include "cpuid.h"
1783		int main ()
1784		{
1785		  unsigned int eax, ebx, ecx, edx;
1786		  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1787		    return 1;
1788
1789		  return ((ecx & (bit_AVX | bit_OSXSAVE))
1790			  != (bit_AVX | bit_OSXSAVE));
1791		}
1792	    } ""
1793	}
1794    }]
1795}
1796
1797# Return 1 if the target supports executing AVX2 instructions, 0
1798# otherwise.  Cache the result.
1799
1800proc check_avx2_hw_available { } {
1801    return [check_cached_effective_target avx2_hw_available {
1802	# If this is not the right target then we can skip the test.
1803	if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1804	    expr 0
1805	} else {
1806	    check_runtime_nocache avx2_hw_available {
1807		#include <stddef.h>
1808		#include "cpuid.h"
1809		int main ()
1810		{
1811		  unsigned int eax, ebx, ecx, edx;
1812
1813		  if (__get_cpuid_max (0, NULL) < 7)
1814		    return 1;
1815
1816		  __cpuid (1, eax, ebx, ecx, edx);
1817
1818		  if (!(ecx & bit_OSXSAVE))
1819		    return 1;
1820
1821		  __cpuid_count (7, 0, eax, ebx, ecx, edx);
1822
1823		  return !(ebx & bit_AVX2);
1824		}
1825	    } ""
1826	}
1827    }]
1828}
1829
1830# Return 1 if the target supports executing AVX512 foundation instructions, 0
1831# otherwise.  Cache the result.
1832
1833proc check_avx512f_hw_available { } {
1834    return [check_cached_effective_target avx512f_hw_available {
1835	# If this is not the right target then we can skip the test.
1836	if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1837	    expr 0
1838	} else {
1839	    check_runtime_nocache avx512f_hw_available {
1840		#include <stddef.h>
1841		#include "cpuid.h"
1842		int main ()
1843		{
1844		  unsigned int eax, ebx, ecx, edx;
1845
1846		  if (__get_cpuid_max (0, NULL) < 7)
1847		    return 1;
1848
1849		  __cpuid (1, eax, ebx, ecx, edx);
1850
1851		  if (!(ecx & bit_OSXSAVE))
1852		    return 1;
1853
1854		  __cpuid_count (7, 0, eax, ebx, ecx, edx);
1855
1856		  return !(ebx & bit_AVX512F);
1857		}
1858	    } ""
1859	}
1860    }]
1861}
1862
1863# Return 1 if the target supports running SSE executables, 0 otherwise.
1864
1865proc check_effective_target_sse_runtime { } {
1866    if { [check_effective_target_sse]
1867	 && [check_sse_hw_available]
1868	 && [check_sse_os_support_available] } {
1869	return 1
1870    }
1871    return 0
1872}
1873
1874# Return 1 if the target supports running SSE2 executables, 0 otherwise.
1875
1876proc check_effective_target_sse2_runtime { } {
1877    if { [check_effective_target_sse2]
1878	 && [check_sse2_hw_available]
1879	 && [check_sse_os_support_available] } {
1880	return 1
1881    }
1882    return 0
1883}
1884
1885# Return 1 if the target supports running SSE4 executables, 0 otherwise.
1886
1887proc check_effective_target_sse4_runtime { } {
1888    if { [check_effective_target_sse4]
1889	 && [check_sse4_hw_available]
1890	 && [check_sse_os_support_available] } {
1891	return 1
1892    }
1893    return 0
1894}
1895
1896# Return 1 if the target supports running AVX executables, 0 otherwise.
1897
1898proc check_effective_target_avx_runtime { } {
1899    if { [check_effective_target_avx]
1900	 && [check_avx_hw_available]
1901	 && [check_avx_os_support_available] } {
1902	return 1
1903    }
1904    return 0
1905}
1906
1907# Return 1 if the target supports running AVX2 executables, 0 otherwise.
1908
1909proc check_effective_target_avx2_runtime { } {
1910    if { [check_effective_target_avx2]
1911	 && [check_avx2_hw_available]
1912	 && [check_avx_os_support_available] } {
1913	return 1
1914    }
1915    return 0
1916}
1917
1918# Return 1 if the target supports running AVX512f executables, 0 otherwise.
1919
1920proc check_effective_target_avx512f_runtime { } {
1921    if { [check_effective_target_avx512f]
1922	 && [check_avx512f_hw_available]
1923	 && [check_avx512_os_support_available] } {
1924	return 1
1925    }
1926    return 0
1927}
1928
1929# Return 1 if bmi2 instructions can be compiled.
1930proc check_effective_target_bmi2 { } {
1931    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1932        return 0
1933    }
1934    return [check_no_compiler_messages bmi2 object {
1935	unsigned int
1936	_bzhi_u32 (unsigned int __X, unsigned int __Y)
1937	{
1938	    return __builtin_ia32_bzhi_si (__X, __Y);
1939	}
1940    } "-mbmi2" ]
1941}
1942
1943# Return 1 if the target supports executing MIPS Paired-Single instructions,
1944# 0 otherwise.  Cache the result.
1945
1946proc check_mpaired_single_hw_available { } {
1947    return [check_cached_effective_target mpaired_single_hw_available {
1948	# If this is not the right target then we can skip the test.
1949	if { !([istarget mips*-*-*]) } {
1950	    expr 0
1951	} else {
1952	    check_runtime_nocache mpaired_single_hw_available {
1953	      int main()
1954	      {
1955		asm volatile ("pll.ps $f2,$f4,$f6");
1956		return 0;
1957	      }
1958	    } ""
1959	}
1960    }]
1961}
1962
1963# Return 1 if the target supports executing Loongson vector instructions,
1964# 0 otherwise.  Cache the result.
1965
1966proc check_mips_loongson_mmi_hw_available { } {
1967    return [check_cached_effective_target mips_loongson_mmi_hw_available {
1968	# If this is not the right target then we can skip the test.
1969	if { !([istarget mips*-*-*]) } {
1970	    expr 0
1971	} else {
1972	    check_runtime_nocache mips_loongson_mmi_hw_available {
1973	      #include <loongson-mmiintrin.h>
1974	      int main()
1975	      {
1976		asm volatile ("paddw $f2,$f4,$f6");
1977		return 0;
1978	      }
1979	    } "-mloongson-mmi"
1980	}
1981    }]
1982}
1983
1984# Return 1 if the target supports executing MIPS MSA instructions, 0
1985# otherwise.  Cache the result.
1986
1987proc check_mips_msa_hw_available { } {
1988  return [check_cached_effective_target mips_msa_hw_available {
1989    # If this is not the right target then we can skip the test.
1990    if { !([istarget mips*-*-*]) } {
1991      expr 0
1992    } else {
1993      check_runtime_nocache mips_msa_hw_available {
1994	#if !defined(__mips_msa)
1995	#error "MSA NOT AVAIL"
1996	#else
1997	#if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2))
1998	#error "MSA NOT AVAIL FOR ISA REV < 2"
1999	#endif
2000	#if !defined(__mips_hard_float)
2001	#error "MSA HARD_FLOAT REQUIRED"
2002	#endif
2003	#if __mips_fpr != 64
2004	#error "MSA 64-bit FPR REQUIRED"
2005	#endif
2006	#include <msa.h>
2007
2008	int main()
2009	{
2010	  v8i16 v = __builtin_msa_ldi_h (0);
2011	  v[0] = 0;
2012	  return v[0];
2013	}
2014	#endif
2015      } "-mmsa"
2016    }
2017  }]
2018}
2019
2020# Return 1 if the target supports running MIPS Paired-Single
2021# executables, 0 otherwise.
2022
2023proc check_effective_target_mpaired_single_runtime { } {
2024    if { [check_effective_target_mpaired_single]
2025	 && [check_mpaired_single_hw_available] } {
2026	return 1
2027    }
2028    return 0
2029}
2030
2031# Return 1 if the target supports running Loongson executables, 0 otherwise.
2032
2033proc check_effective_target_mips_loongson_mmi_runtime { } {
2034    if { [check_effective_target_mips_loongson_mmi]
2035	 && [check_mips_loongson_mmi_hw_available] } {
2036	return 1
2037    }
2038    return 0
2039}
2040
2041# Return 1 if the target supports running MIPS MSA executables, 0 otherwise.
2042
2043proc check_effective_target_mips_msa_runtime { } {
2044  if { [check_effective_target_mips_msa]
2045       && [check_mips_msa_hw_available] } {
2046    return 1
2047  }
2048  return 0
2049}
2050
2051# Return 1 if we are compiling for 64-bit PowerPC but we do not use direct
2052# move instructions for moves from GPR to FPR.
2053
2054proc check_effective_target_powerpc64_no_dm { } {
2055    # The "mulld" checks if we are generating PowerPC64 code.  The "lfd"
2056    # checks if we do not use direct moves, but use the old-fashioned
2057    # slower move-via-the-stack.
2058    return [check_no_messages_and_pattern powerpc64_no_dm \
2059	{\mmulld\M.*\mlfd} assembly {
2060	    double f(long long x) { return x*x; }
2061	} {-O2}]
2062}
2063
2064# Return 1 if the target supports the __builtin_cpu_supports built-in,
2065# including having a new enough library to support the test.  Cache the result.
2066# Require at least a power7 to run on.
2067
2068proc check_ppc_cpu_supports_hw_available { } {
2069    return [check_cached_effective_target ppc_cpu_supports_hw_available {
2070	# Some simulators are known to not support VSX/power8 instructions.
2071	# For now, disable on Darwin
2072	if { [istarget powerpc-*-eabi]
2073	     || [istarget powerpc*-*-eabispe]
2074	     || [istarget *-*-darwin*]} {
2075	    expr 0
2076	} else {
2077	    set options "-mvsx"
2078	    check_runtime_nocache ppc_cpu_supports_hw_available {
2079		int main()
2080		{
2081		#ifdef __MACH__
2082		  asm volatile ("xxlor vs0,vs0,vs0");
2083		#else
2084		  asm volatile ("xxlor 0,0,0");
2085	        #endif
2086		  if (!__builtin_cpu_supports ("vsx"))
2087		    return 1;
2088		  return 0;
2089		}
2090	    } $options
2091	}
2092    }]
2093}
2094
2095# Return 1 if the target supports executing 750CL paired-single instructions, 0
2096# otherwise.  Cache the result.
2097
2098proc check_750cl_hw_available { } {
2099    return [check_cached_effective_target 750cl_hw_available {
2100	# If this is not the right target then we can skip the test.
2101	if { ![istarget powerpc-*paired*] } {
2102	    expr 0
2103	} else {
2104	    check_runtime_nocache 750cl_hw_available {
2105		 int main()
2106		 {
2107		 #ifdef __MACH__
2108		   asm volatile ("ps_mul v0,v0,v0");
2109		 #else
2110		   asm volatile ("ps_mul 0,0,0");
2111		 #endif
2112		   return 0;
2113		 }
2114	    } "-mpaired"
2115	}
2116    }]
2117}
2118
2119# Return 1 if the target supports executing power8 vector instructions, 0
2120# otherwise.  Cache the result.
2121
2122proc check_p8vector_hw_available { } {
2123    return [check_cached_effective_target p8vector_hw_available {
2124	# Some simulators are known to not support VSX/power8 instructions.
2125	# For now, disable on Darwin
2126	if { [istarget powerpc-*-eabi]
2127	     || [istarget powerpc*-*-eabispe]
2128	     || [istarget *-*-darwin*]} {
2129	    expr 0
2130	} else {
2131	    set options "-mpower8-vector"
2132	    check_runtime_nocache p8vector_hw_available {
2133		int main()
2134		{
2135		#ifdef __MACH__
2136		  asm volatile ("xxlorc vs0,vs0,vs0");
2137		#else
2138		  asm volatile ("xxlorc 0,0,0");
2139	        #endif
2140		  return 0;
2141		}
2142	    } $options
2143	}
2144    }]
2145}
2146
2147# Return 1 if the target supports executing power9 vector instructions, 0
2148# otherwise.  Cache the result.
2149
2150proc check_p9vector_hw_available { } {
2151    return [check_cached_effective_target p9vector_hw_available {
2152	# Some simulators are known to not support VSX/power8/power9
2153	# instructions.	For now, disable on Darwin.
2154	if { [istarget powerpc-*-eabi]
2155	     || [istarget powerpc*-*-eabispe]
2156	     || [istarget *-*-darwin*]} {
2157	    expr 0
2158	} else {
2159	    set options "-mpower9-vector"
2160	    check_runtime_nocache p9vector_hw_available {
2161		int main()
2162		{
2163		    long e = -1;
2164		    vector double v = (vector double) { 0.0, 0.0 };
2165		    asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v));
2166		    return e;
2167		}
2168	    } $options
2169	}
2170    }]
2171}
2172
2173# Return 1 if the PowerPC target generates PC-relative instructions
2174# automatically for targets that support PC-relative instructions.
2175proc check_effective_target_powerpc_pcrel { } {
2176    return [check_no_messages_and_pattern powerpc_pcrel \
2177	{\mpla\M} assembly {
2178	    static unsigned short s;
2179	    unsigned short *p_foo (void) { return &s; }
2180	} {-O2 -mcpu=power10}]
2181}
2182
2183# Return 1 if the PowerPC target generates prefixed instructions automatically
2184# for targets that support prefixed instructions.
2185proc check_effective_target_powerpc_prefixed_addr { } {
2186    return [check_no_messages_and_pattern powerpc_prefixed_addr \
2187	{\mplwz\M} assembly {
2188	    unsigned int foo (unsigned int *p) { return p[0x12345]; }
2189	} {-O2 -mcpu=power10}]
2190}
2191
2192# Return 1 if the target supports executing power9 modulo instructions, 0
2193# otherwise.  Cache the result.
2194
2195proc check_p9modulo_hw_available { } {
2196    return [check_cached_effective_target p9modulo_hw_available {
2197	# Some simulators are known to not support VSX/power8/power9
2198	# instructions.	For now, disable on Darwin.
2199	if { [istarget powerpc-*-eabi]
2200	     || [istarget powerpc*-*-eabispe]
2201	     || [istarget *-*-darwin*]} {
2202	    expr 0
2203	} else {
2204	    set options "-mmodulo"
2205	    check_runtime_nocache p9modulo_hw_available {
2206		int main()
2207		{
2208		    int i = 5, j = 3, r = -1;
2209		    asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j));
2210		    return (r == 2);
2211		}
2212	    } $options
2213	}
2214    }]
2215}
2216
2217
2218# Return 1 if the target supports executing power10 instructions, 0 otherwise.
2219# Cache the result.  It is assumed that if a simulator does not support the
2220# power10 instructions, that it will generate an error and this test will fail.
2221
2222proc check_power10_hw_available { } {
2223    return [check_cached_effective_target power10_hw_available {
2224	check_runtime_nocache power10_hw_available {
2225	    int main()
2226	    {
2227		/* Set e first and use +r to check if pli actually works.  */
2228		long e = -1;
2229		asm ("pli %0,%1" : "+r" (e) : "n" (0x12345));
2230		if (e == 0x12345)
2231		  return 0;
2232		return 1;
2233	    }
2234	} "-mcpu=power10"
2235    }]
2236}
2237
2238# Return 1 if the target supports executing MMA instructions, 0 otherwise.
2239# Cache the result.  It is assumed that if a simulator does not support the
2240# MMA instructions, that it will generate an error and this test will fail.
2241
2242proc check_ppc_mma_hw_available { } {
2243    return [check_cached_effective_target ppc_mma_hw_available {
2244	check_runtime_nocache ppc_mma_hw_available {
2245	    #include <altivec.h>
2246	    typedef double v4sf_t __attribute__ ((vector_size (16)));
2247
2248	    int main()
2249	    {
2250		__vector_quad acc0;
2251		v4sf_t result[4];
2252		result[0][0] = 1.0;
2253		__builtin_mma_xxsetaccz (&acc0);
2254		__builtin_mma_disassemble_acc (result, &acc0);
2255		if (result[0][0] != 0.0)
2256		   return 1;
2257		return 0;
2258	    }
2259	} "-mcpu=power10"
2260    }]
2261}
2262
2263# Return 1 if the target supports executing __float128 on PowerPC via software
2264# emulation, 0 otherwise.  Cache the result.
2265
2266proc check_ppc_float128_sw_available { } {
2267    return [check_cached_effective_target ppc_float128_sw_available {
2268	# Some simulators are known to not support VSX/power8/power9
2269	# instructions.	For now, disable on Darwin.
2270	if { [istarget powerpc-*-eabi]
2271	     || [istarget powerpc*-*-eabispe]
2272	     || [istarget *-*-darwin*]} {
2273	    expr 0
2274	} else {
2275	    set options "-mfloat128 -mvsx"
2276	    check_runtime_nocache ppc_float128_sw_available {
2277		volatile __float128 x = 1.0q;
2278		volatile __float128 y = 2.0q;
2279		int main()
2280		{
2281		    __float128 z = x + y;
2282		    return (z != 3.0q);
2283		}
2284	    } $options
2285	}
2286    }]
2287}
2288
2289# Return 1 if the target supports executing __float128 on PowerPC via power9
2290# hardware instructions, 0 otherwise.  Cache the result.
2291
2292proc check_ppc_float128_hw_available { } {
2293    return [check_cached_effective_target ppc_float128_hw_available {
2294	# Some simulators are known to not support VSX/power8/power9
2295	# instructions.	For now, disable on Darwin.
2296	if { [istarget powerpc-*-eabi]
2297	     || [istarget powerpc*-*-eabispe]
2298	     || [istarget *-*-darwin*]} {
2299	    expr 0
2300	} else {
2301	    set options "-mfloat128 -mvsx -mfloat128-hardware -mpower9-vector"
2302	    check_runtime_nocache ppc_float128_hw_available {
2303		volatile __float128 x = 1.0q;
2304		volatile __float128 y = 2.0q;
2305		int main()
2306		{
2307		    __float128 z = x + y;
2308		    __float128 w = -1.0q;
2309
2310		    __asm__ ("xsaddqp %0,%1,%2" : "+v" (w) : "v" (x), "v" (y));
2311		    return ((z != 3.0q) || (z != w));
2312		}
2313	    } $options
2314	}
2315    }]
2316}
2317
2318# See if the __ieee128 keyword is understood.
2319proc check_effective_target_ppc_ieee128_ok { } {
2320    return [check_cached_effective_target ppc_ieee128_ok {
2321	# disable on AIX.
2322	if { [istarget *-*-aix*] } {
2323	    expr 0
2324	} else {
2325	    set options "-mfloat128"
2326	    check_runtime_nocache ppc_ieee128_ok {
2327		int main()
2328		{
2329		  __ieee128 a;
2330		  return 0;
2331		}
2332	    } $options
2333	}
2334    }]
2335}
2336
2337# Return 1 if the target supports executing VSX instructions, 0
2338# otherwise.  Cache the result.
2339
2340proc check_vsx_hw_available { } {
2341    return [check_cached_effective_target vsx_hw_available {
2342	# Some simulators are known to not support VSX instructions.
2343	# For now, disable on Darwin
2344	if { [istarget powerpc-*-eabi]
2345	     || [istarget powerpc*-*-eabispe]
2346	     || [istarget *-*-darwin*]} {
2347	    expr 0
2348	} else {
2349	    set options "-mvsx"
2350	    check_runtime_nocache vsx_hw_available {
2351		int main()
2352		{
2353		#ifdef __MACH__
2354		  asm volatile ("xxlor vs0,vs0,vs0");
2355		#else
2356		  asm volatile ("xxlor 0,0,0");
2357	        #endif
2358		  return 0;
2359		}
2360	    } $options
2361	}
2362    }]
2363}
2364
2365# Return 1 if the target supports executing AltiVec instructions, 0
2366# otherwise.  Cache the result.
2367
2368proc check_vmx_hw_available { } {
2369    return [check_cached_effective_target vmx_hw_available {
2370	# Some simulators are known to not support VMX instructions.
2371	if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } {
2372	    expr 0
2373	} else {
2374	    # Most targets don't require special flags for this test case, but
2375	    # Darwin does.  Just to be sure, make sure VSX is not enabled for
2376	    # the altivec tests.
2377	    if { [istarget *-*-darwin*]
2378		 || [istarget *-*-aix*] } {
2379		set options "-maltivec -mno-vsx"
2380	    } else {
2381		set options "-mno-vsx"
2382	    }
2383	    check_runtime_nocache vmx_hw_available {
2384		int main()
2385		{
2386		#ifdef __MACH__
2387		  asm volatile ("vor v0,v0,v0");
2388		#else
2389		  asm volatile ("vor 0,0,0");
2390	        #endif
2391		  return 0;
2392		}
2393	    } $options
2394	}
2395    }]
2396}
2397
2398proc check_ppc_recip_hw_available { } {
2399    return [check_cached_effective_target ppc_recip_hw_available {
2400	# Some simulators may not support FRE/FRES/FRSQRTE/FRSQRTES
2401	# For now, disable on Darwin
2402	if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
2403	    expr 0
2404	} else {
2405	    set options "-mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb"
2406	    check_runtime_nocache ppc_recip_hw_available {
2407		volatile double d_recip, d_rsqrt, d_four = 4.0;
2408		volatile float f_recip, f_rsqrt, f_four = 4.0f;
2409		int main()
2410		{
2411		  asm volatile ("fres %0,%1" : "=f" (f_recip) : "f" (f_four));
2412		  asm volatile ("fre %0,%1" : "=d" (d_recip) : "d" (d_four));
2413		  asm volatile ("frsqrtes %0,%1" : "=f" (f_rsqrt) : "f" (f_four));
2414		  asm volatile ("frsqrte %0,%1" : "=f" (d_rsqrt) : "d" (d_four));
2415		  return 0;
2416		}
2417	    } $options
2418	}
2419    }]
2420}
2421
2422# Return 1 if the target supports executing AltiVec and Cell PPU
2423# instructions, 0 otherwise.  Cache the result.
2424
2425proc check_effective_target_cell_hw { } {
2426    return [check_cached_effective_target cell_hw_available {
2427	# Some simulators are known to not support VMX and PPU instructions.
2428	if { [istarget powerpc-*-eabi*] } {
2429	    expr 0
2430	} else {
2431	    # Most targets don't require special flags for this test
2432	    # case, but Darwin and AIX do.
2433	    if { [istarget *-*-darwin*]
2434		 || [istarget *-*-aix*] } {
2435		set options "-maltivec -mcpu=cell"
2436	    } else {
2437		set options "-mcpu=cell"
2438	    }
2439	    check_runtime_nocache cell_hw_available {
2440		int main()
2441		{
2442		#ifdef __MACH__
2443		  asm volatile ("vor v0,v0,v0");
2444                  asm volatile ("lvlx v0,r0,r0");
2445		#else
2446		  asm volatile ("vor 0,0,0");
2447                  asm volatile ("lvlx 0,0,0");
2448	        #endif
2449		  return 0;
2450		}
2451	    } $options
2452	}
2453    }]
2454}
2455
2456# Return 1 if the target supports executing 64-bit instructions, 0
2457# otherwise.  Cache the result.
2458
2459proc check_effective_target_powerpc64 { } {
2460    global powerpc64_available_saved
2461    global tool
2462
2463    if [info exists powerpc64_available_saved] {
2464	verbose "check_effective_target_powerpc64 returning saved $powerpc64_available_saved" 2
2465    } else {
2466	set powerpc64_available_saved 0
2467
2468	# Some simulators are known to not support powerpc64 instructions.
2469	if { [istarget powerpc-*-eabi*] || [istarget powerpc-ibm-aix*] } {
2470	    verbose "check_effective_target_powerpc64 returning 0" 2
2471	    return $powerpc64_available_saved
2472	}
2473
2474	# Set up, compile, and execute a test program containing a 64-bit
2475	# instruction.  Include the current process ID in the file
2476	# names to prevent conflicts with invocations for multiple
2477	# testsuites.
2478	set src ppc[pid].c
2479	set exe ppc[pid].x
2480
2481	set f [open $src "w"]
2482	puts $f "int main() {"
2483	puts $f "#ifdef __MACH__"
2484	puts $f "  asm volatile (\"extsw r0,r0\");"
2485	puts $f "#else"
2486	puts $f "  asm volatile (\"extsw 0,0\");"
2487	puts $f "#endif"
2488	puts $f "  return 0; }"
2489	close $f
2490
2491	set opts "additional_flags=-mcpu=G5"
2492
2493	verbose "check_effective_target_powerpc64 compiling testfile $src" 2
2494	set lines [${tool}_target_compile $src $exe executable "$opts"]
2495	file delete $src
2496
2497	if [string match "" $lines] then {
2498	    # No error message, compilation succeeded.
2499	    set result [${tool}_load "./$exe" "" ""]
2500	    set status [lindex $result 0]
2501	    remote_file build delete $exe
2502	    verbose "check_effective_target_powerpc64 testfile status is <$status>" 2
2503
2504	    if { $status == "pass" } then {
2505		set powerpc64_available_saved 1
2506	    }
2507	} else {
2508	    verbose "check_effective_target_powerpc64 testfile compilation failed" 2
2509	}
2510    }
2511
2512    return $powerpc64_available_saved
2513}
2514
2515# GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing
2516# complex float arguments.  This affects gfortran tests that call cabsf
2517# in libm built by an earlier compiler.  Return 0 if libm uses the same
2518# argument passing as the compiler under test, 1 otherwise.
2519
2520proc check_effective_target_broken_cplxf_arg { } {
2521    # Skip the work for targets known not to be affected.
2522    if { ![istarget powerpc*-*-linux*] || ![is-effective-target lp64] } {
2523	return 0
2524    }
2525
2526    return [check_cached_effective_target broken_cplxf_arg {
2527	check_runtime_nocache broken_cplxf_arg {
2528	    #include <complex.h>
2529	    extern void abort (void);
2530	    float fabsf (float);
2531	    float cabsf (_Complex float);
2532	    int main ()
2533	    {
2534	      _Complex float cf;
2535	      float f;
2536	      cf = 3 + 4.0fi;
2537	      f = cabsf (cf);
2538	      if (fabsf (f - 5.0) > 0.0001)
2539		/* Yes, it's broken.  */
2540		return 0;
2541	      /* All fine, not broken.  */
2542	      return 1;
2543	    }
2544	} "-lm"
2545    }]
2546}
2547
2548# Return 1 is this is a TI C6X target supporting C67X instructions
2549proc check_effective_target_ti_c67x { } {
2550    return [check_no_compiler_messages ti_c67x assembly {
2551	#if !defined(_TMS320C6700)
2552	#error !_TMS320C6700
2553	#endif
2554    }]
2555}
2556
2557# Return 1 is this is a TI C6X target supporting C64X+ instructions
2558proc check_effective_target_ti_c64xp { } {
2559    return [check_no_compiler_messages ti_c64xp assembly {
2560	#if !defined(_TMS320C6400_PLUS)
2561	#error !_TMS320C6400_PLUS
2562	#endif
2563    }]
2564}
2565
2566# Check if a -march=... option is given, as part of (earlier) options.
2567proc check_effective_target_march_option { } {
2568    return [check-flags [list "" { *-*-* } { "-march=*" } { "" } ]]
2569}
2570
2571proc check_alpha_max_hw_available { } {
2572    return [check_runtime alpha_max_hw_available {
2573	int main() { return __builtin_alpha_amask(1<<8) != 0; }
2574    }]
2575}
2576
2577# Returns true iff the FUNCTION is available on the target system.
2578# (This is essentially a Tcl implementation of Autoconf's
2579# AC_CHECK_FUNC.)
2580
2581proc check_function_available { function } {
2582    return [check_no_compiler_messages ${function}_available \
2583		executable [subst {
2584	#ifdef __cplusplus
2585	extern "C"
2586	#endif
2587	char $function ();
2588	int main () { $function (); }
2589    }] "-fno-builtin" ]
2590}
2591
2592# Returns true iff "fork" is available on the target system.
2593
2594proc check_fork_available {} {
2595    return [check_function_available "fork"]
2596}
2597
2598# Returns true iff "mkfifo" is available on the target system.
2599
2600proc check_mkfifo_available {} {
2601    if { [istarget *-*-cygwin*] } {
2602       # Cygwin has mkfifo, but support is incomplete.
2603       return 0
2604     }
2605
2606    return [check_function_available "mkfifo"]
2607}
2608
2609# Returns true iff "__cxa_atexit" is used on the target system.
2610
2611proc check_cxa_atexit_available { } {
2612    return [check_cached_effective_target cxa_atexit_available {
2613	if { [istarget hppa*-*-hpux10*] } {
2614	    # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes.
2615	    expr 0
2616	} elseif { [istarget *-*-vxworks] } {
2617	    # vxworks doesn't have __cxa_atexit but subsequent test passes.
2618	    expr 0
2619	} else {
2620	    check_runtime_nocache cxa_atexit_available {
2621		// C++
2622		#include <stdlib.h>
2623		static unsigned int count;
2624		struct X
2625		{
2626		  X() { count = 1; }
2627		  ~X()
2628		  {
2629		    if (count != 3)
2630		      exit(1);
2631		    count = 4;
2632		  }
2633		};
2634		void f()
2635		{
2636		  static X x;
2637		}
2638		struct Y
2639		{
2640		  Y() { f(); count = 2; }
2641		  ~Y()
2642		  {
2643		    if (count != 2)
2644		      exit(1);
2645		    count = 3;
2646		  }
2647		};
2648		Y y;
2649		int main() { return 0; }
2650	    }
2651	}
2652    }]
2653}
2654
2655proc check_effective_target_objc2 { } {
2656    return [check_no_compiler_messages objc2 object {
2657	#ifdef __OBJC2__
2658	int dummy[1];
2659	#else
2660	#error !__OBJC2__
2661	#endif
2662    }]
2663}
2664
2665proc check_effective_target_next_runtime { } {
2666    return [check_no_compiler_messages objc2 object {
2667	#ifdef __NEXT_RUNTIME__
2668	int dummy[1];
2669	#else
2670	#error !__NEXT_RUNTIME__
2671	#endif
2672    }]
2673}
2674
2675# Return 1 if we're generating code for big-endian memory order.
2676
2677proc check_effective_target_be { } {
2678    return [check_no_compiler_messages be object {
2679	int dummy[__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? 1 : -1];
2680    }]
2681}
2682
2683# Return 1 if we're generating code for little-endian memory order.
2684
2685proc check_effective_target_le { } {
2686    return [check_no_compiler_messages le object {
2687	int dummy[__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ? 1 : -1];
2688    }]
2689}
2690
2691# Return 1 if we're generating code for only power8 platforms.
2692
2693proc check_effective_target_p8 {  } {
2694  return [check_no_compiler_messages_nocache p8 assembly {
2695	#if !(!defined(_ARCH_PWR9) && defined(_ARCH_PWR8))
2696	#error NO
2697	#endif
2698  } ""]
2699}
2700
2701# Return 1 if we're generating code for power9 or later platforms.
2702
2703proc check_effective_target_p9+ {  } {
2704  return [check_no_compiler_messages_nocache p9+ assembly {
2705	#if !(defined(_ARCH_PWR9))
2706	#error NO
2707	#endif
2708  } ""]
2709}
2710
2711# Return 1 if we're generating 32-bit code using default options, 0
2712# otherwise.
2713
2714proc check_effective_target_ilp32 { } {
2715    return [check_no_compiler_messages ilp32 object {
2716	int dummy[sizeof (int) == 4
2717		  && sizeof (void *) == 4
2718		  && sizeof (long) == 4 ? 1 : -1];
2719    }]
2720}
2721
2722# Return 1 if we're generating ia32 code using default options, 0
2723# otherwise.
2724
2725proc check_effective_target_ia32 { } {
2726    return [check_no_compiler_messages ia32 object {
2727	int dummy[sizeof (int) == 4
2728		  && sizeof (void *) == 4
2729		  && sizeof (long) == 4 ? 1 : -1] = { __i386__ };
2730    }]
2731}
2732
2733# Return 1 if we're generating x32 code using default options, 0
2734# otherwise.
2735
2736proc check_effective_target_x32 { } {
2737    return [check_no_compiler_messages x32 object {
2738	int dummy[sizeof (int) == 4
2739		  && sizeof (void *) == 4
2740		  && sizeof (long) == 4 ? 1 : -1] = { __x86_64__ };
2741    }]
2742}
2743
2744# Return 1 if we're generating 32-bit integers using default
2745# options, 0 otherwise.
2746
2747proc check_effective_target_int32 { } {
2748    return [check_no_compiler_messages int32 object {
2749	int dummy[sizeof (int) == 4 ? 1 : -1];
2750    }]
2751}
2752
2753# Return 1 if we're generating 32-bit or larger integers using default
2754# options, 0 otherwise.
2755
2756proc check_effective_target_int32plus { } {
2757    return [check_no_compiler_messages int32plus object {
2758	int dummy[sizeof (int) >= 4 ? 1 : -1];
2759    }]
2760}
2761
2762# Return 1 if we're generating 64-bit long long using default options,
2763# 0 otherwise.
2764
2765proc check_effective_target_longlong64 { } {
2766    return [check_no_compiler_messages longlong64 object {
2767	int dummy[sizeof (long long) == 8 ? 1 : -1];
2768    }]
2769}
2770
2771# Return 1 if we're generating 32-bit or larger pointers using default
2772# options, 0 otherwise.
2773
2774proc check_effective_target_ptr32plus { } {
2775    # The msp430 has 16-bit or 20-bit pointers.  The 20-bit pointer is stored
2776    # in a 32-bit slot when in memory, so sizeof(void *) returns 4, but it
2777    # cannot really hold a 32-bit address, so we always return false here.
2778    if { [istarget msp430-*-*] } {
2779        return 0
2780    }
2781
2782    return [check_no_compiler_messages ptr32plus object {
2783	int dummy[sizeof (void *) >= 4 ? 1 : -1];
2784    }]
2785}
2786
2787# Return 1 if we support 16-bit or larger array and structure sizes
2788# using default options, 0 otherwise.
2789# This implies at least a 20-bit address space, as no targets have an address
2790# space between 16 and 20 bits.
2791
2792proc check_effective_target_size20plus { } {
2793    return [check_no_compiler_messages size20plus object {
2794	char dummy[65537L];
2795    }]
2796}
2797
2798# Return 1 if target supports function pointers, 0 otherwise.
2799
2800proc check_effective_target_function_pointers { } {
2801    if { [istarget pru-*-*] } {
2802	return [check_no_compiler_messages func_ptr_avail assembly {
2803	    #ifdef __PRU_EABI_GNU__
2804	    #error unsupported
2805	    #endif
2806	}]
2807    }
2808    return 1
2809}
2810
2811# Return 1 if target supports arbitrarily large return values, 0 otherwise.
2812
2813proc check_effective_target_large_return_values { } {
2814    if { [istarget pru-*-*] } {
2815	return [check_no_compiler_messages large_return_values assembly {
2816	    #ifdef __PRU_EABI_GNU__
2817	    #error unsupported
2818	    #endif
2819	}]
2820    }
2821    return 1
2822}
2823
2824# Return 1 if we support 24-bit or larger array and structure sizes
2825# using default options, 0 otherwise.
2826# This implies at least a 32-bit address space, as no targets have an address
2827# space between 24 and 32 bits.
2828
2829proc check_effective_target_size32plus { } {
2830    return [check_no_compiler_messages size32plus object {
2831	char dummy[16777217L];
2832    }]
2833}
2834
2835# Returns 1 if we're generating 16-bit or smaller integers with the
2836# default options, 0 otherwise.
2837
2838proc check_effective_target_int16 { } {
2839    return [check_no_compiler_messages int16 object {
2840	int dummy[sizeof (int) < 4 ? 1 : -1];
2841    }]
2842}
2843
2844# Return 1 if we're generating 64-bit code using default options, 0
2845# otherwise.
2846
2847proc check_effective_target_lp64 { } {
2848    return [check_no_compiler_messages lp64 object {
2849	int dummy[sizeof (int) == 4
2850		  && sizeof (void *) == 8
2851		  && sizeof (long) == 8 ? 1 : -1];
2852    }]
2853}
2854
2855# Return 1 if we're generating 64-bit code using default llp64 options,
2856# 0 otherwise.
2857
2858proc check_effective_target_llp64 { } {
2859    return [check_no_compiler_messages llp64 object {
2860	int dummy[sizeof (int) == 4
2861		  && sizeof (void *) == 8
2862		  && sizeof (long long) == 8
2863		  && sizeof (long) == 4 ? 1 : -1];
2864    }]
2865}
2866
2867# Return 1 if long and int have different sizes,
2868# 0 otherwise.
2869
2870proc check_effective_target_long_neq_int { } {
2871    return [check_no_compiler_messages long_ne_int object {
2872	int dummy[sizeof (int) != sizeof (long) ? 1 : -1];
2873    }]
2874}
2875
2876# Return 1 if int size is equal to float size,
2877# 0 otherwise.
2878
2879proc check_effective_target_int_eq_float { } {
2880    return [check_no_compiler_messages int_eq_float object {
2881	int dummy[sizeof (int) >= sizeof (float) ? 1 : -1];
2882    }]
2883}
2884
2885# Return 1 if pointer size is equal to long size,
2886# 0 otherwise.
2887
2888proc check_effective_target_ptr_eq_long { } {
2889    # sizeof (void *) == 4 for msp430-elf -mlarge which is equal to
2890    # sizeof (long). Avoid false positive.
2891    if { [istarget msp430-*-*] } {
2892	return 0
2893    }
2894    return [check_no_compiler_messages ptr_eq_long object {
2895	int dummy[sizeof (void *) == sizeof (long) ? 1 : -1];
2896    }]
2897}
2898
2899# Return 1 if the target supports long double larger than double,
2900# 0 otherwise.
2901
2902proc check_effective_target_large_long_double { } {
2903    return [check_no_compiler_messages large_long_double object {
2904	int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
2905    }]
2906}
2907
2908# Return 1 if the target supports double larger than float,
2909# 0 otherwise.
2910
2911proc check_effective_target_large_double { } {
2912    return [check_no_compiler_messages large_double object {
2913	int dummy[sizeof(double) > sizeof(float) ? 1 : -1];
2914    }]
2915}
2916
2917# Return 1 if the target supports long double of 128 bits,
2918# 0 otherwise.
2919
2920proc check_effective_target_longdouble128 { } {
2921    return [check_no_compiler_messages longdouble128 object {
2922	int dummy[sizeof(long double) == 16 ? 1 : -1];
2923    }]
2924}
2925
2926# Return 1 if the target supports long double of 64 bits,
2927# 0 otherwise.
2928
2929proc check_effective_target_longdouble64 { } {
2930    return [check_no_compiler_messages longdouble64 object {
2931	int dummy[sizeof(long double) == 8 ? 1 : -1];
2932    }]
2933}
2934
2935# Return 1 if the target supports double of 64 bits,
2936# 0 otherwise.
2937
2938proc check_effective_target_double64 { } {
2939    return [check_no_compiler_messages double64 object {
2940	int dummy[sizeof(double) == 8 ? 1 : -1];
2941    }]
2942}
2943
2944# Return 1 if the target supports double of at least 64 bits,
2945# 0 otherwise.
2946
2947proc check_effective_target_double64plus { } {
2948    return [check_no_compiler_messages double64plus object {
2949	int dummy[sizeof(double) >= 8 ? 1 : -1];
2950    }]
2951}
2952
2953# Return 1 if the target supports 'w' suffix on floating constant
2954# 0 otherwise.
2955
2956proc check_effective_target_has_w_floating_suffix { } {
2957    set opts ""
2958    if [check_effective_target_c++] {
2959        append opts "-std=gnu++03"
2960    }
2961    return [check_no_compiler_messages w_fp_suffix object {
2962	float dummy = 1.0w;
2963    } "$opts"]
2964}
2965
2966# Return 1 if the target supports 'q' suffix on floating constant
2967# 0 otherwise.
2968
2969proc check_effective_target_has_q_floating_suffix { } {
2970    set opts ""
2971    if [check_effective_target_c++] {
2972        append opts "-std=gnu++03"
2973    }
2974    return [check_no_compiler_messages q_fp_suffix object {
2975	float dummy = 1.0q;
2976    } "$opts"]
2977}
2978
2979# Return 1 if the target supports the _FloatN / _FloatNx type
2980# indicated in the function name, 0 otherwise.
2981
2982proc check_effective_target_float16 {} {
2983    return [check_no_compiler_messages_nocache float16 object {
2984        _Float16 x;
2985    } [add_options_for_float16 ""]]
2986}
2987
2988proc check_effective_target_float32 {} {
2989    return [check_no_compiler_messages_nocache float32 object {
2990        _Float32 x;
2991    } [add_options_for_float32 ""]]
2992}
2993
2994proc check_effective_target_float64 {} {
2995    return [check_no_compiler_messages_nocache float64 object {
2996        _Float64 x;
2997    } [add_options_for_float64 ""]]
2998}
2999
3000proc check_effective_target_float128 {} {
3001    return [check_no_compiler_messages_nocache float128 object {
3002        _Float128 x;
3003    } [add_options_for_float128 ""]]
3004}
3005
3006proc check_effective_target_float32x {} {
3007    return [check_no_compiler_messages_nocache float32x object {
3008        _Float32x x;
3009    } [add_options_for_float32x ""]]
3010}
3011
3012proc check_effective_target_float64x {} {
3013    return [check_no_compiler_messages_nocache float64x object {
3014        _Float64x x;
3015    } [add_options_for_float64x ""]]
3016}
3017
3018proc check_effective_target_float128x {} {
3019    return [check_no_compiler_messages_nocache float128x object {
3020        _Float128x x;
3021    } [add_options_for_float128x ""]]
3022}
3023
3024# Likewise, but runtime support for any special options used as well
3025# as compile-time support is required.
3026
3027proc check_effective_target_float16_runtime {} {
3028    return [check_effective_target_float16]
3029}
3030
3031proc check_effective_target_float32_runtime {} {
3032    return [check_effective_target_float32]
3033}
3034
3035proc check_effective_target_float64_runtime {} {
3036    return [check_effective_target_float64]
3037}
3038
3039proc check_effective_target_float128_runtime {} {
3040    if { ![check_effective_target_float128] } {
3041	return 0
3042    }
3043    if { [istarget powerpc*-*-*] } {
3044	return [check_effective_target_base_quadfloat_support]
3045    }
3046    return 1
3047}
3048
3049proc check_effective_target_float32x_runtime {} {
3050    return [check_effective_target_float32x]
3051}
3052
3053proc check_effective_target_float64x_runtime {} {
3054    if { ![check_effective_target_float64x] } {
3055	return 0
3056    }
3057    if { [istarget powerpc*-*-*] } {
3058	return [check_effective_target_base_quadfloat_support]
3059    }
3060    return 1
3061}
3062
3063proc check_effective_target_float128x_runtime {} {
3064    return [check_effective_target_float128x]
3065}
3066
3067# Return 1 if the target hardware supports any options added for
3068# _FloatN and _FloatNx types, 0 otherwise.
3069
3070proc check_effective_target_floatn_nx_runtime {} {
3071    if { [istarget powerpc*-*-aix*] } {
3072	return 0
3073    }
3074    if { [istarget powerpc*-*-*] } {
3075	return [check_effective_target_base_quadfloat_support]
3076    }
3077    return 1
3078}
3079
3080# Add options needed to use the _FloatN / _FloatNx type indicated in
3081# the function name.
3082
3083proc add_options_for_float16 { flags } {
3084    if { [istarget arm*-*-*] } {
3085	return "$flags -mfp16-format=ieee"
3086    }
3087    return "$flags"
3088}
3089
3090proc add_options_for_float32 { flags } {
3091    return "$flags"
3092}
3093
3094proc add_options_for_float64 { flags } {
3095    return "$flags"
3096}
3097
3098proc add_options_for_float128 { flags } {
3099    return [add_options_for___float128 "$flags"]
3100}
3101
3102proc add_options_for_float32x { flags } {
3103    return "$flags"
3104}
3105
3106proc add_options_for_float64x { flags } {
3107    return [add_options_for___float128 "$flags"]
3108}
3109
3110proc add_options_for_float128x { flags } {
3111    return "$flags"
3112}
3113
3114# Return 1 if the target supports __float128,
3115# 0 otherwise.
3116
3117proc check_effective_target___float128 { } {
3118    if { [istarget powerpc*-*-*] } {
3119	return [check_ppc_float128_sw_available]
3120    }
3121    if { [istarget ia64-*-*]
3122	 || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
3123	return 1
3124    }
3125    return 0
3126}
3127
3128proc add_options_for___float128 { flags } {
3129    if { [istarget powerpc*-*-*] } {
3130	return "$flags -mfloat128 -mvsx"
3131    }
3132    return "$flags"
3133}
3134
3135# Return 1 if the target supports any special run-time requirements
3136# for __float128 or _Float128,
3137# 0 otherwise.
3138
3139proc check_effective_target_base_quadfloat_support { } {
3140    if { [istarget powerpc*-*-*] } {
3141	return [check_vsx_hw_available]
3142    }
3143    return 1
3144}
3145
3146# Return 1 if the target supports all four forms of fused multiply-add
3147# (fma, fms, fnma, and fnms) for both float and double.
3148
3149proc check_effective_target_scalar_all_fma { } {
3150    return [istarget aarch64*-*-*]
3151}
3152
3153# Return 1 if the target supports compiling fixed-point,
3154# 0 otherwise.
3155
3156proc check_effective_target_fixed_point { } {
3157    return [check_no_compiler_messages fixed_point object {
3158        _Sat _Fract x; _Sat _Accum y;
3159    }]
3160}
3161
3162# Return 1 if the target supports compiling decimal floating point,
3163# 0 otherwise.
3164
3165proc check_effective_target_dfp_nocache { } {
3166    verbose "check_effective_target_dfp_nocache: compiling source" 2
3167    set ret [check_no_compiler_messages_nocache dfp object {
3168	float x __attribute__((mode(DD)));
3169    }]
3170    verbose "check_effective_target_dfp_nocache: returning $ret" 2
3171    return $ret
3172}
3173
3174proc check_effective_target_dfprt_nocache { } {
3175    return [check_runtime_nocache dfprt {
3176	typedef float d64 __attribute__((mode(DD)));
3177	d64 x = 1.2df, y = 2.3dd, z;
3178	int main () { z = x + y; return 0; }
3179    }]
3180}
3181
3182# Return 1 if the target supports compiling Decimal Floating Point,
3183# 0 otherwise.
3184#
3185# This won't change for different subtargets so cache the result.
3186
3187proc check_effective_target_dfp { } {
3188    return [check_cached_effective_target dfp {
3189	check_effective_target_dfp_nocache
3190    }]
3191}
3192
3193# Return 1 if the target supports linking and executing Decimal Floating
3194# Point, 0 otherwise.
3195#
3196# This won't change for different subtargets so cache the result.
3197
3198proc check_effective_target_dfprt { } {
3199    return [check_cached_effective_target dfprt {
3200	check_effective_target_dfprt_nocache
3201    }]
3202}
3203
3204# Return 1 iff target has unsigned plain 'char' by default.
3205
3206proc check_effective_target_unsigned_char {} {
3207    return [check_no_compiler_messages unsigned_char assembly {
3208	char ar[(char)-1];
3209    }]
3210}
3211
3212proc check_effective_target_powerpc_popcntb_ok { } {
3213    return [check_cached_effective_target powerpc_popcntb_ok {
3214
3215	# Disable on Darwin.
3216	if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
3217	    expr 0
3218	} else {
3219	    check_runtime_nocache powerpc_popcntb_ok {
3220		volatile int r;
3221		volatile int a = 0x12345678;
3222		int main()
3223		{
3224		    asm volatile ("popcntb %0,%1" : "=r" (r) : "r" (a));
3225		    return 0;
3226		}
3227	    } "-mcpu=power5"
3228	}
3229    }]
3230}
3231
3232# Return 1 if the target supports executing DFP hardware instructions,
3233# 0 otherwise.  Cache the result.
3234
3235proc check_dfp_hw_available { } {
3236    return [check_cached_effective_target dfp_hw_available {
3237	# For now, disable on Darwin
3238	if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
3239	    expr 0
3240	} else {
3241	    check_runtime_nocache dfp_hw_available {
3242		volatile _Decimal64 r;
3243		volatile _Decimal64 a = 4.0DD;
3244		volatile _Decimal64 b = 2.0DD;
3245		int main()
3246		{
3247		  asm volatile ("dadd %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
3248		  asm volatile ("dsub %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
3249		  asm volatile ("dmul %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
3250		  asm volatile ("ddiv %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
3251		  return 0;
3252		}
3253	    } "-mcpu=power6 -mhard-float"
3254	}
3255    }]
3256}
3257
3258# Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
3259
3260proc check_effective_target_ucn_nocache { } {
3261    # -std=c99 is only valid for C
3262    if [check_effective_target_c] {
3263	set ucnopts "-std=c99"
3264    } else {
3265	set ucnopts ""
3266    }
3267    verbose "check_effective_target_ucn_nocache: compiling source" 2
3268    set ret [check_no_compiler_messages_nocache ucn object {
3269	int \u00C0;
3270    } $ucnopts]
3271    verbose "check_effective_target_ucn_nocache: returning $ret" 2
3272    return $ret
3273}
3274
3275# Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
3276#
3277# This won't change for different subtargets, so cache the result.
3278
3279proc check_effective_target_ucn { } {
3280    return [check_cached_effective_target ucn {
3281	check_effective_target_ucn_nocache
3282    }]
3283}
3284
3285# Return 1 if the target needs a command line argument to enable a SIMD
3286# instruction set.
3287
3288proc check_effective_target_vect_cmdline_needed { } {
3289    global et_vect_cmdline_needed_target_name
3290
3291    if { ![info exists et_vect_cmdline_needed_target_name] } {
3292	set et_vect_cmdline_needed_target_name ""
3293    }
3294
3295    # If the target has changed since we set the cached value, clear it.
3296    set current_target [current_target_name]
3297    if { $current_target != $et_vect_cmdline_needed_target_name } {
3298	verbose "check_effective_target_vect_cmdline_needed: `$et_vect_cmdline_needed_target_name' `$current_target'" 2
3299	set et_vect_cmdline_needed_target_name $current_target
3300	if { [info exists et_vect_cmdline_needed_saved] } {
3301	    verbose "check_effective_target_vect_cmdline_needed: removing cached result" 2
3302	    unset et_vect_cmdline_needed_saved
3303	}
3304    }
3305
3306    return [check_cached_effective_target vect_cmdline_needed {
3307	if { [istarget alpha*-*-*]
3308	     || [istarget ia64-*-*]
3309	     || (([istarget i?86-*-*] || [istarget x86_64-*-*])
3310		 && ![is-effective-target ia32])
3311	     || ([istarget powerpc*-*-*]
3312		 && ([check_effective_target_powerpc_spe]
3313		     || [check_effective_target_powerpc_altivec]))
3314	     || ([istarget sparc*-*-*] && [check_effective_target_sparc_vis])
3315	     || ([istarget arm*-*-*] && [check_effective_target_arm_neon])
3316	     || [istarget aarch64*-*-*]
3317             || [istarget amdgcn*-*-*]} {
3318	    return 0
3319	} else {
3320	    return 1
3321	}}]
3322}
3323
3324# Return 1 if the target supports hardware vectors of int, 0 otherwise.
3325#
3326# This won't change for different subtargets so cache the result.
3327
3328proc check_effective_target_vect_int { } {
3329    return [check_cached_effective_target_indexed vect_int {
3330      expr {
3331         [istarget i?86-*-*] || [istarget x86_64-*-*]
3332         || ([istarget powerpc*-*-*]
3333	     && ![istarget powerpc-*-linux*paired*])
3334	 || [istarget amdgcn-*-*]
3335	 || [istarget sparc*-*-*]
3336	 || [istarget alpha*-*-*]
3337	 || [istarget ia64-*-*]
3338	 || [istarget aarch64*-*-*]
3339	 || [is-effective-target arm_neon]
3340	 || ([istarget mips*-*-*]
3341	     && ([et-is-effective-target mips_loongson_mmi]
3342	     || [et-is-effective-target mips_msa]))
3343	 || ([istarget s390*-*-*]
3344	     && [check_effective_target_s390_vx])
3345	}}]
3346}
3347
3348# Return 1 if the target supports signed int->float conversion
3349#
3350
3351proc check_effective_target_vect_intfloat_cvt { } {
3352    return [check_cached_effective_target_indexed vect_intfloat_cvt {
3353      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
3354	     || ([istarget powerpc*-*-*]
3355		 && ![istarget powerpc-*-linux*paired*])
3356	     || [is-effective-target arm_neon]
3357	     || ([istarget mips*-*-*]
3358		 && [et-is-effective-target mips_msa])
3359	     || [istarget amdgcn-*-*] }}]
3360}
3361
3362# Return 1 if the target supports signed double->int conversion
3363#
3364
3365proc check_effective_target_vect_doubleint_cvt { } {
3366    return [check_cached_effective_target_indexed vect_doubleint_cvt {
3367      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
3368	       && [check_no_compiler_messages vect_doubleint_cvt assembly {
3369		   #ifdef __tune_atom__
3370		   # error No double vectorizer support.
3371		   #endif
3372	      }])
3373	    || [istarget aarch64*-*-*]
3374	    || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
3375	    || ([istarget mips*-*-*]
3376		 && [et-is-effective-target mips_msa]) }}]
3377}
3378
3379# Return 1 if the target supports signed int->double conversion
3380#
3381
3382proc check_effective_target_vect_intdouble_cvt { } {
3383    return [check_cached_effective_target_indexed vect_intdouble_cvt {
3384      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
3385	      && [check_no_compiler_messages vect_intdouble_cvt assembly {
3386		  #ifdef __tune_atom__
3387		  # error No double vectorizer support.
3388		  #endif
3389	      }])
3390	     || [istarget aarch64*-*-*]
3391	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
3392	     || ([istarget mips*-*-*]
3393		 && [et-is-effective-target mips_msa]) }}]
3394}
3395
3396#Return 1 if we're supporting __int128 for target, 0 otherwise.
3397
3398proc check_effective_target_int128 { } {
3399    return [check_no_compiler_messages int128 object {
3400	int dummy[
3401    	#ifndef __SIZEOF_INT128__
3402    	-1
3403    	#else
3404    	1
3405    	#endif
3406	];
3407    }]
3408}
3409
3410# Return 1 if the target supports unsigned int->float conversion
3411#
3412
3413proc check_effective_target_vect_uintfloat_cvt { } {
3414    return [check_cached_effective_target_indexed vect_uintfloat_cvt {
3415      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
3416	     || ([istarget powerpc*-*-*]
3417		 && ![istarget powerpc-*-linux*paired*])
3418	     || [istarget aarch64*-*-*]
3419	     || [is-effective-target arm_neon]
3420	     || ([istarget mips*-*-*]
3421		 && [et-is-effective-target mips_msa])
3422	     || [istarget amdgcn-*-*] }}]
3423}
3424
3425
3426# Return 1 if the target supports signed float->int conversion
3427#
3428
3429proc check_effective_target_vect_floatint_cvt { } {
3430    return [check_cached_effective_target_indexed vect_floatint_cvt {
3431      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
3432	     || ([istarget powerpc*-*-*]
3433		 && ![istarget powerpc-*-linux*paired*])
3434	     || [is-effective-target arm_neon]
3435	     || ([istarget mips*-*-*]
3436		 && [et-is-effective-target mips_msa])
3437	     || [istarget amdgcn-*-*] }}]
3438}
3439
3440# Return 1 if the target supports unsigned float->int conversion
3441#
3442
3443proc check_effective_target_vect_floatuint_cvt { } {
3444    return [check_cached_effective_target_indexed vect_floatuint_cvt {
3445      expr { ([istarget powerpc*-*-*]
3446	      && ![istarget powerpc-*-linux*paired*])
3447	    || [is-effective-target arm_neon]
3448	    || ([istarget mips*-*-*]
3449		&& [et-is-effective-target mips_msa])
3450	    || [istarget amdgcn-*-*] }}]
3451}
3452
3453# Return 1 if peeling for alignment might be profitable on the target
3454#
3455
3456proc check_effective_target_vect_peeling_profitable { } {
3457    return [check_cached_effective_target_indexed vect_peeling_profitable {
3458      expr { ([istarget s390*-*-*]
3459	      && [check_effective_target_s390_vx])
3460	    || [check_effective_target_vect_element_align_preferred] }}]
3461}
3462
3463# Return 1 if the target supports #pragma omp declare simd, 0 otherwise.
3464#
3465# This won't change for different subtargets so cache the result.
3466
3467proc check_effective_target_vect_simd_clones { } {
3468    # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx,
3469    # avx2 and avx512f clone.  Only the right clone for the
3470    # specified arch will be chosen, but still we need to at least
3471    # be able to assemble avx512f.
3472    return [check_cached_effective_target_indexed vect_simd_clones {
3473      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
3474	      && [check_effective_target_avx512f])
3475	     || [istarget amdgcn-*-*] }}]
3476}
3477
3478# Return 1 if this is a AArch64 target supporting big endian
3479proc check_effective_target_aarch64_big_endian { } {
3480    return [check_no_compiler_messages aarch64_big_endian assembly {
3481	#if !defined(__aarch64__) || !defined(__AARCH64EB__)
3482	#error !__aarch64__ || !__AARCH64EB__
3483	#endif
3484    }]
3485}
3486
3487# Return 1 if this is a AArch64 target supporting little endian
3488proc check_effective_target_aarch64_little_endian { } {
3489    if { ![istarget aarch64*-*-*] } {
3490	return 0
3491    }
3492
3493    return [check_no_compiler_messages aarch64_little_endian assembly {
3494        #if !defined(__aarch64__) || defined(__AARCH64EB__)
3495        #error FOO
3496        #endif
3497    }]
3498}
3499
3500# Return 1 if this is an AArch64 target supporting SVE.
3501proc check_effective_target_aarch64_sve { } {
3502    if { ![istarget aarch64*-*-*] } {
3503	return 0
3504    }
3505    return [check_no_compiler_messages aarch64_sve assembly {
3506	#if !defined (__ARM_FEATURE_SVE)
3507	#error FOO
3508	#endif
3509    }]
3510}
3511
3512# Return 1 if this is an AArch64 target supporting SVE2.
3513proc check_effective_target_aarch64_sve2 { } {
3514    if { ![istarget aarch64*-*-*] } {
3515	return 0
3516    }
3517    return [check_no_compiler_messages aarch64_sve2 assembly {
3518	#if !defined (__ARM_FEATURE_SVE2)
3519	#error FOO
3520	#endif
3521    }]
3522}
3523
3524# Return 1 if this is an AArch64 target only supporting SVE (not SVE2).
3525proc check_effective_target_aarch64_sve1_only { } {
3526    return [expr { [check_effective_target_aarch64_sve]
3527		   && ![check_effective_target_aarch64_sve2] }]
3528}
3529
3530# Return the size in bits of an SVE vector, or 0 if the size is variable.
3531proc aarch64_sve_bits { } {
3532    return [check_cached_effective_target aarch64_sve_bits {
3533	global tool
3534
3535	set src dummy[pid].c
3536	set f [open $src "w"]
3537	puts $f "int bits = __ARM_FEATURE_SVE_BITS;"
3538	close $f
3539	set output [${tool}_target_compile $src "" preprocess ""]
3540	file delete $src
3541
3542	regsub {.*bits = ([^;]*);.*} $output {\1} bits
3543	expr { $bits }
3544    }]
3545}
3546
3547# Return 1 if this is a compiler supporting ARC atomic operations
3548proc check_effective_target_arc_atomic { } {
3549    return [check_no_compiler_messages arc_atomic assembly {
3550	#if !defined(__ARC_ATOMIC__)
3551	#error FOO
3552	#endif
3553    }]
3554}
3555
3556# Return 1 if this is an arm target using 32-bit instructions
3557proc check_effective_target_arm32 { } {
3558    if { ![istarget arm*-*-*] } {
3559	return 0
3560    }
3561
3562    return [check_no_compiler_messages arm32 assembly {
3563	#if !defined(__arm__) || (defined(__thumb__) && !defined(__thumb2__))
3564	#error !__arm || __thumb__ && !__thumb2__
3565	#endif
3566    }]
3567}
3568
3569# Return 1 if this is an arm target not using Thumb
3570proc check_effective_target_arm_nothumb { } {
3571    if { ![istarget arm*-*-*] } {
3572	return 0
3573    }
3574
3575    return [check_no_compiler_messages arm_nothumb assembly {
3576	#if !defined(__arm__) || (defined(__thumb__) || defined(__thumb2__))
3577	#error !__arm__ || __thumb || __thumb2__
3578	#endif
3579    }]
3580}
3581
3582# Return 1 if this is a little-endian ARM target
3583proc check_effective_target_arm_little_endian { } {
3584    if { ![istarget arm*-*-*] } {
3585	return 0
3586    }
3587
3588    return [check_no_compiler_messages arm_little_endian assembly {
3589	#if !defined(__arm__) || !defined(__ARMEL__)
3590	#error !__arm__ || !__ARMEL__
3591	#endif
3592    }]
3593}
3594
3595# Return 1 if this is an ARM target that only supports aligned vector accesses
3596proc check_effective_target_arm_vect_no_misalign { } {
3597    if { ![istarget arm*-*-*] } {
3598	return 0
3599    }
3600
3601    return [check_no_compiler_messages arm_vect_no_misalign assembly {
3602	#if !defined(__arm__) \
3603	    || (defined(__ARM_FEATURE_UNALIGNED) \
3604	        && defined(__ARMEL__))
3605	#error !__arm__ || (__ARMEL__ && __ARM_FEATURE_UNALIGNED)
3606	#endif
3607    }]
3608}
3609
3610
3611# Return 1 if this is an ARM target supporting -mfloat-abi=soft.  Some
3612# multilibs may be incompatible with this option.
3613
3614proc check_effective_target_arm_soft_ok { } {
3615    if { [check_effective_target_arm32] } {
3616	return [check_no_compiler_messages arm_soft_ok executable {
3617	    int main() { return 0;}
3618	} "-mfloat-abi=soft"]
3619    } else {
3620	return 0
3621    }
3622}
3623
3624# Return 1 if this is an ARM target supporting -mfpu=vfp with an
3625# appropriate abi.
3626
3627proc check_effective_target_arm_vfp_ok_nocache { } {
3628    global et_arm_vfp_flags
3629    set et_arm_vfp_flags ""
3630    if { [check_effective_target_arm32] } {
3631	foreach flags {"-mfpu=vfp" "-mfpu=vfp -mfloat-abi=softfp" "-mfpu=vfp -mfloat-abi=hard"} {
3632	    if { [check_no_compiler_messages_nocache arm_vfp_ok object {
3633		#ifndef __ARM_FP
3634		#error __ARM_FP not defined
3635		#endif
3636	    } "$flags"] } {
3637		set et_arm_vfp_flags $flags
3638		return 1
3639	    }
3640	}
3641    }
3642
3643    return 0
3644}
3645
3646proc check_effective_target_arm_vfp_ok { } {
3647    return [check_cached_effective_target arm_vfp_ok \
3648		check_effective_target_arm_vfp_ok_nocache]
3649}
3650
3651# Add the options needed to compile code with -mfpu=vfp.  We need either
3652# -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already
3653# specified by the multilib, use it.
3654
3655proc add_options_for_arm_vfp { flags } {
3656    if { ! [check_effective_target_arm_vfp_ok] } {
3657	return "$flags"
3658    }
3659    global et_arm_vfp_flags
3660    return "$flags $et_arm_vfp_flags"
3661}
3662
3663# Return 1 if this is an ARM target supporting -mfpu=vfp3
3664# -mfloat-abi=softfp.
3665
3666proc check_effective_target_arm_vfp3_ok { } {
3667    if { [check_effective_target_arm32] } {
3668	return [check_no_compiler_messages arm_vfp3_ok object {
3669	    int dummy;
3670	} "-mfpu=vfp3 -mfloat-abi=softfp"]
3671    } else {
3672	return 0
3673    }
3674}
3675
3676# Return 1 if this is an ARM target supporting -mfpu=fp-armv8
3677# -mfloat-abi=softfp.
3678proc check_effective_target_arm_v8_vfp_ok {} {
3679    if { [check_effective_target_arm32] } {
3680	return [check_no_compiler_messages arm_v8_vfp_ok object {
3681	  int foo (void)
3682	  {
3683	     __asm__ volatile ("vrinta.f32.f32 s0, s0");
3684	     return 0;
3685	  }
3686	} "-mfpu=fp-armv8 -mfloat-abi=softfp"]
3687    } else {
3688	return 0
3689    }
3690}
3691
3692# Return 1 if this is an ARM target supporting -mfpu=vfp
3693# -mfloat-abi=hard.  Some multilibs may be incompatible with these
3694# options.
3695
3696proc check_effective_target_arm_hard_vfp_ok { } {
3697    if { [check_effective_target_arm32]
3698	 && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } {
3699	return [check_no_compiler_messages arm_hard_vfp_ok executable {
3700	    int main() { return 0;}
3701	} "-mfpu=vfp -mfloat-abi=hard"]
3702    } else {
3703	return 0
3704    }
3705}
3706
3707# Return 1 if this is an ARM target defining __ARM_FP. We may need
3708# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
3709# incompatible with these options.  Also set et_arm_fp_flags to the
3710# best options to add.
3711
3712proc check_effective_target_arm_fp_ok_nocache { } {
3713    global et_arm_fp_flags
3714    set et_arm_fp_flags ""
3715    if { [check_effective_target_arm32] } {
3716	foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} {
3717	    if { [check_no_compiler_messages_nocache arm_fp_ok object {
3718		#ifndef __ARM_FP
3719		#error __ARM_FP not defined
3720		#endif
3721	    } "$flags"] } {
3722		set et_arm_fp_flags $flags
3723		return 1
3724	    }
3725	}
3726    }
3727
3728    return 0
3729}
3730
3731proc check_effective_target_arm_fp_ok { } {
3732    return [check_cached_effective_target arm_fp_ok \
3733		check_effective_target_arm_fp_ok_nocache]
3734}
3735
3736# Add the options needed to define __ARM_FP.  We need either
3737# -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already
3738# specified by the multilib, use it.
3739
3740proc add_options_for_arm_fp { flags } {
3741    if { ! [check_effective_target_arm_fp_ok] } {
3742	return "$flags"
3743    }
3744    global et_arm_fp_flags
3745    return "$flags $et_arm_fp_flags"
3746}
3747
3748# Return 1 if this is an ARM target defining __ARM_FP with
3749# double-precision support. We may need -mfloat-abi=softfp or
3750# equivalent options.  Some multilibs may be incompatible with these
3751# options.  Also set et_arm_fp_dp_flags to the best options to add.
3752
3753proc check_effective_target_arm_fp_dp_ok_nocache { } {
3754    global et_arm_fp_dp_flags
3755    set et_arm_fp_dp_flags ""
3756    if { [check_effective_target_arm32] } {
3757	foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} {
3758	    if { [check_no_compiler_messages_nocache arm_fp_dp_ok object {
3759		#ifndef __ARM_FP
3760		#error __ARM_FP not defined
3761		#endif
3762		#if ((__ARM_FP & 8) == 0)
3763		#error __ARM_FP indicates that double-precision is not supported
3764		#endif
3765	    } "$flags"] } {
3766		set et_arm_fp_dp_flags $flags
3767		return 1
3768	    }
3769	}
3770    }
3771
3772    return 0
3773}
3774
3775proc check_effective_target_arm_fp_dp_ok { } {
3776    return [check_cached_effective_target arm_fp_dp_ok \
3777		check_effective_target_arm_fp_dp_ok_nocache]
3778}
3779
3780# Add the options needed to define __ARM_FP with double-precision
3781# support.  We need either -mfloat-abi=softfp or -mfloat-abi=hard, but
3782# if one is already specified by the multilib, use it.
3783
3784proc add_options_for_arm_fp_dp { flags } {
3785    if { ! [check_effective_target_arm_fp_dp_ok] } {
3786	return "$flags"
3787    }
3788    global et_arm_fp_dp_flags
3789    return "$flags $et_arm_fp_dp_flags"
3790}
3791
3792# Return 1 if this is an ARM target that supports DSP multiply with
3793# current multilib flags.
3794
3795proc check_effective_target_arm_dsp { } {
3796    return [check_no_compiler_messages arm_dsp assembly {
3797	#ifndef __ARM_FEATURE_DSP
3798	#error not DSP
3799	#endif
3800	#include <arm_acle.h>
3801	int i;
3802    }]
3803}
3804
3805# Return 1 if this is an ARM target that supports unaligned word/halfword
3806# load/store instructions.
3807
3808proc check_effective_target_arm_unaligned { } {
3809    return [check_no_compiler_messages arm_unaligned assembly {
3810	#ifndef __ARM_FEATURE_UNALIGNED
3811	#error no unaligned support
3812	#endif
3813	int i;
3814    }]
3815}
3816
3817# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
3818# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
3819# incompatible with these options.  Also set et_arm_crypto_flags to the
3820# best options to add.
3821
3822proc check_effective_target_arm_crypto_ok_nocache { } {
3823    global et_arm_crypto_flags
3824    set et_arm_crypto_flags ""
3825    if { [check_effective_target_arm_v8_neon_ok] } {
3826	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} {
3827	    if { [check_no_compiler_messages_nocache arm_crypto_ok object {
3828		#include "arm_neon.h"
3829		uint8x16_t
3830		foo (uint8x16_t a, uint8x16_t b)
3831		{
3832	          return vaeseq_u8 (a, b);
3833		}
3834	    } "$flags"] } {
3835		set et_arm_crypto_flags $flags
3836		return 1
3837	    }
3838	}
3839    }
3840
3841    return 0
3842}
3843
3844# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
3845
3846proc check_effective_target_arm_crypto_ok { } {
3847    return [check_cached_effective_target arm_crypto_ok \
3848		check_effective_target_arm_crypto_ok_nocache]
3849}
3850
3851# Add options for crypto extensions.
3852proc add_options_for_arm_crypto { flags } {
3853    if { ! [check_effective_target_arm_crypto_ok] } {
3854        return "$flags"
3855    }
3856    global et_arm_crypto_flags
3857    return "$flags $et_arm_crypto_flags"
3858}
3859
3860# Add the options needed for NEON.  We need either -mfloat-abi=softfp
3861# or -mfloat-abi=hard, but if one is already specified by the
3862# multilib, use it.  Similarly, if a -mfpu option already enables
3863# NEON, do not add -mfpu=neon.
3864
3865proc add_options_for_arm_neon { flags } {
3866    if { ! [check_effective_target_arm_neon_ok] } {
3867	return "$flags"
3868    }
3869    global et_arm_neon_flags
3870    return "$flags $et_arm_neon_flags"
3871}
3872
3873proc add_options_for_arm_v8_vfp { flags } {
3874    if { ! [check_effective_target_arm_v8_vfp_ok] } {
3875        return "$flags"
3876    }
3877    return "$flags -mfpu=fp-armv8 -mfloat-abi=softfp"
3878}
3879
3880proc add_options_for_arm_v8_neon { flags } {
3881    if { ! [check_effective_target_arm_v8_neon_ok] } {
3882        return "$flags"
3883    }
3884    global et_arm_v8_neon_flags
3885    return "$flags $et_arm_v8_neon_flags -march=armv8-a"
3886}
3887
3888# Add the options needed for ARMv8.1 Adv.SIMD.  Also adds the ARMv8 NEON
3889# options for AArch64 and for ARM.
3890
3891proc add_options_for_arm_v8_1a_neon { flags } {
3892    if { ! [check_effective_target_arm_v8_1a_neon_ok] } {
3893	return "$flags"
3894    }
3895    global et_arm_v8_1a_neon_flags
3896    return "$flags $et_arm_v8_1a_neon_flags"
3897}
3898
3899# Add the options needed for ARMv8.2 with the scalar FP16 extension.
3900# Also adds the ARMv8 FP options for ARM and for AArch64.
3901
3902proc add_options_for_arm_v8_2a_fp16_scalar { flags } {
3903    if { ! [check_effective_target_arm_v8_2a_fp16_scalar_ok] } {
3904	return "$flags"
3905    }
3906    global et_arm_v8_2a_fp16_scalar_flags
3907    return "$flags $et_arm_v8_2a_fp16_scalar_flags"
3908}
3909
3910# Add the options needed for ARMv8.2 with the FP16 extension.  Also adds
3911# the ARMv8 NEON options for ARM and for AArch64.
3912
3913proc add_options_for_arm_v8_2a_fp16_neon { flags } {
3914    if { ! [check_effective_target_arm_v8_2a_fp16_neon_ok] } {
3915	return "$flags"
3916    }
3917    global et_arm_v8_2a_fp16_neon_flags
3918    return "$flags $et_arm_v8_2a_fp16_neon_flags"
3919}
3920
3921proc add_options_for_arm_crc { flags } {
3922    if { ! [check_effective_target_arm_crc_ok] } {
3923        return "$flags"
3924    }
3925    global et_arm_crc_flags
3926    return "$flags $et_arm_crc_flags"
3927}
3928
3929# Add the options needed for NEON.  We need either -mfloat-abi=softfp
3930# or -mfloat-abi=hard, but if one is already specified by the
3931# multilib, use it.  Similarly, if a -mfpu option already enables
3932# NEON, do not add -mfpu=neon.
3933
3934proc add_options_for_arm_neonv2 { flags } {
3935    if { ! [check_effective_target_arm_neonv2_ok] } {
3936	return "$flags"
3937    }
3938    global et_arm_neonv2_flags
3939    return "$flags $et_arm_neonv2_flags"
3940}
3941
3942# Add the options needed for vfp3.
3943proc add_options_for_arm_vfp3 { flags } {
3944    if { ! [check_effective_target_arm_vfp3_ok] } {
3945        return "$flags"
3946    }
3947    return "$flags -mfpu=vfp3 -mfloat-abi=softfp"
3948}
3949
3950# Return 1 if this is an ARM target supporting -mfpu=neon
3951# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
3952# incompatible with these options.  Also set et_arm_neon_flags to the
3953# best options to add.
3954
3955proc check_effective_target_arm_neon_ok_nocache { } {
3956    global et_arm_neon_flags
3957    set et_arm_neon_flags ""
3958    if { [check_effective_target_arm32] } {
3959	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp" "-mfpu=neon -mfloat-abi=softfp -march=armv7-a" "-mfloat-abi=hard" "-mfpu=neon -mfloat-abi=hard" "-mfpu=neon -mfloat-abi=hard -march=armv7-a"} {
3960	    if { [check_no_compiler_messages_nocache arm_neon_ok object {
3961		#include <arm_neon.h>
3962		int dummy;
3963		#ifndef __ARM_NEON__
3964		#error not NEON
3965		#endif
3966		/* Avoid the case where a test adds -mfpu=neon, but the toolchain is
3967		   configured for -mcpu=arm926ej-s, for example.  */
3968		#if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M'
3969		#error Architecture does not support NEON.
3970		#endif
3971	    } "$flags"] } {
3972		set et_arm_neon_flags $flags
3973		return 1
3974	    }
3975	}
3976    }
3977
3978    return 0
3979}
3980
3981proc check_effective_target_arm_neon_ok { } {
3982    return [check_cached_effective_target arm_neon_ok \
3983		check_effective_target_arm_neon_ok_nocache]
3984}
3985
3986
3987# Return 1 if this is an ARM target supporting the SIMD32 intrinsics
3988# from arm_acle.h.  Some multilibs may be incompatible with these options.
3989# Also set et_arm_simd32_flags to the best options to add.
3990# arm_acle.h includes stdint.h which can cause trouble with incompatible
3991# -mfloat-abi= options.
3992
3993proc check_effective_target_arm_simd32_ok_nocache { } {
3994    global et_arm_simd32_flags
3995    set et_arm_simd32_flags ""
3996    foreach flags {"" "-march=armv6" "-march=armv6 -mfloat-abi=softfp" "-march=armv6 -mfloat-abi=hard"} {
3997      if { [check_no_compiler_messages_nocache arm_simd32_ok object {
3998	#include <arm_acle.h>
3999	int dummy;
4000	#ifndef __ARM_FEATURE_SIMD32
4001	#error not SIMD32
4002	#endif
4003      } "$flags"] } {
4004	set et_arm_simd32_flags $flags
4005	return 1
4006      }
4007    }
4008
4009  return 0
4010}
4011
4012proc check_effective_target_arm_simd32_ok { } {
4013    return [check_cached_effective_target arm_simd32_ok \
4014		check_effective_target_arm_simd32_ok_nocache]
4015}
4016
4017proc add_options_for_arm_simd32 { flags } {
4018    if { ! [check_effective_target_arm_simd32_ok] } {
4019	return "$flags"
4020    }
4021    global et_arm_simd32_flags
4022    return "$flags $et_arm_simd32_flags"
4023}
4024
4025# Return 1 if this is an ARM target supporting the saturation intrinsics
4026# from arm_acle.h.  Some multilibs may be incompatible with these options.
4027# Also set et_arm_qbit_flags to the best options to add.
4028# arm_acle.h includes stdint.h which can cause trouble with incompatible
4029# -mfloat-abi= options.
4030
4031proc check_effective_target_arm_qbit_ok_nocache { } {
4032    global et_arm_qbit_flags
4033    set et_arm_qbit_flags ""
4034    foreach flags {"" "-march=armv5te" "-march=armv5te -mfloat-abi=softfp" "-march=armv5te -mfloat-abi=hard"} {
4035      if { [check_no_compiler_messages_nocache et_arm_qbit_flags object {
4036	#include <arm_acle.h>
4037	int dummy;
4038	#ifndef __ARM_FEATURE_QBIT
4039	#error not QBIT
4040	#endif
4041      } "$flags"] } {
4042	set et_arm_qbit_flags $flags
4043	return 1
4044      }
4045    }
4046
4047  return 0
4048}
4049
4050proc check_effective_target_arm_qbit_ok { } {
4051    return [check_cached_effective_target et_arm_qbit_flags \
4052		check_effective_target_arm_qbit_ok_nocache]
4053}
4054
4055proc add_options_for_arm_qbit { flags } {
4056    if { ! [check_effective_target_arm_qbit_ok] } {
4057	return "$flags"
4058    }
4059    global et_arm_qbit_flags
4060    return "$flags $et_arm_qbit_flags"
4061}
4062
4063# Return 1 if this is an ARM target supporting -mfpu=neon without any
4064# -mfloat-abi= option.  Useful in tests where add_options is not
4065# supported (such as lto tests).
4066
4067proc check_effective_target_arm_neon_ok_no_float_abi_nocache { } {
4068    if { [check_effective_target_arm32] } {
4069	foreach flags {"-mfpu=neon"} {
4070	    if { [check_no_compiler_messages_nocache arm_neon_ok_no_float_abi object {
4071		#include <arm_neon.h>
4072		int dummy;
4073		#ifndef __ARM_NEON__
4074		#error not NEON
4075		#endif
4076		/* Avoid the case where a test adds -mfpu=neon, but the toolchain is
4077		   configured for -mcpu=arm926ej-s, for example.  */
4078		#if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M'
4079		#error Architecture does not support NEON.
4080		#endif
4081	    } "$flags"] } {
4082		return 1
4083	    }
4084	}
4085    }
4086
4087    return 0
4088}
4089
4090proc check_effective_target_arm_neon_ok_no_float_abi { } {
4091    return [check_cached_effective_target arm_neon_ok_no_float_abi \
4092		check_effective_target_arm_neon_ok_no_float_abi_nocache]
4093}
4094
4095proc check_effective_target_arm_crc_ok_nocache { } {
4096    global et_arm_crc_flags
4097    set et_arm_crc_flags "-march=armv8-a+crc"
4098    return [check_no_compiler_messages_nocache arm_crc_ok object {
4099	#if !defined (__ARM_FEATURE_CRC32)
4100	#error FOO
4101	#endif
4102	#include <arm_acle.h>
4103    } "$et_arm_crc_flags"]
4104}
4105
4106proc check_effective_target_arm_crc_ok { } {
4107    return [check_cached_effective_target arm_crc_ok \
4108		check_effective_target_arm_crc_ok_nocache]
4109}
4110
4111# Return 1 if this is an ARM target supporting -mfpu=neon-fp16
4112# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
4113# incompatible with these options.  Also set et_arm_neon_fp16_flags to
4114# the best options to add.
4115
4116proc check_effective_target_arm_neon_fp16_ok_nocache { } {
4117    global et_arm_neon_fp16_flags
4118    global et_arm_neon_flags
4119    set et_arm_neon_fp16_flags ""
4120    if { [check_effective_target_arm32]
4121	 && [check_effective_target_arm_neon_ok] } {
4122	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
4123		       "-mfpu=neon-fp16 -mfloat-abi=softfp"
4124		       "-mfp16-format=ieee"
4125		       "-mfloat-abi=softfp -mfp16-format=ieee"
4126		       "-mfpu=neon-fp16 -mfp16-format=ieee"
4127		       "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} {
4128	    if { [check_no_compiler_messages_nocache arm_neon_fp16_ok object {
4129		#include "arm_neon.h"
4130		float16x4_t
4131		foo (float32x4_t arg)
4132		{
4133                  return vcvt_f16_f32 (arg);
4134		}
4135	    } "$et_arm_neon_flags $flags"] } {
4136		set et_arm_neon_fp16_flags [concat $et_arm_neon_flags $flags]
4137		return 1
4138	    }
4139	}
4140    }
4141
4142    return 0
4143}
4144
4145proc check_effective_target_arm_neon_fp16_ok { } {
4146    return [check_cached_effective_target arm_neon_fp16_ok \
4147		check_effective_target_arm_neon_fp16_ok_nocache]
4148}
4149
4150# Return 1 if this is an ARM target supporting -mfpu=neon-fp16
4151# and -mfloat-abi=softfp together.  Some multilibs may be
4152# incompatible with these options.  Also set et_arm_neon_softfp_fp16_flags to
4153# the best options to add.
4154
4155proc check_effective_target_arm_neon_softfp_fp16_ok_nocache { } {
4156    global et_arm_neon_softfp_fp16_flags
4157    global et_arm_neon_flags
4158    set et_arm_neon_softfp_fp16_flags ""
4159    if { [check_effective_target_arm32]
4160	 && [check_effective_target_arm_neon_ok] } {
4161	foreach flags {"-mfpu=neon-fp16 -mfloat-abi=softfp"
4162		       "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} {
4163	    if { [check_no_compiler_messages_nocache arm_neon_softfp_fp16_ok object {
4164		#include "arm_neon.h"
4165		float16x4_t
4166		foo (float32x4_t arg)
4167		{
4168                  return vcvt_f16_f32 (arg);
4169		}
4170	    } "$et_arm_neon_flags $flags"] } {
4171		set et_arm_neon_softfp_fp16_flags [concat $et_arm_neon_flags $flags]
4172		return 1
4173	    }
4174	}
4175    }
4176
4177    return 0
4178}
4179
4180proc check_effective_target_arm_neon_softfp_fp16_ok { } {
4181    return [check_cached_effective_target arm_neon_softfp_fp16_ok \
4182		check_effective_target_arm_neon_softfp_fp16_ok_nocache]
4183}
4184
4185
4186
4187proc check_effective_target_arm_neon_fp16_hw { } {
4188    if {! [check_effective_target_arm_neon_fp16_ok] } {
4189	return 0
4190    }
4191    global et_arm_neon_fp16_flags
4192    check_runtime arm_neon_fp16_hw {
4193	int
4194	main (int argc, char **argv)
4195	{
4196	  asm ("vcvt.f32.f16 q1, d0");
4197	  return 0;
4198	}
4199    } $et_arm_neon_fp16_flags
4200}
4201
4202proc add_options_for_arm_neon_fp16 { flags } {
4203    if { ! [check_effective_target_arm_neon_fp16_ok] } {
4204	return "$flags"
4205    }
4206    global et_arm_neon_fp16_flags
4207    return "$flags $et_arm_neon_fp16_flags"
4208}
4209
4210proc add_options_for_arm_neon_softfp_fp16 { flags } {
4211    if { ! [check_effective_target_arm_neon_softfp_fp16_ok] } {
4212	return "$flags"
4213    }
4214    global et_arm_neon_softfp_fp16_flags
4215    return "$flags $et_arm_neon_softfp_fp16_flags"
4216}
4217
4218proc add_options_for_aarch64_sve { flags } {
4219    if { ![istarget aarch64*-*-*] || [check_effective_target_aarch64_sve] } {
4220        return "$flags"
4221    }
4222    return "$flags -march=armv8.2-a+sve"
4223}
4224
4225# Return 1 if this is an ARM target supporting the FP16 alternative
4226# format.  Some multilibs may be incompatible with the options needed.  Also
4227# set et_arm_neon_fp16_flags to the best options to add.
4228
4229proc check_effective_target_arm_fp16_alternative_ok_nocache { } {
4230    global et_arm_neon_fp16_flags
4231    set et_arm_neon_fp16_flags ""
4232    if { [check_effective_target_arm32] } {
4233	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
4234		       "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
4235	    if { [check_no_compiler_messages_nocache \
4236		      arm_fp16_alternative_ok object {
4237		#if !defined (__ARM_FP16_FORMAT_ALTERNATIVE)
4238		#error __ARM_FP16_FORMAT_ALTERNATIVE not defined
4239		#endif
4240	    } "$flags -mfp16-format=alternative"] } {
4241		set et_arm_neon_fp16_flags "$flags -mfp16-format=alternative"
4242		return 1
4243	    }
4244	}
4245    }
4246
4247    return 0
4248}
4249
4250proc check_effective_target_arm_fp16_alternative_ok { } {
4251    return [check_cached_effective_target arm_fp16_alternative_ok \
4252		check_effective_target_arm_fp16_alternative_ok_nocache]
4253}
4254
4255# Return 1 if this is an ARM target supports specifying the FP16 none
4256# format.  Some multilibs may be incompatible with the options needed.
4257
4258proc check_effective_target_arm_fp16_none_ok_nocache { } {
4259    if { [check_effective_target_arm32] } {
4260	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
4261		       "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
4262	    if { [check_no_compiler_messages_nocache \
4263		      arm_fp16_none_ok object {
4264		#if defined (__ARM_FP16_FORMAT_ALTERNATIVE)
4265		#error __ARM_FP16_FORMAT_ALTERNATIVE defined
4266		#endif
4267		#if defined (__ARM_FP16_FORMAT_IEEE)
4268		#error __ARM_FP16_FORMAT_IEEE defined
4269		#endif
4270	    } "$flags -mfp16-format=none"] } {
4271		return 1
4272	    }
4273	}
4274    }
4275
4276    return 0
4277}
4278
4279proc check_effective_target_arm_fp16_none_ok { } {
4280    return [check_cached_effective_target arm_fp16_none_ok \
4281		check_effective_target_arm_fp16_none_ok_nocache]
4282}
4283
4284# Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8
4285# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
4286# incompatible with these options.  Also set et_arm_v8_neon_flags to the
4287# best options to add.
4288
4289proc check_effective_target_arm_v8_neon_ok_nocache { } {
4290    global et_arm_v8_neon_flags
4291    set et_arm_v8_neon_flags ""
4292    if { [check_effective_target_arm32] } {
4293	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
4294	    if { [check_no_compiler_messages_nocache arm_v8_neon_ok object {
4295		#if __ARM_ARCH < 8
4296		#error not armv8 or later
4297		#endif
4298		#include "arm_neon.h"
4299		void
4300		foo ()
4301		{
4302	          __asm__ volatile ("vrintn.f32 q0, q0");
4303		}
4304	    } "$flags -march=armv8-a"] } {
4305		set et_arm_v8_neon_flags $flags
4306		return 1
4307	    }
4308	}
4309    }
4310
4311    return 0
4312}
4313
4314proc check_effective_target_arm_v8_neon_ok { } {
4315    return [check_cached_effective_target arm_v8_neon_ok \
4316		check_effective_target_arm_v8_neon_ok_nocache]
4317}
4318
4319# Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4
4320# -mfloat-abi=softfp or equivalent options.  Some multilibs may be
4321# incompatible with these options.  Also set et_arm_neonv2_flags to the
4322# best options to add.
4323
4324proc check_effective_target_arm_neonv2_ok_nocache { } {
4325    global et_arm_neonv2_flags
4326    global et_arm_neon_flags
4327    set et_arm_neonv2_flags ""
4328    if { [check_effective_target_arm32]
4329	 && [check_effective_target_arm_neon_ok] } {
4330	foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-vfpv4" "-mfpu=neon-vfpv4 -mfloat-abi=softfp"} {
4331	    if { [check_no_compiler_messages_nocache arm_neonv2_ok object {
4332		#include "arm_neon.h"
4333		float32x2_t
4334		foo (float32x2_t a, float32x2_t b, float32x2_t c)
4335                {
4336                  return vfma_f32 (a, b, c);
4337                }
4338	    } "$et_arm_neon_flags $flags"] } {
4339		set et_arm_neonv2_flags [concat $et_arm_neon_flags $flags]
4340		return 1
4341	    }
4342	}
4343    }
4344
4345    return 0
4346}
4347
4348proc check_effective_target_arm_neonv2_ok { } {
4349    return [check_cached_effective_target arm_neonv2_ok \
4350		check_effective_target_arm_neonv2_ok_nocache]
4351}
4352
4353# Add the options needed for VFP FP16 support.  We need either
4354# -mfloat-abi=softfp or -mfloat-abi=hard.  If one is already specified by
4355# the multilib, use it.
4356
4357proc add_options_for_arm_fp16 { flags } {
4358    if { ! [check_effective_target_arm_fp16_ok] } {
4359	return "$flags"
4360    }
4361    global et_arm_fp16_flags
4362    return "$flags $et_arm_fp16_flags"
4363}
4364
4365# Add the options needed to enable support for IEEE format
4366# half-precision support.  This is valid for ARM targets.
4367
4368proc add_options_for_arm_fp16_ieee { flags } {
4369    if { ! [check_effective_target_arm_fp16_ok] } {
4370	return "$flags"
4371    }
4372    global et_arm_fp16_flags
4373    return "$flags $et_arm_fp16_flags -mfp16-format=ieee"
4374}
4375
4376# Add the options needed to enable support for ARM Alternative format
4377# half-precision support.  This is valid for ARM targets.
4378
4379proc add_options_for_arm_fp16_alternative { flags } {
4380    if { ! [check_effective_target_arm_fp16_ok] } {
4381	return "$flags"
4382    }
4383    global et_arm_fp16_flags
4384    return "$flags $et_arm_fp16_flags -mfp16-format=alternative"
4385}
4386
4387# Return 1 if this is an ARM target that can support a VFP fp16 variant.
4388# Skip multilibs that are incompatible with these options and set
4389# et_arm_fp16_flags to the best options to add.  This test is valid for
4390# ARM only.
4391
4392proc check_effective_target_arm_fp16_ok_nocache { } {
4393    global et_arm_fp16_flags
4394    set et_arm_fp16_flags ""
4395    if { ! [check_effective_target_arm32] } {
4396	return 0;
4397    }
4398    if [check-flags \
4399	    [list "" { *-*-* } { "-mfpu=*" } \
4400		 { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" \
4401		       "-mfpu=*fpv[1-9][0-9]*" "-mfpu=*fp-armv8*" } ]] {
4402	# Multilib flags would override -mfpu.
4403	return 0
4404    }
4405    if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] {
4406	# Must generate floating-point instructions.
4407	return 0
4408    }
4409    if [check_effective_target_arm_hf_eabi] {
4410	# Use existing float-abi and force an fpu which supports fp16
4411	set et_arm_fp16_flags "-mfpu=vfpv4"
4412	return 1;
4413    }
4414    if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] {
4415        # The existing -mfpu value is OK; use it, but add softfp.
4416	set et_arm_fp16_flags "-mfloat-abi=softfp"
4417	return 1;
4418    }
4419    # Add -mfpu for a VFP fp16 variant since there is no preprocessor
4420    # macro to check for this support.
4421    set flags "-mfpu=vfpv4 -mfloat-abi=softfp"
4422    if { [check_no_compiler_messages_nocache arm_fp16_ok assembly {
4423	int dummy;
4424    } "$flags"] } {
4425	set et_arm_fp16_flags "$flags"
4426	return 1
4427    }
4428
4429    return 0
4430}
4431
4432proc check_effective_target_arm_fp16_ok { } {
4433    return [check_cached_effective_target arm_fp16_ok \
4434		check_effective_target_arm_fp16_ok_nocache]
4435}
4436
4437# Return 1 if the target supports executing VFP FP16 instructions, 0
4438# otherwise.  This test is valid for ARM only.
4439
4440proc check_effective_target_arm_fp16_hw { } {
4441    if {! [check_effective_target_arm_fp16_ok] } {
4442	return 0
4443    }
4444    global et_arm_fp16_flags
4445    check_runtime arm_fp16_hw {
4446	int
4447	main (int argc, char **argv)
4448	{
4449	  __fp16 a = 1.0;
4450	  float r;
4451	  asm ("vcvtb.f32.f16 %0, %1"
4452	       : "=w" (r) : "w" (a)
4453	       : /* No clobbers.  */);
4454	  return (r == 1.0) ? 0 : 1;
4455	}
4456    } "$et_arm_fp16_flags -mfp16-format=ieee"
4457}
4458
4459# Creates a series of routines that return 1 if the given architecture
4460# can be selected and a routine to give the flags to select that architecture
4461# Note: Extra flags may be added to disable options from newer compilers
4462# (Thumb in particular - but others may be added in the future).
4463# Warning: Do not use check_effective_target_arm_arch_*_ok for architecture
4464# extension (eg. ARMv8.1-A) since there is no macro defined for them.  See
4465# how only __ARM_ARCH_8A__ is checked for ARMv8.1-A.
4466# Usage: /* { dg-require-effective-target arm_arch_v5_ok } */
4467#        /* { dg-add-options arm_arch_v5t } */
4468#	 /* { dg-require-effective-target arm_arch_v5t_multilib } */
4469foreach { armfunc armflag armdefs } {
4470	v4 "-march=armv4 -marm" __ARM_ARCH_4__
4471	v4t "-march=armv4t -mfloat-abi=softfp" __ARM_ARCH_4T__
4472	v4t_arm "-march=armv4t -marm" __ARM_ARCH_4T__
4473	v4t_thumb "-march=armv4t -mthumb -mfloat-abi=softfp" __ARM_ARCH_4T__
4474	v5t "-march=armv5t -mfloat-abi=softfp" __ARM_ARCH_5T__
4475	v5t_arm "-march=armv5t -marm" __ARM_ARCH_5T__
4476	v5t_thumb "-march=armv5t -mthumb -mfloat-abi=softfp" __ARM_ARCH_5T__
4477	v5te "-march=armv5te -mfloat-abi=softfp" __ARM_ARCH_5TE__
4478	v5te_arm "-march=armv5te -marm" __ARM_ARCH_5TE__
4479	v5te_thumb "-march=armv5te -mthumb -mfloat-abi=softfp" __ARM_ARCH_5TE__
4480	v6 "-march=armv6 -mfloat-abi=softfp" __ARM_ARCH_6__
4481	v6_arm "-march=armv6 -marm" __ARM_ARCH_6__
4482	v6_thumb "-march=armv6 -mthumb -mfloat-abi=softfp" __ARM_ARCH_6__
4483	v6k "-march=armv6k -mfloat-abi=softfp" __ARM_ARCH_6K__
4484	v6k_arm "-march=armv6k -marm" __ARM_ARCH_6K__
4485	v6k_thumb "-march=armv6k -mthumb -mfloat-abi=softfp" __ARM_ARCH_6K__
4486	v6t2 "-march=armv6t2" __ARM_ARCH_6T2__
4487	v6z "-march=armv6z -mfloat-abi=softfp" __ARM_ARCH_6Z__
4488	v6z_arm "-march=armv6z -marm" __ARM_ARCH_6Z__
4489	v6z_thumb "-march=armv6z -mthumb -mfloat-abi=softfp" __ARM_ARCH_6Z__
4490	v6m "-march=armv6-m -mthumb -mfloat-abi=soft" __ARM_ARCH_6M__
4491	v7a "-march=armv7-a" __ARM_ARCH_7A__
4492	v7r "-march=armv7-r" __ARM_ARCH_7R__
4493	v7m "-march=armv7-m -mthumb" __ARM_ARCH_7M__
4494	v7em "-march=armv7e-m -mthumb" __ARM_ARCH_7EM__
4495	v7ve "-march=armv7ve -marm"
4496		"__ARM_ARCH_7A__ && __ARM_FEATURE_IDIV"
4497	v8a "-march=armv8-a" __ARM_ARCH_8A__
4498	v8a_hard "-march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=hard" __ARM_ARCH_8A__
4499	v8_1a "-march=armv8.1-a" __ARM_ARCH_8A__
4500	v8_2a "-march=armv8.2-a" __ARM_ARCH_8A__
4501	v8r "-march=armv8-r" __ARM_ARCH_8R__
4502	v8m_base "-march=armv8-m.base -mthumb -mfloat-abi=soft"
4503		__ARM_ARCH_8M_BASE__
4504	v8m_main "-march=armv8-m.main -mthumb" __ARM_ARCH_8M_MAIN__
4505	v8_1m_main "-march=armv8.1-m.main -mthumb" __ARM_ARCH_8M_MAIN__ } {
4506    eval [string map [list FUNC $armfunc FLAG $armflag DEFS $armdefs ] {
4507	proc check_effective_target_arm_arch_FUNC_ok { } {
4508	    return [check_no_compiler_messages arm_arch_FUNC_ok assembly {
4509		#if !(DEFS)
4510		#error !(DEFS)
4511		#endif
4512		int
4513		main (void)
4514		{
4515		    return 0;
4516		}
4517	    } "FLAG" ]
4518	}
4519
4520	proc add_options_for_arm_arch_FUNC { flags } {
4521	    return "$flags FLAG"
4522	}
4523
4524	proc check_effective_target_arm_arch_FUNC_multilib { } {
4525	    return [check_runtime arm_arch_FUNC_multilib {
4526		int
4527		main (void)
4528		{
4529		    return 0;
4530		}
4531	    } [add_options_for_arm_arch_FUNC ""]]
4532        }
4533    }]
4534}
4535
4536# Return 1 if GCC was configured with --with-mode=
4537proc check_effective_target_default_mode { } {
4538
4539    return [check_configured_with "with-mode="]
4540}
4541
4542# Return 1 if this is an ARM target where -marm causes ARM to be
4543# used (not Thumb)
4544
4545proc check_effective_target_arm_arm_ok { } {
4546    return [check_no_compiler_messages arm_arm_ok assembly {
4547	#if !defined (__arm__) || defined (__thumb__) || defined (__thumb2__)
4548	#error !__arm__ || __thumb__ || __thumb2__
4549	#endif
4550    } "-marm"]
4551}
4552
4553
4554# Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
4555# used.
4556
4557proc check_effective_target_arm_thumb1_ok { } {
4558    return [check_no_compiler_messages arm_thumb1_ok assembly {
4559	#if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
4560	#error !__arm__ || !__thumb__ || __thumb2__
4561	#endif
4562	int foo (int i) { return i; }
4563    } "-mthumb"]
4564}
4565
4566# Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
4567# used.
4568
4569proc check_effective_target_arm_thumb2_ok { } {
4570    return [check_no_compiler_messages arm_thumb2_ok assembly {
4571	#if !defined(__thumb2__)
4572	#error !__thumb2__
4573	#endif
4574	int foo (int i) { return i; }
4575    } "-mthumb"]
4576}
4577
4578# Return 1 if this is an ARM target where Thumb-1 is used without options
4579# added by the test.
4580
4581proc check_effective_target_arm_thumb1 { } {
4582    return [check_no_compiler_messages arm_thumb1 assembly {
4583	#if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
4584	#error !__arm__ || !__thumb__ || __thumb2__
4585	#endif
4586	int i;
4587    } ""]
4588}
4589
4590# Return 1 if this is an ARM target where Thumb-2 is used without options
4591# added by the test.
4592
4593proc check_effective_target_arm_thumb2 { } {
4594    return [check_no_compiler_messages arm_thumb2 assembly {
4595	#if !defined(__thumb2__)
4596	#error !__thumb2__
4597	#endif
4598	int i;
4599    } ""]
4600}
4601
4602# Return 1 if this is an ARM target where conditional execution is available.
4603
4604proc check_effective_target_arm_cond_exec { } {
4605    return [check_no_compiler_messages arm_cond_exec assembly {
4606	#if defined(__arm__) && defined(__thumb__) && !defined(__thumb2__)
4607	#error FOO
4608	#endif
4609	int i;
4610    } ""]
4611}
4612
4613# Return 1 if this is an ARM cortex-M profile cpu
4614
4615proc check_effective_target_arm_cortex_m { } {
4616    if { ![istarget arm*-*-*] } {
4617	return 0
4618    }
4619    return [check_no_compiler_messages arm_cortex_m assembly {
4620	#if defined(__ARM_ARCH_ISA_ARM)
4621	#error __ARM_ARCH_ISA_ARM is defined
4622	#endif
4623	int i;
4624    } "-mthumb"]
4625}
4626
4627# Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be
4628# used and MOVT/MOVW instructions to be available.
4629
4630proc check_effective_target_arm_thumb1_movt_ok {} {
4631    if [check_effective_target_arm_thumb1_ok] {
4632	return [check_no_compiler_messages arm_movt object {
4633	    int
4634	    foo (void)
4635	    {
4636	      asm ("movt r0, #42");
4637	    }
4638	} "-mthumb"]
4639    } else {
4640	return 0
4641    }
4642}
4643
4644# Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be
4645# used and CBZ and CBNZ instructions are available.
4646
4647proc check_effective_target_arm_thumb1_cbz_ok {} {
4648    if [check_effective_target_arm_thumb1_ok] {
4649	return [check_no_compiler_messages arm_movt object {
4650	    int
4651	    foo (void)
4652	    {
4653	      asm ("cbz r0, 2f\n2:");
4654	    }
4655	} "-mthumb"]
4656    } else {
4657	return 0
4658    }
4659}
4660
4661# Return 1 if this is an ARM target where ARMv8-M Security Extensions is
4662# available.
4663
4664proc check_effective_target_arm_cmse_ok {} {
4665    return [check_no_compiler_messages arm_cmse object {
4666	int
4667	foo (void)
4668	{
4669	  asm ("bxns r0");
4670	}
4671    } "-mcmse"];
4672}
4673
4674# Return 1 if the target supports executing MVE instructions, 0
4675# otherwise.
4676
4677proc check_effective_target_arm_mve_hw {} {
4678    return [check_runtime arm_mve_hw_available {
4679	int
4680	main (void)
4681	{
4682	  long long a = 16;
4683	  int b = 3;
4684	  asm ("sqrshrl %Q1, %R1, #64, %2"
4685	       : "=l" (a)
4686	       : "0" (a), "r" (b));
4687	  return (a != 2);
4688	}
4689    } ""]
4690}
4691
4692# Return 1 if this is an ARM target where ARMv8-M Security Extensions with
4693# clearing instructions (clrm, vscclrm, vstr/vldr with FPCXT) is available.
4694
4695proc check_effective_target_arm_cmse_clear_ok {} {
4696    return [check_no_compiler_messages arm_cmse_clear object {
4697	int
4698	foo (void)
4699	{
4700	  asm ("clrm {r1, r2}");
4701	}
4702    } "-mcmse"];
4703}
4704
4705# Return 1 if this compilation turns on string_ops_prefer_neon on.
4706
4707proc check_effective_target_arm_tune_string_ops_prefer_neon { } {
4708    return [check_no_messages_and_pattern arm_tune_string_ops_prefer_neon "@string_ops_prefer_neon:\t1" assembly {
4709	int foo (void) { return 0; }
4710    } "-O2 -mprint-tune-info" ]
4711}
4712
4713# Return 1 if the target supports executing NEON instructions, 0
4714# otherwise.  Cache the result.
4715
4716proc check_effective_target_arm_neon_hw { } {
4717    return [check_runtime arm_neon_hw_available {
4718	int
4719	main (void)
4720	{
4721	  long long a = 0, b = 1;
4722	  asm ("vorr %P0, %P1, %P2"
4723	       : "=w" (a)
4724	       : "0" (a), "w" (b));
4725	  return (a != 1);
4726	}
4727    } [add_options_for_arm_neon ""]]
4728}
4729
4730# Return true if this is an AArch64 target that can run SVE code.
4731
4732proc check_effective_target_aarch64_sve_hw { } {
4733    if { ![istarget aarch64*-*-*] } {
4734	return 0
4735    }
4736    return [check_runtime aarch64_sve_hw_available {
4737	int
4738	main (void)
4739	{
4740	  asm volatile ("ptrue p0.b");
4741	  return 0;
4742	}
4743    } [add_options_for_aarch64_sve ""]]
4744}
4745
4746# Return true if this is an AArch64 target that can run SVE2 code.
4747
4748proc check_effective_target_aarch64_sve2_hw { } {
4749    if { ![istarget aarch64*-*-*] } {
4750	return 0
4751    }
4752    return [check_runtime aarch64_sve2_hw_available {
4753	int
4754	main (void)
4755	{
4756	  asm volatile ("addp z0.b, p0/m, z0.b, z1.b");
4757	  return 0;
4758	}
4759    }]
4760}
4761
4762# Return true if this is an AArch64 target that can run SVE code and
4763# if its SVE vectors have exactly BITS bits.
4764
4765proc aarch64_sve_hw_bits { bits } {
4766    if { ![check_effective_target_aarch64_sve_hw] } {
4767	return 0
4768    }
4769    return [check_runtime aarch64_sve${bits}_hw [subst {
4770	int
4771	main (void)
4772	{
4773	  int res;
4774	  asm volatile ("cntd %0" : "=r" (res));
4775	  if (res * 64 != $bits)
4776	    __builtin_abort ();
4777	  return 0;
4778	}
4779    }] [add_options_for_aarch64_sve ""]]
4780}
4781
4782# Return true if this is an AArch64 target that can run SVE code and
4783# if its SVE vectors have exactly 256 bits.
4784
4785foreach N { 128 256 512 1024 2048 } {
4786    eval [string map [list N $N] {
4787	proc check_effective_target_aarch64_sveN_hw { } {
4788	    return [aarch64_sve_hw_bits N]
4789	}
4790    }]
4791}
4792
4793proc check_effective_target_arm_neonv2_hw { } {
4794    return [check_runtime arm_neon_hwv2_available {
4795	#include "arm_neon.h"
4796	int
4797	main (void)
4798	{
4799	  float32x2_t a, b, c;
4800	  asm ("vfma.f32 %P0, %P1, %P2"
4801	       : "=w" (a)
4802	       : "w" (b), "w" (c));
4803	  return 0;
4804	}
4805    } [add_options_for_arm_neonv2 ""]]
4806}
4807
4808# ID_AA64PFR1_EL1.BT using bits[3:0] == 1 implies BTI implimented.
4809proc check_effective_target_aarch64_bti_hw { } {
4810    if { ![istarget aarch64*-*-*] } {
4811	return 0
4812    }
4813    return [check_runtime aarch64_bti_hw_available {
4814	int
4815	main (void)
4816	{
4817	  int a;
4818	  asm volatile ("mrs %0, id_aa64pfr1_el1" : "=r" (a));
4819	  return !((a & 0xf) == 1);
4820	}
4821    } "-O2" ]
4822}
4823
4824# Return 1 if the target supports executing the armv8.3-a FJCVTZS
4825# instruction.
4826proc check_effective_target_aarch64_fjcvtzs_hw { } {
4827    if { ![istarget aarch64*-*-*] } {
4828	return 0
4829    }
4830    return [check_runtime aarch64_fjcvtzs_hw_available {
4831	int
4832	main (void)
4833	{
4834	  double in = 25.1;
4835	  int out;
4836	  asm volatile ("fjcvtzs %w0, %d1"
4837			: "=r" (out)
4838			: "w" (in)
4839			: /* No clobbers.  */);
4840	  return out != 25;
4841	}
4842    } "-march=armv8.3-a" ]
4843}
4844
4845# Return 1 if GCC was configured with --enable-standard-branch-protection
4846proc check_effective_target_default_branch_protection { } {
4847    return [check_configured_with "enable-standard-branch-protection"]
4848}
4849
4850# Return 1 if this is an ARM target supporting -mfloat-abi=softfp.
4851
4852proc check_effective_target_arm_softfp_ok { } {
4853    return [check_no_compiler_messages arm_softfp_ok object {
4854	#include <stdint.h>
4855	int dummy;
4856	int main (void) { return 0; }
4857	} "-mfloat-abi=softfp"]
4858}
4859
4860# Return 1 if this is an ARM target supporting -mfloat-abi=hard.
4861
4862proc check_effective_target_arm_hard_ok { } {
4863    return [check_no_compiler_messages arm_hard_ok object {
4864	#include <stdint.h>
4865	int dummy;
4866	int main (void) { return 0; }
4867	} "-mfloat-abi=hard"]
4868}
4869
4870# Return 1 if the target supports ARMv8.1-M MVE with floating point
4871# instructions, 0 otherwise.  The test is valid for ARM.
4872# Record the command line options needed.
4873
4874proc check_effective_target_arm_v8_1m_mve_fp_ok_nocache { } {
4875    global et_arm_v8_1m_mve_fp_flags
4876    set et_arm_v8_1m_mve_fp_flags ""
4877
4878    if { ![istarget arm*-*-*] } {
4879	return 0;
4880    }
4881
4882    # Iterate through sets of options to find the compiler flags that
4883    # need to be added to the -march option.
4884    foreach flags {"" "-mfloat-abi=hard -mfpu=auto -march=armv8.1-m.main+mve.fp" "-mfloat-abi=softfp -mfpu=auto -march=armv8.1-m.main+mve.fp"} {
4885	if { [check_no_compiler_messages_nocache \
4886		  arm_v8_1m_mve_fp_ok object {
4887	    #include <arm_mve.h>
4888	    #if !(__ARM_FEATURE_MVE & 2)
4889	    #error "__ARM_FEATURE_MVE for floating point not defined"
4890	    #endif
4891	    #if __ARM_BIG_ENDIAN
4892	    #error "MVE intrinsics are not supported in Big-Endian mode."
4893	    #endif
4894	} "$flags -mthumb"] } {
4895	    set et_arm_v8_1m_mve_fp_flags "$flags -mthumb --save-temps"
4896	    return 1
4897	}
4898    }
4899
4900    return 0;
4901}
4902
4903proc check_effective_target_arm_v8_1m_mve_fp_ok { } {
4904    return [check_cached_effective_target arm_v8_1m_mve_fp_ok \
4905		check_effective_target_arm_v8_1m_mve_fp_ok_nocache]
4906}
4907
4908proc add_options_for_arm_v8_1m_mve_fp { flags } {
4909    if { ! [check_effective_target_arm_v8_1m_mve_fp_ok] } {
4910	return "$flags"
4911    }
4912    global et_arm_v8_1m_mve_fp_flags
4913    return "$flags $et_arm_v8_1m_mve_fp_flags"
4914}
4915
4916# Return 1 if the target supports the ARMv8.1 Adv.SIMD extension, 0
4917# otherwise.  The test is valid for AArch64 and ARM.  Record the command
4918# line options needed.
4919
4920proc check_effective_target_arm_v8_1a_neon_ok_nocache { } {
4921    global et_arm_v8_1a_neon_flags
4922    set et_arm_v8_1a_neon_flags ""
4923
4924    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
4925	return 0;
4926    }
4927
4928    # Iterate through sets of options to find the compiler flags that
4929    # need to be added to the -march option.  Start with the empty set
4930    # since AArch64 only needs the -march setting.
4931    foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \
4932		       "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
4933	foreach arches { "-march=armv8-a+rdma" "-march=armv8.1-a" } {
4934	    if { [check_no_compiler_messages_nocache arm_v8_1a_neon_ok object {
4935		#if !defined (__ARM_FEATURE_QRDMX)
4936		#error "__ARM_FEATURE_QRDMX not defined"
4937		#endif
4938	    } "$flags $arches"] } {
4939		set et_arm_v8_1a_neon_flags "$flags $arches"
4940		return 1
4941	    }
4942	}
4943    }
4944
4945    return 0;
4946}
4947
4948proc check_effective_target_arm_v8_1a_neon_ok { } {
4949    return [check_cached_effective_target arm_v8_1a_neon_ok \
4950		check_effective_target_arm_v8_1a_neon_ok_nocache]
4951}
4952
4953# Return 1 if the target supports ARMv8.2 scalar FP16 arithmetic
4954# instructions, 0 otherwise.  The test is valid for ARM and for AArch64.
4955# Record the command line options needed.
4956
4957proc check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache { } {
4958    global et_arm_v8_2a_fp16_scalar_flags
4959    set et_arm_v8_2a_fp16_scalar_flags ""
4960
4961    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
4962	return 0;
4963    }
4964
4965    # Iterate through sets of options to find the compiler flags that
4966    # need to be added to the -march option.
4967    foreach flags {"" "-mfpu=fp-armv8" "-mfloat-abi=softfp" \
4968		       "-mfpu=fp-armv8 -mfloat-abi=softfp"} {
4969	if { [check_no_compiler_messages_nocache \
4970		  arm_v8_2a_fp16_scalar_ok object {
4971	    #if !defined (__ARM_FEATURE_FP16_SCALAR_ARITHMETIC)
4972	    #error "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC not defined"
4973	    #endif
4974	} "$flags -march=armv8.2-a+fp16"] } {
4975	    set et_arm_v8_2a_fp16_scalar_flags "$flags -march=armv8.2-a+fp16"
4976	    return 1
4977	}
4978    }
4979
4980    return 0;
4981}
4982
4983proc check_effective_target_arm_v8_2a_fp16_scalar_ok { } {
4984    return [check_cached_effective_target arm_v8_2a_fp16_scalar_ok \
4985		check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache]
4986}
4987
4988# Return 1 if the target supports ARMv8.2 Adv.SIMD FP16 arithmetic
4989# instructions, 0 otherwise.  The test is valid for ARM and for AArch64.
4990# Record the command line options needed.
4991
4992proc check_effective_target_arm_v8_2a_fp16_neon_ok_nocache { } {
4993    global et_arm_v8_2a_fp16_neon_flags
4994    set et_arm_v8_2a_fp16_neon_flags ""
4995
4996    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
4997	return 0;
4998    }
4999
5000    # Iterate through sets of options to find the compiler flags that
5001    # need to be added to the -march option.
5002    foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \
5003		       "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
5004	if { [check_no_compiler_messages_nocache \
5005		  arm_v8_2a_fp16_neon_ok object {
5006	    #if !defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
5007	    #error "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC not defined"
5008	    #endif
5009	} "$flags -march=armv8.2-a+fp16"] } {
5010	    set et_arm_v8_2a_fp16_neon_flags "$flags -march=armv8.2-a+fp16"
5011	    return 1
5012	}
5013    }
5014
5015    return 0;
5016}
5017
5018proc check_effective_target_arm_v8_2a_fp16_neon_ok { } {
5019    return [check_cached_effective_target arm_v8_2a_fp16_neon_ok \
5020		check_effective_target_arm_v8_2a_fp16_neon_ok_nocache]
5021}
5022
5023# Return 1 if the target supports ARMv8.2 Adv.SIMD Dot Product
5024# instructions, 0 otherwise.  The test is valid for ARM and for AArch64.
5025# Record the command line options needed.
5026
5027proc check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache { } {
5028    global et_arm_v8_2a_dotprod_neon_flags
5029    set et_arm_v8_2a_dotprod_neon_flags ""
5030
5031    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
5032        return 0;
5033    }
5034
5035    # Iterate through sets of options to find the compiler flags that
5036    # need to be added to the -march option.
5037    foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8"} {
5038        if { [check_no_compiler_messages_nocache \
5039                  arm_v8_2a_dotprod_neon_ok object {
5040	    #include <stdint.h>
5041            #if !defined (__ARM_FEATURE_DOTPROD)
5042            #error "__ARM_FEATURE_DOTPROD not defined"
5043            #endif
5044        } "$flags -march=armv8.2-a+dotprod"] } {
5045            set et_arm_v8_2a_dotprod_neon_flags "$flags -march=armv8.2-a+dotprod"
5046            return 1
5047        }
5048    }
5049
5050    return 0;
5051}
5052
5053# Return 1 if the target supports ARMv8.1-M MVE
5054# instructions, 0 otherwise.  The test is valid for ARM.
5055# Record the command line options needed.
5056
5057proc check_effective_target_arm_v8_1m_mve_ok_nocache { } {
5058    global et_arm_v8_1m_mve_flags
5059    set et_arm_v8_1m_mve_flags ""
5060
5061    if { ![istarget arm*-*-*] } {
5062        return 0;
5063    }
5064
5065    # Iterate through sets of options to find the compiler flags that
5066    # need to be added to the -march option.
5067    foreach flags {"" "-mfloat-abi=hard -mfpu=auto -march=armv8.1-m.main+mve" "-mfloat-abi=softfp -mfpu=auto -march=armv8.1-m.main+mve"} {
5068        if { [check_no_compiler_messages_nocache \
5069                  arm_v8_1m_mve_ok object {
5070            #if !defined (__ARM_FEATURE_MVE)
5071            #error "__ARM_FEATURE_MVE not defined"
5072            #endif
5073	    #if __ARM_BIG_ENDIAN
5074	    #error "MVE intrinsics are not supported in Big-Endian mode."
5075	    #endif
5076	    #include <arm_mve.h>
5077        } "$flags -mthumb"] } {
5078            set et_arm_v8_1m_mve_flags "$flags -mthumb --save-temps"
5079            return 1
5080        }
5081    }
5082
5083    return 0;
5084}
5085
5086proc check_effective_target_arm_v8_1m_mve_ok { } {
5087    return [check_cached_effective_target arm_v8_1m_mve_ok \
5088                check_effective_target_arm_v8_1m_mve_ok_nocache]
5089}
5090
5091proc add_options_for_arm_v8_1m_mve { flags } {
5092    if { ! [check_effective_target_arm_v8_1m_mve_ok] } {
5093        return "$flags"
5094    }
5095    global et_arm_v8_1m_mve_flags
5096    return "$flags $et_arm_v8_1m_mve_flags"
5097}
5098
5099proc check_effective_target_arm_v8_2a_dotprod_neon_ok { } {
5100    return [check_cached_effective_target arm_v8_2a_dotprod_neon_ok \
5101                check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache]
5102}
5103
5104proc add_options_for_arm_v8_2a_dotprod_neon { flags } {
5105    if { ! [check_effective_target_arm_v8_2a_dotprod_neon_ok] } {
5106        return "$flags"
5107    }
5108    global et_arm_v8_2a_dotprod_neon_flags
5109    return "$flags $et_arm_v8_2a_dotprod_neon_flags"
5110}
5111
5112# Return 1 if the target supports ARMv8.2+i8mm Adv.SIMD Dot Product
5113# instructions, 0 otherwise.  The test is valid for ARM and for AArch64.
5114# Record the command line options needed.
5115
5116proc check_effective_target_arm_v8_2a_i8mm_ok_nocache { } {
5117    global et_arm_v8_2a_i8mm_flags
5118    set et_arm_v8_2a_i8mm_flags ""
5119
5120    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
5121        return 0;
5122    }
5123
5124    # Iterate through sets of options to find the compiler flags that
5125    # need to be added to the -march option.
5126    foreach flags {"" "-mfloat-abi=hard -mfpu=neon-fp-armv8" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" } {
5127        if { [check_no_compiler_messages_nocache \
5128                  arm_v8_2a_i8mm_ok object {
5129            #include <arm_neon.h>
5130            #if !defined (__ARM_FEATURE_MATMUL_INT8)
5131            #error "__ARM_FEATURE_MATMUL_INT8 not defined"
5132            #endif
5133        } "$flags -march=armv8.2-a+i8mm"] } {
5134            set et_arm_v8_2a_i8mm_flags "$flags -march=armv8.2-a+i8mm"
5135            return 1
5136        }
5137    }
5138
5139    return 0;
5140}
5141
5142proc check_effective_target_arm_v8_2a_i8mm_ok { } {
5143    return [check_cached_effective_target arm_v8_2a_i8mm_ok \
5144                check_effective_target_arm_v8_2a_i8mm_ok_nocache]
5145}
5146
5147proc add_options_for_arm_v8_2a_i8mm { flags } {
5148    if { ! [check_effective_target_arm_v8_2a_i8mm_ok] } {
5149        return "$flags"
5150    }
5151    global et_arm_v8_2a_i8mm_flags
5152    return "$flags $et_arm_v8_2a_i8mm_flags"
5153}
5154
5155# Return 1 if the target supports FP16 VFMAL and VFMSL
5156# instructions, 0 otherwise.
5157# Record the command line options needed.
5158
5159proc check_effective_target_arm_fp16fml_neon_ok_nocache { } {
5160    global et_arm_fp16fml_neon_flags
5161    set et_arm_fp16fml_neon_flags ""
5162
5163    if { ![istarget arm*-*-*] } {
5164        return 0;
5165    }
5166
5167    # Iterate through sets of options to find the compiler flags that
5168    # need to be added to the -march option.
5169    foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8"} {
5170        if { [check_no_compiler_messages_nocache \
5171                  arm_fp16fml_neon_ok assembly {
5172		#include <arm_neon.h>
5173		float32x2_t
5174		foo (float32x2_t r, float16x4_t a, float16x4_t b)
5175		{
5176		  return vfmlal_high_f16 (r, a, b);
5177		}
5178        } "$flags -march=armv8.2-a+fp16fml"] } {
5179            set et_arm_fp16fml_neon_flags "$flags -march=armv8.2-a+fp16fml"
5180            return 1
5181        }
5182    }
5183
5184    return 0;
5185}
5186
5187proc check_effective_target_arm_fp16fml_neon_ok { } {
5188    return [check_cached_effective_target arm_fp16fml_neon_ok \
5189                check_effective_target_arm_fp16fml_neon_ok_nocache]
5190}
5191
5192proc add_options_for_arm_fp16fml_neon { flags } {
5193    if { ! [check_effective_target_arm_fp16fml_neon_ok] } {
5194        return "$flags"
5195    }
5196    global et_arm_fp16fml_neon_flags
5197    return "$flags $et_arm_fp16fml_neon_flags"
5198}
5199
5200# Return 1 if the target supports BFloat16 SIMD instructions, 0 otherwise.
5201# The test is valid for ARM and for AArch64.
5202
5203proc check_effective_target_arm_v8_2a_bf16_neon_ok_nocache { } {
5204    global et_arm_v8_2a_bf16_neon_flags
5205    set et_arm_v8_2a_bf16_neon_flags ""
5206
5207    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
5208        return 0;
5209    }
5210
5211    foreach flags {"" "-mfloat-abi=hard -mfpu=neon-fp-armv8" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" } {
5212        if { [check_no_compiler_messages_nocache arm_v8_2a_bf16_neon_ok object {
5213            #include <arm_neon.h>
5214            #if !defined (__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)
5215            #error "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC not defined"
5216            #endif
5217        } "$flags -march=armv8.2-a+bf16"] } {
5218            set et_arm_v8_2a_bf16_neon_flags "$flags -march=armv8.2-a+bf16"
5219            return 1
5220        }
5221    }
5222
5223    return 0;
5224}
5225
5226proc check_effective_target_arm_v8_2a_bf16_neon_ok { } {
5227    return [check_cached_effective_target arm_v8_2a_bf16_neon_ok \
5228                check_effective_target_arm_v8_2a_bf16_neon_ok_nocache]
5229}
5230
5231proc add_options_for_arm_v8_2a_bf16_neon { flags } {
5232    if { ! [check_effective_target_arm_v8_2a_bf16_neon_ok] } {
5233        return "$flags"
5234    }
5235    global et_arm_v8_2a_bf16_neon_flags
5236    return "$flags $et_arm_v8_2a_bf16_neon_flags"
5237}
5238
5239# A series of routines are created to 1) check if a given architecture is
5240# effective (check_effective_target_*_ok) and then 2) give the corresponding
5241# flags that enable the architecture (add_options_for_*).
5242# The series includes:
5243#   arm_v8m_main_cde: Armv8-m CDE (Custom Datapath Extension).
5244#   arm_v8m_main_cde_fp: Armv8-m CDE with FP registers.
5245#   arm_v8_1m_main_cde_mve: Armv8.1-m CDE with MVE.
5246# Usage:
5247#   /* { dg-require-effective-target arm_v8m_main_cde_ok } */
5248#   /* { dg-add-options arm_v8m_main_cde } */
5249# The tests are valid for Arm.
5250
5251foreach { armfunc armflag armdef arminc } {
5252	arm_v8m_main_cde
5253		"-march=armv8-m.main+cdecp0+cdecp6 -mthumb"
5254		"defined (__ARM_FEATURE_CDE)"
5255		""
5256	arm_v8m_main_cde_fp
5257		"-march=armv8-m.main+fp+cdecp0+cdecp6 -mthumb -mfpu=auto"
5258		"defined (__ARM_FEATURE_CDE) && defined (__ARM_FP)"
5259		""
5260	arm_v8_1m_main_cde_mve
5261		"-march=armv8.1-m.main+mve+cdecp0+cdecp6 -mthumb -mfpu=auto"
5262		"defined (__ARM_FEATURE_CDE) && defined (__ARM_FEATURE_MVE)"
5263		"#include <arm_mve.h>"
5264	arm_v8_1m_main_cde_mve_fp
5265		"-march=armv8.1-m.main+mve.fp+cdecp0+cdecp6 -mthumb -mfpu=auto"
5266		"defined (__ARM_FEATURE_CDE) || __ARM_FEATURE_MVE == 3"
5267		"#include <arm_mve.h>"
5268	} {
5269    eval [string map [list FUNC $armfunc FLAG $armflag DEF $armdef INC $arminc ] {
5270	proc check_effective_target_FUNC_ok_nocache { } {
5271	    global et_FUNC_flags
5272	    set et_FUNC_flags ""
5273
5274	    if { ![istarget arm*-*-*] } {
5275		return 0;
5276	    }
5277
5278	    if { [check_no_compiler_messages_nocache FUNC_ok assembly {
5279		#if !(DEF)
5280		#error "DEF failed"
5281		#endif
5282		#include <arm_cde.h>
5283		INC
5284	    } "FLAG"] } {
5285		    set et_FUNC_flags "FLAG"
5286		    return 1
5287	    }
5288
5289	    return 0;
5290	}
5291
5292	proc check_effective_target_FUNC_ok { } {
5293	    return [check_cached_effective_target FUNC_ok \
5294		    check_effective_target_FUNC_ok_nocache]
5295	}
5296
5297	proc add_options_for_FUNC { flags } {
5298	    if { ! [check_effective_target_FUNC_ok] } {
5299		return "$flags"
5300	    }
5301	    global et_FUNC_flags
5302	    return "$flags $et_FUNC_flags"
5303	}
5304    }]
5305}
5306
5307# Return 1 if the target supports executing ARMv8 NEON instructions, 0
5308# otherwise.
5309
5310proc check_effective_target_arm_v8_neon_hw { } {
5311    return [check_runtime arm_v8_neon_hw_available {
5312        #include "arm_neon.h"
5313	int
5314	main (void)
5315	{
5316	  float32x2_t a = { 1.0f, 2.0f };
5317	  #ifdef __ARM_ARCH_ISA_A64
5318	  asm ("frinta %0.2s, %1.2s"
5319	      : "=w" (a)
5320	      : "w" (a));
5321	  #else
5322	  asm ("vrinta.f32 %P0, %P1"
5323	       : "=w" (a)
5324	       : "0" (a));
5325	  #endif
5326	  return a[0] == 2.0f;
5327	}
5328    } [add_options_for_arm_v8_neon ""]]
5329}
5330
5331# Return 1 if the target supports executing the ARMv8.1 Adv.SIMD extension, 0
5332# otherwise.  The test is valid for AArch64 and ARM.
5333
5334proc check_effective_target_arm_v8_1a_neon_hw { } {
5335    if { ![check_effective_target_arm_v8_1a_neon_ok] } {
5336	return 0;
5337    }
5338    return [check_runtime arm_v8_1a_neon_hw_available {
5339	int
5340	main (void)
5341	{
5342	  #ifdef __ARM_ARCH_ISA_A64
5343	  __Int32x2_t a = {0, 1};
5344	  __Int32x2_t b = {0, 2};
5345	  __Int32x2_t result;
5346
5347	  asm ("sqrdmlah %0.2s, %1.2s, %2.2s"
5348	       : "=w"(result)
5349	       : "w"(a), "w"(b)
5350	       : /* No clobbers.  */);
5351
5352	  #else
5353
5354	  __simd64_int32_t a = {0, 1};
5355	  __simd64_int32_t b = {0, 2};
5356	  __simd64_int32_t result;
5357
5358	  asm ("vqrdmlah.s32 %P0, %P1, %P2"
5359	       : "=w"(result)
5360	       : "w"(a), "w"(b)
5361	       : /* No clobbers.  */);
5362	  #endif
5363
5364	  return result[0];
5365	}
5366    } [add_options_for_arm_v8_1a_neon ""]]
5367}
5368
5369# Return 1 if the target supports executing floating point instructions from
5370# ARMv8.2 with the FP16 extension, 0 otherwise.  The test is valid for ARM and
5371# for AArch64.
5372
5373proc check_effective_target_arm_v8_2a_fp16_scalar_hw { } {
5374    if { ![check_effective_target_arm_v8_2a_fp16_scalar_ok] } {
5375	return 0;
5376    }
5377    return [check_runtime arm_v8_2a_fp16_scalar_hw_available {
5378	int
5379	main (void)
5380	{
5381	  __fp16 a = 1.0;
5382	  __fp16 result;
5383
5384	  #ifdef __ARM_ARCH_ISA_A64
5385
5386	  asm ("fabs %h0, %h1"
5387	       : "=w"(result)
5388	       : "w"(a)
5389	       : /* No clobbers.  */);
5390
5391	  #else
5392
5393	  asm ("vabs.f16 %0, %1"
5394	       : "=w"(result)
5395	       : "w"(a)
5396	       : /* No clobbers.  */);
5397
5398	  #endif
5399
5400	  return (result == 1.0) ? 0 : 1;
5401	}
5402    } [add_options_for_arm_v8_2a_fp16_scalar ""]]
5403}
5404
5405# Return 1 if the target supports executing Adv.SIMD instructions from ARMv8.2
5406# with the FP16 extension, 0 otherwise.  The test is valid for ARM and for
5407# AArch64.
5408
5409proc check_effective_target_arm_v8_2a_fp16_neon_hw { } {
5410    if { ![check_effective_target_arm_v8_2a_fp16_neon_ok] } {
5411	return 0;
5412    }
5413    return [check_runtime arm_v8_2a_fp16_neon_hw_available {
5414	int
5415	main (void)
5416	{
5417	  #ifdef __ARM_ARCH_ISA_A64
5418
5419	  __Float16x4_t a = {1.0, -1.0, 1.0, -1.0};
5420	  __Float16x4_t result;
5421
5422	  asm ("fabs %0.4h, %1.4h"
5423	       : "=w"(result)
5424	       : "w"(a)
5425	       : /* No clobbers.  */);
5426
5427	  #else
5428
5429	  __simd64_float16_t a = {1.0, -1.0, 1.0, -1.0};
5430	  __simd64_float16_t result;
5431
5432	  asm ("vabs.f16 %P0, %P1"
5433	       : "=w"(result)
5434	       : "w"(a)
5435	       : /* No clobbers.  */);
5436
5437	  #endif
5438
5439	  return (result[0] == 1.0) ? 0 : 1;
5440	}
5441    } [add_options_for_arm_v8_2a_fp16_neon ""]]
5442}
5443
5444# Return 1 if the target supports executing AdvSIMD instructions from ARMv8.2
5445# with the Dot Product extension, 0 otherwise.  The test is valid for ARM and for
5446# AArch64.
5447
5448proc check_effective_target_arm_v8_2a_dotprod_neon_hw { } {
5449    if { ![check_effective_target_arm_v8_2a_dotprod_neon_ok] } {
5450        return 0;
5451    }
5452    return [check_runtime arm_v8_2a_dotprod_neon_hw_available {
5453        #include "arm_neon.h"
5454        int
5455        main (void)
5456        {
5457
5458	  uint32x2_t results = {0,0};
5459	  uint8x8_t a = {1,1,1,1,2,2,2,2};
5460	  uint8x8_t b = {2,2,2,2,3,3,3,3};
5461
5462          #ifdef __ARM_ARCH_ISA_A64
5463          asm ("udot %0.2s, %1.8b, %2.8b"
5464               : "=w"(results)
5465               : "w"(a), "w"(b)
5466               : /* No clobbers.  */);
5467
5468	  #else
5469          asm ("vudot.u8 %P0, %P1, %P2"
5470               : "=w"(results)
5471               : "w"(a), "w"(b)
5472               : /* No clobbers.  */);
5473          #endif
5474
5475          return (results[0] == 8 && results[1] == 24) ? 1 : 0;
5476        }
5477    } [add_options_for_arm_v8_2a_dotprod_neon ""]]
5478}
5479
5480# Return 1 if this is a ARM target with NEON enabled.
5481
5482proc check_effective_target_arm_neon { } {
5483    if { [check_effective_target_arm32] } {
5484	return [check_no_compiler_messages arm_neon object {
5485	    #ifndef __ARM_NEON__
5486	    #error not NEON
5487	    #else
5488	    int dummy;
5489	    #endif
5490	}]
5491    } else {
5492	return 0
5493    }
5494}
5495
5496proc check_effective_target_arm_neonv2 { } {
5497    if { [check_effective_target_arm32] } {
5498	return [check_no_compiler_messages arm_neon object {
5499	    #ifndef __ARM_NEON__
5500	    #error not NEON
5501	    #else
5502	    #ifndef __ARM_FEATURE_FMA
5503	    #error not NEONv2
5504            #else
5505	    int dummy;
5506	    #endif
5507	    #endif
5508	}]
5509    } else {
5510	return 0
5511    }
5512}
5513
5514# Return 1 if this is an ARM target with load acquire and store release
5515# instructions for 8-, 16- and 32-bit types.
5516
5517proc check_effective_target_arm_acq_rel { } {
5518    return [check_no_compiler_messages arm_acq_rel object {
5519	void
5520	load_acquire_store_release (void)
5521	{
5522	  asm ("lda r0, [r1]\n\t"
5523	       "stl r0, [r1]\n\t"
5524	       "ldah r0, [r1]\n\t"
5525	       "stlh r0, [r1]\n\t"
5526	       "ldab r0, [r1]\n\t"
5527	       "stlb r0, [r1]"
5528	       : : : "r0", "memory");
5529	}
5530    }]
5531}
5532
5533# Add the options needed for MIPS Paired-Single.
5534
5535proc add_options_for_mpaired_single { flags } {
5536    if { ! [check_effective_target_mpaired_single] } {
5537	return "$flags"
5538    }
5539    return "$flags -mpaired-single"
5540}
5541
5542# Add the options needed for MIPS SIMD Architecture.
5543
5544proc add_options_for_mips_msa { flags } {
5545  if { ! [check_effective_target_mips_msa] } {
5546    return "$flags"
5547  }
5548  return "$flags -mmsa"
5549}
5550
5551# Add the options needed for MIPS Loongson MMI Architecture.
5552
5553proc add_options_for_mips_loongson_mmi { flags } {
5554  if { ! [check_effective_target_mips_loongson_mmi] } {
5555    return "$flags"
5556  }
5557  return "$flags -mloongson-mmi"
5558}
5559
5560
5561# Return 1 if this a Loongson-2E or -2F target using an ABI that supports
5562# the Loongson vector modes.
5563
5564proc check_effective_target_mips_loongson_mmi { } {
5565    return [check_no_compiler_messages loongson assembly {
5566	#if !defined(__mips_loongson_mmi)
5567	#error !__mips_loongson_mmi
5568	#endif
5569	#if !defined(__mips_loongson_vector_rev)
5570	#error !__mips_loongson_vector_rev
5571	#endif
5572    }]
5573}
5574
5575# Return 1 if this is a MIPS target that supports the legacy NAN.
5576
5577proc check_effective_target_mips_nanlegacy { } {
5578    return [check_no_compiler_messages nanlegacy assembly {
5579	#include <stdlib.h>
5580	int main () { return 0; }
5581    } "-mnan=legacy"]
5582}
5583
5584# Return 1 if an MSA program can be compiled to object
5585
5586proc check_effective_target_mips_msa { } {
5587  if ![check_effective_target_nomips16] {
5588    return 0
5589  }
5590  return [check_no_compiler_messages msa object {
5591    #if !defined(__mips_msa)
5592    #error "MSA NOT AVAIL"
5593    #else
5594    #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2))
5595    #error "MSA NOT AVAIL FOR ISA REV < 2"
5596    #endif
5597    #if !defined(__mips_hard_float)
5598    #error "MSA HARD_FLOAT REQUIRED"
5599    #endif
5600    #if __mips_fpr != 64
5601    #error "MSA 64-bit FPR REQUIRED"
5602    #endif
5603    #include <msa.h>
5604
5605    int main()
5606    {
5607      v8i16 v = __builtin_msa_ldi_h (1);
5608
5609      return v[0];
5610    }
5611    #endif
5612  } "-mmsa" ]
5613}
5614
5615# Return 1 if this is an ARM target that adheres to the ABI for the ARM
5616# Architecture.
5617
5618proc check_effective_target_arm_eabi { } {
5619    return [check_no_compiler_messages arm_eabi object {
5620	#ifndef __ARM_EABI__
5621	#error not EABI
5622	#else
5623	int dummy;
5624	#endif
5625    }]
5626}
5627
5628# Return 1 if this is an ARM target that adheres to the hard-float variant of
5629# the ABI for the ARM Architecture (e.g. -mfloat-abi=hard).
5630
5631proc check_effective_target_arm_hf_eabi { } {
5632    return [check_no_compiler_messages arm_hf_eabi object {
5633	#if !defined(__ARM_EABI__) || !defined(__ARM_PCS_VFP)
5634	#error not hard-float EABI
5635	#else
5636	int dummy;
5637	#endif
5638    }]
5639}
5640
5641# Return 1 if this is an ARM target that uses the soft float ABI
5642# with no floating-point instructions at all (e.g. -mfloat-abi=soft).
5643
5644proc check_effective_target_arm_softfloat { } {
5645    return [check_no_compiler_messages arm_softfloat object {
5646	#if !defined(__SOFTFP__)
5647	#error not soft-float EABI
5648	#else
5649	int dummy;
5650	#endif
5651    }]
5652}
5653
5654# Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
5655# Some multilibs may be incompatible with this option.
5656
5657proc check_effective_target_arm_iwmmxt_ok { } {
5658    if { [check_effective_target_arm32] } {
5659	return [check_no_compiler_messages arm_iwmmxt_ok object {
5660	    int dummy;
5661	} "-mcpu=iwmmxt"]
5662    } else {
5663	return 0
5664    }
5665}
5666
5667# Return true if LDRD/STRD instructions are prefered over LDM/STM instructions
5668# for an ARM target.
5669proc check_effective_target_arm_prefer_ldrd_strd { } {
5670    if { ![check_effective_target_arm32] } {
5671      return 0;
5672    }
5673
5674    return [check_no_messages_and_pattern arm_prefer_ldrd_strd "strd\tr" assembly {
5675        void foo (void) { __asm__ ("" ::: "r4", "r5"); }
5676    }  "-O2 -mthumb" ]
5677}
5678
5679# Return true if LDRD/STRD instructions are available on this target.
5680proc check_effective_target_arm_ldrd_strd_ok { } {
5681    if { ![check_effective_target_arm32] } {
5682      return 0;
5683    }
5684
5685    return [check_no_compiler_messages arm_ldrd_strd_ok object {
5686      int main(void)
5687      {
5688        __UINT64_TYPE__ a = 1, b = 10;
5689        __UINT64_TYPE__ *c = &b;
5690        // `a` will be in a valid register since it's a DImode quantity.
5691        asm ("ldrd %0, %1"
5692             : "=r" (a)
5693             : "m" (c));
5694        return a == 10;
5695      }
5696    }]
5697}
5698
5699# Return 1 if this is a PowerPC target supporting -meabi.
5700
5701proc check_effective_target_powerpc_eabi_ok { } {
5702    if { [istarget powerpc*-*-*] } {
5703	return [check_no_compiler_messages powerpc_eabi_ok object {
5704	    int dummy;
5705	} "-meabi"]
5706    } else {
5707	return 0
5708    }
5709}
5710
5711# Return 1 if this is a PowerPC target with floating-point registers.
5712
5713proc check_effective_target_powerpc_fprs { } {
5714    if { [istarget powerpc*-*-*]
5715	 || [istarget rs6000-*-*] } {
5716	return [check_no_compiler_messages powerpc_fprs object {
5717	    #ifdef __NO_FPRS__
5718	    #error no FPRs
5719	    #else
5720	    int dummy;
5721	    #endif
5722	}]
5723    } else {
5724	return 0
5725    }
5726}
5727
5728# Return 1 if this is a PowerPC target with hardware double-precision
5729# floating point.
5730
5731proc check_effective_target_powerpc_hard_double { } {
5732    if { [istarget powerpc*-*-*]
5733	 || [istarget rs6000-*-*] } {
5734	return [check_no_compiler_messages powerpc_hard_double object {
5735	    #ifdef _SOFT_DOUBLE
5736	    #error soft double
5737	    #else
5738	    int dummy;
5739	    #endif
5740	}]
5741    } else {
5742	return 0
5743    }
5744}
5745
5746# Return 1 if this is a PowerPC target supporting -maltivec.
5747
5748proc check_effective_target_powerpc_altivec_ok { } {
5749    if { ([istarget powerpc*-*-*]
5750         && ![istarget powerpc-*-linux*paired*])
5751	 || [istarget rs6000-*-*] } {
5752	# AltiVec is not supported on AIX before 5.3.
5753	if { [istarget powerpc*-*-aix4*]
5754	     || [istarget powerpc*-*-aix5.1*]
5755	     || [istarget powerpc*-*-aix5.2*] } {
5756	    return 0
5757	}
5758	return [check_no_compiler_messages powerpc_altivec_ok object {
5759	    int dummy;
5760	} "-maltivec"]
5761    } else {
5762	return 0
5763    }
5764}
5765
5766# Return 1 if this is a PowerPC target supporting -mpower8-vector
5767
5768proc check_effective_target_powerpc_p8vector_ok { } {
5769    if { ([istarget powerpc*-*-*]
5770         && ![istarget powerpc-*-linux*paired*])
5771	 || [istarget rs6000-*-*] } {
5772	# AltiVec is not supported on AIX before 5.3.
5773	if { [istarget powerpc*-*-aix4*]
5774	     || [istarget powerpc*-*-aix5.1*]
5775	     || [istarget powerpc*-*-aix5.2*] } {
5776	    return 0
5777	}
5778	# Darwin doesn't run on power8, so far.
5779	if { [istarget *-*-darwin*] } {
5780	    return 0
5781	}
5782	return [check_no_compiler_messages powerpc_p8vector_ok object {
5783	    int main (void) {
5784		asm volatile ("xxlorc 0,0,0");
5785		return 0;
5786	    }
5787	} "-mpower8-vector"]
5788    } else {
5789	return 0
5790    }
5791}
5792
5793# Return 1 if this is a PowerPC target supporting -mpower9-vector
5794
5795proc check_effective_target_powerpc_p9vector_ok { } {
5796    if { ([istarget powerpc*-*-*]
5797         && ![istarget powerpc-*-linux*paired*])
5798	 || [istarget rs6000-*-*] } {
5799	# AltiVec is not supported on AIX before 5.3.
5800	if { [istarget powerpc*-*-aix4*]
5801	     || [istarget powerpc*-*-aix5.1*]
5802	     || [istarget powerpc*-*-aix5.2*] } {
5803	    return 0
5804	}
5805	# Darwin doesn't run on power9, so far.
5806	if { [istarget *-*-darwin*] } {
5807	    return 0
5808	}
5809	return [check_no_compiler_messages powerpc_p9vector_ok object {
5810	    int main (void) {
5811		long e = -1;
5812		vector double v = (vector double) { 0.0, 0.0 };
5813		asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v));
5814		return e;
5815	    }
5816	} "-mpower9-vector"]
5817    } else {
5818	return 0
5819    }
5820}
5821
5822# Return 1 if this is a PowerPC target supporting -mmodulo
5823
5824proc check_effective_target_powerpc_p9modulo_ok { } {
5825    if { ([istarget powerpc*-*-*]
5826         && ![istarget powerpc-*-linux*paired*])
5827	 || [istarget rs6000-*-*] } {
5828	# AltiVec is not supported on AIX before 5.3.
5829	if { [istarget powerpc*-*-aix4*]
5830	     || [istarget powerpc*-*-aix5.1*]
5831	     || [istarget powerpc*-*-aix5.2*] } {
5832	    return 0
5833	}
5834	return [check_no_compiler_messages powerpc_p9modulo_ok object {
5835	    int main (void) {
5836		int i = 5, j = 3, r = -1;
5837		asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j));
5838		return (r == 2);
5839	    }
5840	} "-mmodulo"]
5841    } else {
5842	return 0
5843    }
5844}
5845
5846# return 1 if our compiler returns the ARCH_PWR defines with the options
5847# as provided by the test.
5848proc check_effective_target_has_arch_pwr5 { } {
5849	return [check_no_compiler_messages arch_pwr5 assembly {
5850		#ifndef _ARCH_PWR5
5851		#error does not have power5 support.
5852		#else
5853		/* "has power5 support" */
5854		#endif
5855	}]
5856}
5857
5858proc check_effective_target_has_arch_pwr6 { } {
5859	return [check_no_compiler_messages arch_pwr6 assembly {
5860		#ifndef _ARCH_PWR6
5861		#error does not have power6 support.
5862		#else
5863		/* "has power6 support" */
5864		#endif
5865	}]
5866}
5867
5868proc check_effective_target_has_arch_pwr7 { } {
5869	return [check_no_compiler_messages arch_pwr7 assembly {
5870		#ifndef _ARCH_PWR7
5871		#error does not have power7 support.
5872		#else
5873		/* "has power7 support" */
5874		#endif
5875	}]
5876}
5877
5878proc check_effective_target_has_arch_pwr8 { } {
5879	return [check_no_compiler_messages arch_pwr8 assembly {
5880		#ifndef _ARCH_PWR8
5881		#error does not have power8 support.
5882		#else
5883		/* "has power8 support" */
5884		#endif
5885	}]
5886}
5887
5888proc check_effective_target_has_arch_pwr9 { } {
5889	return [check_no_compiler_messages arch_pwr9 assembly {
5890		#ifndef _ARCH_PWR9
5891		#error does not have power9 support.
5892		#else
5893		/* "has power9 support" */
5894		#endif
5895	}]
5896}
5897
5898# Return 1 if this is a PowerPC target supporting -mcpu=power10.
5899# Limit this to 64-bit linux systems for now until other targets support
5900# power10.
5901
5902proc check_effective_target_power10_ok { } {
5903    if { ([istarget powerpc64*-*-linux*]) } {
5904	return [check_no_compiler_messages power10_ok object {
5905	    int main (void) {
5906		long e;
5907		asm ("pli %0,%1" : "=r" (e) : "n" (0x12345));
5908		return e;
5909	    }
5910	} "-mcpu=power10"]
5911    } else {
5912	return 0
5913    }
5914}
5915
5916# Return 1 if this is a PowerPC target supporting -mfloat128 via either
5917# software emulation on power7/power8 systems or hardware support on power9.
5918
5919proc check_effective_target_powerpc_float128_sw_ok { } {
5920    if { ([istarget powerpc*-*-*]
5921         && ![istarget powerpc-*-linux*paired*])
5922	 || [istarget rs6000-*-*] } {
5923	# AltiVec is not supported on AIX before 5.3.
5924	if { [istarget powerpc*-*-aix4*]
5925	     || [istarget powerpc*-*-aix5.1*]
5926	     || [istarget powerpc*-*-aix5.2*] } {
5927	    return 0
5928	}
5929	# Darwin doesn't have VSX, so no soft support for float128.
5930	if { [istarget *-*-darwin*] } {
5931	    return 0
5932	}
5933	return [check_no_compiler_messages powerpc_float128_sw_ok object {
5934		volatile __float128 x = 1.0q;
5935		volatile __float128 y = 2.0q;
5936		int main() {
5937		    __float128 z = x + y;
5938		    return (z == 3.0q);
5939		}
5940	    } "-mfloat128 -mvsx"]
5941    } else {
5942	return 0
5943    }
5944}
5945
5946# Return 1 if this is a PowerPC target supporting -mfloat128 via hardware
5947# support on power9.
5948
5949proc check_effective_target_powerpc_float128_hw_ok { } {
5950    if { ([istarget powerpc*-*-*]
5951         && ![istarget powerpc-*-linux*paired*])
5952	 || [istarget rs6000-*-*] } {
5953	# AltiVec is not supported on AIX before 5.3.
5954	if { [istarget powerpc*-*-aix4*]
5955	     || [istarget powerpc*-*-aix5.1*]
5956	     || [istarget powerpc*-*-aix5.2*] } {
5957	    return 0
5958	}
5959	# Darwin doesn't run on any machine with float128 h/w so far.
5960	if { [istarget *-*-darwin*] } {
5961	    return 0
5962	}
5963	return [check_no_compiler_messages powerpc_float128_hw_ok object {
5964		volatile __float128 x = 1.0q;
5965		volatile __float128 y = 2.0q;
5966		int main() {
5967		    __float128 z;
5968		    __asm__ ("xsaddqp %0,%1,%2" : "=v" (z) : "v" (x), "v" (y));
5969		    return (z == 3.0q);
5970		}
5971	} "-mfloat128-hardware"]
5972    } else {
5973	return 0
5974    }
5975}
5976
5977# Return 1 if current options define float128, 0 otherwise.
5978
5979proc check_effective_target_ppc_float128 { } {
5980    return [check_no_compiler_messages_nocache ppc_float128 object {
5981	#ifndef __FLOAT128__
5982	  nope no good
5983	#endif
5984    }]
5985}
5986
5987# Return 1 if current options generate float128 insns, 0 otherwise.
5988
5989proc check_effective_target_ppc_float128_insns { } {
5990    return [check_no_compiler_messages_nocache ppc_float128 object {
5991	#ifndef __FLOAT128_HARDWARE__
5992	  nope no good
5993	#endif
5994    }]
5995}
5996
5997# Return 1 if current options generate VSX instructions, 0 otherwise.
5998
5999proc check_effective_target_powerpc_vsx { } {
6000    return [check_no_compiler_messages_nocache powerpc_vsx object {
6001	#ifndef __VSX__
6002	  nope no vsx
6003	#endif
6004    }]
6005}
6006
6007# Return 1 if this is a PowerPC target supporting -mvsx
6008
6009proc check_effective_target_powerpc_vsx_ok { } {
6010    if { ([istarget powerpc*-*-*]
6011         && ![istarget powerpc-*-linux*paired*])
6012	 || [istarget rs6000-*-*] } {
6013	# VSX is not supported on AIX before 7.1.
6014	if { [istarget powerpc*-*-aix4*]
6015	     || [istarget powerpc*-*-aix5*]
6016	     || [istarget powerpc*-*-aix6*] } {
6017	    return 0
6018	}
6019	# Darwin doesn't have VSX, even if it's used with an assembler
6020	# which recognises the insns.
6021	if { [istarget *-*-darwin*] } {
6022	    return 0
6023	}
6024	return [check_no_compiler_messages powerpc_vsx_ok object {
6025	    int main (void) {
6026		asm volatile ("xxlor 0,0,0");
6027		return 0;
6028	    }
6029	} "-mvsx"]
6030    } else {
6031	return 0
6032    }
6033}
6034
6035# Return 1 if this is a PowerPC target supporting -mhtm
6036
6037proc check_effective_target_powerpc_htm_ok { } {
6038    if { ([istarget powerpc*-*-*]
6039         && ![istarget powerpc-*-linux*paired*])
6040	 || [istarget rs6000-*-*] } {
6041	# HTM is not supported on AIX yet.
6042	if { [istarget powerpc*-*-aix*] } {
6043	    return 0
6044	}
6045	return [check_no_compiler_messages powerpc_htm_ok object {
6046	    int main (void) {
6047		asm volatile ("tbegin. 0");
6048		return 0;
6049	    }
6050	} "-mhtm"]
6051    } else {
6052	return 0
6053    }
6054}
6055
6056# Return 1 if the target supports executing HTM hardware instructions,
6057# 0 otherwise.  Cache the result.
6058
6059proc check_htm_hw_available { } {
6060    return [check_cached_effective_target htm_hw_available {
6061	# For now, disable on Darwin
6062	if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
6063	    expr 0
6064	} else {
6065	    check_runtime_nocache htm_hw_available {
6066		int main()
6067		{
6068		  __builtin_ttest ();
6069		  return 0;
6070		}
6071	    } "-mhtm"
6072	}
6073    }]
6074}
6075# Return 1 if this is a PowerPC target supporting -mcpu=cell.
6076
6077proc check_effective_target_powerpc_ppu_ok { } {
6078    if [check_effective_target_powerpc_altivec_ok] {
6079	return [check_no_compiler_messages cell_asm_available object {
6080	    int main (void) {
6081#ifdef __MACH__
6082		asm volatile ("lvlx v0,v0,v0");
6083#else
6084		asm volatile ("lvlx 0,0,0");
6085#endif
6086		return 0;
6087	    }
6088	}]
6089    } else {
6090	return 0
6091    }
6092}
6093
6094# Return 1 if this is a PowerPC target that supports SPU.
6095
6096proc check_effective_target_powerpc_spu { } {
6097    if { [istarget powerpc*-*-linux*] } {
6098	return [check_effective_target_powerpc_altivec_ok]
6099    } else {
6100	return 0
6101    }
6102}
6103
6104# Return 1 if this is a PowerPC SPE target.  The check includes options
6105# specified by dg-options for this test, so don't cache the result.
6106
6107proc check_effective_target_powerpc_spe_nocache { } {
6108    if { [istarget powerpc*-*-*] } {
6109	return [check_no_compiler_messages_nocache powerpc_spe object {
6110	    #ifndef __SPE__
6111	    #error not SPE
6112	    #else
6113	    int dummy;
6114	    #endif
6115	} [current_compiler_flags]]
6116    } else {
6117	return 0
6118    }
6119}
6120
6121# Return 1 if this is a PowerPC target with SPE enabled.
6122
6123proc check_effective_target_powerpc_spe { } {
6124    if { [istarget powerpc*-*-*] } {
6125	return [check_no_compiler_messages powerpc_spe object {
6126	    #ifndef __SPE__
6127	    #error not SPE
6128	    #else
6129	    int dummy;
6130	    #endif
6131	}]
6132    } else {
6133	return 0
6134    }
6135}
6136
6137# Return 1 if this is a PowerPC target with Altivec enabled.
6138
6139proc check_effective_target_powerpc_altivec { } {
6140    if { [istarget powerpc*-*-*] } {
6141	return [check_no_compiler_messages powerpc_altivec object {
6142	    #ifndef __ALTIVEC__
6143	    #error not Altivec
6144	    #else
6145	    int dummy;
6146	    #endif
6147	}]
6148    } else {
6149	return 0
6150    }
6151}
6152
6153# Return 1 if this is a PowerPC 405 target.  The check includes options
6154# specified by dg-options for this test, so don't cache the result.
6155
6156proc check_effective_target_powerpc_405_nocache { } {
6157    if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } {
6158	return [check_no_compiler_messages_nocache powerpc_405 object {
6159	    #ifdef __PPC405__
6160	    int dummy;
6161	    #else
6162	    #error not a PPC405
6163	    #endif
6164	} [current_compiler_flags]]
6165    } else {
6166	return 0
6167    }
6168}
6169
6170# Return 1 if this is a PowerPC target using the ELFv2 ABI.
6171
6172proc check_effective_target_powerpc_elfv2 { } {
6173    if { [istarget powerpc*-*-*] } {
6174	return [check_no_compiler_messages powerpc_elfv2 object {
6175	    #if _CALL_ELF != 2
6176	    #error not ELF v2 ABI
6177	    #else
6178	    int dummy;
6179	    #endif
6180	}]
6181    } else {
6182	return 0
6183    }
6184}
6185
6186# The VxWorks SPARC simulator accepts only EM_SPARC executables and
6187# chokes on EM_SPARC32PLUS or EM_SPARCV9 executables.  Return 1 if the
6188# test environment appears to run executables on such a simulator.
6189
6190proc check_effective_target_ultrasparc_hw { } {
6191    return [check_runtime ultrasparc_hw {
6192	int main() { return 0; }
6193    } "-mcpu=ultrasparc"]
6194}
6195
6196# Return 1 if the test environment supports executing UltraSPARC VIS2
6197# instructions.  We check this by attempting: "bmask %g0, %g0, %g0"
6198
6199proc check_effective_target_ultrasparc_vis2_hw { } {
6200    return [check_runtime ultrasparc_vis2_hw {
6201	int main() { __asm__(".word 0x81b00320"); return 0; }
6202    } "-mcpu=ultrasparc3"]
6203}
6204
6205# Return 1 if the test environment supports executing UltraSPARC VIS3
6206# instructions.  We check this by attempting: "addxc %g0, %g0, %g0"
6207
6208proc check_effective_target_ultrasparc_vis3_hw { } {
6209    return [check_runtime ultrasparc_vis3_hw {
6210	int main() { __asm__(".word 0x81b00220"); return 0; }
6211    } "-mcpu=niagara3"]
6212}
6213
6214# Return 1 if this is a SPARC-V9 target.
6215
6216proc check_effective_target_sparc_v9 { } {
6217    if { [istarget sparc*-*-*] } {
6218	return [check_no_compiler_messages sparc_v9 object {
6219	    int main (void) {
6220		asm volatile ("return %i7+8");
6221		return 0;
6222	    }
6223	}]
6224    } else {
6225	return 0
6226    }
6227}
6228
6229# Return 1 if this is a SPARC target with VIS enabled.
6230
6231proc check_effective_target_sparc_vis { } {
6232    if { [istarget sparc*-*-*] } {
6233	return [check_no_compiler_messages sparc_vis object {
6234	    #ifndef __VIS__
6235	    #error not VIS
6236	    #else
6237	    int dummy;
6238	    #endif
6239	}]
6240    } else {
6241	return 0
6242    }
6243}
6244
6245# Return 1 if the target supports hardware vector shift operation.
6246
6247proc check_effective_target_vect_shift { } {
6248    return [check_cached_effective_target_indexed vect_shift {
6249      expr {([istarget powerpc*-*-*]
6250	      && ![istarget powerpc-*-linux*paired*])
6251	     || [istarget ia64-*-*]
6252	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
6253	     || [istarget aarch64*-*-*]
6254	     || [is-effective-target arm_neon]
6255	     || ([istarget mips*-*-*]
6256		 && ([et-is-effective-target mips_msa]
6257		     || [et-is-effective-target mips_loongson_mmi]))
6258	     || ([istarget s390*-*-*]
6259		 && [check_effective_target_s390_vx])
6260	     || [istarget amdgcn-*-*] }}]
6261}
6262
6263# Return 1 if the target supports hardware vector shift by register operation.
6264
6265proc check_effective_target_vect_var_shift { } {
6266    return [check_cached_effective_target_indexed vect_var_shift {
6267      expr {(([istarget i?86-*-*] || [istarget x86_64-*-*])
6268	     && [check_avx2_available])
6269      }}]
6270}
6271
6272proc check_effective_target_whole_vector_shift { } {
6273    if { [istarget i?86-*-*] || [istarget x86_64-*-*]
6274	 || [istarget ia64-*-*]
6275	 || [istarget aarch64*-*-*]
6276	 || [istarget powerpc64*-*-*]
6277	 || ([is-effective-target arm_neon]
6278	     && [check_effective_target_arm_little_endian])
6279	 || ([istarget mips*-*-*]
6280	     && [et-is-effective-target mips_loongson_mmi])
6281	 || ([istarget s390*-*-*]
6282	     && [check_effective_target_s390_vx])
6283	 || [istarget amdgcn-*-*] } {
6284	set answer 1
6285    } else {
6286	set answer 0
6287    }
6288
6289    verbose "check_effective_target_vect_long: returning $answer" 2
6290    return $answer
6291}
6292
6293# Return 1 if the target supports vector bswap operations.
6294
6295proc check_effective_target_vect_bswap { } {
6296    return [check_cached_effective_target_indexed vect_bswap {
6297      expr { [istarget aarch64*-*-*]
6298	     || [is-effective-target arm_neon]
6299	     || [istarget amdgcn-*-*] }}]
6300}
6301
6302# Return 1 if the target supports comparison of bool vectors for at
6303# least one vector length.
6304
6305proc check_effective_target_vect_bool_cmp { } {
6306    return [check_cached_effective_target_indexed vect_bool_cmp {
6307      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
6308	     || [istarget aarch64*-*-*]
6309	     || [is-effective-target arm_neon] }}]
6310}
6311
6312# Return 1 if the target supports addition of char vectors for at least
6313# one vector length.
6314
6315proc check_effective_target_vect_char_add { } {
6316    return [check_cached_effective_target_indexed vect_char_add {
6317      expr {
6318         [istarget i?86-*-*] || [istarget x86_64-*-*]
6319         || ([istarget powerpc*-*-*]
6320	     && ![istarget powerpc-*-linux*paired*])
6321	 || [istarget amdgcn-*-*]
6322	 || [istarget ia64-*-*]
6323	 || [istarget aarch64*-*-*]
6324	 || [is-effective-target arm_neon]
6325	 || ([istarget mips*-*-*]
6326	     && ([et-is-effective-target mips_loongson_mmi]
6327	     || [et-is-effective-target mips_msa]))
6328	 || ([istarget s390*-*-*]
6329	     && [check_effective_target_s390_vx])
6330	}}]
6331}
6332
6333# Return 1 if the target supports hardware vector shift operation for char.
6334
6335proc check_effective_target_vect_shift_char { } {
6336    return [check_cached_effective_target_indexed vect_shift_char {
6337      expr { ([istarget powerpc*-*-*]
6338             && ![istarget powerpc-*-linux*paired*])
6339	     || [is-effective-target arm_neon]
6340	     || ([istarget mips*-*-*]
6341		 && [et-is-effective-target mips_msa])
6342	     || ([istarget s390*-*-*]
6343		 && [check_effective_target_s390_vx])
6344	     || [istarget amdgcn-*-*] }}]
6345}
6346
6347# Return 1 if the target supports hardware vectors of long, 0 otherwise.
6348#
6349# This can change for different subtargets so do not cache the result.
6350
6351proc check_effective_target_vect_long { } {
6352    if { [istarget i?86-*-*] || [istarget x86_64-*-*]
6353	 || (([istarget powerpc*-*-*]
6354              && ![istarget powerpc-*-linux*paired*])
6355              && [check_effective_target_ilp32])
6356	 || [is-effective-target arm_neon]
6357	 || ([istarget sparc*-*-*] && [check_effective_target_ilp32])
6358	 || [istarget aarch64*-*-*]
6359	 || ([istarget mips*-*-*]
6360	      && [et-is-effective-target mips_msa])
6361	 || ([istarget s390*-*-*]
6362	     && [check_effective_target_s390_vx])
6363	 || [istarget amdgcn-*-*] } {
6364	set answer 1
6365    } else {
6366	set answer 0
6367    }
6368
6369    verbose "check_effective_target_vect_long: returning $answer" 2
6370    return $answer
6371}
6372
6373# Return 1 if the target supports hardware vectors of float when
6374# -funsafe-math-optimizations is enabled, 0 otherwise.
6375#
6376# This won't change for different subtargets so cache the result.
6377
6378proc check_effective_target_vect_float { } {
6379    return [check_cached_effective_target_indexed vect_float {
6380      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
6381	     || [istarget powerpc*-*-*]
6382	     || [istarget mips-sde-elf]
6383	     || [istarget mipsisa64*-*-*]
6384	     || [istarget ia64-*-*]
6385	     || [istarget aarch64*-*-*]
6386	     || ([istarget mips*-*-*]
6387		 && [et-is-effective-target mips_msa])
6388	     || [is-effective-target arm_neon]
6389	     || ([istarget s390*-*-*]
6390		 && [check_effective_target_s390_vxe])
6391	     || [istarget amdgcn-*-*] }}]
6392}
6393
6394# Return 1 if the target supports hardware vectors of float without
6395# -funsafe-math-optimizations being enabled, 0 otherwise.
6396
6397proc check_effective_target_vect_float_strict { } {
6398    return [expr { [check_effective_target_vect_float]
6399		   && ![istarget arm*-*-*] }]
6400}
6401
6402# Return 1 if the target supports hardware vectors of double, 0 otherwise.
6403#
6404# This won't change for different subtargets so cache the result.
6405
6406proc check_effective_target_vect_double { } {
6407    return [check_cached_effective_target_indexed vect_double {
6408        expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
6409	         && [check_no_compiler_messages vect_double assembly {
6410		  #ifdef __tune_atom__
6411		  # error No double vectorizer support.
6412		  #endif
6413		}])
6414	     || [istarget aarch64*-*-*]
6415	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
6416	     || ([istarget mips*-*-*]
6417		 && [et-is-effective-target mips_msa])
6418	     || ([istarget s390*-*-*]
6419		 && [check_effective_target_s390_vx])
6420	     || [istarget amdgcn-*-*]} }]
6421}
6422
6423# Return 1 if the target supports conditional addition, subtraction,
6424# multiplication, division, minimum and maximum on vectors of double,
6425# via the cond_ optabs.  Return 0 otherwise.
6426
6427proc check_effective_target_vect_double_cond_arith { } {
6428    return [check_effective_target_aarch64_sve]
6429}
6430
6431# Return 1 if the target supports hardware vectors of long long, 0 otherwise.
6432#
6433# This won't change for different subtargets so cache the result.
6434
6435proc check_effective_target_vect_long_long { } {
6436    return [check_cached_effective_target_indexed vect_long_long {
6437      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
6438	     || ([istarget mips*-*-*]
6439		 && [et-is-effective-target mips_msa])
6440	     || ([istarget s390*-*-*]
6441		 && [check_effective_target_s390_vx]) }}]
6442}
6443
6444
6445# Return 1 if the target plus current options does not support a vector
6446# max instruction on "int", 0 otherwise.
6447#
6448# This won't change for different subtargets so cache the result.
6449
6450proc check_effective_target_vect_no_int_min_max { } {
6451    return [check_cached_effective_target_indexed vect_no_int_min_max {
6452      expr { [istarget sparc*-*-*]
6453	     || [istarget alpha*-*-*]
6454	     || ([istarget mips*-*-*]
6455		 && [et-is-effective-target mips_loongson_mmi]) }}]
6456}
6457
6458# Return 1 if the target plus current options does not support a vector
6459# add instruction on "int", 0 otherwise.
6460#
6461# This won't change for different subtargets so cache the result.
6462
6463proc check_effective_target_vect_no_int_add { } {
6464    # Alpha only supports vector add on V8QI and V4HI.
6465    return [check_cached_effective_target_indexed vect_no_int_add {
6466      expr { [istarget alpha*-*-*] }}]
6467}
6468
6469# Return 1 if the target plus current options does not support vector
6470# bitwise instructions, 0 otherwise.
6471#
6472# This won't change for different subtargets so cache the result.
6473
6474proc check_effective_target_vect_no_bitwise { } {
6475    return [check_cached_effective_target_indexed vect_no_bitwise { return 0 }]
6476}
6477
6478# Return 1 if the target plus current options supports vector permutation,
6479# 0 otherwise.
6480#
6481# This won't change for different subtargets so cache the result.
6482
6483proc check_effective_target_vect_perm { } {
6484    return [check_cached_effective_target_indexed vect_perm {
6485      expr { [is-effective-target arm_neon]
6486	     || [istarget aarch64*-*-*]
6487	     || [istarget powerpc*-*-*]
6488	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
6489	     || ([istarget mips*-*-*]
6490		 && ([et-is-effective-target mpaired_single]
6491		     || [et-is-effective-target mips_msa]))
6492	     || ([istarget s390*-*-*]
6493		 && [check_effective_target_s390_vx])
6494	     || [istarget amdgcn-*-*] }}]
6495}
6496
6497# Return 1 if, for some VF:
6498#
6499# - the target's default vector size is VF * ELEMENT_BITS bits
6500#
6501# - it is possible to implement the equivalent of:
6502#
6503#      int<ELEMENT_BITS>_t s1[COUNT][COUNT * VF], s2[COUNT * VF];
6504#      for (int i = 0; i < COUNT; ++i)
6505#        for (int j = 0; j < COUNT * VF; ++j)
6506#          s1[i][j] = s2[j - j % COUNT + i]
6507#
6508#   using only a single 2-vector permute for each vector in s1.
6509#
6510# E.g. for COUNT == 3 and vector length 4, the two arrays would be:
6511#
6512#    s2    | a0 a1 a2 a3 | b0 b1 b2 b3 | c0 c1 c2 c3
6513#    ------+-------------+-------------+------------
6514#    s1[0] | a0 a0 a0 a3 | a3 a3 b2 b2 | b2 c1 c1 c1
6515#    s1[1] | a1 a1 a1 b0 | b0 b0 b3 b3 | b3 c2 c2 c2
6516#    s1[2] | a2 a2 a2 b1 | b1 b1 c0 c0 | c0 c3 c3 c3
6517#
6518# Each s1 permute requires only two of a, b and c.
6519#
6520# The distance between the start of vector n in s1[0] and the start
6521# of vector n in s2 is:
6522#
6523#    A = (n * VF) % COUNT
6524#
6525# The corresponding value for the end of vector n is:
6526#
6527#    B = (n * VF + VF - 1) % COUNT
6528#
6529# Subtracting i from each value gives the corresponding difference
6530# for s1[i].  The condition being tested by this function is false
6531# iff A - i > 0 and B - i < 0 for some i and n, such that the first
6532# element for s1[i] comes from vector n - 1 of s2 and the last element
6533# comes from vector n + 1 of s2.  The condition is therefore true iff
6534# A <= B for all n.  This is turn means the condition is true iff:
6535#
6536#    (n * VF) % COUNT + (VF - 1) % COUNT < COUNT
6537#
6538# for all n.  COUNT - (n * VF) % COUNT is bounded by gcd (VF, COUNT),
6539# and will be that value for at least one n in [0, COUNT), so we want:
6540#
6541#    (VF - 1) % COUNT < gcd (VF, COUNT)
6542
6543proc vect_perm_supported { count element_bits } {
6544    set vector_bits [lindex [available_vector_sizes] 0]
6545    # The number of vectors has to be a power of 2 when permuting
6546    # variable-length vectors.
6547    if { $vector_bits <= 0 && ($count & -$count) != $count } {
6548	return 0
6549    }
6550    set vf [expr { $vector_bits / $element_bits }]
6551
6552    # Compute gcd (VF, COUNT).
6553    set gcd $vf
6554    set temp1 $count
6555    while { $temp1 > 0 } {
6556	set temp2 [expr { $gcd % $temp1 }]
6557	set gcd $temp1
6558	set temp1 $temp2
6559    }
6560    return [expr { ($vf - 1) % $count < $gcd }]
6561}
6562
6563# Return 1 if the target supports SLP permutation of 3 vectors when each
6564# element has 32 bits.
6565
6566proc check_effective_target_vect_perm3_int { } {
6567    return [expr { [check_effective_target_vect_perm]
6568		   && [vect_perm_supported 3 32] }]
6569}
6570
6571# Return 1 if the target plus current options supports vector permutation
6572# on byte-sized elements, 0 otherwise.
6573#
6574# This won't change for different subtargets so cache the result.
6575
6576proc check_effective_target_vect_perm_byte { } {
6577    return [check_cached_effective_target_indexed vect_perm_byte {
6578      expr { ([is-effective-target arm_neon]
6579	      && [is-effective-target arm_little_endian])
6580	     || ([istarget aarch64*-*-*]
6581		 && [is-effective-target aarch64_little_endian])
6582	     || [istarget powerpc*-*-*]
6583	     || ([istarget mips-*.*]
6584		 && [et-is-effective-target mips_msa])
6585	     || ([istarget s390*-*-*]
6586		 && [check_effective_target_s390_vx])
6587	     || [istarget amdgcn-*-*] }}]
6588}
6589
6590# Return 1 if the target supports SLP permutation of 3 vectors when each
6591# element has 8 bits.
6592
6593proc check_effective_target_vect_perm3_byte { } {
6594    return [expr { [check_effective_target_vect_perm_byte]
6595		   && [vect_perm_supported 3 8] }]
6596}
6597
6598# Return 1 if the target plus current options supports vector permutation
6599# on short-sized elements, 0 otherwise.
6600#
6601# This won't change for different subtargets so cache the result.
6602
6603proc check_effective_target_vect_perm_short { } {
6604    return [check_cached_effective_target_indexed vect_perm_short {
6605      expr { ([is-effective-target arm_neon]
6606	      && [is-effective-target arm_little_endian])
6607	     || ([istarget aarch64*-*-*]
6608		 && [is-effective-target aarch64_little_endian])
6609	     || [istarget powerpc*-*-*]
6610	     || (([istarget i?86-*-*] || [istarget x86_64-*-*])
6611	         && [check_ssse3_available])
6612	     || ([istarget mips*-*-*]
6613		  && [et-is-effective-target mips_msa])
6614	     || ([istarget s390*-*-*]
6615		 && [check_effective_target_s390_vx])
6616	     || [istarget amdgcn-*-*] }}]
6617}
6618
6619# Return 1 if the target supports SLP permutation of 3 vectors when each
6620# element has 16 bits.
6621
6622proc check_effective_target_vect_perm3_short { } {
6623    return [expr { [check_effective_target_vect_perm_short]
6624		   && [vect_perm_supported 3 16] }]
6625}
6626
6627# Return 1 if the target plus current options supports folding of
6628# copysign into XORSIGN.
6629#
6630# This won't change for different subtargets so cache the result.
6631
6632proc check_effective_target_xorsign { } {
6633    return [check_cached_effective_target_indexed xorsign {
6634      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
6635	     || [istarget aarch64*-*-*] || [istarget arm*-*-*] }}]
6636}
6637
6638# Return 1 if the target plus current options supports a vector
6639# widening summation of *short* args into *int* result, 0 otherwise.
6640#
6641# This won't change for different subtargets so cache the result.
6642
6643proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
6644    return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si_pattern {
6645      expr { [istarget powerpc*-*-*]
6646             || ([istarget aarch64*-*-*]
6647		 && ![check_effective_target_aarch64_sve])
6648	     || [is-effective-target arm_neon]
6649             || [istarget ia64-*-*] }}]
6650}
6651
6652# Return 1 if the target plus current options supports a vector
6653# widening summation of *short* args into *int* result, 0 otherwise.
6654# A target can also support this widening summation if it can support
6655# promotion (unpacking) from shorts to ints.
6656#
6657# This won't change for different subtargets so cache the result.
6658
6659proc check_effective_target_vect_widen_sum_hi_to_si { } {
6660    return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si {
6661      expr { [check_effective_target_vect_unpack]
6662             || [istarget powerpc*-*-*]
6663	     || [istarget ia64-*-*] }}]
6664}
6665
6666# Return 1 if the target plus current options supports a vector
6667# widening summation of *char* args into *short* result, 0 otherwise.
6668# A target can also support this widening summation if it can support
6669# promotion (unpacking) from chars to shorts.
6670#
6671# This won't change for different subtargets so cache the result.
6672
6673proc check_effective_target_vect_widen_sum_qi_to_hi { } {
6674    return [check_cached_effective_target_indexed vect_widen_sum_qi_to_hi {
6675      expr { [check_effective_target_vect_unpack]
6676	     || [is-effective-target arm_neon]
6677	     || [istarget ia64-*-*] }}]
6678}
6679
6680# Return 1 if the target plus current options supports a vector
6681# widening summation of *char* args into *int* result, 0 otherwise.
6682#
6683# This won't change for different subtargets so cache the result.
6684
6685proc check_effective_target_vect_widen_sum_qi_to_si { } {
6686    return [check_cached_effective_target_indexed vect_widen_sum_qi_to_si {
6687      expr { [istarget powerpc*-*-*] }}]
6688}
6689
6690# Return 1 if the target plus current options supports a vector
6691# widening multiplication of *char* args into *short* result, 0 otherwise.
6692# A target can also support this widening multplication if it can support
6693# promotion (unpacking) from chars to shorts, and vect_short_mult (non-widening
6694# multiplication of shorts).
6695#
6696# This won't change for different subtargets so cache the result.
6697
6698
6699proc check_effective_target_vect_widen_mult_qi_to_hi { } {
6700    return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi {
6701      expr { ([check_effective_target_vect_unpack]
6702	       && [check_effective_target_vect_short_mult])
6703	      || ([istarget powerpc*-*-*]
6704		  || ([istarget aarch64*-*-*]
6705		      && ![check_effective_target_aarch64_sve])
6706		  || [is-effective-target arm_neon]
6707		  || ([istarget s390*-*-*]
6708		      && [check_effective_target_s390_vx]))
6709	      || [istarget amdgcn-*-*] }}]
6710}
6711
6712# Return 1 if the target plus current options supports a vector
6713# widening multiplication of *short* args into *int* result, 0 otherwise.
6714# A target can also support this widening multplication if it can support
6715# promotion (unpacking) from shorts to ints, and vect_int_mult (non-widening
6716# multiplication of ints).
6717#
6718# This won't change for different subtargets so cache the result.
6719
6720
6721proc check_effective_target_vect_widen_mult_hi_to_si { } {
6722    return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si {
6723      expr { ([check_effective_target_vect_unpack]
6724              && [check_effective_target_vect_int_mult])
6725	     || ([istarget powerpc*-*-*]
6726		 || [istarget ia64-*-*]
6727		 || ([istarget aarch64*-*-*]
6728		     && ![check_effective_target_aarch64_sve])
6729		 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6730		 || [is-effective-target arm_neon]
6731		 || ([istarget s390*-*-*]
6732		     && [check_effective_target_s390_vx]))
6733	     || [istarget amdgcn-*-*] }}]
6734}
6735
6736# Return 1 if the target plus current options supports a vector
6737# widening multiplication of *char* args into *short* result, 0 otherwise.
6738#
6739# This won't change for different subtargets so cache the result.
6740
6741proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
6742    return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi_pattern {
6743      expr { [istarget powerpc*-*-*]
6744             || ([is-effective-target arm_neon]
6745		 && [check_effective_target_arm_little_endian])
6746	     || ([istarget s390*-*-*]
6747		 && [check_effective_target_s390_vx])
6748	     || [istarget amdgcn-*-*] }}]
6749}
6750
6751# Return 1 if the target plus current options supports a vector
6752# widening multiplication of *short* args into *int* result, 0 otherwise.
6753#
6754# This won't change for different subtargets so cache the result.
6755
6756proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
6757    return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si_pattern {
6758      expr { [istarget powerpc*-*-*]
6759	     || [istarget ia64-*-*]
6760	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
6761	     || ([is-effective-target arm_neon]
6762		 && [check_effective_target_arm_little_endian])
6763	     || ([istarget s390*-*-*]
6764		 && [check_effective_target_s390_vx])
6765	     || [istarget amdgcn-*-*] }}]
6766}
6767
6768# Return 1 if the target plus current options supports a vector
6769# widening multiplication of *int* args into *long* result, 0 otherwise.
6770#
6771# This won't change for different subtargets so cache the result.
6772
6773proc check_effective_target_vect_widen_mult_si_to_di_pattern { } {
6774    return [check_cached_effective_target_indexed vect_widen_mult_si_to_di_pattern {
6775      expr { [istarget ia64-*-*]
6776	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
6777	     || ([istarget s390*-*-*]
6778		 && [check_effective_target_s390_vx]) }}]
6779}
6780
6781# Return 1 if the target plus current options supports a vector
6782# widening shift, 0 otherwise.
6783#
6784# This won't change for different subtargets so cache the result.
6785
6786proc check_effective_target_vect_widen_shift { } {
6787    return [check_cached_effective_target_indexed vect_widen_shift {
6788      expr { [is-effective-target arm_neon] }}]
6789}
6790
6791# Return 1 if the target plus current options supports a vector
6792# dot-product of signed chars, 0 otherwise.
6793#
6794# This won't change for different subtargets so cache the result.
6795
6796proc check_effective_target_vect_sdot_qi { } {
6797    return [check_cached_effective_target_indexed vect_sdot_qi {
6798      expr { [istarget ia64-*-*]
6799	     || [istarget aarch64*-*-*]
6800	     || [istarget arm*-*-*]
6801	     || ([istarget mips*-*-*]
6802		 && [et-is-effective-target mips_msa]) }}]
6803}
6804
6805# Return 1 if the target plus current options supports a vector
6806# dot-product of unsigned chars, 0 otherwise.
6807#
6808# This won't change for different subtargets so cache the result.
6809
6810proc check_effective_target_vect_udot_qi { } {
6811    return [check_cached_effective_target_indexed vect_udot_qi {
6812      expr { [istarget powerpc*-*-*]
6813	     || [istarget aarch64*-*-*]
6814	     || [istarget arm*-*-*]
6815	     || [istarget ia64-*-*]
6816	     || ([istarget mips*-*-*]
6817		 && [et-is-effective-target mips_msa]) }}]
6818}
6819
6820# Return 1 if the target plus current options supports a vector
6821# dot-product of signed shorts, 0 otherwise.
6822#
6823# This won't change for different subtargets so cache the result.
6824
6825proc check_effective_target_vect_sdot_hi { } {
6826    return [check_cached_effective_target_indexed vect_sdot_hi {
6827      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
6828	     || [istarget ia64-*-*]
6829	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
6830	     || ([istarget mips*-*-*]
6831		 && [et-is-effective-target mips_msa]) }}]
6832}
6833
6834# Return 1 if the target plus current options supports a vector
6835# dot-product of unsigned shorts, 0 otherwise.
6836#
6837# This won't change for different subtargets so cache the result.
6838
6839proc check_effective_target_vect_udot_hi { } {
6840    return [check_cached_effective_target_indexed vect_udot_hi {
6841      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
6842	     || ([istarget mips*-*-*]
6843		 && [et-is-effective-target mips_msa]) }}]
6844}
6845
6846# Return 1 if the target plus current options supports a vector
6847# sad operation of unsigned chars, 0 otherwise.
6848#
6849# This won't change for different subtargets so cache the result.
6850
6851proc check_effective_target_vect_usad_char { } {
6852    return [check_cached_effective_target_indexed vect_usad_char {
6853      expr { [istarget i?86-*-*]
6854	      || [istarget x86_64-*-*]
6855	      || ([istarget aarch64*-*-*]
6856		  && ![check_effective_target_aarch64_sve])
6857	      || ([istarget powerpc*-*-*]
6858		  && [check_p9vector_hw_available])}}]
6859}
6860
6861# Return 1 if the target plus current options supports both signed
6862# and unsigned average operations on vectors of bytes.
6863
6864proc check_effective_target_vect_avg_qi {} {
6865    return [expr { [istarget aarch64*-*-*]
6866		   && ![check_effective_target_aarch64_sve1_only] }]
6867}
6868
6869# Return 1 if the target plus current options supports both signed
6870# and unsigned multiply-high-with-round-and-scale operations
6871# on vectors of half-words.
6872
6873proc check_effective_target_vect_mulhrs_hi {} {
6874    return [expr { [istarget aarch64*-*-*]
6875		   && [check_effective_target_aarch64_sve2] }]
6876}
6877
6878# Return 1 if the target plus current options supports signed division
6879# by power-of-2 operations on vectors of 4-byte integers.
6880
6881proc check_effective_target_vect_sdiv_pow2_si {} {
6882    return [expr { [istarget aarch64*-*-*]
6883		   && [check_effective_target_aarch64_sve] }]
6884}
6885
6886# Return 1 if the target plus current options supports a vector
6887# demotion (packing) of shorts (to chars) and ints (to shorts)
6888# using modulo arithmetic, 0 otherwise.
6889#
6890# This won't change for different subtargets so cache the result.
6891
6892proc check_effective_target_vect_pack_trunc { } {
6893    return [check_cached_effective_target_indexed vect_pack_trunc {
6894      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
6895             || [istarget i?86-*-*] || [istarget x86_64-*-*]
6896             || [istarget aarch64*-*-*]
6897             || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
6898		 && [check_effective_target_arm_little_endian])
6899	     || ([istarget mips*-*-*]
6900		 && [et-is-effective-target mips_msa])
6901	     || ([istarget s390*-*-*]
6902		 && [check_effective_target_s390_vx])
6903             || [istarget amdgcn*-*-*] }}]
6904}
6905
6906# Return 1 if the target plus current options supports a vector
6907# promotion (unpacking) of chars (to shorts) and shorts (to ints), 0 otherwise.
6908#
6909# This won't change for different subtargets so cache the result.
6910
6911proc check_effective_target_vect_unpack { } {
6912    return [check_cached_effective_target_indexed vect_unpack {
6913      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
6914             || [istarget i?86-*-*] || [istarget x86_64-*-*]
6915             || [istarget ia64-*-*]
6916             || [istarget aarch64*-*-*]
6917	     || ([istarget mips*-*-*]
6918		 && [et-is-effective-target mips_msa])
6919             || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
6920		 && [check_effective_target_arm_little_endian])
6921	     || ([istarget s390*-*-*]
6922		 && [check_effective_target_s390_vx])
6923	     || [istarget amdgcn*-*-*] }}]
6924}
6925
6926# Return 1 if the target plus current options does not guarantee
6927# that its STACK_BOUNDARY is >= the reguired vector alignment.
6928#
6929# This won't change for different subtargets so cache the result.
6930
6931proc check_effective_target_unaligned_stack { } {
6932    return [check_cached_effective_target_indexed unaligned_stack { expr 0 }]
6933}
6934
6935# Return 1 if the target plus current options does not support a vector
6936# alignment mechanism, 0 otherwise.
6937#
6938# This won't change for different subtargets so cache the result.
6939
6940proc check_effective_target_vect_no_align { } {
6941    return [check_cached_effective_target_indexed vect_no_align {
6942      expr { [istarget mipsisa64*-*-*]
6943	     || [istarget mips-sde-elf]
6944	     || [istarget sparc*-*-*]
6945	     || [istarget ia64-*-*]
6946	     || [check_effective_target_arm_vect_no_misalign]
6947	     || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
6948	     || ([istarget mips*-*-*]
6949		 && [et-is-effective-target mips_loongson_mmi]) }}]
6950}
6951
6952# Return 1 if the target supports a vector misalign access, 0 otherwise.
6953#
6954# This won't change for different subtargets so cache the result.
6955
6956proc check_effective_target_vect_hw_misalign { } {
6957    return [check_cached_effective_target_indexed vect_hw_misalign {
6958	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
6959	     || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
6960	     || [istarget aarch64*-*-*]
6961	     || ([istarget mips*-*-*] && [et-is-effective-target mips_msa])
6962	     || ([istarget s390*-*-*]
6963		 && [check_effective_target_s390_vx]) } {
6964	  return 1
6965	}
6966	if { [istarget arm*-*-*]
6967	     && ![check_effective_target_arm_vect_no_misalign] } {
6968	  return 1
6969	}
6970        return 0
6971    }]
6972}
6973
6974
6975# Return 1 if arrays are aligned to the vector alignment
6976# boundary, 0 otherwise.
6977
6978proc check_effective_target_vect_aligned_arrays { } {
6979    set et_vect_aligned_arrays 0
6980    if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
6981	  && !([is-effective-target ia32]
6982	       || ([check_avx_available] && ![check_prefer_avx128]))) } {
6983	set et_vect_aligned_arrays 1
6984    }
6985
6986    verbose "check_effective_target_vect_aligned_arrays:\
6987	     returning $et_vect_aligned_arrays" 2
6988    return $et_vect_aligned_arrays
6989}
6990
6991# Return 1 if types of size 32 bit or less are naturally aligned
6992# (aligned to their type-size), 0 otherwise.
6993#
6994# This won't change for different subtargets so cache the result.
6995
6996proc check_effective_target_natural_alignment_32 { } {
6997    # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
6998    # FIXME: m68k has -malign-int
6999    return [check_cached_effective_target_indexed natural_alignment_32 {
7000      if { ([istarget *-*-darwin*] && [is-effective-target lp64])
7001	   || [istarget avr-*-*]
7002	   || [istarget m68k-*-linux*]
7003	   || [istarget pru-*-*]
7004	   || [istarget stormy16-*-*]
7005	   || [istarget rl78-*-*]
7006	   || [istarget pdp11-*-*]
7007	   || [istarget msp430-*-*]
7008	   || [istarget m32c-*-*]
7009	   || [istarget cris-*-*] } {
7010	   return 0
7011	 } else {
7012	   return 1
7013	 }
7014      }]
7015}
7016
7017# Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
7018# type-size), 0 otherwise.
7019#
7020# This won't change for different subtargets so cache the result.
7021
7022proc check_effective_target_natural_alignment_64 { } {
7023    return [check_cached_effective_target_indexed natural_alignment_64 {
7024      expr { [is-effective-target natural_alignment_32]
7025             && [is-effective-target lp64] && ![istarget *-*-darwin*] }
7026    }]
7027}
7028
7029# Return 1 if all vector types are naturally aligned (aligned to their
7030# type-size), 0 otherwise.
7031
7032proc check_effective_target_vect_natural_alignment { } {
7033    set et_vect_natural_alignment 1
7034    if { [check_effective_target_arm_eabi]
7035	 || [istarget nvptx-*-*]
7036	 || [istarget s390*-*-*]
7037	 || [istarget amdgcn-*-*] } {
7038	set et_vect_natural_alignment 0
7039    }
7040    verbose "check_effective_target_vect_natural_alignment:\
7041	     returning $et_vect_natural_alignment" 2
7042    return $et_vect_natural_alignment
7043}
7044
7045# Return true if the target supports the check_raw_ptrs and check_war_ptrs
7046# optabs on vectors.
7047
7048proc check_effective_target_vect_check_ptrs { } {
7049    return [check_effective_target_aarch64_sve2]
7050}
7051
7052# Return true if fully-masked loops are supported.
7053
7054proc check_effective_target_vect_fully_masked { } {
7055    return [expr { [check_effective_target_aarch64_sve]
7056	           || [istarget amdgcn*-*-*] }]
7057}
7058
7059# Return 1 if the target doesn't prefer any alignment beyond element
7060# alignment during vectorization.
7061
7062proc check_effective_target_vect_element_align_preferred { } {
7063    return [expr { [check_effective_target_aarch64_sve]
7064		   && [check_effective_target_vect_variable_length] }]
7065}
7066
7067# Return 1 if we can align stack data to the preferred vector alignment.
7068
7069proc check_effective_target_vect_align_stack_vars { } {
7070    if { [check_effective_target_aarch64_sve] } {
7071	return [check_effective_target_vect_variable_length]
7072    }
7073    return 1
7074}
7075
7076# Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise.
7077
7078proc check_effective_target_vector_alignment_reachable { } {
7079    set et_vector_alignment_reachable 0
7080    if { [check_effective_target_vect_aligned_arrays]
7081	 || [check_effective_target_natural_alignment_32] } {
7082	set et_vector_alignment_reachable 1
7083    }
7084    verbose "check_effective_target_vector_alignment_reachable:\
7085	     returning $et_vector_alignment_reachable" 2
7086    return $et_vector_alignment_reachable
7087}
7088
7089# Return 1 if vector alignment for 64 bit is reachable, 0 otherwise.
7090
7091proc check_effective_target_vector_alignment_reachable_for_64bit { } {
7092    set et_vector_alignment_reachable_for_64bit 0
7093    if { [check_effective_target_vect_aligned_arrays]
7094	 || [check_effective_target_natural_alignment_64] } {
7095	set et_vector_alignment_reachable_for_64bit 1
7096    }
7097    verbose "check_effective_target_vector_alignment_reachable_for_64bit:\
7098	     returning $et_vector_alignment_reachable_for_64bit" 2
7099    return $et_vector_alignment_reachable_for_64bit
7100}
7101
7102# Return 1 if the target only requires element alignment for vector accesses
7103
7104proc check_effective_target_vect_element_align { } {
7105    return [check_cached_effective_target_indexed vect_element_align {
7106      expr { ([istarget arm*-*-*]
7107	      && ![check_effective_target_arm_vect_no_misalign])
7108	     || [check_effective_target_vect_hw_misalign]
7109	     || [istarget amdgcn-*-*] }}]
7110}
7111
7112# Return 1 if we expect to see unaligned accesses in at least some
7113# vector dumps.
7114
7115proc check_effective_target_vect_unaligned_possible { } {
7116    return [expr { ![check_effective_target_vect_element_align_preferred]
7117		   && (![check_effective_target_vect_no_align]
7118		       || [check_effective_target_vect_hw_misalign]) }]
7119}
7120
7121# Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise.
7122
7123proc check_effective_target_vect_load_lanes { } {
7124    # We don't support load_lanes correctly on big-endian arm.
7125    return [check_cached_effective_target vect_load_lanes {
7126      expr { ([check_effective_target_arm_little_endian]
7127	      && [check_effective_target_arm_neon_ok])
7128	     || [istarget aarch64*-*-*] }}]
7129}
7130
7131# Return 1 if the target supports vector masked stores.
7132
7133proc check_effective_target_vect_masked_store { } {
7134    return [expr { [check_effective_target_aarch64_sve]
7135		   || [istarget amdgcn*-*-*] }]
7136}
7137
7138# Return 1 if the target supports vector scatter stores.
7139
7140proc check_effective_target_vect_scatter_store { } {
7141    return [expr { [check_effective_target_aarch64_sve]
7142		   || [istarget amdgcn*-*-*] }]
7143}
7144
7145# Return 1 if the target supports vector conditional operations, 0 otherwise.
7146
7147proc check_effective_target_vect_condition { } {
7148    return [check_cached_effective_target_indexed vect_condition {
7149      expr { [istarget aarch64*-*-*]
7150	     || [istarget powerpc*-*-*]
7151	     || [istarget ia64-*-*]
7152	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
7153	     || ([istarget mips*-*-*]
7154		 && [et-is-effective-target mips_msa])
7155	     || ([istarget arm*-*-*]
7156		 && [check_effective_target_arm_neon_ok])
7157	     || ([istarget s390*-*-*]
7158		 && [check_effective_target_s390_vx])
7159	     || [istarget amdgcn-*-*] }}]
7160}
7161
7162# Return 1 if the target supports vector conditional operations where
7163# the comparison has different type from the lhs, 0 otherwise.
7164
7165proc check_effective_target_vect_cond_mixed { } {
7166    return [check_cached_effective_target_indexed vect_cond_mixed {
7167      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
7168	     || [istarget aarch64*-*-*]
7169	     || [istarget powerpc*-*-*]
7170	     || ([istarget mips*-*-*]
7171		 && [et-is-effective-target mips_msa])
7172	     || ([istarget s390*-*-*]
7173		 && [check_effective_target_s390_vx])
7174	     || [istarget amdgcn-*-*] }}]
7175}
7176
7177# Return 1 if the target supports vector char multiplication, 0 otherwise.
7178
7179proc check_effective_target_vect_char_mult { } {
7180    return [check_cached_effective_target_indexed vect_char_mult {
7181      expr { [istarget aarch64*-*-*]
7182	     || [istarget ia64-*-*]
7183	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
7184	     || [check_effective_target_arm32]
7185	     || [check_effective_target_powerpc_altivec]
7186	     || ([istarget mips*-*-*]
7187		 && [et-is-effective-target mips_msa])
7188	     || ([istarget s390*-*-*]
7189		 && [check_effective_target_s390_vx])
7190	     || [istarget amdgcn-*-*] }}]
7191}
7192
7193# Return 1 if the target supports vector short multiplication, 0 otherwise.
7194
7195proc check_effective_target_vect_short_mult { } {
7196    return [check_cached_effective_target_indexed vect_short_mult {
7197      expr { [istarget ia64-*-*]
7198	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
7199	     || [istarget powerpc*-*-*]
7200	     || [istarget aarch64*-*-*]
7201	     || [check_effective_target_arm32]
7202	     || ([istarget mips*-*-*]
7203		 && ([et-is-effective-target mips_msa]
7204		     || [et-is-effective-target mips_loongson_mmi]))
7205	     || ([istarget s390*-*-*]
7206		 && [check_effective_target_s390_vx])
7207	     || [istarget amdgcn-*-*] }}]
7208}
7209
7210# Return 1 if the target supports vector int multiplication, 0 otherwise.
7211
7212proc check_effective_target_vect_int_mult { } {
7213    return [check_cached_effective_target_indexed vect_int_mult {
7214      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
7215	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
7216	     || [istarget ia64-*-*]
7217	     || [istarget aarch64*-*-*]
7218	     || ([istarget mips*-*-*]
7219		 && [et-is-effective-target mips_msa])
7220	     || [check_effective_target_arm32]
7221	     || ([istarget s390*-*-*]
7222		 && [check_effective_target_s390_vx])
7223	     || [istarget amdgcn-*-*] }}]
7224}
7225
7226# Return 1 if the target supports 64 bit hardware vector
7227# multiplication of long operands with a long result, 0 otherwise.
7228#
7229# This can change for different subtargets so do not cache the result.
7230
7231proc check_effective_target_vect_long_mult { } {
7232    if { [istarget i?86-*-*] || [istarget x86_64-*-*]
7233	 || (([istarget powerpc*-*-*]
7234              && ![istarget powerpc-*-linux*paired*])
7235              && [check_effective_target_ilp32])
7236	 || [is-effective-target arm_neon]
7237	 || ([istarget sparc*-*-*] && [check_effective_target_ilp32])
7238	 || [istarget aarch64*-*-*]
7239	 || ([istarget mips*-*-*]
7240	      && [et-is-effective-target mips_msa]) } {
7241	set answer 1
7242    } else {
7243	set answer 0
7244    }
7245
7246    verbose "check_effective_target_vect_long_mult: returning $answer" 2
7247    return $answer
7248}
7249
7250# Return 1 if the target supports vector even/odd elements extraction, 0 otherwise.
7251
7252proc check_effective_target_vect_extract_even_odd { } {
7253    return [check_cached_effective_target_indexed extract_even_odd {
7254      expr { [istarget aarch64*-*-*]
7255	     || [istarget powerpc*-*-*]
7256	     || [is-effective-target arm_neon]
7257             || [istarget i?86-*-*] || [istarget x86_64-*-*]
7258             || [istarget ia64-*-*]
7259	     || ([istarget mips*-*-*]
7260		 && ([et-is-effective-target mips_msa]
7261		     || [et-is-effective-target mpaired_single]))
7262	     || ([istarget s390*-*-*]
7263		 && [check_effective_target_s390_vx]) }}]
7264}
7265
7266# Return 1 if the target supports vector interleaving, 0 otherwise.
7267
7268proc check_effective_target_vect_interleave { } {
7269    return [check_cached_effective_target_indexed vect_interleave {
7270      expr { [istarget aarch64*-*-*]
7271	     || [istarget powerpc*-*-*]
7272	     || [is-effective-target arm_neon]
7273             || [istarget i?86-*-*] || [istarget x86_64-*-*]
7274             || [istarget ia64-*-*]
7275	     || ([istarget mips*-*-*]
7276		 && ([et-is-effective-target mpaired_single]
7277		     || [et-is-effective-target mips_msa]))
7278	     || ([istarget s390*-*-*]
7279		 && [check_effective_target_s390_vx]) }}]
7280}
7281
7282foreach N {2 3 4 8} {
7283    eval [string map [list N $N] {
7284	# Return 1 if the target supports 2-vector interleaving
7285	proc check_effective_target_vect_stridedN { } {
7286	    return [check_cached_effective_target_indexed vect_stridedN {
7287		if { (N & -N) == N
7288		     && [check_effective_target_vect_interleave]
7289		     && [check_effective_target_vect_extract_even_odd] } {
7290		    return 1
7291		}
7292		if { ([istarget arm*-*-*]
7293		      || [istarget aarch64*-*-*]) && N >= 2 && N <= 4 } {
7294		    return 1
7295		}
7296		if [check_effective_target_vect_fully_masked] {
7297		    return 1
7298		}
7299		return 0
7300	    }]
7301	}
7302    }]
7303}
7304
7305# Return the list of vector sizes (in bits) that each target supports.
7306# A vector length of "0" indicates variable-length vectors.
7307
7308proc available_vector_sizes { } {
7309    set result {}
7310    if { [istarget aarch64*-*-*] } {
7311	if { [check_effective_target_aarch64_sve] } {
7312	    lappend result [aarch64_sve_bits]
7313	}
7314	lappend result 128 64
7315    } elseif { [istarget arm*-*-*]
7316		&& [check_effective_target_arm_neon_ok] } {
7317	lappend result 128 64
7318    } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
7319	if { [check_avx_available] && ![check_prefer_avx128] } {
7320	    lappend result 256
7321	}
7322	lappend result 128
7323	if { ![is-effective-target ia32] } {
7324	    lappend result 64
7325	}
7326    } elseif { [istarget sparc*-*-*] } {
7327	lappend result 64
7328    } elseif { [istarget amdgcn*-*-*] } {
7329	lappend result 4096
7330    } else {
7331	# The traditional default asumption.
7332	lappend result 128
7333    }
7334    return $result
7335}
7336
7337# Return 1 if the target supports multiple vector sizes
7338
7339proc check_effective_target_vect_multiple_sizes { } {
7340    return [expr { [llength [available_vector_sizes]] > 1 }]
7341}
7342
7343# Return true if variable-length vectors are supported.
7344
7345proc check_effective_target_vect_variable_length { } {
7346    return [expr { [lindex [available_vector_sizes] 0] == 0 }]
7347}
7348
7349# Return 1 if the target supports vectors of 64 bits.
7350
7351proc check_effective_target_vect64 { } {
7352    return [expr { [lsearch -exact [available_vector_sizes] 64] >= 0 }]
7353}
7354
7355# Return 1 if the target supports vector copysignf calls.
7356
7357proc check_effective_target_vect_call_copysignf { } {
7358    return [check_cached_effective_target_indexed vect_call_copysignf {
7359      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
7360	     || [istarget powerpc*-*-*]
7361	     || [istarget aarch64*-*-*] }}]
7362}
7363
7364# Return 1 if the target supports hardware square root instructions.
7365
7366proc check_effective_target_sqrt_insn { } {
7367    return [check_cached_effective_target sqrt_insn {
7368      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
7369	     || [istarget powerpc*-*-*]
7370	     || [istarget aarch64*-*-*]
7371	     || ([istarget arm*-*-*] && [check_effective_target_arm_vfp_ok])
7372	     || ([istarget s390*-*-*]
7373		 && [check_effective_target_s390_vx])
7374	     || [istarget amdgcn-*-*] }}]
7375}
7376
7377# Return any additional options to enable square root intructions.
7378
7379proc add_options_for_sqrt_insn { flags } {
7380    if { [istarget amdgcn*-*-*] } {
7381	return "$flags -ffast-math"
7382    }
7383    if { [istarget arm*-*-*] } {
7384	return [add_options_for_arm_vfp "$flags"]
7385    }
7386    return $flags
7387}
7388
7389# Return 1 if the target supports vector sqrtf calls.
7390
7391proc check_effective_target_vect_call_sqrtf { } {
7392    return [check_cached_effective_target_indexed vect_call_sqrtf {
7393      expr { [istarget aarch64*-*-*]
7394	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
7395	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
7396	     || ([istarget s390*-*-*]
7397		 && [check_effective_target_s390_vx]) }}]
7398}
7399
7400# Return 1 if the target supports vector lrint calls.
7401
7402proc check_effective_target_vect_call_lrint { } {
7403    set et_vect_call_lrint 0
7404    if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
7405	  && [check_effective_target_ilp32])
7406	 || [istarget amdgcn-*-*] } {
7407	set et_vect_call_lrint 1
7408    }
7409
7410    verbose "check_effective_target_vect_call_lrint: returning $et_vect_call_lrint" 2
7411    return $et_vect_call_lrint
7412}
7413
7414# Return 1 if the target supports vector btrunc calls.
7415
7416proc check_effective_target_vect_call_btrunc { } {
7417    return [check_cached_effective_target_indexed vect_call_btrunc {
7418      expr { [istarget aarch64*-*-*]
7419	     || [istarget amdgcn-*-*] }}]
7420}
7421
7422# Return 1 if the target supports vector btruncf calls.
7423
7424proc check_effective_target_vect_call_btruncf { } {
7425    return [check_cached_effective_target_indexed vect_call_btruncf {
7426      expr { [istarget aarch64*-*-*]
7427	     || [istarget amdgcn-*-*] }}]
7428}
7429
7430# Return 1 if the target supports vector ceil calls.
7431
7432proc check_effective_target_vect_call_ceil { } {
7433    return [check_cached_effective_target_indexed vect_call_ceil {
7434      expr { [istarget aarch64*-*-*]
7435	     || [istarget amdgcn-*-*] }}]
7436}
7437
7438# Return 1 if the target supports vector ceilf calls.
7439
7440proc check_effective_target_vect_call_ceilf { } {
7441    return [check_cached_effective_target_indexed vect_call_ceilf {
7442      expr { [istarget aarch64*-*-*] }}]
7443}
7444
7445# Return 1 if the target supports vector floor calls.
7446
7447proc check_effective_target_vect_call_floor { } {
7448    return [check_cached_effective_target_indexed vect_call_floor {
7449      expr { [istarget aarch64*-*-*] }}]
7450}
7451
7452# Return 1 if the target supports vector floorf calls.
7453
7454proc check_effective_target_vect_call_floorf { } {
7455    return [check_cached_effective_target_indexed vect_call_floorf {
7456      expr { [istarget aarch64*-*-*]
7457	     || [istarget amdgcn-*-*] }}]
7458}
7459
7460# Return 1 if the target supports vector lceil calls.
7461
7462proc check_effective_target_vect_call_lceil { } {
7463    return [check_cached_effective_target_indexed vect_call_lceil {
7464      expr { [istarget aarch64*-*-*] }}]
7465}
7466
7467# Return 1 if the target supports vector lfloor calls.
7468
7469proc check_effective_target_vect_call_lfloor { } {
7470    return [check_cached_effective_target_indexed vect_call_lfloor {
7471      expr { [istarget aarch64*-*-*] }}]
7472}
7473
7474# Return 1 if the target supports vector nearbyint calls.
7475
7476proc check_effective_target_vect_call_nearbyint { } {
7477    return [check_cached_effective_target_indexed vect_call_nearbyint {
7478      expr { [istarget aarch64*-*-*] }}]
7479}
7480
7481# Return 1 if the target supports vector nearbyintf calls.
7482
7483proc check_effective_target_vect_call_nearbyintf { } {
7484    return [check_cached_effective_target_indexed vect_call_nearbyintf {
7485      expr { [istarget aarch64*-*-*] }}]
7486}
7487
7488# Return 1 if the target supports vector round calls.
7489
7490proc check_effective_target_vect_call_round { } {
7491    return [check_cached_effective_target_indexed vect_call_round {
7492      expr { [istarget aarch64*-*-*] }}]
7493}
7494
7495# Return 1 if the target supports vector roundf calls.
7496
7497proc check_effective_target_vect_call_roundf { } {
7498    return [check_cached_effective_target_indexed vect_call_roundf {
7499      expr { [istarget aarch64*-*-*] }}]
7500}
7501
7502# Return 1 if the target supports AND, OR and XOR reduction.
7503
7504proc check_effective_target_vect_logical_reduc { } {
7505    return [check_effective_target_aarch64_sve]
7506}
7507
7508# Return 1 if the target supports the fold_extract_last optab.
7509
7510proc check_effective_target_vect_fold_extract_last { } {
7511    return [expr { [check_effective_target_aarch64_sve]
7512		   || [istarget amdgcn*-*-*] }]
7513}
7514
7515# Return 1 if the target supports section-anchors
7516
7517proc check_effective_target_section_anchors { } {
7518    return [check_cached_effective_target section_anchors {
7519      expr { [istarget powerpc*-*-*]
7520	     || [istarget arm*-*-*]
7521	     || [istarget aarch64*-*-*] }}]
7522}
7523
7524# Return 1 if the target supports atomic operations on "int_128" values.
7525
7526proc check_effective_target_sync_int_128 { } {
7527    return 0
7528}
7529
7530# Return 1 if the target supports atomic operations on "int_128" values
7531# and can execute them.
7532# This requires support for both compare-and-swap and true atomic loads.
7533
7534proc check_effective_target_sync_int_128_runtime { } {
7535    return 0
7536}
7537
7538# Return 1 if the target supports atomic operations on "long long".
7539#
7540# Note: 32bit x86 targets require -march=pentium in dg-options.
7541# Note: 32bit s390 targets require -mzarch in dg-options.
7542
7543proc check_effective_target_sync_long_long { } {
7544    if { [istarget i?86-*-*] || [istarget x86_64-*-*])
7545	 || [istarget aarch64*-*-*]
7546	 || [istarget arm*-*-*]
7547	 || [istarget alpha*-*-*]
7548	 || ([istarget sparc*-*-*] && [check_effective_target_lp64])
7549	 || [istarget s390*-*-*] } {
7550	return 1
7551    } else {
7552	return 0
7553    }
7554}
7555
7556# Return 1 if the target supports popcount on long.
7557
7558proc check_effective_target_popcountl { } {
7559    return [check_no_messages_and_pattern popcountl "!\\(call" rtl-expand {
7560	int foo (long b)
7561	  {
7562	    return __builtin_popcountl (b);
7563	  }
7564    } "" ]
7565}
7566
7567# Return 1 if the target supports popcount on long long.
7568
7569proc check_effective_target_popcountll { } {
7570    return [check_no_messages_and_pattern popcountll "!\\(call" rtl-expand {
7571        int foo (long long b)
7572          {
7573            return __builtin_popcountll (b);
7574          }
7575    } "" ]
7576}
7577
7578
7579# Return 1 if the target supports popcount on int.
7580
7581proc check_effective_target_popcount { } {
7582    return [check_no_messages_and_pattern popcount "!\\(call" rtl-expand {
7583        int foo (int b)
7584          {
7585            return __builtin_popcount (b);
7586          }
7587    } "" ]
7588}
7589
7590# Return 1 if the target supports atomic operations on "long long"
7591# and can execute them.
7592#
7593# Note: 32bit x86 targets require -march=pentium in dg-options.
7594
7595proc check_effective_target_sync_long_long_runtime { } {
7596    if { (([istarget x86_64-*-*] || [istarget i?86-*-*])
7597	  && [check_cached_effective_target sync_long_long_available {
7598	      check_runtime_nocache sync_long_long_available {
7599		  #include "cpuid.h"
7600		  int main ()
7601		  {
7602		      unsigned int eax, ebx, ecx, edx;
7603		      if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
7604			return !(edx & bit_CMPXCHG8B);
7605		      return 1;
7606		  }
7607	      } ""
7608	  }])
7609	 || [istarget aarch64*-*-*]
7610	 || [istarget arm*-*-uclinuxfdpiceabi]
7611	 || ([istarget arm*-*-linux-*]
7612	     && [check_runtime sync_longlong_runtime {
7613		 #include <stdlib.h>
7614		 int main ()
7615		 {
7616		     long long l1;
7617
7618		     if (sizeof (long long) != 8)
7619		     exit (1);
7620
7621		     /* Just check for native;
7622			checking for kernel fallback is tricky.  */
7623		     asm volatile ("ldrexd r0,r1, [%0]"
7624				   : : "r" (&l1) : "r0", "r1");
7625		     exit (0);
7626		 }
7627	     } "" ])
7628	 || [istarget alpha*-*-*]
7629	 || ([istarget sparc*-*-*]
7630	     && [check_effective_target_lp64]
7631	     && [check_effective_target_ultrasparc_hw])
7632	 || ([istarget powerpc*-*-*] && [check_effective_target_lp64]) } {
7633	return 1
7634    } else {
7635	return 0
7636    }
7637}
7638
7639# Return 1 if the target supports byte swap instructions.
7640
7641proc check_effective_target_bswap { } {
7642    return [check_cached_effective_target bswap {
7643      expr { [istarget aarch64*-*-*]
7644	     || [istarget alpha*-*-*]
7645	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
7646	     || [istarget m68k-*-*]
7647	     || [istarget powerpc*-*-*]
7648	     || [istarget rs6000-*-*]
7649	     || [istarget s390*-*-*]
7650	     || ([istarget arm*-*-*]
7651		 && [check_no_compiler_messages_nocache arm_v6_or_later object {
7652		     #if __ARM_ARCH < 6
7653		     #error not armv6 or later
7654		     #endif
7655		     int i;
7656		 } ""]) }}]
7657}
7658
7659# Return 1 if the target supports atomic operations on "int" and "long".
7660
7661proc check_effective_target_sync_int_long { } {
7662# This is intentionally powerpc but not rs6000, rs6000 doesn't have the
7663# load-reserved/store-conditional instructions.
7664    return [check_cached_effective_target sync_int_long {
7665      expr { [istarget ia64-*-*]
7666	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
7667	     || [istarget aarch64*-*-*]
7668	     || [istarget alpha*-*-*]
7669	     || [istarget arm*-*-linux-*]
7670	     || [istarget arm*-*-uclinuxfdpiceabi]
7671	     || ([istarget arm*-*-*]
7672		 && [check_effective_target_arm_acq_rel])
7673	     || [istarget bfin*-*linux*]
7674	     || [istarget hppa*-*linux*]
7675	     || [istarget s390*-*-*]
7676	     || [istarget powerpc*-*-*]
7677	     || [istarget crisv32-*-*] || [istarget cris-*-*]
7678	     || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
7679	     || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
7680	     || [check_effective_target_mips_llsc] }}]
7681}
7682
7683# Return 1 if the target supports atomic operations on "char" and "short".
7684
7685proc check_effective_target_sync_char_short { } {
7686# This is intentionally powerpc but not rs6000, rs6000 doesn't have the
7687# load-reserved/store-conditional instructions.
7688    return [check_cached_effective_target sync_char_short {
7689      expr { [istarget aarch64*-*-*]
7690	     || [istarget ia64-*-*]
7691	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
7692	     || [istarget alpha*-*-*]
7693	     || [istarget arm*-*-linux-*]
7694	     || [istarget arm*-*-uclinuxfdpiceabi]
7695	     || ([istarget arm*-*-*]
7696		 && [check_effective_target_arm_acq_rel])
7697	     || [istarget hppa*-*linux*]
7698	     || [istarget s390*-*-*]
7699	     || [istarget powerpc*-*-*]
7700	     || [istarget crisv32-*-*] || [istarget cris-*-*]
7701	     || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
7702	     || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
7703	     || [check_effective_target_mips_llsc] }}]
7704}
7705
7706# Return 1 if the target uses a ColdFire FPU.
7707
7708proc check_effective_target_coldfire_fpu { } {
7709    return [check_no_compiler_messages coldfire_fpu assembly {
7710	#ifndef __mcffpu__
7711	#error !__mcffpu__
7712	#endif
7713    }]
7714}
7715
7716# Return true if this is a uClibc target.
7717
7718proc check_effective_target_uclibc {} {
7719    return [check_no_compiler_messages uclibc object {
7720	#include <features.h>
7721	#if !defined (__UCLIBC__)
7722	#error !__UCLIBC__
7723	#endif
7724    }]
7725}
7726
7727# Return true if this is a uclibc target and if the uclibc feature
7728# described by __$feature__ is not present.
7729
7730proc check_missing_uclibc_feature {feature} {
7731    return [check_no_compiler_messages $feature object "
7732	#include <features.h>
7733	#if !defined (__UCLIBC) || defined (__${feature}__)
7734	#error FOO
7735	#endif
7736    "]
7737}
7738
7739# Return true if this is a Newlib target.
7740
7741proc check_effective_target_newlib {} {
7742    return [check_no_compiler_messages newlib object {
7743	#include <newlib.h>
7744    }]
7745}
7746
7747# Return true if GCC was configured with --enable-newlib-nano-formatted-io
7748proc check_effective_target_newlib_nano_io { } {
7749    return [check_configured_with "--enable-newlib-nano-formatted-io"]
7750}
7751
7752# Some newlib versions don't provide a frexpl and instead depend
7753# on frexp to implement long double conversions in their printf-like
7754# functions.  This leads to broken results.  Detect such versions here.
7755
7756proc check_effective_target_newlib_broken_long_double_io {} {
7757  if { [is-effective-target newlib] && ![is-effective-target frexpl] } {
7758	return 1
7759  }
7760  return 0
7761}
7762
7763# Return true if this is NOT a Bionic target.
7764
7765proc check_effective_target_non_bionic {} {
7766    return [check_no_compiler_messages non_bionic object {
7767	#include <ctype.h>
7768	#if defined (__BIONIC__)
7769	#error FOO
7770	#endif
7771    }]
7772}
7773
7774# Return true if this target has error.h header.
7775
7776proc check_effective_target_error_h {} {
7777    return [check_no_compiler_messages error_h object {
7778 #include <error.h>
7779    }]
7780}
7781
7782# Return true if this target has tgmath.h header.
7783
7784proc check_effective_target_tgmath_h {} {
7785    return [check_no_compiler_messages tgmath_h object {
7786 #include <tgmath.h>
7787    }]
7788}
7789
7790# Return true if target's libc supports complex functions.
7791
7792proc check_effective_target_libc_has_complex_functions {} {
7793    return [check_no_compiler_messages libc_has_complex_functions object {
7794 #include <complex.h>
7795    }]
7796}
7797
7798# Return 1 if
7799#   (a) an error of a few ULP is expected in string to floating-point
7800#       conversion functions; and
7801#   (b) overflow is not always detected correctly by those functions.
7802
7803proc check_effective_target_lax_strtofp {} {
7804    # By default, assume that all uClibc targets suffer from this.
7805    return [check_effective_target_uclibc]
7806}
7807
7808# Return 1 if this is a target for which wcsftime is a dummy
7809# function that always returns 0.
7810
7811proc check_effective_target_dummy_wcsftime {} {
7812    # By default, assume that all uClibc targets suffer from this.
7813    return [check_effective_target_uclibc]
7814}
7815
7816# Return 1 if constructors with initialization priority arguments are
7817# supposed on this target.
7818
7819proc check_effective_target_init_priority {} {
7820    return [check_no_compiler_messages init_priority assembly "
7821	void f() __attribute__((constructor (1000)));
7822	void f() \{\}
7823    "]
7824}
7825
7826# Return 1 if the target matches the effective target 'arg', 0 otherwise.
7827# This can be used with any check_* proc that takes no argument and
7828# returns only 1 or 0.  It could be used with check_* procs that take
7829# arguments with keywords that pass particular arguments.
7830
7831proc is-effective-target { arg } {
7832    global et_index
7833    set selected 0
7834    if { ![info exists et_index] } {
7835	# Initialize the effective target index that is used in some
7836	# check_effective_target_* procs.
7837	set et_index 0
7838    }
7839    if { [info procs check_effective_target_${arg}] != [list] } {
7840	set selected [check_effective_target_${arg}]
7841    } else {
7842	switch $arg {
7843	  "vmx_hw"         { set selected [check_vmx_hw_available] }
7844	  "vsx_hw"         { set selected [check_vsx_hw_available] }
7845	  "p8vector_hw"    { set selected [check_p8vector_hw_available] }
7846	  "p9vector_hw"    { set selected [check_p9vector_hw_available] }
7847	  "p9modulo_hw"    { set selected [check_p9modulo_hw_available] }
7848	  "power10_hw"     { set selected [check_power10_hw_available] }
7849	  "ppc_float128_sw" { set selected [check_ppc_float128_sw_available] }
7850	  "ppc_float128_hw" { set selected [check_ppc_float128_hw_available] }
7851	  "ppc_recip_hw"   { set selected [check_ppc_recip_hw_available] }
7852	  "ppc_cpu_supports_hw" { set selected [check_ppc_cpu_supports_hw_available] }
7853	  "ppc_mma_hw"     { set selected [check_ppc_mma_hw_available] }
7854	  "dfp_hw"         { set selected [check_dfp_hw_available] }
7855	  "htm_hw"         { set selected [check_htm_hw_available] }
7856	  "named_sections" { set selected [check_named_sections_available] }
7857	  "gc_sections"    { set selected [check_gc_sections_available] }
7858	  "cxa_atexit"     { set selected [check_cxa_atexit_available] }
7859	  default          { error "unknown effective target keyword `$arg'" }
7860	}
7861    }
7862
7863    verbose "is-effective-target: $arg $selected" 2
7864    return $selected
7865}
7866
7867# Return 1 if the argument is an effective-target keyword, 0 otherwise.
7868
7869proc is-effective-target-keyword { arg } {
7870    if { [info procs check_effective_target_${arg}] != [list] } {
7871	return 1
7872    } else {
7873	# These have different names for their check_* procs.
7874	switch $arg {
7875	  "vmx_hw"         { return 1 }
7876	  "vsx_hw"         { return 1 }
7877	  "p8vector_hw"    { return 1 }
7878	  "p9vector_hw"    { return 1 }
7879	  "p9modulo_hw"    { return 1 }
7880	  "power10_hw"     { return 1 }
7881	  "ppc_float128_sw" { return 1 }
7882	  "ppc_float128_hw" { return 1 }
7883	  "ppc_recip_hw"   { return 1 }
7884	  "ppc_mma_hw"     { return 1 }
7885	  "dfp_hw"         { return 1 }
7886	  "htm_hw"         { return 1 }
7887	  "named_sections" { return 1 }
7888	  "gc_sections"    { return 1 }
7889	  "cxa_atexit"     { return 1 }
7890	  default          { return 0 }
7891	}
7892    }
7893}
7894
7895# Execute tests for all targets in EFFECTIVE_TARGETS list.  Set et_index to
7896# indicate what target is currently being processed.  This is for
7897# the vectorizer tests, e.g. vect_int, to keep track what target supports
7898# a given feature.
7899
7900proc et-dg-runtest { runtest testcases flags default-extra-flags } {
7901    global dg-do-what-default
7902    global EFFECTIVE_TARGETS
7903    global et_index
7904
7905    if { [llength $EFFECTIVE_TARGETS] > 0 } {
7906	foreach target $EFFECTIVE_TARGETS {
7907	    set target_flags $flags
7908	    set dg-do-what-default compile
7909	    set et_index [lsearch -exact $EFFECTIVE_TARGETS $target]
7910	    if { [info procs add_options_for_${target}] != [list] } {
7911		set target_flags [add_options_for_${target} "$flags"]
7912	    }
7913	    if { [info procs check_effective_target_${target}_runtime]
7914		 != [list] && [check_effective_target_${target}_runtime] } {
7915		set dg-do-what-default run
7916	    }
7917	    $runtest $testcases $target_flags ${default-extra-flags}
7918	}
7919    } else {
7920	set et_index 0
7921	$runtest $testcases $flags ${default-extra-flags}
7922    }
7923}
7924
7925# Return 1 if a target matches the target in EFFECTIVE_TARGETS at index
7926# et_index, 0 otherwise.
7927
7928proc et-is-effective-target { target } {
7929    global EFFECTIVE_TARGETS
7930    global et_index
7931
7932    if { [llength $EFFECTIVE_TARGETS] > $et_index
7933	 && [lindex $EFFECTIVE_TARGETS $et_index] == $target } {
7934	    return 1
7935    }
7936    return 0
7937}
7938
7939# Return 1 if target default to short enums
7940
7941proc check_effective_target_short_enums { } {
7942    return [check_no_compiler_messages short_enums assembly {
7943	enum foo { bar };
7944	int s[sizeof (enum foo) == 1 ? 1 : -1];
7945    }]
7946}
7947
7948# Return 1 if target supports merging string constants at link time.
7949
7950proc check_effective_target_string_merging { } {
7951    return [check_no_messages_and_pattern string_merging \
7952		"rodata\\.str" assembly {
7953		    const char *var = "String";
7954		} {-O2}]
7955}
7956
7957# Return 1 if target has the basic signed and unsigned types in
7958# <stdint.h>, 0 otherwise.  This will be obsolete when GCC ensures a
7959# working <stdint.h> for all targets.
7960
7961proc check_effective_target_stdint_types { } {
7962    return [check_no_compiler_messages stdint_types assembly {
7963	#include <stdint.h>
7964	int8_t a; int16_t b; int32_t c; int64_t d;
7965	uint8_t e; uint16_t f; uint32_t g; uint64_t h;
7966    }]
7967}
7968
7969# Return 1 if target has the basic signed and unsigned types in
7970# <inttypes.h>, 0 otherwise.  This is for tests that GCC's notions of
7971# these types agree with those in the header, as some systems have
7972# only <inttypes.h>.
7973
7974proc check_effective_target_inttypes_types { } {
7975    return [check_no_compiler_messages inttypes_types assembly {
7976	#include <inttypes.h>
7977	int8_t a; int16_t b; int32_t c; int64_t d;
7978	uint8_t e; uint16_t f; uint32_t g; uint64_t h;
7979    }]
7980}
7981
7982# Return 1 if programs are intended to be run on a simulator
7983# (i.e. slowly) rather than hardware (i.e. fast).
7984
7985proc check_effective_target_simulator { } {
7986
7987    # All "src/sim" simulators set this one.
7988    if [board_info target exists is_simulator] {
7989	return [board_info target is_simulator]
7990    }
7991
7992    # The "sid" simulators don't set that one, but at least they set
7993    # this one.
7994    if [board_info target exists slow_simulator] {
7995	return [board_info target slow_simulator]
7996    }
7997
7998    return 0
7999}
8000
8001# Return 1 if programs are intended to be run on hardware rather than
8002# on a simulator
8003
8004proc check_effective_target_hw { } {
8005
8006    # All "src/sim" simulators set this one.
8007    if [board_info target exists is_simulator] {
8008	if [board_info target is_simulator] {
8009	  return 0
8010	} else {
8011	  return 1
8012	}
8013    }
8014
8015    # The "sid" simulators don't set that one, but at least they set
8016    # this one.
8017    if [board_info target exists slow_simulator] {
8018	if [board_info target slow_simulator] {
8019	  return 0
8020	} else {
8021	  return 1
8022	}
8023    }
8024
8025    return 1
8026}
8027
8028# Return 1 if the target is a VxWorks kernel.
8029
8030proc check_effective_target_vxworks_kernel { } {
8031    return [check_no_compiler_messages vxworks_kernel assembly {
8032	#if !defined __vxworks || defined __RTP__
8033	#error NO
8034	#endif
8035    }]
8036}
8037
8038# Return 1 if the target is a VxWorks RTP.
8039
8040proc check_effective_target_vxworks_rtp { } {
8041    return [check_no_compiler_messages vxworks_rtp assembly {
8042	#if !defined __vxworks || !defined __RTP__
8043	#error NO
8044	#endif
8045    }]
8046}
8047
8048# Return 1 if the target is expected to provide wide character support.
8049
8050proc check_effective_target_wchar { } {
8051    if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} {
8052	return 0
8053    }
8054    return [check_no_compiler_messages wchar assembly {
8055	#include <wchar.h>
8056    }]
8057}
8058
8059# Return 1 if the target has <pthread.h>.
8060
8061proc check_effective_target_pthread_h { } {
8062    return [check_no_compiler_messages pthread_h assembly {
8063	#include <pthread.h>
8064    }]
8065}
8066
8067# Return 1 if the target can truncate a file from a file-descriptor,
8068# as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or
8069# chsize.  We test for a trivially functional truncation; no stubs.
8070# As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a
8071# different function to be used.
8072
8073proc check_effective_target_fd_truncate { } {
8074    set prog {
8075	#define _FILE_OFFSET_BITS 64
8076	#include <unistd.h>
8077	#include <stdio.h>
8078	#include <stdlib.h>
8079	#include <string.h>
8080	int main ()
8081	{
8082	  FILE *f = fopen ("tst.tmp", "wb");
8083	  int fd;
8084	  const char t[] = "test writing more than ten characters";
8085	  char s[11];
8086	  int status = 0;
8087	  fd = fileno (f);
8088	  write (fd, t, sizeof (t) - 1);
8089	  lseek (fd, 0, 0);
8090	  if (ftruncate (fd, 10) != 0)
8091	    status = 1;
8092	  close (fd);
8093	  fclose (f);
8094	  if (status)
8095	    {
8096	      unlink ("tst.tmp");
8097	      exit (status);
8098	    }
8099	  f = fopen ("tst.tmp", "rb");
8100	  if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0)
8101	    status = 1;
8102	  fclose (f);
8103	  unlink ("tst.tmp");
8104	  exit (status);
8105	}
8106    }
8107
8108    if { [check_runtime ftruncate $prog] } {
8109      return 1;
8110    }
8111
8112    regsub "ftruncate" $prog "chsize" prog
8113    return [check_runtime chsize $prog]
8114}
8115
8116# Add to FLAGS all the target-specific flags needed to enable
8117# full IEEE compliance mode.
8118
8119proc add_options_for_ieee { flags } {
8120    if { [istarget alpha*-*-*]
8121         || [istarget sh*-*-*] } {
8122       return "$flags -mieee"
8123    }
8124    if { [istarget rx-*-*] } {
8125       return "$flags -mnofpu"
8126    }
8127    return $flags
8128}
8129
8130if {![info exists flags_to_postpone]} {
8131    set flags_to_postpone ""
8132}
8133
8134# Add to FLAGS the flags needed to enable functions to bind locally
8135# when using pic/PIC passes in the testsuite.
8136proc add_options_for_bind_pic_locally { flags } {
8137    global flags_to_postpone
8138
8139    # Instead of returning 'flags' with the -fPIE or -fpie appended, we save it
8140    # in 'flags_to_postpone' and append it later in gcc_target_compile procedure in
8141    # order to make sure that the multilib_flags doesn't override this.
8142
8143    if {[check_no_compiler_messages using_pic2 assembly {
8144        #if __PIC__ != 2
8145        #error __PIC__ != 2
8146        #endif
8147    }]} {
8148        set flags_to_postpone "-fPIE"
8149        return $flags
8150    }
8151    if {[check_no_compiler_messages using_pic1 assembly {
8152        #if __PIC__ != 1
8153        #error __PIC__ != 1
8154        #endif
8155    }]} {
8156        set flags_to_postpone "-fpie"
8157        return $flags
8158    }
8159    return $flags
8160}
8161
8162# Add to FLAGS the flags needed to enable 64-bit vectors.
8163
8164proc add_options_for_double_vectors { flags } {
8165    if [is-effective-target arm_neon_ok] {
8166	return "$flags -mvectorize-with-neon-double"
8167    }
8168
8169    return $flags
8170}
8171
8172# Add to FLAGS the flags needed to define the STACK_SIZE macro.
8173
8174proc add_options_for_stack_size { flags } {
8175    if [is-effective-target stack_size] {
8176	set stack_size [dg-effective-target-value stack_size]
8177	return "$flags -DSTACK_SIZE=$stack_size"
8178    }
8179
8180    return $flags
8181}
8182
8183# Return 1 if the target provides a full C99 runtime.
8184
8185proc check_effective_target_c99_runtime { } {
8186    return [check_cached_effective_target c99_runtime {
8187	global srcdir
8188
8189	set file [open "$srcdir/gcc.dg/builtins-config.h"]
8190	set contents [read $file]
8191	close $file
8192	append contents {
8193	    #ifndef HAVE_C99_RUNTIME
8194	    #error !HAVE_C99_RUNTIME
8195	    #endif
8196	}
8197	check_no_compiler_messages_nocache c99_runtime assembly $contents
8198    }]
8199}
8200
8201# Return 1 if the target provides the D runtime.
8202
8203proc check_effective_target_d_runtime { } {
8204    return [check_no_compiler_messages d_runtime executable {
8205	// D
8206	module mod;
8207
8208	extern(C) int main() {
8209	    return 0;
8210	}
8211    }]
8212}
8213
8214# Return 1 if the target provides the D standard library.
8215
8216proc check_effective_target_d_runtime_has_std_library { } {
8217    return [check_no_compiler_messages d_runtime_has_std_library executable {
8218	// D
8219	module mod;
8220
8221	extern(C) int main() {
8222	    import std.math;
8223	    real function(real) pcos = &cos;
8224	    return 0;
8225	}
8226    }]
8227}
8228
8229# Return 1 if  target wchar_t is at least 4 bytes.
8230
8231proc check_effective_target_4byte_wchar_t { } {
8232    return [check_no_compiler_messages 4byte_wchar_t object {
8233	int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1];
8234    }]
8235}
8236
8237# Return 1 if the target supports automatic stack alignment.
8238
8239proc check_effective_target_automatic_stack_alignment  { } {
8240    # Ordinarily x86 supports automatic stack alignment ...
8241    if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
8242        if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
8243	    # ... except Win64 SEH doesn't.  Succeed for Win32 though.
8244	    return [check_effective_target_ilp32];
8245	}
8246	return 1;
8247    }
8248    return 0;
8249}
8250
8251# Return true if we are compiling for AVX target.
8252
8253proc check_avx_available { } {
8254  if { [check_no_compiler_messages avx_available assembly {
8255    #ifndef __AVX__
8256    #error unsupported
8257    #endif
8258  } ""] } {
8259    return 1;
8260  }
8261  return 0;
8262}
8263
8264# Return true if we are compiling for AVX2 target.
8265
8266proc check_avx2_available { } {
8267  if { [check_no_compiler_messages avx2_available assembly {
8268    #ifndef __AVX2__
8269    #error unsupported
8270    #endif
8271  } ""] } {
8272    return 1;
8273  }
8274  return 0;
8275}
8276
8277# Return true if we are compiling for SSSE3 target.
8278
8279proc check_ssse3_available { } {
8280  if { [check_no_compiler_messages sse3a_available assembly {
8281    #ifndef __SSSE3__
8282    #error unsupported
8283    #endif
8284  } ""] } {
8285    return 1;
8286  }
8287  return 0;
8288}
8289
8290# Return true if 32- and 16-bytes vectors are available.
8291
8292proc check_effective_target_vect_sizes_32B_16B { } {
8293    return [expr { [available_vector_sizes] == [list 256 128] }]
8294}
8295
8296# Return true if 16- and 8-bytes vectors are available.
8297
8298proc check_effective_target_vect_sizes_16B_8B { } {
8299  if { [check_avx_available]
8300       || [is-effective-target arm_neon]
8301       || [istarget aarch64*-*-*] } {
8302     return 1;
8303  } else {
8304    return 0;
8305  }
8306}
8307
8308
8309# Return true if 128-bits vectors are preferred even if 256-bits vectors
8310# are available.
8311
8312proc check_prefer_avx128 { } {
8313    if ![check_avx_available] {
8314      return 0;
8315    }
8316    return [check_no_messages_and_pattern avx_explicit "xmm" assembly {
8317      float a[1024],b[1024],c[1024];
8318      void foo (void) { int i; for (i = 0; i < 1024; i++) a[i]=b[i]+c[i];}
8319    } "-O2 -ftree-vectorize"]
8320}
8321
8322
8323# Return 1 if avx512f instructions can be compiled.
8324
8325proc check_effective_target_avx512f { } {
8326    return [check_no_compiler_messages avx512f object {
8327	typedef double __m512d __attribute__ ((__vector_size__ (64)));
8328	typedef double __m128d __attribute__ ((__vector_size__ (16)));
8329
8330	__m512d _mm512_add (__m512d a)
8331	{
8332	  return __builtin_ia32_addpd512_mask (a, a, a, 1, 4);
8333	}
8334
8335	__m128d _mm128_add (__m128d a)
8336	{
8337	  return __builtin_ia32_addsd_round (a, a, 8);
8338	}
8339
8340	__m128d _mm128_getmant (__m128d a)
8341	{
8342	  return __builtin_ia32_getmantsd_round (a, a, 0, 8);
8343	}
8344    } "-O2 -mavx512f" ]
8345}
8346
8347# Return 1 if avx instructions can be compiled.
8348
8349proc check_effective_target_avx { } {
8350    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
8351	return 0
8352    }
8353    return [check_no_compiler_messages avx object {
8354	void _mm256_zeroall (void)
8355	{
8356	   __builtin_ia32_vzeroall ();
8357	}
8358    } "-O2 -mavx" ]
8359}
8360
8361# Return 1 if avx2 instructions can be compiled.
8362proc check_effective_target_avx2 { } {
8363    return [check_no_compiler_messages avx2 object {
8364	typedef long long __v4di __attribute__ ((__vector_size__ (32)));
8365	__v4di
8366	mm256_is32_andnotsi256  (__v4di __X, __v4di __Y)
8367        {
8368	   return __builtin_ia32_andnotsi256 (__X, __Y);
8369	}
8370    } "-O0 -mavx2" ]
8371}
8372
8373# Return 1 if sse instructions can be compiled.
8374proc check_effective_target_sse { } {
8375    return [check_no_compiler_messages sse object {
8376	int main ()
8377	{
8378	    __builtin_ia32_stmxcsr ();
8379	    return 0;
8380	}
8381    } "-O2 -msse" ]
8382}
8383
8384# Return 1 if sse2 instructions can be compiled.
8385proc check_effective_target_sse2 { } {
8386    return [check_no_compiler_messages sse2 object {
8387	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8388
8389	__m128i _mm_srli_si128 (__m128i __A, int __N)
8390	{
8391	    return (__m128i)__builtin_ia32_psrldqi128 (__A, 8);
8392	}
8393    } "-O2 -msse2" ]
8394}
8395
8396# Return 1 if sse4.1 instructions can be compiled.
8397proc check_effective_target_sse4 { } {
8398    return [check_no_compiler_messages sse4.1 object {
8399	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8400	typedef int __v4si __attribute__ ((__vector_size__ (16)));
8401
8402	__m128i _mm_mullo_epi32 (__m128i __X, __m128i __Y)
8403	{
8404	    return (__m128i) __builtin_ia32_pmulld128 ((__v4si)__X,
8405						       (__v4si)__Y);
8406	}
8407    } "-O2 -msse4.1" ]
8408}
8409
8410# Return 1 if F16C instructions can be compiled.
8411
8412proc check_effective_target_f16c { } {
8413    return [check_no_compiler_messages f16c object {
8414	#include "immintrin.h"
8415	float
8416	foo (unsigned short val)
8417	{
8418	  return _cvtsh_ss (val);
8419	}
8420    } "-O2 -mf16c" ]
8421}
8422
8423proc check_effective_target_ms_hook_prologue { } {
8424    if { [check_no_compiler_messages ms_hook_prologue object {
8425	     void __attribute__ ((__ms_hook_prologue__)) foo ();
8426	 } ""] } {
8427	return 1
8428    } else {
8429	return 0
8430    }
8431}
8432
8433# Return 1 if 3dnow instructions can be compiled.
8434proc check_effective_target_3dnow { } {
8435    return [check_no_compiler_messages 3dnow object {
8436	typedef int __m64 __attribute__ ((__vector_size__ (8)));
8437	typedef float __v2sf __attribute__ ((__vector_size__ (8)));
8438
8439	__m64 _m_pfadd (__m64 __A, __m64 __B)
8440	{
8441	    return (__m64) __builtin_ia32_pfadd ((__v2sf)__A, (__v2sf)__B);
8442	}
8443    } "-O2 -m3dnow" ]
8444}
8445
8446# Return 1 if sse3 instructions can be compiled.
8447proc check_effective_target_sse3 { } {
8448    return [check_no_compiler_messages sse3 object {
8449	typedef double __m128d __attribute__ ((__vector_size__ (16)));
8450	typedef double __v2df __attribute__ ((__vector_size__ (16)));
8451
8452	__m128d _mm_addsub_pd (__m128d __X, __m128d __Y)
8453	{
8454	    return (__m128d) __builtin_ia32_addsubpd ((__v2df)__X, (__v2df)__Y);
8455	}
8456    } "-O2 -msse3" ]
8457}
8458
8459# Return 1 if ssse3 instructions can be compiled.
8460proc check_effective_target_ssse3 { } {
8461    return [check_no_compiler_messages ssse3 object {
8462	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8463	typedef int __v4si __attribute__ ((__vector_size__ (16)));
8464
8465	__m128i _mm_abs_epi32 (__m128i __X)
8466	{
8467	    return (__m128i) __builtin_ia32_pabsd128 ((__v4si)__X);
8468	}
8469    } "-O2 -mssse3" ]
8470}
8471
8472# Return 1 if aes instructions can be compiled.
8473proc check_effective_target_aes { } {
8474    return [check_no_compiler_messages aes object {
8475	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8476	typedef long long __v2di __attribute__ ((__vector_size__ (16)));
8477
8478	__m128i _mm_aesimc_si128 (__m128i __X)
8479	{
8480	    return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X);
8481	}
8482    } "-O2 -maes" ]
8483}
8484
8485# Return 1 if vaes instructions can be compiled.
8486proc check_effective_target_vaes { } {
8487    return [check_no_compiler_messages vaes object {
8488	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8489	typedef long long __v2di __attribute__ ((__vector_size__ (16)));
8490
8491	__m128i _mm_aesimc_si128 (__m128i __X)
8492	{
8493	    return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X);
8494	}
8495    } "-O2 -maes -mavx" ]
8496}
8497
8498# Return 1 if pclmul instructions can be compiled.
8499proc check_effective_target_pclmul { } {
8500    return [check_no_compiler_messages pclmul object {
8501	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8502	typedef long long __v2di __attribute__ ((__vector_size__ (16)));
8503
8504	__m128i pclmulqdq_test (__m128i __X, __m128i __Y)
8505	{
8506	    return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X,
8507							  (__v2di)__Y,
8508							  1);
8509	}
8510    } "-O2 -mpclmul" ]
8511}
8512
8513# Return 1 if vpclmul instructions can be compiled.
8514proc check_effective_target_vpclmul { } {
8515    return [check_no_compiler_messages vpclmul object {
8516	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8517	typedef long long __v2di __attribute__ ((__vector_size__ (16)));
8518
8519	__m128i pclmulqdq_test (__m128i __X, __m128i __Y)
8520	{
8521	    return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X,
8522							  (__v2di)__Y,
8523							  1);
8524	}
8525    } "-O2 -mpclmul -mavx" ]
8526}
8527
8528# Return 1 if sse4a instructions can be compiled.
8529proc check_effective_target_sse4a { } {
8530    return [check_no_compiler_messages sse4a object {
8531	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8532	typedef long long __v2di __attribute__ ((__vector_size__ (16)));
8533
8534	__m128i _mm_insert_si64 (__m128i __X,__m128i __Y)
8535	{
8536	    return (__m128i) __builtin_ia32_insertq ((__v2di)__X, (__v2di)__Y);
8537	}
8538    } "-O2 -msse4a" ]
8539}
8540
8541# Return 1 if fma4 instructions can be compiled.
8542proc check_effective_target_fma4 { } {
8543    return [check_no_compiler_messages fma4 object {
8544        typedef float __m128 __attribute__ ((__vector_size__ (16)));
8545	typedef float __v4sf __attribute__ ((__vector_size__ (16)));
8546	__m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C)
8547	{
8548	    return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A,
8549						     (__v4sf)__B,
8550						     (__v4sf)__C);
8551	}
8552    } "-O2 -mfma4" ]
8553}
8554
8555# Return 1 if fma instructions can be compiled.
8556proc check_effective_target_fma { } {
8557    return [check_no_compiler_messages fma object {
8558        typedef float __m128 __attribute__ ((__vector_size__ (16)));
8559	typedef float __v4sf __attribute__ ((__vector_size__ (16)));
8560	__m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C)
8561	{
8562	    return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A,
8563						     (__v4sf)__B,
8564						     (__v4sf)__C);
8565	}
8566    } "-O2 -mfma" ]
8567}
8568
8569# Return 1 if xop instructions can be compiled.
8570proc check_effective_target_xop { } {
8571    return [check_no_compiler_messages xop object {
8572	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8573	typedef short __v8hi __attribute__ ((__vector_size__ (16)));
8574	__m128i _mm_maccs_epi16(__m128i __A, __m128i __B, __m128i __C)
8575	{
8576	    return (__m128i) __builtin_ia32_vpmacssww ((__v8hi)__A,
8577						       (__v8hi)__B,
8578						       (__v8hi)__C);
8579	}
8580    } "-O2 -mxop" ]
8581}
8582
8583# Return 1 if lzcnt instruction can be compiled.
8584proc check_effective_target_lzcnt { } {
8585    return [check_no_compiler_messages lzcnt object {
8586	unsigned short _lzcnt (unsigned short __X)
8587	{
8588	   return __builtin_clzs (__X);
8589	}
8590    } "-mlzcnt" ]
8591}
8592
8593# Return 1 if bmi instructions can be compiled.
8594proc check_effective_target_bmi { } {
8595    return [check_no_compiler_messages bmi object {
8596	unsigned int __bextr_u32 (unsigned int __X, unsigned int __Y)
8597	{
8598	  return __builtin_ia32_bextr_u32 (__X, __Y);
8599	}
8600    } "-mbmi" ]
8601}
8602
8603# Return 1 if ADX instructions can be compiled.
8604proc check_effective_target_adx { } {
8605    return [check_no_compiler_messages adx object {
8606	unsigned char
8607	_adxcarry_u32 (unsigned char __CF, unsigned int __X,
8608		   unsigned int __Y, unsigned int *__P)
8609	{
8610	    return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P);
8611	}
8612    } "-madx" ]
8613}
8614
8615# Return 1 if rtm instructions can be compiled.
8616proc check_effective_target_rtm { } {
8617    return [check_no_compiler_messages rtm object {
8618	void
8619	_rtm_xend (void)
8620	{
8621	    return __builtin_ia32_xend ();
8622	}
8623    } "-mrtm" ]
8624}
8625
8626# Return 1 if avx512vl instructions can be compiled.
8627proc check_effective_target_avx512vl { } {
8628    return [check_no_compiler_messages avx512vl object {
8629	typedef long long __v4di __attribute__ ((__vector_size__ (32)));
8630	__v4di
8631	mm256_and_epi64  (__v4di __X, __v4di __Y)
8632	{
8633            __v4di __W;
8634            return __builtin_ia32_pandq256_mask (__X, __Y, __W, -1);
8635	}
8636    } "-mavx512vl" ]
8637}
8638
8639# Return 1 if avx512cd instructions can be compiled.
8640proc check_effective_target_avx512cd { } {
8641    return [check_no_compiler_messages avx512cd_trans object {
8642	typedef long long __v8di __attribute__ ((__vector_size__ (64)));
8643	__v8di
8644	_mm512_conflict_epi64 (__v8di __W, __v8di __A)
8645	{
8646	  return (__v8di) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A,
8647								 (__v8di) __W,
8648								 -1);
8649	}
8650   } "-Wno-psabi -mavx512cd" ]
8651}
8652
8653# Return 1 if avx512er instructions can be compiled.
8654proc check_effective_target_avx512er { } {
8655    return [check_no_compiler_messages avx512er_trans object {
8656	typedef float __v16sf __attribute__ ((__vector_size__ (64)));
8657	__v16sf
8658	mm512_exp2a23_ps  (__v16sf __X)
8659	{
8660	    return __builtin_ia32_exp2ps_mask (__X, __X, -1, 4);
8661	}
8662   } "-Wno-psabi -mavx512er" ]
8663}
8664
8665# Return 1 if sha instructions can be compiled.
8666proc check_effective_target_sha { } {
8667    return [check_no_compiler_messages sha object {
8668	typedef long long __m128i __attribute__ ((__vector_size__ (16)));
8669	typedef int __v4si __attribute__ ((__vector_size__ (16)));
8670
8671	__m128i _mm_sha1msg1_epu32 (__m128i __X, __m128i __Y)
8672	{
8673            return (__m128i) __builtin_ia32_sha1msg1 ((__v4si)__X,
8674						      (__v4si)__Y);
8675	}
8676    } "-O2 -msha" ]
8677}
8678
8679# Return 1 if avx512dq instructions can be compiled.
8680proc check_effective_target_avx512dq { } {
8681    return [check_no_compiler_messages avx512dq object {
8682	typedef long long __v8di __attribute__ ((__vector_size__ (64)));
8683	__v8di
8684	_mm512_mask_mullo_epi64 (__v8di __W, __v8di __A, __v8di __B)
8685	{
8686	    return (__v8di) __builtin_ia32_pmullq512_mask ((__v8di) __A,
8687							    (__v8di) __B,
8688							    (__v8di) __W,
8689							    -1);
8690	}
8691    } "-mavx512dq" ]
8692}
8693
8694# Return 1 if avx512bw instructions can be compiled.
8695proc check_effective_target_avx512bw { } {
8696    return [check_no_compiler_messages avx512bw object {
8697	typedef short __v32hi __attribute__ ((__vector_size__ (64)));
8698	__v32hi
8699	_mm512_mask_mulhrs_epi16 (__v32hi __W, __v32hi __A, __v32hi __B)
8700	{
8701	    return (__v32hi) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A,
8702							    (__v32hi) __B,
8703							    (__v32hi) __W,
8704							    -1);
8705	}
8706    } "-mavx512bw" ]
8707}
8708
8709# Return 1 if avx512vp2intersect instructions can be compiled.
8710proc check_effective_target_avx512vp2intersect { } {
8711    return [check_no_compiler_messages avx512vp2intersect object {
8712	typedef int __v16si __attribute__ ((__vector_size__ (64)));
8713	typedef short __mmask16;
8714	void
8715	_mm512_2intersect_epi32 (__v16si __A, __v16si __B, __mmask16 *__U,
8716				 __mmask16 *__M)
8717	{
8718	    __builtin_ia32_2intersectd512 (__U, __M, (__v16si) __A, (__v16si) __B);
8719	}
8720    } "-mavx512vp2intersect" ]
8721}
8722
8723# Return 1 if avx512ifma instructions can be compiled.
8724proc check_effective_target_avx512ifma { } {
8725    return [check_no_compiler_messages avx512ifma object {
8726	typedef long long __v8di __attribute__ ((__vector_size__ (64)));
8727	__v8di
8728	_mm512_madd52lo_epu64 (__v8di __X, __v8di __Y, __v8di __Z)
8729	{
8730	  return (__v8di) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __X,
8731							       (__v8di) __Y,
8732						               (__v8di) __Z,
8733						               -1);
8734	}
8735    } "-mavx512ifma" ]
8736}
8737
8738# Return 1 if avx512vbmi instructions can be compiled.
8739proc check_effective_target_avx512vbmi { } {
8740    return [check_no_compiler_messages avx512vbmi object {
8741	typedef char __v64qi __attribute__ ((__vector_size__ (64)));
8742	__v64qi
8743	_mm512_multishift_epi64_epi8 (__v64qi __X, __v64qi __Y)
8744	{
8745	  return (__v64qi) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X,
8746								 (__v64qi) __Y,
8747								 (__v64qi) __Y,
8748								 -1);
8749	}
8750    } "-mavx512vbmi" ]
8751}
8752
8753# Return 1 if avx512_4fmaps instructions can be compiled.
8754proc check_effective_target_avx5124fmaps { } {
8755    return [check_no_compiler_messages avx5124fmaps object {
8756	typedef float __v16sf __attribute__ ((__vector_size__ (64)));
8757	typedef float __v4sf __attribute__ ((__vector_size__ (16)));
8758
8759	__v16sf
8760	_mm512_mask_4fmadd_ps (__v16sf __DEST, __v16sf __A, __v16sf __B, __v16sf __C,
8761			       __v16sf __D, __v16sf __E, __v4sf *__F)
8762	{
8763	    return (__v16sf) __builtin_ia32_4fmaddps_mask ((__v16sf) __A,
8764							  (__v16sf) __B,
8765							  (__v16sf) __C,
8766							  (__v16sf) __D,
8767							  (__v16sf) __E,
8768							  (const __v4sf *) __F,
8769							  (__v16sf) __DEST,
8770							  0xffff);
8771	}
8772    } "-mavx5124fmaps" ]
8773}
8774
8775# Return 1 if avx512_4vnniw instructions can be compiled.
8776proc check_effective_target_avx5124vnniw { } {
8777    return [check_no_compiler_messages avx5124vnniw object {
8778	typedef int __v16si __attribute__ ((__vector_size__ (64)));
8779	typedef int __v4si __attribute__ ((__vector_size__ (16)));
8780
8781	__v16si
8782	_mm512_4dpwssd_epi32 (__v16si __A, __v16si __B, __v16si __C,
8783			      __v16si __D, __v16si __E, __v4si *__F)
8784	{
8785	    return (__v16si) __builtin_ia32_vp4dpwssd ((__v16si) __B,
8786						       (__v16si) __C,
8787						       (__v16si) __D,
8788						       (__v16si) __E,
8789						       (__v16si) __A,
8790						       (const __v4si *) __F);
8791	}
8792    } "-mavx5124vnniw" ]
8793}
8794
8795# Return 1 if avx512_vpopcntdq instructions can be compiled.
8796proc check_effective_target_avx512vpopcntdq { } {
8797    return [check_no_compiler_messages avx512vpopcntdq object {
8798        typedef int __v16si __attribute__ ((__vector_size__ (64)));
8799
8800        __v16si
8801        _mm512_popcnt_epi32 (__v16si __A)
8802        {
8803            return (__v16si) __builtin_ia32_vpopcountd_v16si ((__v16si) __A);
8804        }
8805    } "-mavx512vpopcntdq" ]
8806}
8807
8808# Return 1 if 128 or 256-bit avx512_vpopcntdq instructions can be compiled.
8809proc check_effective_target_avx512vpopcntdqvl { } {
8810    return [check_no_compiler_messages avx512vpopcntdqvl object {
8811        typedef int __v8si __attribute__ ((__vector_size__ (32)));
8812
8813        __v8si
8814        _mm256_popcnt_epi32 (__v8si __A)
8815        {
8816            return (__v8si) __builtin_ia32_vpopcountd_v8si ((__v8si) __A);
8817        }
8818    } "-mavx512vpopcntdq -mavx512vl" ]
8819}
8820
8821# Return 1 if gfni instructions can be compiled.
8822proc check_effective_target_gfni { } {
8823    return [check_no_compiler_messages gfni object {
8824        typedef char __v16qi __attribute__ ((__vector_size__ (16)));
8825
8826        __v16qi
8827        _mm_gf2p8affineinv_epi64_epi8 (__v16qi __A, __v16qi __B, const int __C)
8828        {
8829            return (__v16qi) __builtin_ia32_vgf2p8affineinvqb_v16qi ((__v16qi) __A,
8830								     (__v16qi) __B,
8831								      0);
8832        }
8833    } "-mgfni" ]
8834}
8835
8836# Return 1 if avx512vbmi2 instructions can be compiled.
8837proc check_effective_target_avx512vbmi2 { } {
8838    return [check_no_compiler_messages avx512vbmi2 object {
8839        typedef char __v16qi __attribute__ ((__vector_size__ (16)));
8840	typedef unsigned long long __mmask16;
8841
8842	__v16qi
8843	_mm_mask_compress_epi8 (__v16qi __A, __mmask16 __B, __v16qi __C)
8844	{
8845  		return (__v16qi) __builtin_ia32_compressqi128_mask((__v16qi)__C,
8846								   (__v16qi)__A,
8847								   (__mmask16)__B);
8848	}
8849    } "-mavx512vbmi2 -mavx512vl" ]
8850}
8851
8852# Return 1 if avx512vbmi2 instructions can be compiled.
8853proc check_effective_target_avx512vnni { } {
8854    return [check_no_compiler_messages avx512vnni object {
8855        typedef int __v16si __attribute__ ((__vector_size__ (64)));
8856
8857	__v16si
8858	_mm_mask_compress_epi8 (__v16si __A, __v16si __B, __v16si __C)
8859	{
8860  		return (__v16si) __builtin_ia32_vpdpbusd_v16si ((__v16si)__A,
8861								(__v16si)__B,
8862								(__v16si)__C);
8863	}
8864    } "-mavx512vnni -mavx512f" ]
8865}
8866
8867# Return 1 if vaes instructions can be compiled.
8868proc check_effective_target_avx512vaes { } {
8869    return [check_no_compiler_messages avx512vaes object {
8870
8871        typedef int __v16si __attribute__ ((__vector_size__ (64)));
8872
8873	__v32qi
8874	_mm256_aesdec_epi128 (__v32qi __A, __v32qi __B)
8875	{
8876	  return (__v32qi)__builtin_ia32_vaesdec_v32qi ((__v32qi) __A, (__v32qi) __B);
8877	}
8878    } "-mvaes" ]
8879}
8880
8881# Return 1 if vpclmulqdq instructions can be compiled.
8882proc check_effective_target_vpclmulqdq { } {
8883    return [check_no_compiler_messages vpclmulqdq object {
8884        typedef long long __v4di __attribute__ ((__vector_size__ (32)));
8885
8886        __v4di
8887        _mm256_clmulepi64_epi128 (__v4di __A, __v4di __B)
8888        {
8889            return (__v4di) __builtin_ia32_vpclmulqdq_v4di (__A, __B, 0);
8890        }
8891    } "-mvpclmulqdq -mavx512vl" ]
8892}
8893
8894# Return 1 if avx512_bitalg instructions can be compiled.
8895proc check_effective_target_avx512bitalg { } {
8896    return [check_no_compiler_messages avx512bitalg object {
8897        typedef short int __v32hi __attribute__ ((__vector_size__ (64)));
8898
8899        __v32hi
8900        _mm512_popcnt_epi16 (__v32hi __A)
8901        {
8902            return (__v32hi) __builtin_ia32_vpopcountw_v32hi ((__v32hi) __A);
8903        }
8904    } "-mavx512bitalg" ]
8905}
8906
8907# Return 1 if C wchar_t type is compatible with char16_t.
8908
8909proc check_effective_target_wchar_t_char16_t_compatible { } {
8910    return [check_no_compiler_messages wchar_t_char16_t object {
8911        __WCHAR_TYPE__ wc;
8912        __CHAR16_TYPE__ *p16 = &wc;
8913        char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
8914    }]
8915}
8916
8917# Return 1 if C wchar_t type is compatible with char32_t.
8918
8919proc check_effective_target_wchar_t_char32_t_compatible { } {
8920    return [check_no_compiler_messages wchar_t_char32_t object {
8921        __WCHAR_TYPE__ wc;
8922        __CHAR32_TYPE__ *p32 = &wc;
8923        char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
8924    }]
8925}
8926
8927# Return 1 if pow10 function exists.
8928
8929proc check_effective_target_pow10 { } {
8930    return [check_runtime pow10 {
8931	#include <math.h>
8932	int main () {
8933	double x;
8934	x = pow10 (1);
8935	return 0;
8936	}
8937    } "-lm" ]
8938}
8939
8940# Return 1 if frexpl function exists.
8941
8942proc check_effective_target_frexpl { } {
8943    return [check_runtime frexpl {
8944	#include <math.h>
8945	int main () {
8946	long double x;
8947	int y;
8948	x = frexpl (5.0, &y);
8949	return 0;
8950	}
8951    } "-lm" ]
8952}
8953
8954
8955# Return 1 if issignaling function exists.
8956proc check_effective_target_issignaling {} {
8957    return [check_runtime issignaling {
8958	#define _GNU_SOURCE
8959	#include <math.h>
8960	int main ()
8961	{
8962	  return issignaling (0.0);
8963	}
8964    } "-lm" ]
8965}
8966
8967# Return 1 if current options generate DFP instructions, 0 otherwise.
8968proc check_effective_target_hard_dfp {} {
8969    return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly {
8970	typedef float d64 __attribute__((mode(DD)));
8971	d64 x, y, z;
8972	void foo (void) { z = x + y; }
8973    }]
8974}
8975
8976# Return 1 if string.h and wchar.h headers provide C++ requires overloads
8977# for strchr etc. functions.
8978
8979proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
8980    return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly {
8981	#include <string.h>
8982	#include <wchar.h>
8983	#if !defined(__cplusplus) \
8984	    || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \
8985	    || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO)
8986	ISO C++ correct string.h and wchar.h protos not supported.
8987	#else
8988	int i;
8989	#endif
8990    }]
8991}
8992
8993# Return 1 if GNU as is used.
8994
8995proc check_effective_target_gas { } {
8996    global use_gas_saved
8997    global tool
8998
8999    if {![info exists use_gas_saved]} {
9000	# Check if the as used by gcc is GNU as.
9001	set options [list "additional_flags=-print-prog-name=as"]
9002	set gcc_as [lindex [${tool}_target_compile "" "" "none" $options] 0]
9003	# Provide /dev/null as input, otherwise gas times out reading from
9004	# stdin.
9005	set status [remote_exec host "$gcc_as" "-v /dev/null"]
9006	set as_output [lindex $status 1]
9007	if { [ string first "GNU" $as_output ] >= 0 } {
9008	    set use_gas_saved 1
9009	} else {
9010	    set use_gas_saved 0
9011	}
9012    }
9013    return $use_gas_saved
9014}
9015
9016# Return 1 if GNU ld is used.
9017
9018proc check_effective_target_gld { } {
9019    global use_gld_saved
9020    global tool
9021
9022    if {![info exists use_gld_saved]} {
9023	# Check if the ld used by gcc is GNU ld.
9024	set options [list "additional_flags=-print-prog-name=ld"]
9025	set gcc_ld [lindex [${tool}_target_compile "" "" "none" $options] 0]
9026	set status [remote_exec host "$gcc_ld" "--version"]
9027	set ld_output [lindex $status 1]
9028	if { [ string first "GNU" $ld_output ] >= 0 } {
9029	    set use_gld_saved 1
9030	} else {
9031	    set use_gld_saved 0
9032	}
9033    }
9034    return $use_gld_saved
9035}
9036
9037# Return 1 if the compiler has been configure with link-time optimization
9038# (LTO) support.
9039
9040proc check_effective_target_lto { } {
9041    if { [istarget nvptx-*-*]
9042	 || [istarget amdgcn-*-*] } {
9043	return 0;
9044    }
9045    return [check_no_compiler_messages lto object {
9046	void foo (void) { }
9047    } "-flto"]
9048}
9049
9050# Return 1 if the compiler and linker support incremental link-time
9051# optimization.
9052
9053proc check_effective_target_lto_incremental { } {
9054    if ![check_effective_target_lto] {
9055	return 0
9056    }
9057    return [check_no_compiler_messages lto_incremental executable {
9058	int main () { return 0; }
9059    } "-flto -r -nostdlib"]
9060}
9061
9062# Return 1 if the compiler has been configured with analyzer support.
9063
9064proc check_effective_target_analyzer { } {
9065    return [check_no_compiler_messages analyzer object {
9066	void foo (void) { }
9067    } "-fanalyzer"]
9068}
9069
9070# Return 1 if -mx32 -maddress-mode=short can compile, 0 otherwise.
9071
9072proc check_effective_target_maybe_x32 { } {
9073    return [check_no_compiler_messages maybe_x32 object {
9074        void foo (void) {}
9075    } "-mx32 -maddress-mode=short"]
9076}
9077
9078# Return 1 if this target supports the -fsplit-stack option, 0
9079# otherwise.
9080
9081proc check_effective_target_split_stack {} {
9082    return [check_no_compiler_messages split_stack object {
9083	void foo (void) { }
9084    } "-fsplit-stack"]
9085}
9086
9087# Return 1 if this target supports the -masm=intel option, 0
9088# otherwise
9089
9090proc check_effective_target_masm_intel  {} {
9091    return [check_no_compiler_messages masm_intel object {
9092	extern void abort (void);
9093    } "-masm=intel"]
9094}
9095
9096# Return 1 if the language for the compiler under test is C.
9097
9098proc check_effective_target_c { } {
9099    global tool
9100    if [string match $tool "gcc"] {
9101	return 1
9102    }
9103 return 0
9104}
9105
9106# Return 1 if the language for the compiler under test is C++.
9107
9108proc check_effective_target_c++ { } {
9109    global tool
9110    if { [string match $tool "g++"] || [string match $tool "libstdc++"] } {
9111	return 1
9112    }
9113 return 0
9114}
9115
9116set cxx_default "c++14"
9117# Check whether the current active language standard supports the features
9118# of C++11/C++14 by checking for the presence of one of the -std flags.
9119# This assumes that the default for the compiler is $cxx_default, and that
9120# there will never be multiple -std= arguments on the command line.
9121proc check_effective_target_c++11_only { } {
9122    global cxx_default
9123    if ![check_effective_target_c++] {
9124	return 0
9125    }
9126    if [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }] {
9127	return 1
9128    }
9129    if { $cxx_default == "c++11" && [check-flags { { } { } { } { -std=* } }] } {
9130	return 1
9131    }
9132    return 0
9133}
9134proc check_effective_target_c++11 { } {
9135    if [check_effective_target_c++11_only] {
9136	return 1
9137    }
9138    return [check_effective_target_c++14]
9139}
9140proc check_effective_target_c++11_down { } {
9141    if ![check_effective_target_c++] {
9142	return 0
9143    }
9144    return [expr ![check_effective_target_c++14] ]
9145}
9146
9147proc check_effective_target_c++14_only { } {
9148    global cxx_default
9149    if ![check_effective_target_c++] {
9150	return 0
9151    }
9152    if [check-flags { { } { } { -std=c++14 -std=gnu++14 -std=c++14 -std=gnu++14 } }] {
9153	return 1
9154    }
9155    if { $cxx_default == "c++14" && [check-flags { { } { } { } { -std=* } }] } {
9156	return 1
9157    }
9158    return 0
9159}
9160
9161proc check_effective_target_c++14 { } {
9162    if [check_effective_target_c++14_only] {
9163	return 1
9164    }
9165    return [check_effective_target_c++17]
9166}
9167proc check_effective_target_c++14_down { } {
9168    if ![check_effective_target_c++] {
9169	return 0
9170    }
9171    return [expr ![check_effective_target_c++17] ]
9172}
9173
9174proc check_effective_target_c++98_only { } {
9175    global cxx_default
9176    if ![check_effective_target_c++] {
9177	return 0
9178    }
9179    if [check-flags { { } { } { -std=c++98 -std=gnu++98 -std=c++03 -std=gnu++03 } }] {
9180	return 1
9181    }
9182    if { $cxx_default == "c++98" && [check-flags { { } { } { } { -std=* } }] } {
9183	return 1
9184    }
9185    return 0
9186}
9187
9188proc check_effective_target_c++17_only { } {
9189    global cxx_default
9190    if ![check_effective_target_c++] {
9191	return 0
9192    }
9193    if [check-flags { { } { } { -std=c++17 -std=gnu++17 -std=c++1z -std=gnu++1z } }] {
9194	return 1
9195    }
9196    if { $cxx_default == "c++17" && [check-flags { { } { } { } { -std=* } }] } {
9197	return 1
9198    }
9199    return 0
9200}
9201
9202proc check_effective_target_c++17 { } {
9203    if [check_effective_target_c++17_only] {
9204	return 1
9205    }
9206    return [check_effective_target_c++2a]
9207}
9208proc check_effective_target_c++17_down { } {
9209    if ![check_effective_target_c++] {
9210	return 0
9211    }
9212    return [expr ![check_effective_target_c++2a] ]
9213}
9214
9215proc check_effective_target_c++2a_only { } {
9216    global cxx_default
9217    if ![check_effective_target_c++] {
9218	return 0
9219    }
9220    if [check-flags { { } { } { -std=c++2a -std=gnu++2a -std=c++20 -std=gnu++20 } }] {
9221	return 1
9222    }
9223    if { $cxx_default == "c++20" && [check-flags { { } { } { } { -std=* } }] } {
9224	return 1
9225    }
9226    return 0
9227}
9228proc check_effective_target_c++2a { } {
9229    return [check_effective_target_c++2a_only]
9230}
9231
9232proc check_effective_target_c++20_only { } {
9233    return [check_effective_target_c++2a_only]
9234}
9235
9236proc check_effective_target_c++20 { } {
9237    return [check_effective_target_c++2a]
9238}
9239
9240# Check for C++ Concepts support, i.e. -fconcepts flag.
9241proc check_effective_target_concepts { } {
9242    if [check_effective_target_c++2a] {
9243	return 1
9244    }
9245    return [check-flags { "" { } { -fconcepts } }]
9246}
9247
9248# Return 1 if expensive testcases should be run.
9249
9250proc check_effective_target_run_expensive_tests { } {
9251    if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } {
9252        return 1
9253    }
9254    return 0
9255}
9256
9257# Returns 1 if "mempcpy" is available on the target system.
9258
9259proc check_effective_target_mempcpy {} {
9260    return [check_function_available "mempcpy"]
9261}
9262
9263# Returns 1 if "stpcpy" is available on the target system.
9264
9265proc check_effective_target_stpcpy {} {
9266    return [check_function_available "stpcpy"]
9267}
9268
9269# Returns 1 if "sigsetjmp" is available on the target system.
9270# Also check if "__sigsetjmp" is defined since that's what glibc
9271# uses.
9272
9273proc check_effective_target_sigsetjmp {} {
9274    if { [check_function_available "sigsetjmp"]
9275         || [check_function_available "__sigsetjmp"] } {
9276	return 1
9277    }
9278    return 0
9279}
9280
9281# Check whether the vectorizer tests are supported by the target and
9282# append additional target-dependent compile flags to DEFAULT_VECTCFLAGS.
9283# If a port wants to execute the tests more than once it should append
9284# the supported target to EFFECTIVE_TARGETS instead, and the compile flags
9285# will be added by a call to add_options_for_<target>.
9286# Set dg-do-what-default to either compile or run, depending on target
9287# capabilities.  Do not set this if the supported target is appended to
9288# EFFECTIVE_TARGETS.  Flags and this variable will be set by et-dg-runtest
9289# automatically.  Return the number of effective targets if vectorizer tests
9290# are supported, 0 otherwise.
9291
9292proc check_vect_support_and_set_flags { } {
9293    global DEFAULT_VECTCFLAGS
9294    global dg-do-what-default
9295    global EFFECTIVE_TARGETS
9296
9297    if  [istarget powerpc-*paired*]  {
9298        lappend DEFAULT_VECTCFLAGS "-mpaired"
9299        if [check_750cl_hw_available] {
9300            set dg-do-what-default run
9301        } else {
9302            set dg-do-what-default compile
9303        }
9304    } elseif [istarget powerpc*-*-*] {
9305        # Skip targets not supporting -maltivec.
9306        if ![is-effective-target powerpc_altivec_ok] {
9307            return 0
9308        }
9309
9310        lappend DEFAULT_VECTCFLAGS "-maltivec"
9311        if [check_p9vector_hw_available] {
9312            lappend DEFAULT_VECTCFLAGS "-mpower9-vector"
9313        } elseif [check_p8vector_hw_available] {
9314            lappend DEFAULT_VECTCFLAGS "-mpower8-vector"
9315        } elseif [check_vsx_hw_available] {
9316            lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
9317        }
9318
9319        if [check_vmx_hw_available] {
9320            set dg-do-what-default run
9321        } else {
9322            if [is-effective-target ilp32] {
9323                # Specify a cpu that supports VMX for compile-only tests.
9324                lappend DEFAULT_VECTCFLAGS "-mcpu=970"
9325            }
9326            set dg-do-what-default compile
9327        }
9328    } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
9329        lappend DEFAULT_VECTCFLAGS "-msse2"
9330        if { [check_effective_target_sse2_runtime] } {
9331            set dg-do-what-default run
9332        } else {
9333            set dg-do-what-default compile
9334        }
9335    } elseif { [istarget mips*-*-*]
9336	       && [check_effective_target_nomips16] } {
9337	if { [check_effective_target_mpaired_single] } {
9338	    lappend EFFECTIVE_TARGETS mpaired_single
9339	}
9340	if { [check_effective_target_mips_loongson_mmi] } {
9341	    lappend EFFECTIVE_TARGETS mips_loongson_mmi
9342	}
9343	if { [check_effective_target_mips_msa] } {
9344	    lappend EFFECTIVE_TARGETS mips_msa
9345        }
9346	return [llength $EFFECTIVE_TARGETS]
9347    } elseif [istarget sparc*-*-*] {
9348        lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
9349        if [check_effective_target_ultrasparc_hw] {
9350            set dg-do-what-default run
9351        } else {
9352            set dg-do-what-default compile
9353        }
9354    } elseif [istarget alpha*-*-*] {
9355        # Alpha's vectorization capabilities are extremely limited.
9356        # It's more effort than its worth disabling all of the tests
9357        # that it cannot pass.  But if you actually want to see what
9358        # does work, command out the return.
9359        return 0
9360
9361        lappend DEFAULT_VECTCFLAGS "-mmax"
9362        if [check_alpha_max_hw_available] {
9363            set dg-do-what-default run
9364        } else {
9365            set dg-do-what-default compile
9366        }
9367    } elseif [istarget ia64-*-*] {
9368        set dg-do-what-default run
9369    } elseif [is-effective-target arm_neon_ok] {
9370        eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
9371        # NEON does not support denormals, so is not used for vectorization by
9372        # default to avoid loss of precision.  We must pass -ffast-math to test
9373        # vectorization of float operations.
9374        lappend DEFAULT_VECTCFLAGS "-ffast-math"
9375        if [is-effective-target arm_neon_hw] {
9376            set dg-do-what-default run
9377        } else {
9378            set dg-do-what-default compile
9379        }
9380    } elseif [istarget "aarch64*-*-*"] {
9381        set dg-do-what-default run
9382    } elseif [istarget s390*-*-*] {
9383	# The S/390 backend set a default of 2 for that value.
9384	# Override it to have the same situation as with other
9385	# targets.
9386	lappend DEFAULT_VECTCFLAGS "--param" "min-vect-loop-bound=1"
9387	lappend DEFAULT_VECTCFLAGS "--param" "max-unrolled-insns=200"
9388	lappend DEFAULT_VECTCFLAGS "--param" "max-unroll-times=8"
9389	lappend DEFAULT_VECTCFLAGS "--param" "max-completely-peeled-insns=200"
9390	lappend DEFAULT_VECTCFLAGS "--param" "max-completely-peel-times=16"
9391        if [check_effective_target_s390_vxe] {
9392	    lappend DEFAULT_VECTCFLAGS "-march=z14" "-mzarch"
9393            set dg-do-what-default run
9394	} elseif [check_effective_target_s390_vx] {
9395	    lappend DEFAULT_VECTCFLAGS "-march=z13" "-mzarch"
9396            set dg-do-what-default run
9397        } else {
9398	    lappend DEFAULT_VECTCFLAGS "-march=z14" "-mzarch"
9399            set dg-do-what-default compile
9400        }
9401    } elseif [istarget amdgcn-*-*] {
9402        set dg-do-what-default run
9403    } else {
9404        return 0
9405    }
9406
9407    return 1
9408}
9409
9410# Return 1 if the target does *not* require strict alignment.
9411
9412proc check_effective_target_non_strict_align {} {
9413
9414    # On ARM, the default is to use STRICT_ALIGNMENT, but there
9415    # are interfaces defined for misaligned access and thus
9416    # depending on the architecture levels unaligned access is
9417    # available.
9418    if [istarget "arm*-*-*"] {
9419	return [check_effective_target_arm_unaligned]
9420    }
9421
9422    return [check_no_compiler_messages non_strict_align assembly {
9423	char *y;
9424	typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c;
9425	c *z;
9426	void foo(void) { z = (c *) y; }
9427    } "-Wcast-align"]
9428}
9429
9430# Return 1 if the target has <ucontext.h>.
9431
9432proc check_effective_target_ucontext_h { } {
9433    return [check_no_compiler_messages ucontext_h assembly {
9434	#include <ucontext.h>
9435    }]
9436}
9437
9438proc check_effective_target_aarch64_tiny { } {
9439    if { [istarget aarch64*-*-*] } {
9440	return [check_no_compiler_messages aarch64_tiny object {
9441	    #ifdef __AARCH64_CMODEL_TINY__
9442	    int dummy;
9443	    #else
9444	    #error target not AArch64 tiny code model
9445	    #endif
9446	}]
9447    } else {
9448	return 0
9449    }
9450}
9451
9452# Create functions to check that the AArch64 assembler supports the
9453# various architecture extensions via the .arch_extension pseudo-op.
9454
9455foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve"
9456			  "i8mm" "f32mm" "f64mm" "bf16" "sb" } {
9457    eval [string map [list FUNC $aarch64_ext] {
9458	proc check_effective_target_aarch64_asm_FUNC_ok { } {
9459	  if { [istarget aarch64*-*-*] } {
9460		return [check_no_compiler_messages aarch64_FUNC_assembler object {
9461			__asm__ (".arch_extension FUNC");
9462		} "-march=armv8-a+FUNC"]
9463	  } else {
9464		return 0
9465	  }
9466	}
9467    }]
9468}
9469
9470proc check_effective_target_aarch64_small { } {
9471    if { [istarget aarch64*-*-*] } {
9472	return [check_no_compiler_messages aarch64_small object {
9473	    #ifdef __AARCH64_CMODEL_SMALL__
9474	    int dummy;
9475	    #else
9476	    #error target not AArch64 small code model
9477	    #endif
9478	}]
9479    } else {
9480	return 0
9481    }
9482}
9483
9484proc check_effective_target_aarch64_large { } {
9485    if { [istarget aarch64*-*-*] } {
9486	return [check_no_compiler_messages aarch64_large object {
9487	    #ifdef __AARCH64_CMODEL_LARGE__
9488	    int dummy;
9489	    #else
9490	    #error target not AArch64 large code model
9491	    #endif
9492	}]
9493    } else {
9494	return 0
9495    }
9496}
9497
9498# Return 1 if the assembler accepts the aarch64 .variant_pcs directive.
9499
9500proc check_effective_target_aarch64_variant_pcs { } {
9501    if { [istarget aarch64*-*-*] } {
9502	return [check_no_compiler_messages aarch64_variant_pcs object {
9503	    __asm__ (".variant_pcs foo");
9504	}]
9505    } else {
9506	return 0
9507    }
9508}
9509
9510# Return 1 if this is a reduced AVR Tiny core.  Such cores have different
9511# register set, instruction set, addressing capabilities and ABI.
9512
9513proc check_effective_target_avr_tiny { } {
9514    if { [istarget avr*-*-*] } {
9515        return [check_no_compiler_messages avr_tiny object {
9516            #ifdef __AVR_TINY__
9517            int dummy;
9518            #else
9519            #error target not a reduced AVR Tiny core
9520            #endif
9521        }]
9522    } else {
9523        return 0
9524    }
9525}
9526
9527# Return 1 if <fenv.h> is available.
9528
9529proc check_effective_target_fenv {} {
9530    return [check_no_compiler_messages fenv object {
9531	#include <fenv.h>
9532    } [add_options_for_ieee "-std=gnu99"]]
9533}
9534
9535# Return 1 if <fenv.h> is available with all the standard IEEE
9536# exceptions and floating-point exceptions are raised by arithmetic
9537# operations.  (If the target requires special options for "inexact"
9538# exceptions, those need to be specified in the testcases.)
9539
9540proc check_effective_target_fenv_exceptions {} {
9541    return [check_runtime fenv_exceptions {
9542	#include <fenv.h>
9543	#include <stdlib.h>
9544	#ifndef FE_DIVBYZERO
9545	# error Missing FE_DIVBYZERO
9546	#endif
9547	#ifndef FE_INEXACT
9548	# error Missing FE_INEXACT
9549	#endif
9550	#ifndef FE_INVALID
9551	# error Missing FE_INVALID
9552	#endif
9553	#ifndef FE_OVERFLOW
9554	# error Missing FE_OVERFLOW
9555	#endif
9556	#ifndef FE_UNDERFLOW
9557	# error Missing FE_UNDERFLOW
9558	#endif
9559	volatile float a = 0.0f, r;
9560	int
9561	main (void)
9562	{
9563	  r = a / a;
9564	  if (fetestexcept (FE_INVALID))
9565	    exit (0);
9566	  else
9567	    abort ();
9568	}
9569    } [add_options_for_ieee "-std=gnu99"]]
9570}
9571
9572# Return 1 if -fexceptions is supported.
9573
9574proc check_effective_target_exceptions {} {
9575    if { [istarget amdgcn*-*-*] } {
9576	return 0
9577    }
9578    return 1
9579}
9580
9581# Used to check if the testing configuration supports exceptions.
9582# Returns 0 if exceptions are unsupported or disabled (e.g. by passing
9583# -fno-exceptions). Returns 1 if exceptions are enabled.
9584proc check_effective_target_exceptions_enabled {} {
9585    return [check_cached_effective_target exceptions_enabled {
9586	if { [check_effective_target_exceptions] } {
9587	    return [check_no_compiler_messages exceptions_enabled assembly {
9588		void foo (void)
9589		{
9590		    throw 1;
9591		}
9592	    }]
9593	} else {
9594	    # If exceptions aren't supported, then they're not enabled.
9595	    return 0
9596	}
9597    }]
9598}
9599
9600proc check_effective_target_tiny {} {
9601    return [check_cached_effective_target tiny {
9602      if { [istarget aarch64*-*-*]
9603		 && [check_effective_target_aarch64_tiny] } {
9604	   return 1
9605      }
9606      if { [istarget avr-*-*]
9607	    && [check_effective_target_avr_tiny] } {
9608	   return 1
9609      }
9610      # PRU Program Counter is 16-bits, and trampolines are not supported.
9611      # Hence directly declare as a tiny target.
9612      if [istarget pru-*-*] {
9613	   return 1
9614      }
9615      return 0
9616    }]
9617}
9618
9619# Return 1 if the target supports -mbranch-cost=N option.
9620
9621proc check_effective_target_branch_cost {} {
9622    if { [   istarget arm*-*-*]
9623	 || [istarget avr*-*-*]
9624	 || [istarget csky*-*-*]
9625	 || [istarget epiphany*-*-*]
9626	 || [istarget frv*-*-*]
9627	 || [istarget i?86-*-*] || [istarget x86_64-*-*]
9628	 || [istarget mips*-*-*]
9629	 || [istarget s390*-*-*]
9630	 || [istarget riscv*-*-*]
9631	 || [istarget sh*-*-*] } {
9632	return 1
9633    }
9634    return 0
9635}
9636
9637# Record that dg-final test TEST requires convential compilation.
9638
9639proc force_conventional_output_for { test } {
9640    if { [info proc $test] == "" } {
9641	perror "$test does not exist"
9642	exit 1
9643    }
9644    proc ${test}_required_options {} {
9645	global gcc_force_conventional_output
9646	upvar 1 extra_tool_flags extra_tool_flags
9647	if {[regexp -- "^scan-assembler" [info level 0]]
9648	    && ![string match "*-fident*" $extra_tool_flags]} {
9649	    # Do not let .ident confuse assembler scan tests
9650	    return [list $gcc_force_conventional_output "-fno-ident"]
9651	}
9652	return $gcc_force_conventional_output
9653    }
9654}
9655
9656# Record that dg-final test scan-ltrans-tree-dump* requires -flto-partition=one
9657# in order to force a single partition, allowing scan-ltrans-tree-dump* to scan
9658# a dump file *.exe.ltrans0.*.
9659
9660proc scan-ltrans-tree-dump_required_options {} {
9661    return "-flto-partition=one"
9662}
9663proc scan-ltrans-tree-dump-times_required_options {} {
9664    return "-flto-partition=one"
9665}
9666proc scan-ltrans-tree-dump-not_required_options {} {
9667    return "-flto-partition=one"
9668}
9669proc scan-ltrans-tree-dump-dem_required_options {} {
9670    return "-flto-partition=one"
9671}
9672proc scan-ltrans-tree-dump-dem-not_required_options {} {
9673    return "-flto-partition=one"
9674}
9675
9676# Return 1 if the x86-64 target supports PIE with copy reloc, 0
9677# otherwise.  Cache the result.
9678
9679proc check_effective_target_pie_copyreloc { } {
9680    global tool
9681    global GCC_UNDER_TEST
9682
9683    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
9684	return 0
9685    }
9686
9687    # Need auto-host.h to check linker support.
9688    if { ![file exists ../../auto-host.h ] } {
9689	return 0
9690    }
9691
9692    return [check_cached_effective_target pie_copyreloc {
9693	# Set up and compile to see if linker supports PIE with copy
9694	# reloc.  Include the current process ID in the file names to
9695	# prevent conflicts with invocations for multiple testsuites.
9696
9697	set src pie[pid].c
9698	set obj pie[pid].o
9699
9700	set f [open $src "w"]
9701	puts $f "#include \"../../auto-host.h\""
9702	puts $f "#if HAVE_LD_PIE_COPYRELOC == 0"
9703	puts $f "# error Linker does not support PIE with copy reloc."
9704	puts $f "#endif"
9705	close $f
9706
9707	verbose "check_effective_target_pie_copyreloc compiling testfile $src" 2
9708	set lines [${tool}_target_compile $src $obj object ""]
9709
9710	file delete $src
9711	file delete $obj
9712
9713	if [string match "" $lines] then {
9714	    verbose "check_effective_target_pie_copyreloc testfile compilation passed" 2
9715	    return 1
9716	} else {
9717	    verbose "check_effective_target_pie_copyreloc testfile compilation failed" 2
9718	    return 0
9719	}
9720    }]
9721}
9722
9723# Return 1 if the x86 target supports R_386_GOT32X relocation, 0
9724# otherwise.  Cache the result.
9725
9726proc check_effective_target_got32x_reloc { } {
9727    global tool
9728    global GCC_UNDER_TEST
9729
9730    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
9731	return 0
9732    }
9733
9734    # Need auto-host.h to check linker support.
9735    if { ![file exists ../../auto-host.h ] } {
9736	return 0
9737    }
9738
9739    return [check_cached_effective_target got32x_reloc {
9740	# Include the current process ID in the file names to prevent
9741	# conflicts with invocations for multiple testsuites.
9742
9743	set src got32x[pid].c
9744	set obj got32x[pid].o
9745
9746	set f [open $src "w"]
9747	puts $f "#include \"../../auto-host.h\""
9748	puts $f "#if HAVE_AS_IX86_GOT32X == 0"
9749	puts $f "# error Assembler does not support R_386_GOT32X."
9750	puts $f "#endif"
9751	close $f
9752
9753	verbose "check_effective_target_got32x_reloc compiling testfile $src" 2
9754	set lines [${tool}_target_compile $src $obj object ""]
9755
9756	file delete $src
9757	file delete $obj
9758
9759	if [string match "" $lines] then {
9760	    verbose "check_effective_target_got32x_reloc testfile compilation passed" 2
9761	    return 1
9762	} else {
9763	    verbose "check_effective_target_got32x_reloc testfile compilation failed" 2
9764	    return 0
9765	}
9766    }]
9767
9768    return $got32x_reloc_available_saved
9769}
9770
9771# Return 1 if the x86 target supports calling ___tls_get_addr via GOT,
9772# 0 otherwise.  Cache the result.
9773
9774proc check_effective_target_tls_get_addr_via_got { } {
9775    global tool
9776    global GCC_UNDER_TEST
9777
9778    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
9779	return 0
9780    }
9781
9782    # Need auto-host.h to check linker support.
9783    if { ![file exists ../../auto-host.h ] } {
9784	return 0
9785    }
9786
9787    return [check_cached_effective_target tls_get_addr_via_got {
9788	# Include the current process ID in the file names to prevent
9789	# conflicts with invocations for multiple testsuites.
9790
9791	set src tls_get_addr_via_got[pid].c
9792	set obj tls_get_addr_via_got[pid].o
9793
9794	set f [open $src "w"]
9795	puts $f "#include \"../../auto-host.h\""
9796	puts $f "#if HAVE_AS_IX86_TLS_GET_ADDR_GOT == 0"
9797	puts $f "# error Assembler/linker do not support calling ___tls_get_addr via GOT."
9798	puts $f "#endif"
9799	close $f
9800
9801	verbose "check_effective_target_tls_get_addr_via_got compiling testfile $src" 2
9802	set lines [${tool}_target_compile $src $obj object ""]
9803
9804	file delete $src
9805	file delete $obj
9806
9807	if [string match "" $lines] then {
9808	    verbose "check_effective_target_tls_get_addr_via_got testfile compilation passed" 2
9809	    return 1
9810	} else {
9811	    verbose "check_effective_target_tls_get_addr_via_got testfile compilation failed" 2
9812	    return 0
9813	}
9814    }]
9815}
9816
9817# Return 1 if the target uses comdat groups.
9818
9819proc check_effective_target_comdat_group {} {
9820    return [check_no_messages_and_pattern comdat_group "\.section\[^\n\r]*,comdat|\.group\[^\n\r]*,#comdat" assembly {
9821	// C++
9822	inline int foo () { return 1; }
9823	int (*fn) () = foo;
9824    }]
9825}
9826
9827# Return 1 if target supports __builtin_eh_return
9828proc check_effective_target_builtin_eh_return { } {
9829    return [check_no_compiler_messages builtin_eh_return object {
9830	void test (long l, void *p)
9831	{
9832	    __builtin_eh_return (l, p);
9833	}
9834    } "" ]
9835}
9836
9837# Return 1 if the target supports max reduction for vectors.
9838
9839proc check_effective_target_vect_max_reduc { } {
9840    if { [istarget aarch64*-*-*] || [is-effective-target arm_neon] } {
9841	return 1
9842    }
9843    return 0
9844}
9845
9846# Return 1 if the compiler has been configured with hsa offloading.
9847
9848proc check_effective_target_offload_hsa { } {
9849    return [check_no_compiler_messages offload_hsa assembly {
9850	int main () {return 0;}
9851    } "-foffload=hsa" ]
9852}
9853
9854# Return 1 if the compiler has been configured with hsa offloading.
9855
9856proc check_effective_target_offload_gcn { } {
9857    return [check_no_compiler_messages offload_gcn assembly {
9858	int main () {return 0;}
9859    } "-foffload=amdgcn-amdhsa" ]
9860}
9861
9862# Return 1 if the target support -fprofile-update=atomic
9863proc check_effective_target_profile_update_atomic {} {
9864    return [check_no_compiler_messages profile_update_atomic assembly {
9865	int main (void) { return 0; }
9866    } "-fprofile-update=atomic -fprofile-generate"]
9867}
9868
9869# Return 1 if vector (va - vector add) instructions are understood by
9870# the assembler and can be executed.  This also covers checking for
9871# the VX kernel feature.  A kernel without that feature does not
9872# enable the vector facility and the following check will die with a
9873# signal.
9874proc check_effective_target_s390_vx { } {
9875    if ![istarget s390*-*-*] then {
9876	return 0;
9877    }
9878
9879    return [check_runtime s390_check_vx {
9880	int main (void)
9881	{
9882	    asm ("va %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28");
9883	    return 0;
9884	}
9885    } "-march=z13 -mzarch" ]
9886}
9887
9888# Same as above but for the z14 vector enhancement facility. Test
9889# is performed with the vector nand instruction.
9890proc check_effective_target_s390_vxe { } {
9891    if ![istarget s390*-*-*] then {
9892	return 0;
9893    }
9894
9895    return [check_runtime s390_check_vxe {
9896	int main (void)
9897	{
9898	    asm ("vnn %%v24, %%v26, %%v28" : : : "v24", "v26", "v28");
9899	    return 0;
9900	}
9901    } "-march=z14 -mzarch" ]
9902}
9903
9904# Same as above but for the arch13 vector enhancement facility. Test
9905# is performed with the vector shift left double by bit instruction.
9906proc check_effective_target_s390_vxe2 { } {
9907    if ![istarget s390*-*-*] then {
9908	return 0;
9909    }
9910
9911    return [check_runtime s390_check_vxe2 {
9912	int main (void)
9913	{
9914	    asm ("vsld %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28");
9915	    return 0;
9916	}
9917    } "-march=arch13 -mzarch" ]
9918}
9919
9920#For versions of ARM architectures that have hardware div insn,
9921#disable the divmod transform
9922
9923proc check_effective_target_arm_divmod_simode { } {
9924    return [check_no_compiler_messages arm_divmod assembly {
9925	#ifdef __ARM_ARCH_EXT_IDIV__
9926	#error has div insn
9927	#endif
9928	int i;
9929    }]
9930}
9931
9932# Return 1 if target supports divmod hardware insn or divmod libcall.
9933
9934proc check_effective_target_divmod { } {
9935    #TODO: Add checks for all targets that have either hardware divmod insn
9936    # or define libfunc for divmod.
9937    if { [istarget arm*-*-*]
9938	 || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
9939	return 1
9940    }
9941    return 0
9942}
9943
9944# Return 1 if target supports divmod for SImode. The reason for
9945# separating this from check_effective_target_divmod is that
9946# some versions of ARM architecture define div instruction
9947# only for simode, and for these archs, we do not want to enable
9948# divmod transform for simode.
9949
9950proc check_effective_target_divmod_simode { } {
9951    if { [istarget arm*-*-*] } {
9952	return [check_effective_target_arm_divmod_simode]
9953    }
9954
9955    return [check_effective_target_divmod]
9956}
9957
9958# Return 1 if store merging optimization is applicable for target.
9959# Store merging is not profitable for targets like the avr which
9960# can load/store only one byte at a time. Use int size as a proxy
9961# for the number of bytes the target can write, and skip for targets
9962# with a smallish (< 32) size.
9963
9964proc check_effective_target_store_merge { } {
9965    if { [is-effective-target non_strict_align ] && [is-effective-target int32plus] } {
9966	return 1
9967    }
9968
9969    return 0
9970}
9971
9972# Return 1 if we're able to assemble rdrand
9973
9974proc check_effective_target_rdrand { } {
9975    return [check_no_compiler_messages_nocache rdrand object {
9976	unsigned int
9977	__foo(void)
9978	{
9979	    unsigned int val;
9980	    __builtin_ia32_rdrand32_step(&val);
9981	    return val;
9982	}
9983    } "-mrdrnd" ]
9984}
9985
9986# Return 1 if the target supports coprocessor instructions: cdp, ldc, ldcl,
9987# stc, stcl, mcr and mrc.
9988proc check_effective_target_arm_coproc1_ok_nocache { } {
9989    if { ![istarget arm*-*-*] } {
9990	return 0
9991    }
9992    return [check_no_compiler_messages_nocache arm_coproc1_ok assembly {
9993	#if (__thumb__ && !__thumb2__) || __ARM_ARCH < 4
9994	#error FOO
9995	#endif
9996	#include <arm_acle.h>
9997    }]
9998}
9999
10000proc check_effective_target_arm_coproc1_ok { } {
10001    return [check_cached_effective_target arm_coproc1_ok \
10002		check_effective_target_arm_coproc1_ok_nocache]
10003}
10004
10005# Return 1 if the target supports all coprocessor instructions checked by
10006# check_effective_target_arm_coproc1_ok in addition to the following: cdp2,
10007# ldc2, ldc2l, stc2, stc2l, mcr2 and mrc2.
10008proc check_effective_target_arm_coproc2_ok_nocache { } {
10009    if { ![check_effective_target_arm_coproc1_ok] } {
10010	return 0
10011    }
10012    return [check_no_compiler_messages_nocache arm_coproc2_ok assembly {
10013	#if (__thumb__ && !__thumb2__) || __ARM_ARCH < 5
10014	#error FOO
10015	#endif
10016	#include <arm_acle.h>
10017    }]
10018}
10019
10020proc check_effective_target_arm_coproc2_ok { } {
10021    return [check_cached_effective_target arm_coproc2_ok \
10022		check_effective_target_arm_coproc2_ok_nocache]
10023}
10024
10025# Return 1 if the target supports all coprocessor instructions checked by
10026# check_effective_target_arm_coproc2_ok in addition the following: mcrr and
10027# mrrc.
10028proc check_effective_target_arm_coproc3_ok_nocache { } {
10029    if { ![check_effective_target_arm_coproc2_ok] } {
10030	return 0
10031    }
10032    return [check_no_compiler_messages_nocache arm_coproc3_ok assembly {
10033	#if (__thumb__ && !__thumb2__) \
10034	    || (__ARM_ARCH < 6 && !defined (__ARM_ARCH_5TE__))
10035	#error FOO
10036	#endif
10037	#include <arm_acle.h>
10038    }]
10039}
10040
10041proc check_effective_target_arm_coproc3_ok { } {
10042    return [check_cached_effective_target arm_coproc3_ok \
10043		check_effective_target_arm_coproc3_ok_nocache]
10044}
10045
10046# Return 1 if the target supports all coprocessor instructions checked by
10047# check_effective_target_arm_coproc3_ok in addition the following: mcrr2 and
10048# mrcc2.
10049proc check_effective_target_arm_coproc4_ok_nocache { } {
10050    if { ![check_effective_target_arm_coproc3_ok] } {
10051	return 0
10052    }
10053    return [check_no_compiler_messages_nocache arm_coproc4_ok assembly {
10054	#if (__thumb__ && !__thumb2__) || __ARM_ARCH < 6
10055	#error FOO
10056	#endif
10057	#include <arm_acle.h>
10058    }]
10059}
10060
10061proc check_effective_target_arm_coproc4_ok { } {
10062    return [check_cached_effective_target arm_coproc4_ok \
10063		check_effective_target_arm_coproc4_ok_nocache]
10064}
10065
10066# Return 1 if the target supports the auto_inc_dec optimization pass.
10067proc check_effective_target_autoincdec { } {
10068    if { ![check_no_compiler_messages auto_incdec assembly { void f () { }
10069	 } "-O2 -fdump-rtl-auto_inc_dec" ] } {
10070      return 0
10071    }
10072
10073    set dumpfile [glob -nocomplain "auto_incdec[pid].c.\[0-9\]\[0-9\]\[0-9\]r.auto_inc_dec"]
10074    if { [file exists $dumpfile ] } {
10075	file delete $dumpfile
10076	return 1
10077    }
10078    return 0
10079}
10080
10081# Return 1 if the target has support for stack probing designed
10082# to avoid stack-clash style attacks.
10083#
10084# This is used to restrict the stack-clash mitigation tests to
10085# just those targets that have been explicitly supported.
10086#
10087# In addition to the prologue work on those targets, each target's
10088# properties should be described in the functions below so that
10089# tests do not become a mess of unreadable target conditions.
10090#
10091proc check_effective_target_supports_stack_clash_protection { } {
10092
10093    if { [istarget x86_64-*-*] || [istarget i?86-*-*]
10094	  || [istarget powerpc*-*-*] || [istarget rs6000*-*-*]
10095	  || [istarget aarch64*-**] || [istarget s390*-*-*] } {
10096	return 1
10097    }
10098  return 0
10099}
10100
10101# Return 1 if the target creates a frame pointer for non-leaf functions
10102# Note we ignore cases where we apply tail call optimization here.
10103proc check_effective_target_frame_pointer_for_non_leaf { } {
10104  # Solaris/x86 defaults to -fno-omit-frame-pointer.
10105  if { [istarget i?86-*-solaris*] || [istarget x86_64-*-solaris*] } {
10106    return 1
10107  }
10108
10109  return 0
10110}
10111
10112# Return 1 if the target's calling sequence or its ABI
10113# create implicit stack probes at or prior to function entry.
10114proc check_effective_target_caller_implicit_probes { } {
10115
10116  # On x86/x86_64 the call instruction itself pushes the return
10117  # address onto the stack.  That is an implicit probe of *sp.
10118  if { [istarget x86_64-*-*] || [istarget i?86-*-*] } {
10119	return 1
10120  }
10121
10122  # On PPC, the ABI mandates that the address of the outer
10123  # frame be stored at *sp.  Thus each allocation of stack
10124  # space is itself an implicit probe of *sp.
10125  if { [istarget powerpc*-*-*] || [istarget rs6000*-*-*] } {
10126	return 1
10127  }
10128
10129  # s390's ABI has a register save area allocated by the
10130  # caller for use by the callee.  The mere existence does
10131  # not constitute a probe by the caller, but when the slots
10132  # used by the callee those stores are implicit probes.
10133  if { [istarget s390*-*-*] } {
10134	return 1
10135  }
10136
10137  # Not strictly true on aarch64, but we have agreed that we will
10138  # consider any function that pushes SP more than 3kbytes into
10139  # the guard page as broken.  This essentially means that we can
10140  # consider the aarch64 as having a caller implicit probe at
10141  # *(sp + 1k).
10142  if { [istarget aarch64*-*-*] } {
10143	return 1;
10144  }
10145
10146  return 0
10147}
10148
10149# Targets that potentially realign the stack pointer often cause residual
10150# stack allocations and make it difficult to elimination loops or residual
10151# allocations for dynamic stack allocations
10152proc check_effective_target_callee_realigns_stack { } {
10153  if { [istarget x86_64-*-*] || [istarget i?86-*-*] } {
10154	return 1
10155  }
10156  return 0
10157}
10158
10159# Return 1 if CET instructions can be compiled.
10160proc check_effective_target_cet { } {
10161    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
10162	return 0
10163    }
10164    return [check_no_compiler_messages cet object {
10165	void foo (void)
10166	{
10167	  asm ("setssbsy");
10168	}
10169    } "-O2 -fcf-protection" ]
10170}
10171
10172# Return 1 if target supports floating point "infinite"
10173proc check_effective_target_inf { } {
10174    return [check_no_compiler_messages supports_inf assembly {
10175        const double pinf = __builtin_inf ();
10176    }]
10177}
10178
10179# Return 1 if the target supports ARMv8.3 Adv.SIMD Complex instructions
10180# instructions, 0 otherwise.  The test is valid for ARM and for AArch64.
10181# Record the command line options needed.
10182
10183proc check_effective_target_arm_v8_3a_complex_neon_ok_nocache { } {
10184    global et_arm_v8_3a_complex_neon_flags
10185    set et_arm_v8_3a_complex_neon_flags ""
10186
10187    if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
10188        return 0;
10189    }
10190
10191    # Iterate through sets of options to find the compiler flags that
10192    # need to be added to the -march option.
10193    foreach flags {"" "-mfloat-abi=softfp -mfpu=auto" "-mfloat-abi=hard -mfpu=auto"} {
10194        if { [check_no_compiler_messages_nocache \
10195                  arm_v8_3a_complex_neon_ok object {
10196            #if !defined (__ARM_FEATURE_COMPLEX)
10197            #error "__ARM_FEATURE_COMPLEX not defined"
10198            #endif
10199        } "$flags -march=armv8.3-a"] } {
10200            set et_arm_v8_3a_complex_neon_flags "$flags -march=armv8.3-a"
10201            return 1
10202        }
10203    }
10204
10205    return 0;
10206}
10207
10208proc check_effective_target_arm_v8_3a_complex_neon_ok { } {
10209    return [check_cached_effective_target arm_v8_3a_complex_neon_ok \
10210                check_effective_target_arm_v8_3a_complex_neon_ok_nocache]
10211}
10212
10213proc add_options_for_arm_v8_3a_complex_neon { flags } {
10214    if { ! [check_effective_target_arm_v8_3a_complex_neon_ok] } {
10215        return "$flags"
10216    }
10217    global et_arm_v8_3a_complex_neon_flags
10218    return "$flags $et_arm_v8_3a_complex_neon_flags"
10219}
10220
10221# Return 1 if the target supports executing AdvSIMD instructions from ARMv8.3
10222# with the complex instruction extension, 0 otherwise.  The test is valid for
10223# ARM and for AArch64.
10224
10225proc check_effective_target_arm_v8_3a_complex_neon_hw { } {
10226    if { ![check_effective_target_arm_v8_3a_complex_neon_ok] } {
10227        return 0;
10228    }
10229    return [check_runtime arm_v8_3a_complex_neon_hw_available {
10230        #include "arm_neon.h"
10231        int
10232        main (void)
10233        {
10234
10235          float32x2_t results = {-4.0,5.0};
10236          float32x2_t a = {1.0,3.0};
10237          float32x2_t b = {2.0,5.0};
10238
10239          #ifdef __ARM_ARCH_ISA_A64
10240          asm ("fcadd %0.2s, %1.2s, %2.2s, #90"
10241               : "=w"(results)
10242               : "w"(a), "w"(b)
10243               : /* No clobbers.  */);
10244
10245          #else
10246          asm ("vcadd.f32 %P0, %P1, %P2, #90"
10247               : "=w"(results)
10248               : "w"(a), "w"(b)
10249               : /* No clobbers.  */);
10250          #endif
10251
10252          return (results[0] == 8 && results[1] == 24) ? 1 : 0;
10253        }
10254    } [add_options_for_arm_v8_3a_complex_neon ""]]
10255}
10256
10257# Return 1 if the assembler supports assembling the Armv8.3 pointer authentication B key directive
10258proc check_effective_target_arm_v8_3a_bkey_directive { } {
10259	return [check_no_compiler_messages cet object {
10260		int main(void) {
10261			asm (".cfi_b_key_frame");
10262			return 0;
10263		}
10264	}]
10265}
10266
10267# Returns 1 if the target is using glibc, 0 otherwise.
10268
10269proc check_effective_target_glibc { } {
10270    return [check_no_compiler_messages glibc_object assembly {
10271  #include <stdlib.h>
10272	#if !defined(__GLIBC__)
10273	#error undefined
10274	#endif
10275    }]
10276}
10277
10278# Return 1 if the target plus current options supports a vector
10279# complex addition with rotate of half and single float modes, 0 otherwise.
10280#
10281# This won't change for different subtargets so cache the result.
10282
10283foreach N {hf sf} {
10284    eval [string map [list N $N] {
10285        proc check_effective_target_vect_complex_rot_N { } {
10286            return [check_cached_effective_target_indexed vect_complex_rot_N {
10287            expr { [istarget aarch64*-*-*]
10288                    || [istarget arm*-*-*] }}]
10289        }
10290    }]
10291}
10292
10293# Return 1 if the target plus current options supports a vector
10294# complex addition with rotate of double float modes, 0 otherwise.
10295#
10296# This won't change for different subtargets so cache the result.
10297
10298foreach N {df} {
10299    eval [string map [list N $N] {
10300        proc check_effective_target_vect_complex_rot_N { } {
10301            return [check_cached_effective_target_indexed vect_complex_rot_N {
10302            expr { [istarget aarch64*-*-*] }}]
10303        }
10304    }]
10305}
10306
10307# Return 1 if this target uses an LLVM assembler and/or linker
10308proc check_effective_target_llvm_binutils { } {
10309    return [check_cached_effective_target llvm_binutils {
10310	      expr { [istarget amdgcn*-*-*]
10311		     || [check_effective_target_offload_gcn] }}]
10312}
10313
10314# Return 1 if the compiler supports '-mfentry'.
10315
10316proc check_effective_target_mfentry { } {
10317    if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
10318        return 0
10319    }
10320    return [check_no_compiler_messages mfentry object {
10321	        void foo (void) { }
10322    } "-mfentry"]
10323}
10324
10325# Return 1 if this target supports indirect calls
10326proc check_effective_target_indirect_calls { } {
10327  if { [istarget bpf-*-*] } {
10328        return 0
10329  }
10330  return 1
10331}
10332
10333# Return 1 if we're able to assemble movdiri and movdir64b
10334
10335proc check_effective_target_movdir { } {
10336    return [check_no_compiler_messages movdir object {
10337	void
10338	foo (unsigned int *d, unsigned int s)
10339	{
10340	  __builtin_ia32_directstoreu_u32 (d, s);
10341	}
10342	void
10343	bar (void *d, const void *s)
10344	{
10345	  __builtin_ia32_movdir64b (d, s);
10346	}
10347    } "-mmovdiri -mmovdir64b" ]
10348}
10349
10350# Return 1 if GCC was configured with --with-tune=cortex-a76
10351proc check_effective_target_tune_cortex_a76 { } {
10352    return [check_configured_with "with-tune=cortex-a76"]
10353}
10354
10355# Return 1 if target is not support address sanitize, 1 otherwise.
10356
10357proc check_effective_target_no_fsanitize_address {} {
10358    if ![check_no_compiler_messages fsanitize_address executable {
10359	int main (void) { return 0; }
10360    }] {
10361	return 1;
10362    }
10363    return 0;
10364}
10365