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