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