* config/rs6000/rs6000-protos.h (output_probe_stack_range): Update
[official-gcc.git] / gcc / testsuite / lib / target-supports.exp
blob3ded1e32f49a988a68a5bcdd4fe962f3784ecde8
1 # Copyright (C) 1999-2017 Free Software Foundation, Inc.
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.
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.
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/>.
17 # Please email any bugs, comments, and/or additions to this file to:
18 # gcc-patches@gcc.gnu.org
20 # This file defines procs for determining features supported by the target.
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.
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.
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.
40 proc check_compile {basename type contents args} {
41 global tool
42 verbose "check_compile tool: $tool for $basename"
44 # Save additional_sources to avoid compiling testsuite's sources
45 # against check_compile's source.
46 global additional_sources
47 if [info exists additional_sources] {
48 set tmp_additional_sources "$additional_sources"
49 set additional_sources ""
52 if { [llength $args] > 0 } {
53 set options [list "additional_flags=[lindex $args 0]"]
54 } else {
55 set options ""
57 switch -glob -- $contents {
58 "*! Fortran*" { set src ${basename}[pid].f90 }
59 "*// C++*" { set src ${basename}[pid].cc }
60 "*// ObjC++*" { set src ${basename}[pid].mm }
61 "*/* ObjC*" { set src ${basename}[pid].m }
62 "*// Go*" { set src ${basename}[pid].go }
63 default {
64 switch -- $tool {
65 "objc" { set src ${basename}[pid].m }
66 "obj-c++" { set src ${basename}[pid].mm }
67 default { set src ${basename}[pid].c }
72 set compile_type $type
73 switch -glob $type {
74 assembly { set output ${basename}[pid].s }
75 object { set output ${basename}[pid].o }
76 executable { set output ${basename}[pid].exe }
77 "rtl-*" {
78 set output ${basename}[pid].s
79 lappend options "additional_flags=-fdump-$type"
80 set compile_type assembly
83 set f [open $src "w"]
84 puts $f $contents
85 close $f
86 set lines [${tool}_target_compile $src $output $compile_type "$options"]
87 file delete $src
89 set scan_output $output
90 # Don't try folding this into the switch above; calling "glob" before the
91 # file is created won't work.
92 if [regexp "rtl-(.*)" $type dummy rtl_type] {
93 set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]"
94 file delete $output
97 # Restore additional_sources.
98 if [info exists additional_sources] {
99 set additional_sources "$tmp_additional_sources"
102 return [list $lines $scan_output]
105 proc current_target_name { } {
106 global target_info
107 if [info exists target_info(target,name)] {
108 set answer $target_info(target,name)
109 } else {
110 set answer ""
112 return $answer
115 # Implement an effective-target check for property PROP by invoking
116 # the Tcl command ARGS and seeing if it returns true.
118 proc check_cached_effective_target { prop args } {
119 global et_cache
120 global et_prop_list
122 set target [current_target_name]
123 if {![info exists et_cache($prop,target)]
124 || $et_cache($prop,target) != $target} {
125 verbose "check_cached_effective_target $prop: checking $target" 2
126 set et_cache($prop,target) $target
127 set et_cache($prop,value) [uplevel eval $args]
128 if {![info exists et_prop_list]
129 || [lsearch $et_prop_list $prop] < 0} {
130 lappend et_prop_list $prop
132 verbose "check_cached_effective_target cached list is now: $et_prop_list" 2
134 set value $et_cache($prop,value)
135 verbose "check_cached_effective_target $prop: returning $value for $target" 2
136 return $value
139 # Clear effective-target cache. This is useful after testing
140 # effective-target features and overriding TEST_ALWAYS_FLAGS and/or
141 # ALWAYS_CXXFLAGS.
142 # If one changes ALWAYS_CXXFLAGS or TEST_ALWAYS_FLAGS then they should
143 # do a clear_effective_target_cache at the end as the target cache can
144 # make decisions based upon the flags, and those decisions need to be
145 # redone when the flags change. An example of this is the
146 # asan_init/asan_finish pair.
148 proc clear_effective_target_cache { } {
149 global et_cache
150 global et_prop_list
152 if {[info exists et_prop_list]} {
153 verbose "clear_effective_target_cache: $et_prop_list" 2
154 foreach prop $et_prop_list {
155 unset et_cache($prop,value)
156 unset et_cache($prop,target)
158 unset et_prop_list
162 # Like check_compile, but delete the output file and return true if the
163 # compiler printed no messages.
164 proc check_no_compiler_messages_nocache {args} {
165 set result [eval check_compile $args]
166 set lines [lindex $result 0]
167 set output [lindex $result 1]
168 remote_file build delete $output
169 return [string match "" $lines]
172 # Like check_no_compiler_messages_nocache, but cache the result.
173 # PROP is the property we're checking, and doubles as a prefix for
174 # temporary filenames.
175 proc check_no_compiler_messages {prop args} {
176 return [check_cached_effective_target $prop {
177 eval [list check_no_compiler_messages_nocache $prop] $args
181 # Like check_compile, but return true if the compiler printed no
182 # messages and if the contents of the output file satisfy PATTERN.
183 # If PATTERN has the form "!REGEXP", the contents satisfy it if they
184 # don't match regular expression REGEXP, otherwise they satisfy it
185 # if they do match regular expression PATTERN. (PATTERN can start
186 # with something like "[!]" if the regular expression needs to match
187 # "!" as the first character.)
189 # Delete the output file before returning. The other arguments are
190 # as for check_compile.
191 proc check_no_messages_and_pattern_nocache {basename pattern args} {
192 global tool
194 set result [eval [list check_compile $basename] $args]
195 set lines [lindex $result 0]
196 set output [lindex $result 1]
198 set ok 0
199 if { [string match "" $lines] } {
200 set chan [open "$output"]
201 set invert [regexp {^!(.*)} $pattern dummy pattern]
202 set ok [expr { [regexp $pattern [read $chan]] != $invert }]
203 close $chan
206 remote_file build delete $output
207 return $ok
210 # Like check_no_messages_and_pattern_nocache, but cache the result.
211 # PROP is the property we're checking, and doubles as a prefix for
212 # temporary filenames.
213 proc check_no_messages_and_pattern {prop pattern args} {
214 return [check_cached_effective_target $prop {
215 eval [list check_no_messages_and_pattern_nocache $prop $pattern] $args
219 # Try to compile and run an executable from code CONTENTS. Return true
220 # if the compiler reports no messages and if execution "passes" in the
221 # usual DejaGNU sense. The arguments are as for check_compile, with
222 # TYPE implicitly being "executable".
223 proc check_runtime_nocache {basename contents args} {
224 global tool
226 set result [eval [list check_compile $basename executable $contents] $args]
227 set lines [lindex $result 0]
228 set output [lindex $result 1]
230 set ok 0
231 if { [string match "" $lines] } {
232 # No error messages, everything is OK.
233 set result [remote_load target "./$output" "" ""]
234 set status [lindex $result 0]
235 verbose "check_runtime_nocache $basename: status is <$status>" 2
236 if { $status == "pass" } {
237 set ok 1
240 remote_file build delete $output
241 return $ok
244 # Like check_runtime_nocache, but cache the result. PROP is the
245 # property we're checking, and doubles as a prefix for temporary
246 # filenames.
247 proc check_runtime {prop args} {
248 global tool
250 return [check_cached_effective_target $prop {
251 eval [list check_runtime_nocache $prop] $args
255 # Return 1 if GCC was configured with $pattern.
256 proc check_configured_with { pattern } {
257 global tool
259 set gcc_output [${tool}_target_compile "-v" "" "none" ""]
260 if { [ regexp "Configured with: \[^\n\]*$pattern" $gcc_output ] } {
261 verbose "Matched: $pattern" 2
262 return 1
265 verbose "Failed to match: $pattern" 2
266 return 0
269 ###############################
270 # proc check_weak_available { }
271 ###############################
273 # weak symbols are only supported in some configs/object formats
274 # this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure
276 proc check_weak_available { } {
277 global target_cpu
279 # All mips targets should support it
281 if { [ string first "mips" $target_cpu ] >= 0 } {
282 return 1
285 # All AIX targets should support it
287 if { [istarget *-*-aix*] } {
288 return 1
291 # All solaris2 targets should support it
293 if { [istarget *-*-solaris2*] } {
294 return 1
297 # Windows targets Cygwin and MingW32 support it
299 if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
300 return 1
303 # HP-UX 10.X doesn't support it
305 if { [istarget hppa*-*-hpux10*] } {
306 return 0
309 # nvptx (nearly) supports it
311 if { [istarget nvptx-*-*] } {
312 return 1
315 # ELF and ECOFF support it. a.out does with gas/gld but may also with
316 # other linkers, so we should try it
318 set objformat [gcc_target_object_format]
320 switch $objformat {
321 elf { return 1 }
322 ecoff { return 1 }
323 a.out { return 1 }
324 mach-o { return 1 }
325 som { return 1 }
326 unknown { return -1 }
327 default { return 0 }
331 ###############################
332 # proc check_weak_override_available { }
333 ###############################
335 # Like check_weak_available, but return 0 if weak symbol definitions
336 # cannot be overridden.
338 proc check_weak_override_available { } {
339 if { [istarget *-*-mingw*] } {
340 return 0
342 return [check_weak_available]
345 ###############################
346 # proc check_visibility_available { what_kind }
347 ###############################
349 # The visibility attribute is only support in some object formats
350 # This proc returns 1 if it is supported, 0 if not.
351 # The argument is the kind of visibility, default/protected/hidden/internal.
353 proc check_visibility_available { what_kind } {
354 if [string match "" $what_kind] { set what_kind "hidden" }
356 return [check_no_compiler_messages visibility_available_$what_kind object "
357 void f() __attribute__((visibility(\"$what_kind\")));
358 void f() {}
362 ###############################
363 # proc check_alias_available { }
364 ###############################
366 # Determine if the target toolchain supports the alias attribute.
368 # Returns 2 if the target supports aliases. Returns 1 if the target
369 # only supports weak aliased. Returns 0 if the target does not
370 # support aliases at all. Returns -1 if support for aliases could not
371 # be determined.
373 proc check_alias_available { } {
374 global alias_available_saved
375 global tool
377 if [info exists alias_available_saved] {
378 verbose "check_alias_available returning saved $alias_available_saved" 2
379 } else {
380 set src alias[pid].c
381 set obj alias[pid].o
382 verbose "check_alias_available compiling testfile $src" 2
383 set f [open $src "w"]
384 # Compile a small test program. The definition of "g" is
385 # necessary to keep the Solaris assembler from complaining
386 # about the program.
387 puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
388 puts $f "void g() {} void f() __attribute__((alias(\"g\")));"
389 close $f
390 set lines [${tool}_target_compile $src $obj object ""]
391 file delete $src
392 remote_file build delete $obj
394 if [string match "" $lines] then {
395 # No error messages, everything is OK.
396 set alias_available_saved 2
397 } else {
398 if [regexp "alias definitions not supported" $lines] {
399 verbose "check_alias_available target does not support aliases" 2
401 set objformat [gcc_target_object_format]
403 if { $objformat == "elf" } {
404 verbose "check_alias_available but target uses ELF format, so it ought to" 2
405 set alias_available_saved -1
406 } else {
407 set alias_available_saved 0
409 } else {
410 if [regexp "only weak aliases are supported" $lines] {
411 verbose "check_alias_available target supports only weak aliases" 2
412 set alias_available_saved 1
413 } else {
414 set alias_available_saved -1
419 verbose "check_alias_available returning $alias_available_saved" 2
422 return $alias_available_saved
425 # Returns 1 if the target toolchain supports strong aliases, 0 otherwise.
427 proc check_effective_target_alias { } {
428 if { [check_alias_available] < 2 } {
429 return 0
430 } else {
431 return 1
435 # Returns 1 if the target toolchain supports ifunc, 0 otherwise.
437 proc check_ifunc_available { } {
438 return [check_no_compiler_messages ifunc_available object {
439 #ifdef __cplusplus
440 extern "C" {
441 #endif
442 typedef void F (void);
443 F* g() {}
444 void f() __attribute__((ifunc("g")));
445 #ifdef __cplusplus
447 #endif
451 # Returns true if --gc-sections is supported on the target.
453 proc check_gc_sections_available { } {
454 global gc_sections_available_saved
455 global tool
457 if {![info exists gc_sections_available_saved]} {
458 # Some targets don't support gc-sections despite whatever's
459 # advertised by ld's options.
460 if { [istarget alpha*-*-*]
461 || [istarget ia64-*-*] } {
462 set gc_sections_available_saved 0
463 return 0
466 # elf2flt uses -q (--emit-relocs), which is incompatible with
467 # --gc-sections.
468 if { [board_info target exists ldflags]
469 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
470 set gc_sections_available_saved 0
471 return 0
474 # VxWorks kernel modules are relocatable objects linked with -r,
475 # while RTP executables are linked with -q (--emit-relocs).
476 # Both of these options are incompatible with --gc-sections.
477 if { [istarget *-*-vxworks*] } {
478 set gc_sections_available_saved 0
479 return 0
482 # Check if the ld used by gcc supports --gc-sections.
483 set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=ld" "" "none" ""] 0]
484 set ld_output [remote_exec host "$gcc_ld" "--help"]
485 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
486 set gc_sections_available_saved 1
487 } else {
488 set gc_sections_available_saved 0
491 return $gc_sections_available_saved
494 # Return 1 if according to target_info struct and explicit target list
495 # target is supposed to support trampolines.
497 proc check_effective_target_trampolines { } {
498 if [target_info exists gcc,no_trampolines] {
499 return 0
501 if { [istarget avr-*-*]
502 || [istarget msp430-*-*]
503 || [istarget nvptx-*-*]
504 || [istarget hppa2.0w-hp-hpux11.23]
505 || [istarget hppa64-hp-hpux11.23] } {
506 return 0;
508 return 1
511 # Return 1 if target has limited stack size.
513 proc check_effective_target_stack_size { } {
514 if [target_info exists gcc,stack_size] {
515 return 1
517 return 0
520 # Return the value attribute of an effective target, otherwise return 0.
522 proc dg-effective-target-value { effective_target } {
523 if { "$effective_target" == "stack_size" } {
524 if [check_effective_target_stack_size] {
525 return [target_info gcc,stack_size]
529 return 0
532 # Return 1 if signal.h is supported.
534 proc check_effective_target_signal { } {
535 if [target_info exists gcc,signal_suppress] {
536 return 0
538 return 1
541 # Return 1 if according to target_info struct and explicit target list
542 # target disables -fdelete-null-pointer-checks. Targets should return 0
543 # if they simply default to -fno-delete-null-pointer-checks but obey
544 # -fdelete-null-pointer-checks when passed explicitly (and tests that
545 # depend on this option should do that).
547 proc check_effective_target_keeps_null_pointer_checks { } {
548 if [target_info exists keeps_null_pointer_checks] {
549 return 1
551 if { [istarget avr-*-*] } {
552 return 1;
554 return 0
557 # Return the autofdo profile wrapper
559 # Linux by default allows 516KB of perf event buffers
560 # in /proc/sys/kernel/perf_event_mlock_kb
561 # Each individual perf tries to grab it
562 # This causes problems with parallel test suite runs. Instead
563 # limit us to 8 pages (32K), which should be good enough
564 # for the small test programs. With the default settings
565 # this allows parallelism of 16 and higher of parallel gcc-auto-profile
566 proc profopt-perf-wrapper { } {
567 global srcdir
568 return "$srcdir/../config/i386/gcc-auto-profile -o perf.data -m8 "
571 # Return true if profiling is supported on the target.
573 proc check_profiling_available { test_what } {
574 global profiling_available_saved
576 verbose "Profiling argument is <$test_what>" 1
578 # These conditions depend on the argument so examine them before
579 # looking at the cache variable.
581 # Tree profiling requires TLS runtime support.
582 if { $test_what == "-fprofile-generate" } {
583 if { ![check_effective_target_tls_runtime] } {
584 return 0
588 if { $test_what == "-fauto-profile" } {
589 if { !([istarget i?86-*-linux*] || [istarget x86_64-*-linux*]) } {
590 verbose "autofdo only supported on linux"
591 return 0
593 # not cross compiling?
594 if { ![isnative] } {
595 verbose "autofdo not supported for non native builds"
596 return 0
598 set event [profopt-perf-wrapper]
599 if {$event == "" } {
600 verbose "autofdo not supported"
601 return 0
603 global srcdir
604 set status [remote_exec host "$srcdir/../config/i386/gcc-auto-profile" "true -v >/dev/null"]
605 if { [lindex $status 0] != 0 } {
606 verbose "autofdo not supported because perf does not work"
607 return 0
610 # no good way to check this in advance -- check later instead.
611 #set status [remote_exec host "create_gcov" "2>/dev/null"]
612 #if { [lindex $status 0] != 255 } {
613 # verbose "autofdo not supported due to missing create_gcov"
614 # return 0
618 # Support for -p on solaris2 relies on mcrt1.o which comes with the
619 # vendor compiler. We cannot reliably predict the directory where the
620 # vendor compiler (and thus mcrt1.o) is installed so we can't
621 # necessarily find mcrt1.o even if we have it.
622 if { [istarget *-*-solaris2*] && $test_what == "-p" } {
623 return 0
626 # We don't yet support profiling for MIPS16.
627 if { [istarget mips*-*-*]
628 && ![check_effective_target_nomips16]
629 && ($test_what == "-p" || $test_what == "-pg") } {
630 return 0
633 # MinGW does not support -p.
634 if { [istarget *-*-mingw*] && $test_what == "-p" } {
635 return 0
638 # cygwin does not support -p.
639 if { [istarget *-*-cygwin*] && $test_what == "-p" } {
640 return 0
643 # uClibc does not have gcrt1.o.
644 if { [check_effective_target_uclibc]
645 && ($test_what == "-p" || $test_what == "-pg") } {
646 return 0
649 # Now examine the cache variable.
650 if {![info exists profiling_available_saved]} {
651 # Some targets don't have any implementation of __bb_init_func or are
652 # missing other needed machinery.
653 if {[istarget aarch64*-*-elf]
654 || [istarget am3*-*-linux*]
655 || [istarget arm*-*-eabi*]
656 || [istarget arm*-*-elf]
657 || [istarget arm*-*-symbianelf*]
658 || [istarget avr-*-*]
659 || [istarget bfin-*-*]
660 || [istarget cris-*-*]
661 || [istarget crisv32-*-*]
662 || [istarget fido-*-elf]
663 || [istarget h8300-*-*]
664 || [istarget lm32-*-*]
665 || [istarget m32c-*-elf]
666 || [istarget m68k-*-elf]
667 || [istarget m68k-*-uclinux*]
668 || [istarget mips*-*-elf*]
669 || [istarget mmix-*-*]
670 || [istarget mn10300-*-elf*]
671 || [istarget moxie-*-elf*]
672 || [istarget msp430-*-*]
673 || [istarget nds32*-*-elf]
674 || [istarget nios2-*-elf]
675 || [istarget nvptx-*-*]
676 || [istarget powerpc-*-eabi*]
677 || [istarget powerpc-*-elf]
678 || [istarget rx-*-*]
679 || [istarget tic6x-*-elf]
680 || [istarget visium-*-*]
681 || [istarget xstormy16-*]
682 || [istarget xtensa*-*-elf]
683 || [istarget *-*-rtems*]
684 || [istarget *-*-vxworks*] } {
685 set profiling_available_saved 0
686 } else {
687 set profiling_available_saved 1
691 # -pg link test result can't be cached since it may change between
692 # runs.
693 set profiling_working $profiling_available_saved
694 if { $profiling_available_saved == 1
695 && ![check_no_compiler_messages_nocache profiling executable {
696 int main() { return 0; } } "-pg"] } {
697 set profiling_working 0
700 return $profiling_working
703 # Check to see if a target is "freestanding". This is as per the definition
704 # in Section 4 of C99 standard. Effectively, it is a target which supports no
705 # extra headers or libraries other than what is considered essential.
706 proc check_effective_target_freestanding { } {
707 if { [istarget nvptx-*-*] } {
708 return 1
710 return 0
713 # Return 1 if target has packed layout of structure members by
714 # default, 0 otherwise. Note that this is slightly different than
715 # whether the target has "natural alignment": both attributes may be
716 # false.
718 proc check_effective_target_default_packed { } {
719 return [check_no_compiler_messages default_packed assembly {
720 struct x { char a; long b; } c;
721 int s[sizeof (c) == sizeof (char) + sizeof (long) ? 1 : -1];
725 # Return 1 if target has PCC_BITFIELD_TYPE_MATTERS defined. See
726 # documentation, where the test also comes from.
728 proc check_effective_target_pcc_bitfield_type_matters { } {
729 # PCC_BITFIELD_TYPE_MATTERS isn't just about unnamed or empty
730 # bitfields, but let's stick to the example code from the docs.
731 return [check_no_compiler_messages pcc_bitfield_type_matters assembly {
732 struct foo1 { char x; char :0; char y; };
733 struct foo2 { char x; int :0; char y; };
734 int s[sizeof (struct foo1) != sizeof (struct foo2) ? 1 : -1];
738 # Add to FLAGS all the target-specific flags needed to use thread-local storage.
740 proc add_options_for_tls { flags } {
741 # On Solaris 9, __tls_get_addr/___tls_get_addr only lives in
742 # libthread, so always pass -pthread for native TLS. Same for AIX.
743 # Need to duplicate native TLS check from
744 # check_effective_target_tls_native to avoid recursion.
745 if { ([istarget powerpc-ibm-aix*]) &&
746 [check_no_messages_and_pattern tls_native "!emutls" assembly {
747 __thread int i;
748 int f (void) { return i; }
749 void g (int j) { i = j; }
750 }] } {
751 return "-pthread [g++_link_flags [get_multilibs "-pthread"] ] $flags "
753 return $flags
756 # Return 1 if indirect jumps are supported, 0 otherwise.
758 proc check_effective_target_indirect_jumps {} {
759 if { [istarget nvptx-*-*] } {
760 return 0
762 return 1
765 # Return 1 if nonlocal goto is supported, 0 otherwise.
767 proc check_effective_target_nonlocal_goto {} {
768 if { [istarget nvptx-*-*] } {
769 return 0
771 return 1
774 # Return 1 if global constructors are supported, 0 otherwise.
776 proc check_effective_target_global_constructor {} {
777 if { [istarget nvptx-*-*] } {
778 return 0
780 return 1
783 # Return 1 if taking label values is supported, 0 otherwise.
785 proc check_effective_target_label_values {} {
786 if { [istarget nvptx-*-*] || [target_info exists gcc,no_label_values] } {
787 return 0
790 return 1
793 # Return 1 if builtin_return_address and builtin_frame_address are
794 # supported, 0 otherwise.
796 proc check_effective_target_return_address {} {
797 if { [istarget nvptx-*-*] } {
798 return 0
800 return 1
803 # Return 1 if the assembler does not verify function types against
804 # calls, 0 otherwise. Such verification will typically show up problems
805 # with K&R C function declarations.
807 proc check_effective_target_untyped_assembly {} {
808 if { [istarget nvptx-*-*] } {
809 return 0
811 return 1
814 # Return 1 if alloca is supported, 0 otherwise.
816 proc check_effective_target_alloca {} {
817 if { [istarget nvptx-*-*] } {
818 return [check_no_compiler_messages alloca assembly {
819 void f (void*);
820 void g (int n) { f (__builtin_alloca (n)); }
823 return 1
826 # Return 1 if thread local storage (TLS) is supported, 0 otherwise.
828 proc check_effective_target_tls {} {
829 return [check_no_compiler_messages tls assembly {
830 __thread int i;
831 int f (void) { return i; }
832 void g (int j) { i = j; }
836 # Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise.
838 proc check_effective_target_tls_native {} {
839 # VxWorks uses emulated TLS machinery, but with non-standard helper
840 # functions, so we fail to automatically detect it.
841 if { [istarget *-*-vxworks*] } {
842 return 0
845 return [check_no_messages_and_pattern tls_native "!emutls" assembly {
846 __thread int i;
847 int f (void) { return i; }
848 void g (int j) { i = j; }
852 # Return 1 if *emulated* thread local storage (TLS) is supported, 0 otherwise.
854 proc check_effective_target_tls_emulated {} {
855 # VxWorks uses emulated TLS machinery, but with non-standard helper
856 # functions, so we fail to automatically detect it.
857 if { [istarget *-*-vxworks*] } {
858 return 1
861 return [check_no_messages_and_pattern tls_emulated "emutls" assembly {
862 __thread int i;
863 int f (void) { return i; }
864 void g (int j) { i = j; }
868 # Return 1 if TLS executables can run correctly, 0 otherwise.
870 proc check_effective_target_tls_runtime {} {
871 # The runtime does not have TLS support, but just
872 # running the test below is insufficient to show this.
873 if { [istarget msp430-*-*] || [istarget visium-*-*] } {
874 return 0
876 return [check_runtime tls_runtime {
877 __thread int thr = 0;
878 int main (void) { return thr; }
879 } [add_options_for_tls ""]]
882 # Return 1 if atomic compare-and-swap is supported on 'int'
884 proc check_effective_target_cas_char {} {
885 return [check_no_compiler_messages cas_char assembly {
886 #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
887 #error unsupported
888 #endif
889 } ""]
892 proc check_effective_target_cas_int {} {
893 return [check_no_compiler_messages cas_int assembly {
894 #if __INT_MAX__ == 0x7fff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
895 /* ok */
896 #elif __INT_MAX__ == 0x7fffffff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
897 /* ok */
898 #else
899 #error unsupported
900 #endif
901 } ""]
904 # Return 1 if -ffunction-sections is supported, 0 otherwise.
906 proc check_effective_target_function_sections {} {
907 # Darwin has its own scheme and silently accepts -ffunction-sections.
908 if { [istarget *-*-darwin*] } {
909 return 0
912 return [check_no_compiler_messages functionsections assembly {
913 void foo (void) { }
914 } "-ffunction-sections"]
917 # Return 1 if instruction scheduling is available, 0 otherwise.
919 proc check_effective_target_scheduling {} {
920 return [check_no_compiler_messages scheduling object {
921 void foo (void) { }
922 } "-fschedule-insns"]
925 # Return 1 if trapping arithmetic is available, 0 otherwise.
927 proc check_effective_target_trapping {} {
928 return [check_no_compiler_messages trapping object {
929 int add (int a, int b) { return a + b; }
930 } "-ftrapv"]
933 # Return 1 if compilation with -fgraphite is error-free for trivial
934 # code, 0 otherwise.
936 proc check_effective_target_fgraphite {} {
937 return [check_no_compiler_messages fgraphite object {
938 void foo (void) { }
939 } "-O1 -fgraphite"]
942 # Return 1 if compilation with -fopenacc is error-free for trivial
943 # code, 0 otherwise.
945 proc check_effective_target_fopenacc {} {
946 # nvptx can be built with the device-side bits of openacc, but it
947 # does not make sense to test it as an openacc host.
948 if [istarget nvptx-*-*] { return 0 }
950 return [check_no_compiler_messages fopenacc object {
951 void foo (void) { }
952 } "-fopenacc"]
955 # Return 1 if compilation with -fopenmp is error-free for trivial
956 # code, 0 otherwise.
958 proc check_effective_target_fopenmp {} {
959 # nvptx can be built with the device-side bits of libgomp, but it
960 # does not make sense to test it as an openmp host.
961 if [istarget nvptx-*-*] { return 0 }
963 return [check_no_compiler_messages fopenmp object {
964 void foo (void) { }
965 } "-fopenmp"]
968 # Return 1 if compilation with -fgnu-tm is error-free for trivial
969 # code, 0 otherwise.
971 proc check_effective_target_fgnu_tm {} {
972 return [check_no_compiler_messages fgnu_tm object {
973 void foo (void) { }
974 } "-fgnu-tm"]
977 # Return 1 if the target supports mmap, 0 otherwise.
979 proc check_effective_target_mmap {} {
980 return [check_function_available "mmap"]
983 # Return 1 if the target supports dlopen, 0 otherwise.
984 proc check_effective_target_dlopen {} {
985 return [check_no_compiler_messages dlopen executable {
986 #include <dlfcn.h>
987 int main(void) { dlopen ("dummy.so", RTLD_NOW); }
988 } [add_options_for_dlopen ""]]
991 proc add_options_for_dlopen { flags } {
992 return "$flags -ldl"
995 # Return 1 if the target supports clone, 0 otherwise.
996 proc check_effective_target_clone {} {
997 return [check_function_available "clone"]
1000 # Return 1 if the target supports setrlimit, 0 otherwise.
1001 proc check_effective_target_setrlimit {} {
1002 # Darwin has non-posix compliant RLIMIT_AS
1003 if { [istarget *-*-darwin*] } {
1004 return 0
1006 return [check_function_available "setrlimit"]
1009 # Return 1 if the target supports gettimeofday, 0 otherwise.
1010 proc check_effective_target_gettimeofday {} {
1011 return [check_function_available "gettimeofday"]
1014 # Return 1 if the target supports swapcontext, 0 otherwise.
1015 proc check_effective_target_swapcontext {} {
1016 return [check_no_compiler_messages swapcontext executable {
1017 #include <ucontext.h>
1018 int main (void)
1020 ucontext_t orig_context,child_context;
1021 if (swapcontext(&child_context, &orig_context) < 0) { }
1026 # Return 1 if compilation with -pthread is error-free for trivial
1027 # code, 0 otherwise.
1029 proc check_effective_target_pthread {} {
1030 return [check_no_compiler_messages pthread object {
1031 void foo (void) { }
1032 } "-pthread"]
1035 # Return 1 if compilation with -gstabs is error-free for trivial
1036 # code, 0 otherwise.
1038 proc check_effective_target_stabs {} {
1039 return [check_no_compiler_messages stabs object {
1040 void foo (void) { }
1041 } "-gstabs"]
1044 # Return 1 if compilation with -mpe-aligned-commons is error-free
1045 # for trivial code, 0 otherwise.
1047 proc check_effective_target_pe_aligned_commons {} {
1048 if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
1049 return [check_no_compiler_messages pe_aligned_commons object {
1050 int foo;
1051 } "-mpe-aligned-commons"]
1053 return 0
1056 # Return 1 if the target supports -static
1057 proc check_effective_target_static {} {
1058 return [check_no_compiler_messages static executable {
1059 int main (void) { return 0; }
1060 } "-static"]
1063 # Return 1 if the target supports -fstack-protector
1064 proc check_effective_target_fstack_protector {} {
1065 return [check_runtime fstack_protector {
1066 int main (void) { return 0; }
1067 } "-fstack-protector"]
1070 # Return 1 if the target supports -fstack-check or -fstack-check=$stack_kind
1071 proc check_stack_check_available { stack_kind } {
1072 if [string match "" $stack_kind] then {
1073 set stack_opt "-fstack-check"
1074 } else { set stack_opt "-fstack-check=$stack_kind" }
1076 return [check_no_compiler_messages stack_check_$stack_kind executable {
1077 int main (void) { return 0; }
1078 } "$stack_opt"]
1081 # Return 1 if compilation with -freorder-blocks-and-partition is error-free
1082 # for trivial code, 0 otherwise. As some targets (ARM for example) only
1083 # warn when -fprofile-use is also supplied we test that combination too.
1085 proc check_effective_target_freorder {} {
1086 if { [check_no_compiler_messages freorder object {
1087 void foo (void) { }
1088 } "-freorder-blocks-and-partition"]
1089 && [check_no_compiler_messages fprofile_use_freorder object {
1090 void foo (void) { }
1091 } "-fprofile-use -freorder-blocks-and-partition"] } {
1092 return 1
1094 return 0
1097 # Return 1 if -fpic and -fPIC are supported, as in no warnings or errors
1098 # emitted, 0 otherwise. Whether a shared library can actually be built is
1099 # out of scope for this test.
1101 proc check_effective_target_fpic { } {
1102 # Note that M68K has a multilib that supports -fpic but not
1103 # -fPIC, so we need to check both. We test with a program that
1104 # requires GOT references.
1105 foreach arg {fpic fPIC} {
1106 if [check_no_compiler_messages $arg object {
1107 extern int foo (void); extern int bar;
1108 int baz (void) { return foo () + bar; }
1109 } "-$arg"] {
1110 return 1
1113 return 0
1116 # On AArch64, if -fpic is not supported, then we will fall back to -fPIC
1117 # silently. So, we can't rely on above "check_effective_target_fpic" as it
1118 # assumes compiler will give warning if -fpic not supported. Here we check
1119 # whether binutils supports those new -fpic relocation modifiers, and assume
1120 # -fpic is supported if there is binutils support. GCC configuration will
1121 # enable -fpic for AArch64 in this case.
1123 # "check_effective_target_aarch64_small_fpic" is dedicated for checking small
1124 # memory model -fpic relocation types.
1126 proc check_effective_target_aarch64_small_fpic { } {
1127 if { [istarget aarch64*-*-*] } {
1128 return [check_no_compiler_messages aarch64_small_fpic object {
1129 void foo (void) { asm ("ldr x0, [x2, #:gotpage_lo15:globalsym]"); }
1131 } else {
1132 return 0
1136 # On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize
1137 # the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported
1138 # in binutils since 2015-03-04 as PR gas/17843.
1140 # This test directive make sure binutils support all features needed by TLS LE
1141 # under -mtls-size=32 on AArch64.
1143 proc check_effective_target_aarch64_tlsle32 { } {
1144 if { [istarget aarch64*-*-*] } {
1145 return [check_no_compiler_messages aarch64_tlsle32 object {
1146 void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); }
1148 } else {
1149 return 0
1153 # Return 1 if -shared is supported, as in no warnings or errors
1154 # emitted, 0 otherwise.
1156 proc check_effective_target_shared { } {
1157 # Note that M68K has a multilib that supports -fpic but not
1158 # -fPIC, so we need to check both. We test with a program that
1159 # requires GOT references.
1160 return [check_no_compiler_messages shared executable {
1161 extern int foo (void); extern int bar;
1162 int baz (void) { return foo () + bar; }
1163 } "-shared -fpic"]
1166 # Return 1 if -pie, -fpie and -fPIE are supported, 0 otherwise.
1168 proc check_effective_target_pie { } {
1169 if { [istarget *-*-darwin\[912\]*]
1170 || [istarget *-*-dragonfly*]
1171 || [istarget *-*-freebsd*]
1172 || [istarget *-*-linux*]
1173 || [istarget *-*-gnu*] } {
1174 return 1;
1176 if { [istarget *-*-solaris2.1\[1-9\]*] } {
1177 # Full PIE support was added in Solaris 11.x and Solaris 12, but gcc
1178 # errors out if missing, so check for that.
1179 return [check_no_compiler_messages pie executable {
1180 int main (void) { return 0; }
1181 } "-pie -fpie"]
1183 return 0
1186 # Return true if the target supports -mpaired-single (as used on MIPS).
1188 proc check_effective_target_mpaired_single { } {
1189 return [check_no_compiler_messages mpaired_single object {
1190 void foo (void) { }
1191 } "-mpaired-single"]
1194 # Return true if the target has access to FPU instructions.
1196 proc check_effective_target_hard_float { } {
1197 if { [istarget mips*-*-*] } {
1198 return [check_no_compiler_messages hard_float assembly {
1199 #if (defined __mips_soft_float || defined __mips16)
1200 #error __mips_soft_float || __mips16
1201 #endif
1205 # This proc is actually checking the availabilty of FPU
1206 # support for doubles, so on the RX we must fail if the
1207 # 64-bit double multilib has been selected.
1208 if { [istarget rx-*-*] } {
1209 return 0
1210 # return [check_no_compiler_messages hard_float assembly {
1211 #if defined __RX_64_BIT_DOUBLES__
1212 #error __RX_64_BIT_DOUBLES__
1213 #endif
1214 # }]
1217 # The generic test equates hard_float with "no call for adding doubles".
1218 return [check_no_messages_and_pattern hard_float "!\\(call" rtl-expand {
1219 double a (double b, double c) { return b + c; }
1223 # Return true if the target is a 64-bit MIPS target.
1225 proc check_effective_target_mips64 { } {
1226 return [check_no_compiler_messages mips64 assembly {
1227 #ifndef __mips64
1228 #error !__mips64
1229 #endif
1233 # Return true if the target is a MIPS target that does not produce
1234 # MIPS16 code.
1236 proc check_effective_target_nomips16 { } {
1237 return [check_no_compiler_messages nomips16 object {
1238 #ifndef __mips
1239 #error !__mips
1240 #else
1241 /* A cheap way of testing for -mflip-mips16. */
1242 void foo (void) { asm ("addiu $20,$20,1"); }
1243 void bar (void) { asm ("addiu $20,$20,1"); }
1244 #endif
1248 # Add the options needed for MIPS16 function attributes. At the moment,
1249 # we don't support MIPS16 PIC.
1251 proc add_options_for_mips16_attribute { flags } {
1252 return "$flags -mno-abicalls -fno-pic -DMIPS16=__attribute__((mips16))"
1255 # Return true if we can force a mode that allows MIPS16 code generation.
1256 # We don't support MIPS16 PIC, and only support MIPS16 -mhard-float
1257 # for o32 and o64.
1259 proc check_effective_target_mips16_attribute { } {
1260 return [check_no_compiler_messages mips16_attribute assembly {
1261 #ifdef PIC
1262 #error PIC
1263 #endif
1264 #if defined __mips_hard_float \
1265 && (!defined _ABIO32 || _MIPS_SIM != _ABIO32) \
1266 && (!defined _ABIO64 || _MIPS_SIM != _ABIO64)
1267 #error __mips_hard_float && (!_ABIO32 || !_ABIO64)
1268 #endif
1269 } [add_options_for_mips16_attribute ""]]
1272 # Return 1 if the target supports long double larger than double when
1273 # using the new ABI, 0 otherwise.
1275 proc check_effective_target_mips_newabi_large_long_double { } {
1276 return [check_no_compiler_messages mips_newabi_large_long_double object {
1277 int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
1278 } "-mabi=64"]
1281 # Return true if the target is a MIPS target that has access
1282 # to the LL and SC instructions.
1284 proc check_effective_target_mips_llsc { } {
1285 if { ![istarget mips*-*-*] } {
1286 return 0
1288 # Assume that these instructions are always implemented for
1289 # non-elf* targets, via emulation if necessary.
1290 if { ![istarget *-*-elf*] } {
1291 return 1
1293 # Otherwise assume LL/SC support for everything but MIPS I.
1294 return [check_no_compiler_messages mips_llsc assembly {
1295 #if __mips == 1
1296 #error __mips == 1
1297 #endif
1301 # Return true if the target is a MIPS target that uses in-place relocations.
1303 proc check_effective_target_mips_rel { } {
1304 if { ![istarget mips*-*-*] } {
1305 return 0
1307 return [check_no_compiler_messages mips_rel object {
1308 #if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
1309 || (defined _ABI64 && _MIPS_SIM == _ABI64)
1310 #error _ABIN32 && (_ABIN32 || _ABI64)
1311 #endif
1315 # Return true if the target is a MIPS target that uses the EABI.
1317 proc check_effective_target_mips_eabi { } {
1318 if { ![istarget mips*-*-*] } {
1319 return 0
1321 return [check_no_compiler_messages mips_eabi object {
1322 #ifndef __mips_eabi
1323 #error !__mips_eabi
1324 #endif
1328 # Return 1 if the current multilib does not generate PIC by default.
1330 proc check_effective_target_nonpic { } {
1331 return [check_no_compiler_messages nonpic assembly {
1332 #if __PIC__
1333 #error __PIC__
1334 #endif
1338 # Return 1 if the current multilib generates PIE by default.
1340 proc check_effective_target_pie_enabled { } {
1341 return [check_no_compiler_messages pie_enabled assembly {
1342 #ifndef __PIE__
1343 #error unsupported
1344 #endif
1348 # Return 1 if the target generates -fstack-protector by default.
1350 proc check_effective_target_fstack_protector_enabled {} {
1351 return [ check_no_compiler_messages fstack_protector_enabled assembly {
1352 #if !defined(__SSP__) && !defined(__SSP_ALL__) && \
1353 !defined(__SSP_STRONG__) && !defined(__SSP_EXPICIT__)
1354 #error unsupported
1355 #endif
1359 # Return 1 if the target does not use a status wrapper.
1361 proc check_effective_target_unwrapped { } {
1362 if { [target_info needs_status_wrapper] != "" \
1363 && [target_info needs_status_wrapper] != "0" } {
1364 return 0
1366 return 1
1369 # Return true if iconv is supported on the target. In particular IBM1047.
1371 proc check_iconv_available { test_what } {
1372 global libiconv
1374 # If the tool configuration file has not set libiconv, try "-liconv"
1375 if { ![info exists libiconv] } {
1376 set libiconv "-liconv"
1378 set test_what [lindex $test_what 1]
1379 return [check_runtime_nocache $test_what [subst {
1380 #include <iconv.h>
1381 int main (void)
1383 iconv_t cd;
1385 cd = iconv_open ("$test_what", "UTF-8");
1386 if (cd == (iconv_t) -1)
1387 return 1;
1388 return 0;
1390 }] $libiconv]
1393 # Return true if Cilk Library is supported on the target.
1394 proc check_effective_target_cilkplus_runtime { } {
1395 return [ check_no_compiler_messages_nocache cilkplus_runtime executable {
1396 #ifdef __cplusplus
1397 extern "C"
1398 #endif
1399 int __cilkrts_set_param (const char *, const char *);
1400 int main (void) {
1401 int x = __cilkrts_set_param ("nworkers", "0");
1402 return x;
1404 } "-fcilkplus -lcilkrts" ]
1407 # Return true if the atomic library is supported on the target.
1408 proc check_effective_target_libatomic_available { } {
1409 return [check_no_compiler_messages libatomic_available executable {
1410 int main (void) { return 0; }
1411 } "-latomic"]
1414 # Return 1 if an ASCII locale is supported on this host, 0 otherwise.
1416 proc check_ascii_locale_available { } {
1417 return 1
1420 # Return true if named sections are supported on this target.
1422 proc check_named_sections_available { } {
1423 return [check_no_compiler_messages named_sections assembly {
1424 int __attribute__ ((section("whatever"))) foo;
1428 # Return true if the "naked" function attribute is supported on this target.
1430 proc check_effective_target_naked_functions { } {
1431 return [check_no_compiler_messages naked_functions assembly {
1432 void f() __attribute__((naked));
1436 # Return 1 if the target supports Fortran real kinds larger than real(8),
1437 # 0 otherwise.
1439 # When the target name changes, replace the cached result.
1441 proc check_effective_target_fortran_large_real { } {
1442 return [check_no_compiler_messages fortran_large_real executable {
1443 ! Fortran
1444 integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1)
1445 real(kind=k) :: x
1446 x = cos (x)
1451 # Return 1 if the target supports Fortran real kind real(16),
1452 # 0 otherwise. Contrary to check_effective_target_fortran_large_real
1453 # this checks for Real(16) only; the other returned real(10) if
1454 # both real(10) and real(16) are available.
1456 # When the target name changes, replace the cached result.
1458 proc check_effective_target_fortran_real_16 { } {
1459 return [check_no_compiler_messages fortran_real_16 executable {
1460 ! Fortran
1461 real(kind=16) :: x
1462 x = cos (x)
1468 # Return 1 if the target supports Fortran's IEEE modules,
1469 # 0 otherwise.
1471 # When the target name changes, replace the cached result.
1473 proc check_effective_target_fortran_ieee { flags } {
1474 return [check_no_compiler_messages fortran_ieee executable {
1475 ! Fortran
1476 use, intrinsic :: ieee_features
1478 } $flags ]
1482 # Return 1 if the target supports SQRT for the largest floating-point
1483 # type. (Some targets lack the libm support for this FP type.)
1484 # On most targets, this check effectively checks either whether sqrtl is
1485 # available or on __float128 systems whether libquadmath is installed,
1486 # which provides sqrtq.
1488 # When the target name changes, replace the cached result.
1490 proc check_effective_target_fortran_largest_fp_has_sqrt { } {
1491 return [check_no_compiler_messages fortran_largest_fp_has_sqrt executable {
1492 ! Fortran
1493 use iso_fortran_env, only: real_kinds
1494 integer,parameter:: maxFP = real_kinds(ubound(real_kinds,dim=1))
1495 real(kind=maxFP), volatile :: x
1496 x = 2.0_maxFP
1497 x = sqrt (x)
1503 # Return 1 if the target supports Fortran integer kinds larger than
1504 # integer(8), 0 otherwise.
1506 # When the target name changes, replace the cached result.
1508 proc check_effective_target_fortran_large_int { } {
1509 return [check_no_compiler_messages fortran_large_int executable {
1510 ! Fortran
1511 integer,parameter :: k = selected_int_kind (range (0_8) + 1)
1512 integer(kind=k) :: i
1517 # Return 1 if the target supports Fortran integer(16), 0 otherwise.
1519 # When the target name changes, replace the cached result.
1521 proc check_effective_target_fortran_integer_16 { } {
1522 return [check_no_compiler_messages fortran_integer_16 executable {
1523 ! Fortran
1524 integer(16) :: i
1529 # Return 1 if we can statically link libgfortran, 0 otherwise.
1531 # When the target name changes, replace the cached result.
1533 proc check_effective_target_static_libgfortran { } {
1534 return [check_no_compiler_messages static_libgfortran executable {
1535 ! Fortran
1536 print *, 'test'
1538 } "-static"]
1541 # Return 1 if we can use the -rdynamic option, 0 otherwise.
1543 proc check_effective_target_rdynamic { } {
1544 return [check_no_compiler_messages rdynamic executable {
1545 int main() { return 0; }
1546 } "-rdynamic"]
1549 # Return 1 if cilk-plus is supported by the target, 0 otherwise.
1551 proc check_effective_target_cilkplus { } {
1552 # Skip cilk-plus tests on int16 and size16 targets for now.
1553 # The cilk-plus tests are not generic enough to cover these
1554 # cases and would throw hundreds of FAILs.
1555 if { [check_effective_target_int16]
1556 || ![check_effective_target_size32plus] } {
1557 return 0;
1560 # Skip AVR, its RAM is too small and too many tests would fail.
1561 if { [istarget avr-*-*] } {
1562 return 0;
1565 if { ! [check_effective_target_pthread] } {
1566 return 0;
1569 return 1
1572 proc check_linker_plugin_available { } {
1573 return [check_no_compiler_messages_nocache linker_plugin executable {
1574 int main() { return 0; }
1575 } "-flto -fuse-linker-plugin"]
1578 # Return 1 if the target OS supports running SSE executables, 0
1579 # otherwise. Cache the result.
1581 proc check_sse_os_support_available { } {
1582 return [check_cached_effective_target sse_os_support_available {
1583 # If this is not the right target then we can skip the test.
1584 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1585 expr 0
1586 } elseif { [istarget i?86-*-solaris2*] } {
1587 # The Solaris 2 kernel doesn't save and restore SSE registers
1588 # before Solaris 9 4/04. Before that, executables die with SIGILL.
1589 check_runtime_nocache sse_os_support_available {
1590 int main ()
1592 asm volatile ("movaps %xmm0,%xmm0");
1593 return 0;
1595 } "-msse"
1596 } else {
1597 expr 1
1602 # Return 1 if the target OS supports running AVX executables, 0
1603 # otherwise. Cache the result.
1605 proc check_avx_os_support_available { } {
1606 return [check_cached_effective_target avx_os_support_available {
1607 # If this is not the right target then we can skip the test.
1608 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1609 expr 0
1610 } else {
1611 # Check that OS has AVX and SSE saving enabled.
1612 check_runtime_nocache avx_os_support_available {
1613 int main ()
1615 unsigned int eax, edx;
1617 asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
1618 return (eax & 0x06) != 0x06;
1620 } ""
1625 # Return 1 if the target OS supports running AVX executables, 0
1626 # otherwise. Cache the result.
1628 proc check_avx512_os_support_available { } {
1629 return [check_cached_effective_target avx512_os_support_available {
1630 # If this is not the right target then we can skip the test.
1631 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1632 expr 0
1633 } else {
1634 # Check that OS has AVX512, AVX and SSE saving enabled.
1635 check_runtime_nocache avx512_os_support_available {
1636 int main ()
1638 unsigned int eax, edx;
1640 asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
1641 return (eax & 0xe6) != 0xe6;
1643 } ""
1648 # Return 1 if the target supports executing SSE instructions, 0
1649 # otherwise. Cache the result.
1651 proc check_sse_hw_available { } {
1652 return [check_cached_effective_target sse_hw_available {
1653 # If this is not the right target then we can skip the test.
1654 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1655 expr 0
1656 } else {
1657 check_runtime_nocache sse_hw_available {
1658 #include "cpuid.h"
1659 int main ()
1661 unsigned int eax, ebx, ecx, edx;
1662 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1663 return 1;
1665 return !(edx & bit_SSE);
1667 } ""
1672 # Return 1 if the target supports executing SSE2 instructions, 0
1673 # otherwise. Cache the result.
1675 proc check_sse2_hw_available { } {
1676 return [check_cached_effective_target sse2_hw_available {
1677 # If this is not the right target then we can skip the test.
1678 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1679 expr 0
1680 } else {
1681 check_runtime_nocache sse2_hw_available {
1682 #include "cpuid.h"
1683 int main ()
1685 unsigned int eax, ebx, ecx, edx;
1686 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1687 return 1;
1689 return !(edx & bit_SSE2);
1691 } ""
1696 # Return 1 if the target supports executing SSE4 instructions, 0
1697 # otherwise. Cache the result.
1699 proc check_sse4_hw_available { } {
1700 return [check_cached_effective_target sse4_hw_available {
1701 # If this is not the right target then we can skip the test.
1702 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1703 expr 0
1704 } else {
1705 check_runtime_nocache sse4_hw_available {
1706 #include "cpuid.h"
1707 int main ()
1709 unsigned int eax, ebx, ecx, edx;
1710 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1711 return 1;
1713 return !(ecx & bit_SSE4_2);
1715 } ""
1720 # Return 1 if the target supports executing AVX instructions, 0
1721 # otherwise. Cache the result.
1723 proc check_avx_hw_available { } {
1724 return [check_cached_effective_target avx_hw_available {
1725 # If this is not the right target then we can skip the test.
1726 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
1727 expr 0
1728 } else {
1729 check_runtime_nocache avx_hw_available {
1730 #include "cpuid.h"
1731 int main ()
1733 unsigned int eax, ebx, ecx, edx;
1734 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
1735 return 1;
1737 return ((ecx & (bit_AVX | bit_OSXSAVE))
1738 != (bit_AVX | bit_OSXSAVE));
1740 } ""
1745 # Return 1 if the target supports executing AVX2 instructions, 0
1746 # otherwise. Cache the result.
1748 proc check_avx2_hw_available { } {
1749 return [check_cached_effective_target avx2_hw_available {
1750 # If this is not the right target then we can skip the test.
1751 if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1752 expr 0
1753 } else {
1754 check_runtime_nocache avx2_hw_available {
1755 #include <stddef.h>
1756 #include "cpuid.h"
1757 int main ()
1759 unsigned int eax, ebx, ecx, edx;
1761 if (__get_cpuid_max (0, NULL) < 7)
1762 return 1;
1764 __cpuid (1, eax, ebx, ecx, edx);
1766 if (!(ecx & bit_OSXSAVE))
1767 return 1;
1769 __cpuid_count (7, 0, eax, ebx, ecx, edx);
1771 return !(ebx & bit_AVX2);
1773 } ""
1778 # Return 1 if the target supports executing AVX512 foundation instructions, 0
1779 # otherwise. Cache the result.
1781 proc check_avx512f_hw_available { } {
1782 return [check_cached_effective_target avx512f_hw_available {
1783 # If this is not the right target then we can skip the test.
1784 if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
1785 expr 0
1786 } else {
1787 check_runtime_nocache avx512f_hw_available {
1788 #include <stddef.h>
1789 #include "cpuid.h"
1790 int main ()
1792 unsigned int eax, ebx, ecx, edx;
1794 if (__get_cpuid_max (0, NULL) < 7)
1795 return 1;
1797 __cpuid (1, eax, ebx, ecx, edx);
1799 if (!(ecx & bit_OSXSAVE))
1800 return 1;
1802 __cpuid_count (7, 0, eax, ebx, ecx, edx);
1804 return !(ebx & bit_AVX512F);
1806 } ""
1811 # Return 1 if the target supports running SSE executables, 0 otherwise.
1813 proc check_effective_target_sse_runtime { } {
1814 if { [check_effective_target_sse]
1815 && [check_sse_hw_available]
1816 && [check_sse_os_support_available] } {
1817 return 1
1819 return 0
1822 # Return 1 if the target supports running SSE2 executables, 0 otherwise.
1824 proc check_effective_target_sse2_runtime { } {
1825 if { [check_effective_target_sse2]
1826 && [check_sse2_hw_available]
1827 && [check_sse_os_support_available] } {
1828 return 1
1830 return 0
1833 # Return 1 if the target supports running SSE4 executables, 0 otherwise.
1835 proc check_effective_target_sse4_runtime { } {
1836 if { [check_effective_target_sse4]
1837 && [check_sse4_hw_available]
1838 && [check_sse_os_support_available] } {
1839 return 1
1841 return 0
1844 # Return 1 if the target supports running AVX executables, 0 otherwise.
1846 proc check_effective_target_avx_runtime { } {
1847 if { [check_effective_target_avx]
1848 && [check_avx_hw_available]
1849 && [check_avx_os_support_available] } {
1850 return 1
1852 return 0
1855 # Return 1 if the target supports running AVX2 executables, 0 otherwise.
1857 proc check_effective_target_avx2_runtime { } {
1858 if { [check_effective_target_avx2]
1859 && [check_avx2_hw_available]
1860 && [check_avx_os_support_available] } {
1861 return 1
1863 return 0
1866 # Return 1 if the target supports running AVX512f executables, 0 otherwise.
1868 proc check_effective_target_avx512f_runtime { } {
1869 if { [check_effective_target_avx512f]
1870 && [check_avx512f_hw_available]
1871 && [check_avx512_os_support_available] } {
1872 return 1
1874 return 0
1877 # Return 1 if the target supports executing MIPS Paired-Single instructions,
1878 # 0 otherwise. Cache the result.
1880 proc check_mpaired_single_hw_available { } {
1881 return [check_cached_effective_target mpaired_single_hw_available {
1882 # If this is not the right target then we can skip the test.
1883 if { !([istarget mips*-*-*]) } {
1884 expr 0
1885 } else {
1886 check_runtime_nocache mpaired_single_hw_available {
1887 int main()
1889 asm volatile ("pll.ps $f2,$f4,$f6");
1890 return 0;
1892 } ""
1897 # Return 1 if the target supports executing Loongson vector instructions,
1898 # 0 otherwise. Cache the result.
1900 proc check_mips_loongson_hw_available { } {
1901 return [check_cached_effective_target mips_loongson_hw_available {
1902 # If this is not the right target then we can skip the test.
1903 if { !([istarget mips*-*-*]) } {
1904 expr 0
1905 } else {
1906 check_runtime_nocache mips_loongson_hw_available {
1907 #include <loongson.h>
1908 int main()
1910 asm volatile ("paddw $f2,$f4,$f6");
1911 return 0;
1913 } ""
1918 # Return 1 if the target supports executing MIPS MSA instructions, 0
1919 # otherwise. Cache the result.
1921 proc check_mips_msa_hw_available { } {
1922 return [check_cached_effective_target mips_msa_hw_available {
1923 # If this is not the right target then we can skip the test.
1924 if { !([istarget mips*-*-*]) } {
1925 expr 0
1926 } else {
1927 check_runtime_nocache mips_msa_hw_available {
1928 #if !defined(__mips_msa)
1929 #error "MSA NOT AVAIL"
1930 #else
1931 #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2))
1932 #error "MSA NOT AVAIL FOR ISA REV < 2"
1933 #endif
1934 #if !defined(__mips_hard_float)
1935 #error "MSA HARD_FLOAT REQUIRED"
1936 #endif
1937 #if __mips_fpr != 64
1938 #error "MSA 64-bit FPR REQUIRED"
1939 #endif
1940 #include <msa.h>
1942 int main()
1944 v8i16 v = __builtin_msa_ldi_h (0);
1945 v[0] = 0;
1946 return v[0];
1948 #endif
1949 } "-mmsa"
1954 # Return 1 if the target supports running MIPS Paired-Single
1955 # executables, 0 otherwise.
1957 proc check_effective_target_mpaired_single_runtime { } {
1958 if { [check_effective_target_mpaired_single]
1959 && [check_mpaired_single_hw_available] } {
1960 return 1
1962 return 0
1965 # Return 1 if the target supports running Loongson executables, 0 otherwise.
1967 proc check_effective_target_mips_loongson_runtime { } {
1968 if { [check_effective_target_mips_loongson]
1969 && [check_mips_loongson_hw_available] } {
1970 return 1
1972 return 0
1975 # Return 1 if the target supports running MIPS MSA executables, 0 otherwise.
1977 proc check_effective_target_mips_msa_runtime { } {
1978 if { [check_effective_target_mips_msa]
1979 && [check_mips_msa_hw_available] } {
1980 return 1
1982 return 0
1985 # Return 1 if we are compiling for 64-bit PowerPC but we do not use direct
1986 # move instructions for moves from GPR to FPR.
1988 proc check_effective_target_powerpc64_no_dm { } {
1989 # The "mulld" checks if we are generating PowerPC64 code. The "lfd"
1990 # checks if we do not use direct moves, but use the old-fashioned
1991 # slower move-via-the-stack.
1992 return [check_no_messages_and_pattern powerpc64_no_dm \
1993 {\mmulld\M.*\mlfd} assembly {
1994 double f(long long x) { return x*x; }
1995 } {-O2}]
1998 # Return 1 if the target supports the __builtin_cpu_supports built-in,
1999 # including having a new enough library to support the test. Cache the result.
2000 # Require at least a power7 to run on.
2002 proc check_ppc_cpu_supports_hw_available { } {
2003 return [check_cached_effective_target ppc_cpu_supports_hw_available {
2004 # Some simulators are known to not support VSX/power8 instructions.
2005 # For now, disable on Darwin
2006 if { [istarget powerpc-*-eabi]
2007 || [istarget powerpc*-*-eabispe]
2008 || [istarget *-*-darwin*]} {
2009 expr 0
2010 } else {
2011 set options "-mvsx"
2012 check_runtime_nocache ppc_cpu_supports_hw_available {
2013 int main()
2015 #ifdef __MACH__
2016 asm volatile ("xxlor vs0,vs0,vs0");
2017 #else
2018 asm volatile ("xxlor 0,0,0");
2019 #endif
2020 if (!__builtin_cpu_supports ("vsx"))
2021 return 1;
2022 return 0;
2024 } $options
2029 # Return 1 if the target supports executing 750CL paired-single instructions, 0
2030 # otherwise. Cache the result.
2032 proc check_750cl_hw_available { } {
2033 return [check_cached_effective_target 750cl_hw_available {
2034 # If this is not the right target then we can skip the test.
2035 if { ![istarget powerpc-*paired*] } {
2036 expr 0
2037 } else {
2038 check_runtime_nocache 750cl_hw_available {
2039 int main()
2041 #ifdef __MACH__
2042 asm volatile ("ps_mul v0,v0,v0");
2043 #else
2044 asm volatile ("ps_mul 0,0,0");
2045 #endif
2046 return 0;
2048 } "-mpaired"
2053 # Return 1 if the target supports executing power8 vector instructions, 0
2054 # otherwise. Cache the result.
2056 proc check_p8vector_hw_available { } {
2057 return [check_cached_effective_target p8vector_hw_available {
2058 # Some simulators are known to not support VSX/power8 instructions.
2059 # For now, disable on Darwin
2060 if { [istarget powerpc-*-eabi]
2061 || [istarget powerpc*-*-eabispe]
2062 || [istarget *-*-darwin*]} {
2063 expr 0
2064 } else {
2065 set options "-mpower8-vector"
2066 check_runtime_nocache p8vector_hw_available {
2067 int main()
2069 #ifdef __MACH__
2070 asm volatile ("xxlorc vs0,vs0,vs0");
2071 #else
2072 asm volatile ("xxlorc 0,0,0");
2073 #endif
2074 return 0;
2076 } $options
2081 # Return 1 if the target supports executing power9 vector instructions, 0
2082 # otherwise. Cache the result.
2084 proc check_p9vector_hw_available { } {
2085 return [check_cached_effective_target p9vector_hw_available {
2086 # Some simulators are known to not support VSX/power8/power9
2087 # instructions. For now, disable on Darwin.
2088 if { [istarget powerpc-*-eabi]
2089 || [istarget powerpc*-*-eabispe]
2090 || [istarget *-*-darwin*]} {
2091 expr 0
2092 } else {
2093 set options "-mpower9-vector"
2094 check_runtime_nocache p9vector_hw_available {
2095 int main()
2097 long e = -1;
2098 vector double v = (vector double) { 0.0, 0.0 };
2099 asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v));
2100 return e;
2102 } $options
2107 # Return 1 if the target supports executing power9 modulo instructions, 0
2108 # otherwise. Cache the result.
2110 proc check_p9modulo_hw_available { } {
2111 return [check_cached_effective_target p9modulo_hw_available {
2112 # Some simulators are known to not support VSX/power8/power9
2113 # instructions. For now, disable on Darwin.
2114 if { [istarget powerpc-*-eabi]
2115 || [istarget powerpc*-*-eabispe]
2116 || [istarget *-*-darwin*]} {
2117 expr 0
2118 } else {
2119 set options "-mmodulo"
2120 check_runtime_nocache p9modulo_hw_available {
2121 int main()
2123 int i = 5, j = 3, r = -1;
2124 asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j));
2125 return (r == 2);
2127 } $options
2132 # Return 1 if the target supports executing __float128 on PowerPC via software
2133 # emulation, 0 otherwise. Cache the result.
2135 proc check_ppc_float128_sw_available { } {
2136 return [check_cached_effective_target ppc_float128_sw_available {
2137 # Some simulators are known to not support VSX/power8/power9
2138 # instructions. For now, disable on Darwin.
2139 if { [istarget powerpc-*-eabi]
2140 || [istarget powerpc*-*-eabispe]
2141 || [istarget *-*-darwin*]} {
2142 expr 0
2143 } else {
2144 set options "-mfloat128 -mvsx"
2145 check_runtime_nocache ppc_float128_sw_available {
2146 volatile __float128 x = 1.0q;
2147 volatile __float128 y = 2.0q;
2148 int main()
2150 __float128 z = x + y;
2151 return (z != 3.0q);
2153 } $options
2158 # Return 1 if the target supports executing __float128 on PowerPC via power9
2159 # hardware instructions, 0 otherwise. Cache the result.
2161 proc check_ppc_float128_hw_available { } {
2162 return [check_cached_effective_target ppc_float128_hw_available {
2163 # Some simulators are known to not support VSX/power8/power9
2164 # instructions. For now, disable on Darwin.
2165 if { [istarget powerpc-*-eabi]
2166 || [istarget powerpc*-*-eabispe]
2167 || [istarget *-*-darwin*]} {
2168 expr 0
2169 } else {
2170 set options "-mfloat128 -mvsx -mfloat128-hardware -mpower9-vector"
2171 check_runtime_nocache ppc_float128_hw_available {
2172 volatile __float128 x = 1.0q;
2173 volatile __float128 y = 2.0q;
2174 int main()
2176 __float128 z = x + y;
2177 __float128 w = -1.0q;
2179 __asm__ ("xsaddqp %0,%1,%2" : "+v" (w) : "v" (x), "v" (y));
2180 return ((z != 3.0q) || (z != w);
2182 } $options
2187 # Return 1 if the target supports executing VSX instructions, 0
2188 # otherwise. Cache the result.
2190 proc check_vsx_hw_available { } {
2191 return [check_cached_effective_target vsx_hw_available {
2192 # Some simulators are known to not support VSX instructions.
2193 # For now, disable on Darwin
2194 if { [istarget powerpc-*-eabi]
2195 || [istarget powerpc*-*-eabispe]
2196 || [istarget *-*-darwin*]} {
2197 expr 0
2198 } else {
2199 set options "-mvsx"
2200 check_runtime_nocache vsx_hw_available {
2201 int main()
2203 #ifdef __MACH__
2204 asm volatile ("xxlor vs0,vs0,vs0");
2205 #else
2206 asm volatile ("xxlor 0,0,0");
2207 #endif
2208 return 0;
2210 } $options
2215 # Return 1 if the target supports executing AltiVec instructions, 0
2216 # otherwise. Cache the result.
2218 proc check_vmx_hw_available { } {
2219 return [check_cached_effective_target vmx_hw_available {
2220 # Some simulators are known to not support VMX instructions.
2221 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } {
2222 expr 0
2223 } else {
2224 # Most targets don't require special flags for this test case, but
2225 # Darwin does. Just to be sure, make sure VSX is not enabled for
2226 # the altivec tests.
2227 if { [istarget *-*-darwin*]
2228 || [istarget *-*-aix*] } {
2229 set options "-maltivec -mno-vsx"
2230 } else {
2231 set options "-mno-vsx"
2233 check_runtime_nocache vmx_hw_available {
2234 int main()
2236 #ifdef __MACH__
2237 asm volatile ("vor v0,v0,v0");
2238 #else
2239 asm volatile ("vor 0,0,0");
2240 #endif
2241 return 0;
2243 } $options
2248 proc check_ppc_recip_hw_available { } {
2249 return [check_cached_effective_target ppc_recip_hw_available {
2250 # Some simulators may not support FRE/FRES/FRSQRTE/FRSQRTES
2251 # For now, disable on Darwin
2252 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
2253 expr 0
2254 } else {
2255 set options "-mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb"
2256 check_runtime_nocache ppc_recip_hw_available {
2257 volatile double d_recip, d_rsqrt, d_four = 4.0;
2258 volatile float f_recip, f_rsqrt, f_four = 4.0f;
2259 int main()
2261 asm volatile ("fres %0,%1" : "=f" (f_recip) : "f" (f_four));
2262 asm volatile ("fre %0,%1" : "=d" (d_recip) : "d" (d_four));
2263 asm volatile ("frsqrtes %0,%1" : "=f" (f_rsqrt) : "f" (f_four));
2264 asm volatile ("frsqrte %0,%1" : "=f" (d_rsqrt) : "d" (d_four));
2265 return 0;
2267 } $options
2272 # Return 1 if the target supports executing AltiVec and Cell PPU
2273 # instructions, 0 otherwise. Cache the result.
2275 proc check_effective_target_cell_hw { } {
2276 return [check_cached_effective_target cell_hw_available {
2277 # Some simulators are known to not support VMX and PPU instructions.
2278 if { [istarget powerpc-*-eabi*] } {
2279 expr 0
2280 } else {
2281 # Most targets don't require special flags for this test
2282 # case, but Darwin and AIX do.
2283 if { [istarget *-*-darwin*]
2284 || [istarget *-*-aix*] } {
2285 set options "-maltivec -mcpu=cell"
2286 } else {
2287 set options "-mcpu=cell"
2289 check_runtime_nocache cell_hw_available {
2290 int main()
2292 #ifdef __MACH__
2293 asm volatile ("vor v0,v0,v0");
2294 asm volatile ("lvlx v0,r0,r0");
2295 #else
2296 asm volatile ("vor 0,0,0");
2297 asm volatile ("lvlx 0,0,0");
2298 #endif
2299 return 0;
2301 } $options
2306 # Return 1 if the target supports executing 64-bit instructions, 0
2307 # otherwise. Cache the result.
2309 proc check_effective_target_powerpc64 { } {
2310 global powerpc64_available_saved
2311 global tool
2313 if [info exists powerpc64_available_saved] {
2314 verbose "check_effective_target_powerpc64 returning saved $powerpc64_available_saved" 2
2315 } else {
2316 set powerpc64_available_saved 0
2318 # Some simulators are known to not support powerpc64 instructions.
2319 if { [istarget powerpc-*-eabi*] || [istarget powerpc-ibm-aix*] } {
2320 verbose "check_effective_target_powerpc64 returning 0" 2
2321 return $powerpc64_available_saved
2324 # Set up, compile, and execute a test program containing a 64-bit
2325 # instruction. Include the current process ID in the file
2326 # names to prevent conflicts with invocations for multiple
2327 # testsuites.
2328 set src ppc[pid].c
2329 set exe ppc[pid].x
2331 set f [open $src "w"]
2332 puts $f "int main() {"
2333 puts $f "#ifdef __MACH__"
2334 puts $f " asm volatile (\"extsw r0,r0\");"
2335 puts $f "#else"
2336 puts $f " asm volatile (\"extsw 0,0\");"
2337 puts $f "#endif"
2338 puts $f " return 0; }"
2339 close $f
2341 set opts "additional_flags=-mcpu=G5"
2343 verbose "check_effective_target_powerpc64 compiling testfile $src" 2
2344 set lines [${tool}_target_compile $src $exe executable "$opts"]
2345 file delete $src
2347 if [string match "" $lines] then {
2348 # No error message, compilation succeeded.
2349 set result [${tool}_load "./$exe" "" ""]
2350 set status [lindex $result 0]
2351 remote_file build delete $exe
2352 verbose "check_effective_target_powerpc64 testfile status is <$status>" 2
2354 if { $status == "pass" } then {
2355 set powerpc64_available_saved 1
2357 } else {
2358 verbose "check_effective_target_powerpc64 testfile compilation failed" 2
2362 return $powerpc64_available_saved
2365 # GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing
2366 # complex float arguments. This affects gfortran tests that call cabsf
2367 # in libm built by an earlier compiler. Return 0 if libm uses the same
2368 # argument passing as the compiler under test, 1 otherwise.
2370 proc check_effective_target_broken_cplxf_arg { } {
2371 # Skip the work for targets known not to be affected.
2372 if { ![istarget powerpc*-*-linux*] || ![is-effective-target lp64] } {
2373 return 0
2376 return [check_cached_effective_target broken_cplxf_arg {
2377 check_runtime_nocache broken_cplxf_arg {
2378 #include <complex.h>
2379 extern void abort (void);
2380 float fabsf (float);
2381 float cabsf (_Complex float);
2382 int main ()
2384 _Complex float cf;
2385 float f;
2386 cf = 3 + 4.0fi;
2387 f = cabsf (cf);
2388 if (fabsf (f - 5.0) > 0.0001)
2389 /* Yes, it's broken. */
2390 return 0;
2391 /* All fine, not broken. */
2392 return 1;
2394 } "-lm"
2398 # Return 1 is this is a TI C6X target supporting C67X instructions
2399 proc check_effective_target_ti_c67x { } {
2400 return [check_no_compiler_messages ti_c67x assembly {
2401 #if !defined(_TMS320C6700)
2402 #error !_TMS320C6700
2403 #endif
2407 # Return 1 is this is a TI C6X target supporting C64X+ instructions
2408 proc check_effective_target_ti_c64xp { } {
2409 return [check_no_compiler_messages ti_c64xp assembly {
2410 #if !defined(_TMS320C6400_PLUS)
2411 #error !_TMS320C6400_PLUS
2412 #endif
2417 proc check_alpha_max_hw_available { } {
2418 return [check_runtime alpha_max_hw_available {
2419 int main() { return __builtin_alpha_amask(1<<8) != 0; }
2423 # Returns true iff the FUNCTION is available on the target system.
2424 # (This is essentially a Tcl implementation of Autoconf's
2425 # AC_CHECK_FUNC.)
2427 proc check_function_available { function } {
2428 return [check_no_compiler_messages ${function}_available \
2429 executable [subst {
2430 #ifdef __cplusplus
2431 extern "C"
2432 #endif
2433 char $function ();
2434 int main () { $function (); }
2435 }] "-fno-builtin" ]
2438 # Returns true iff "fork" is available on the target system.
2440 proc check_fork_available {} {
2441 return [check_function_available "fork"]
2444 # Returns true iff "mkfifo" is available on the target system.
2446 proc check_mkfifo_available {} {
2447 if { [istarget *-*-cygwin*] } {
2448 # Cygwin has mkfifo, but support is incomplete.
2449 return 0
2452 return [check_function_available "mkfifo"]
2455 # Returns true iff "__cxa_atexit" is used on the target system.
2457 proc check_cxa_atexit_available { } {
2458 return [check_cached_effective_target cxa_atexit_available {
2459 if { [istarget hppa*-*-hpux10*] } {
2460 # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes.
2461 expr 0
2462 } elseif { [istarget *-*-vxworks] } {
2463 # vxworks doesn't have __cxa_atexit but subsequent test passes.
2464 expr 0
2465 } else {
2466 check_runtime_nocache cxa_atexit_available {
2467 // C++
2468 #include <stdlib.h>
2469 static unsigned int count;
2470 struct X
2472 X() { count = 1; }
2473 ~X()
2475 if (count != 3)
2476 exit(1);
2477 count = 4;
2480 void f()
2482 static X x;
2484 struct Y
2486 Y() { f(); count = 2; }
2487 ~Y()
2489 if (count != 2)
2490 exit(1);
2491 count = 3;
2494 Y y;
2495 int main() { return 0; }
2501 proc check_effective_target_objc2 { } {
2502 return [check_no_compiler_messages objc2 object {
2503 #ifdef __OBJC2__
2504 int dummy[1];
2505 #else
2506 #error !__OBJC2__
2507 #endif
2511 proc check_effective_target_next_runtime { } {
2512 return [check_no_compiler_messages objc2 object {
2513 #ifdef __NEXT_RUNTIME__
2514 int dummy[1];
2515 #else
2516 #error !__NEXT_RUNTIME__
2517 #endif
2521 # Return 1 if we're generating 32-bit code using default options, 0
2522 # otherwise.
2524 proc check_effective_target_ilp32 { } {
2525 return [check_no_compiler_messages ilp32 object {
2526 int dummy[sizeof (int) == 4
2527 && sizeof (void *) == 4
2528 && sizeof (long) == 4 ? 1 : -1];
2532 # Return 1 if we're generating ia32 code using default options, 0
2533 # otherwise.
2535 proc check_effective_target_ia32 { } {
2536 return [check_no_compiler_messages ia32 object {
2537 int dummy[sizeof (int) == 4
2538 && sizeof (void *) == 4
2539 && sizeof (long) == 4 ? 1 : -1] = { __i386__ };
2543 # Return 1 if we're generating x32 code using default options, 0
2544 # otherwise.
2546 proc check_effective_target_x32 { } {
2547 return [check_no_compiler_messages x32 object {
2548 int dummy[sizeof (int) == 4
2549 && sizeof (void *) == 4
2550 && sizeof (long) == 4 ? 1 : -1] = { __x86_64__ };
2554 # Return 1 if we're generating 32-bit integers using default
2555 # options, 0 otherwise.
2557 proc check_effective_target_int32 { } {
2558 return [check_no_compiler_messages int32 object {
2559 int dummy[sizeof (int) == 4 ? 1 : -1];
2563 # Return 1 if we're generating 32-bit or larger integers using default
2564 # options, 0 otherwise.
2566 proc check_effective_target_int32plus { } {
2567 return [check_no_compiler_messages int32plus object {
2568 int dummy[sizeof (int) >= 4 ? 1 : -1];
2572 # Return 1 if we're generating 32-bit or larger pointers using default
2573 # options, 0 otherwise.
2575 proc check_effective_target_ptr32plus { } {
2576 # The msp430 has 16-bit or 20-bit pointers. The 20-bit pointer is stored
2577 # in a 32-bit slot when in memory, so sizeof(void *) returns 4, but it
2578 # cannot really hold a 32-bit address, so we always return false here.
2579 if { [istarget msp430-*-*] } {
2580 return 0
2583 return [check_no_compiler_messages ptr32plus object {
2584 int dummy[sizeof (void *) >= 4 ? 1 : -1];
2588 # Return 1 if we support 32-bit or larger array and structure sizes
2589 # using default options, 0 otherwise. Avoid false positive on
2590 # targets with 20 or 24 bit address spaces.
2592 proc check_effective_target_size32plus { } {
2593 return [check_no_compiler_messages size32plus object {
2594 char dummy[16777217L];
2598 # Returns 1 if we're generating 16-bit or smaller integers with the
2599 # default options, 0 otherwise.
2601 proc check_effective_target_int16 { } {
2602 return [check_no_compiler_messages int16 object {
2603 int dummy[sizeof (int) < 4 ? 1 : -1];
2607 # Return 1 if we're generating 64-bit code using default options, 0
2608 # otherwise.
2610 proc check_effective_target_lp64 { } {
2611 return [check_no_compiler_messages lp64 object {
2612 int dummy[sizeof (int) == 4
2613 && sizeof (void *) == 8
2614 && sizeof (long) == 8 ? 1 : -1];
2618 # Return 1 if we're generating 64-bit code using default llp64 options,
2619 # 0 otherwise.
2621 proc check_effective_target_llp64 { } {
2622 return [check_no_compiler_messages llp64 object {
2623 int dummy[sizeof (int) == 4
2624 && sizeof (void *) == 8
2625 && sizeof (long long) == 8
2626 && sizeof (long) == 4 ? 1 : -1];
2630 # Return 1 if long and int have different sizes,
2631 # 0 otherwise.
2633 proc check_effective_target_long_neq_int { } {
2634 return [check_no_compiler_messages long_ne_int object {
2635 int dummy[sizeof (int) != sizeof (long) ? 1 : -1];
2639 # Return 1 if the target supports long double larger than double,
2640 # 0 otherwise.
2642 proc check_effective_target_large_long_double { } {
2643 return [check_no_compiler_messages large_long_double object {
2644 int dummy[sizeof(long double) > sizeof(double) ? 1 : -1];
2648 # Return 1 if the target supports double larger than float,
2649 # 0 otherwise.
2651 proc check_effective_target_large_double { } {
2652 return [check_no_compiler_messages large_double object {
2653 int dummy[sizeof(double) > sizeof(float) ? 1 : -1];
2657 # Return 1 if the target supports long double of 128 bits,
2658 # 0 otherwise.
2660 proc check_effective_target_longdouble128 { } {
2661 return [check_no_compiler_messages longdouble128 object {
2662 int dummy[sizeof(long double) == 16 ? 1 : -1];
2666 # Return 1 if the target supports double of 64 bits,
2667 # 0 otherwise.
2669 proc check_effective_target_double64 { } {
2670 return [check_no_compiler_messages double64 object {
2671 int dummy[sizeof(double) == 8 ? 1 : -1];
2675 # Return 1 if the target supports double of at least 64 bits,
2676 # 0 otherwise.
2678 proc check_effective_target_double64plus { } {
2679 return [check_no_compiler_messages double64plus object {
2680 int dummy[sizeof(double) >= 8 ? 1 : -1];
2684 # Return 1 if the target supports 'w' suffix on floating constant
2685 # 0 otherwise.
2687 proc check_effective_target_has_w_floating_suffix { } {
2688 set opts ""
2689 if [check_effective_target_c++] {
2690 append opts "-std=gnu++03"
2692 return [check_no_compiler_messages w_fp_suffix object {
2693 float dummy = 1.0w;
2694 } "$opts"]
2697 # Return 1 if the target supports 'q' suffix on floating constant
2698 # 0 otherwise.
2700 proc check_effective_target_has_q_floating_suffix { } {
2701 set opts ""
2702 if [check_effective_target_c++] {
2703 append opts "-std=gnu++03"
2705 return [check_no_compiler_messages q_fp_suffix object {
2706 float dummy = 1.0q;
2707 } "$opts"]
2710 # Return 1 if the target supports the _FloatN / _FloatNx type
2711 # indicated in the function name, 0 otherwise.
2713 proc check_effective_target_float16 {} {
2714 return [check_no_compiler_messages_nocache float16 object {
2715 _Float16 x;
2716 } [add_options_for_float16 ""]]
2719 proc check_effective_target_float32 {} {
2720 return [check_no_compiler_messages_nocache float32 object {
2721 _Float32 x;
2722 } [add_options_for_float32 ""]]
2725 proc check_effective_target_float64 {} {
2726 return [check_no_compiler_messages_nocache float64 object {
2727 _Float64 x;
2728 } [add_options_for_float64 ""]]
2731 proc check_effective_target_float128 {} {
2732 return [check_no_compiler_messages_nocache float128 object {
2733 _Float128 x;
2734 } [add_options_for_float128 ""]]
2737 proc check_effective_target_float32x {} {
2738 return [check_no_compiler_messages_nocache float32x object {
2739 _Float32x x;
2740 } [add_options_for_float32x ""]]
2743 proc check_effective_target_float64x {} {
2744 return [check_no_compiler_messages_nocache float64x object {
2745 _Float64x x;
2746 } [add_options_for_float64x ""]]
2749 proc check_effective_target_float128x {} {
2750 return [check_no_compiler_messages_nocache float128x object {
2751 _Float128x x;
2752 } [add_options_for_float128x ""]]
2755 # Likewise, but runtime support for any special options used as well
2756 # as compile-time support is required.
2758 proc check_effective_target_float16_runtime {} {
2759 return [check_effective_target_float16]
2762 proc check_effective_target_float32_runtime {} {
2763 return [check_effective_target_float32]
2766 proc check_effective_target_float64_runtime {} {
2767 return [check_effective_target_float64]
2770 proc check_effective_target_float128_runtime {} {
2771 if { ![check_effective_target_float128] } {
2772 return 0
2774 if { [istarget powerpc*-*-*] } {
2775 return [check_effective_target_base_quadfloat_support]
2777 return 1
2780 proc check_effective_target_float32x_runtime {} {
2781 return [check_effective_target_float32x]
2784 proc check_effective_target_float64x_runtime {} {
2785 if { ![check_effective_target_float64x] } {
2786 return 0
2788 if { [istarget powerpc*-*-*] } {
2789 return [check_effective_target_base_quadfloat_support]
2791 return 1
2794 proc check_effective_target_float128x_runtime {} {
2795 return [check_effective_target_float128x]
2798 # Return 1 if the target hardware supports any options added for
2799 # _FloatN and _FloatNx types, 0 otherwise.
2801 proc check_effective_target_floatn_nx_runtime {} {
2802 if { [istarget powerpc*-*-aix*] } {
2803 return 0
2805 if { [istarget powerpc*-*-*] } {
2806 return [check_effective_target_base_quadfloat_support]
2808 return 1
2811 # Add options needed to use the _FloatN / _FloatNx type indicated in
2812 # the function name.
2814 proc add_options_for_float16 { flags } {
2815 if { [istarget arm*-*-*] } {
2816 return "$flags -mfp16-format=ieee"
2818 return "$flags"
2821 proc add_options_for_float32 { flags } {
2822 return "$flags"
2825 proc add_options_for_float64 { flags } {
2826 return "$flags"
2829 proc add_options_for_float128 { flags } {
2830 return [add_options_for___float128 "$flags"]
2833 proc add_options_for_float32x { flags } {
2834 return "$flags"
2837 proc add_options_for_float64x { flags } {
2838 return [add_options_for___float128 "$flags"]
2841 proc add_options_for_float128x { flags } {
2842 return "$flags"
2845 # Return 1 if the target supports __float128,
2846 # 0 otherwise.
2848 proc check_effective_target___float128 { } {
2849 if { [istarget powerpc*-*-*] } {
2850 return [check_ppc_float128_sw_available]
2852 if { [istarget ia64-*-*]
2853 || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
2854 return 1
2856 return 0
2859 proc add_options_for___float128 { flags } {
2860 if { [istarget powerpc*-*-*] } {
2861 return "$flags -mfloat128 -mvsx"
2863 return "$flags"
2866 # Return 1 if the target supports any special run-time requirements
2867 # for __float128 or _Float128,
2868 # 0 otherwise.
2870 proc check_effective_target_base_quadfloat_support { } {
2871 if { [istarget powerpc*-*-*] } {
2872 return [check_vsx_hw_available]
2874 return 1
2877 # Return 1 if the target supports compiling fixed-point,
2878 # 0 otherwise.
2880 proc check_effective_target_fixed_point { } {
2881 return [check_no_compiler_messages fixed_point object {
2882 _Sat _Fract x; _Sat _Accum y;
2886 # Return 1 if the target supports compiling decimal floating point,
2887 # 0 otherwise.
2889 proc check_effective_target_dfp_nocache { } {
2890 verbose "check_effective_target_dfp_nocache: compiling source" 2
2891 set ret [check_no_compiler_messages_nocache dfp object {
2892 float x __attribute__((mode(DD)));
2894 verbose "check_effective_target_dfp_nocache: returning $ret" 2
2895 return $ret
2898 proc check_effective_target_dfprt_nocache { } {
2899 return [check_runtime_nocache dfprt {
2900 typedef float d64 __attribute__((mode(DD)));
2901 d64 x = 1.2df, y = 2.3dd, z;
2902 int main () { z = x + y; return 0; }
2906 # Return 1 if the target supports compiling Decimal Floating Point,
2907 # 0 otherwise.
2909 # This won't change for different subtargets so cache the result.
2911 proc check_effective_target_dfp { } {
2912 return [check_cached_effective_target dfp {
2913 check_effective_target_dfp_nocache
2917 # Return 1 if the target supports linking and executing Decimal Floating
2918 # Point, 0 otherwise.
2920 # This won't change for different subtargets so cache the result.
2922 proc check_effective_target_dfprt { } {
2923 return [check_cached_effective_target dfprt {
2924 check_effective_target_dfprt_nocache
2928 proc check_effective_target_powerpc_popcntb_ok { } {
2929 return [check_cached_effective_target powerpc_popcntb_ok {
2931 # Disable on Darwin.
2932 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
2933 expr 0
2934 } else {
2935 check_runtime_nocache powerpc_popcntb_ok {
2936 volatile int r;
2937 volatile int a = 0x12345678;
2938 int main()
2940 asm volatile ("popcntb %0,%1" : "=r" (r) : "r" (a));
2941 return 0;
2943 } "-mcpu=power5"
2948 # Return 1 if the target supports executing DFP hardware instructions,
2949 # 0 otherwise. Cache the result.
2951 proc check_dfp_hw_available { } {
2952 return [check_cached_effective_target dfp_hw_available {
2953 # For now, disable on Darwin
2954 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
2955 expr 0
2956 } else {
2957 check_runtime_nocache dfp_hw_available {
2958 volatile _Decimal64 r;
2959 volatile _Decimal64 a = 4.0DD;
2960 volatile _Decimal64 b = 2.0DD;
2961 int main()
2963 asm volatile ("dadd %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
2964 asm volatile ("dsub %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
2965 asm volatile ("dmul %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
2966 asm volatile ("ddiv %0,%1,%2" : "=d" (r) : "d" (a), "d" (b));
2967 return 0;
2969 } "-mcpu=power6 -mhard-float"
2974 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
2976 proc check_effective_target_ucn_nocache { } {
2977 # -std=c99 is only valid for C
2978 if [check_effective_target_c] {
2979 set ucnopts "-std=c99"
2980 } else {
2981 set ucnopts ""
2983 verbose "check_effective_target_ucn_nocache: compiling source" 2
2984 set ret [check_no_compiler_messages_nocache ucn object {
2985 int \u00C0;
2986 } $ucnopts]
2987 verbose "check_effective_target_ucn_nocache: returning $ret" 2
2988 return $ret
2991 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
2993 # This won't change for different subtargets, so cache the result.
2995 proc check_effective_target_ucn { } {
2996 return [check_cached_effective_target ucn {
2997 check_effective_target_ucn_nocache
3001 # Return 1 if the target needs a command line argument to enable a SIMD
3002 # instruction set.
3004 proc check_effective_target_vect_cmdline_needed { } {
3005 global et_vect_cmdline_needed_saved
3006 global et_vect_cmdline_needed_target_name
3008 if { ![info exists et_vect_cmdline_needed_target_name] } {
3009 set et_vect_cmdline_needed_target_name ""
3012 # If the target has changed since we set the cached value, clear it.
3013 set current_target [current_target_name]
3014 if { $current_target != $et_vect_cmdline_needed_target_name } {
3015 verbose "check_effective_target_vect_cmdline_needed: `$et_vect_cmdline_needed_target_name' `$current_target'" 2
3016 set et_vect_cmdline_needed_target_name $current_target
3017 if { [info exists et_vect_cmdline_needed_saved] } {
3018 verbose "check_effective_target_vect_cmdline_needed: removing cached result" 2
3019 unset et_vect_cmdline_needed_saved
3023 if [info exists et_vect_cmdline_needed_saved] {
3024 verbose "check_effective_target_vect_cmdline_needed: using cached result" 2
3025 } else {
3026 set et_vect_cmdline_needed_saved 1
3027 if { [istarget alpha*-*-*]
3028 || [istarget ia64-*-*]
3029 || (([istarget i?86-*-*] || [istarget x86_64-*-*])
3030 && ![is-effective-target ia32])
3031 || ([istarget powerpc*-*-*]
3032 && ([check_effective_target_powerpc_spe]
3033 || [check_effective_target_powerpc_altivec]))
3034 || ([istarget sparc*-*-*] && [check_effective_target_sparc_vis])
3035 || [istarget spu-*-*]
3036 || ([istarget arm*-*-*] && [check_effective_target_arm_neon])
3037 || [istarget aarch64*-*-*] } {
3038 set et_vect_cmdline_needed_saved 0
3042 verbose "check_effective_target_vect_cmdline_needed: returning $et_vect_cmdline_needed_saved" 2
3043 return $et_vect_cmdline_needed_saved
3046 # Return 1 if the target supports hardware vectors of int, 0 otherwise.
3048 # This won't change for different subtargets so cache the result.
3050 proc check_effective_target_vect_int { } {
3051 global et_vect_int_saved
3052 global et_index
3054 if [info exists et_vect_int_saved($et_index)] {
3055 verbose "check_effective_target_vect_int: using cached result" 2
3056 } else {
3057 set et_vect_int_saved($et_index) 0
3058 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
3059 || ([istarget powerpc*-*-*]
3060 && ![istarget powerpc-*-linux*paired*])
3061 || [istarget spu-*-*]
3062 || [istarget sparc*-*-*]
3063 || [istarget alpha*-*-*]
3064 || [istarget ia64-*-*]
3065 || [istarget aarch64*-*-*]
3066 || [is-effective-target arm_neon]
3067 || ([istarget mips*-*-*]
3068 && ([et-is-effective-target mips_loongson]
3069 || [et-is-effective-target mips_msa])) } {
3070 set et_vect_int_saved($et_index) 1
3074 verbose "check_effective_target_vect_int:\
3075 returning $et_vect_int_saved($et_index)" 2
3076 return $et_vect_int_saved($et_index)
3079 # Return 1 if the target supports signed int->float conversion
3082 proc check_effective_target_vect_intfloat_cvt { } {
3083 global et_vect_intfloat_cvt_saved
3084 global et_index
3086 if [info exists et_vect_intfloat_cvt_saved($et_index)] {
3087 verbose "check_effective_target_vect_intfloat_cvt:\
3088 using cached result" 2
3089 } else {
3090 set et_vect_intfloat_cvt_saved($et_index) 0
3091 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
3092 || ([istarget powerpc*-*-*]
3093 && ![istarget powerpc-*-linux*paired*])
3094 || [is-effective-target arm_neon]
3095 || ([istarget mips*-*-*]
3096 && [et-is-effective-target mips_msa]) } {
3097 set et_vect_intfloat_cvt_saved($et_index) 1
3101 verbose "check_effective_target_vect_intfloat_cvt:\
3102 returning $et_vect_intfloat_cvt_saved($et_index)" 2
3103 return $et_vect_intfloat_cvt_saved($et_index)
3106 #Return 1 if we're supporting __int128 for target, 0 otherwise.
3108 proc check_effective_target_int128 { } {
3109 return [check_no_compiler_messages int128 object {
3110 int dummy[
3111 #ifndef __SIZEOF_INT128__
3113 #else
3115 #endif
3120 # Return 1 if the target supports unsigned int->float conversion
3123 proc check_effective_target_vect_uintfloat_cvt { } {
3124 global et_vect_uintfloat_cvt_saved
3125 global et_index
3127 if [info exists et_vect_uintfloat_cvt_saved($et_index)] {
3128 verbose "check_effective_target_vect_uintfloat_cvt:\
3129 using cached result" 2
3130 } else {
3131 set et_vect_uintfloat_cvt_saved($et_index) 0
3132 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
3133 || ([istarget powerpc*-*-*]
3134 && ![istarget powerpc-*-linux*paired*])
3135 || [istarget aarch64*-*-*]
3136 || [is-effective-target arm_neon]
3137 || ([istarget mips*-*-*]
3138 && [et-is-effective-target mips_msa]) } {
3139 set et_vect_uintfloat_cvt_saved($et_index) 1
3143 verbose "check_effective_target_vect_uintfloat_cvt:\
3144 returning $et_vect_uintfloat_cvt_saved($et_index)" 2
3145 return $et_vect_uintfloat_cvt_saved($et_index)
3149 # Return 1 if the target supports signed float->int conversion
3152 proc check_effective_target_vect_floatint_cvt { } {
3153 global et_vect_floatint_cvt_saved
3154 global et_index
3156 if [info exists et_vect_floatint_cvt_saved($et_index)] {
3157 verbose "check_effective_target_vect_floatint_cvt:\
3158 using cached result" 2
3159 } else {
3160 set et_vect_floatint_cvt_saved($et_index) 0
3161 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
3162 || ([istarget powerpc*-*-*]
3163 && ![istarget powerpc-*-linux*paired*])
3164 || [is-effective-target arm_neon]
3165 || ([istarget mips*-*-*]
3166 && [et-is-effective-target mips_msa]) } {
3167 set et_vect_floatint_cvt_saved($et_index) 1
3171 verbose "check_effective_target_vect_floatint_cvt:\
3172 returning $et_vect_floatint_cvt_saved($et_index)" 2
3173 return $et_vect_floatint_cvt_saved($et_index)
3176 # Return 1 if the target supports unsigned float->int conversion
3179 proc check_effective_target_vect_floatuint_cvt { } {
3180 global et_vect_floatuint_cvt_saved
3181 global et_index
3183 if [info exists et_vect_floatuint_cvt_saved($et_index)] {
3184 verbose "check_effective_target_vect_floatuint_cvt:\
3185 using cached result" 2
3186 } else {
3187 set et_vect_floatuint_cvt_saved($et_index) 0
3188 if { ([istarget powerpc*-*-*]
3189 && ![istarget powerpc-*-linux*paired*])
3190 || [is-effective-target arm_neon]
3191 || ([istarget mips*-*-*]
3192 && [et-is-effective-target mips_msa]) } {
3193 set et_vect_floatuint_cvt_saved($et_index) 1
3197 verbose "check_effective_target_vect_floatuint_cvt:\
3198 returning $et_vect_floatuint_cvt_saved($et_index)" 2
3199 return $et_vect_floatuint_cvt_saved($et_index)
3202 # Return 1 if the target supports #pragma omp declare simd, 0 otherwise.
3204 # This won't change for different subtargets so cache the result.
3206 proc check_effective_target_vect_simd_clones { } {
3207 global et_vect_simd_clones_saved
3208 global et_index
3210 if [info exists et_vect_simd_clones_saved($et_index)] {
3211 verbose "check_effective_target_vect_simd_clones: using cached result" 2
3212 } else {
3213 set et_vect_simd_clones_saved($et_index) 0
3214 # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx,
3215 # avx2 and avx512f clone. Only the right clone for the
3216 # specified arch will be chosen, but still we need to at least
3217 # be able to assemble avx512f.
3218 if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
3219 && [check_effective_target_avx512f]) } {
3220 set et_vect_simd_clones_saved($et_index) 1
3224 verbose "check_effective_target_vect_simd_clones:\
3225 returning $et_vect_simd_clones_saved($et_index)" 2
3226 return $et_vect_simd_clones_saved($et_index)
3229 # Return 1 if this is a AArch64 target supporting big endian
3230 proc check_effective_target_aarch64_big_endian { } {
3231 return [check_no_compiler_messages aarch64_big_endian assembly {
3232 #if !defined(__aarch64__) || !defined(__AARCH64EB__)
3233 #error !__aarch64__ || !__AARCH64EB__
3234 #endif
3238 # Return 1 if this is a AArch64 target supporting little endian
3239 proc check_effective_target_aarch64_little_endian { } {
3240 if { ![istarget aarch64*-*-*] } {
3241 return 0
3244 return [check_no_compiler_messages aarch64_little_endian assembly {
3245 #if !defined(__aarch64__) || defined(__AARCH64EB__)
3246 #error FOO
3247 #endif
3251 # Return 1 if this is a compiler supporting ARC atomic operations
3252 proc check_effective_target_arc_atomic { } {
3253 return [check_no_compiler_messages arc_atomic assembly {
3254 #if !defined(__ARC_ATOMIC__)
3255 #error FOO
3256 #endif
3260 # Return 1 if this is an arm target using 32-bit instructions
3261 proc check_effective_target_arm32 { } {
3262 if { ![istarget arm*-*-*] } {
3263 return 0
3266 return [check_no_compiler_messages arm32 assembly {
3267 #if !defined(__arm__) || (defined(__thumb__) && !defined(__thumb2__))
3268 #error !__arm || __thumb__ && !__thumb2__
3269 #endif
3273 # Return 1 if this is an arm target not using Thumb
3274 proc check_effective_target_arm_nothumb { } {
3275 if { ![istarget arm*-*-*] } {
3276 return 0
3279 return [check_no_compiler_messages arm_nothumb assembly {
3280 #if !defined(__arm__) || (defined(__thumb__) || defined(__thumb2__))
3281 #error !__arm__ || __thumb || __thumb2__
3282 #endif
3286 # Return 1 if this is a little-endian ARM target
3287 proc check_effective_target_arm_little_endian { } {
3288 if { ![istarget arm*-*-*] } {
3289 return 0
3292 return [check_no_compiler_messages arm_little_endian assembly {
3293 #if !defined(__arm__) || !defined(__ARMEL__)
3294 #error !__arm__ || !__ARMEL__
3295 #endif
3299 # Return 1 if this is an ARM target that only supports aligned vector accesses
3300 proc check_effective_target_arm_vect_no_misalign { } {
3301 if { ![istarget arm*-*-*] } {
3302 return 0
3305 return [check_no_compiler_messages arm_vect_no_misalign assembly {
3306 #if !defined(__arm__) \
3307 || (defined(__ARM_FEATURE_UNALIGNED) \
3308 && defined(__ARMEL__))
3309 #error !__arm__ || (__ARMEL__ && __ARM_FEATURE_UNALIGNED)
3310 #endif
3315 # Return 1 if this is an ARM target supporting -mfpu=vfp
3316 # -mfloat-abi=softfp. Some multilibs may be incompatible with these
3317 # options.
3319 proc check_effective_target_arm_vfp_ok { } {
3320 if { [check_effective_target_arm32] } {
3321 return [check_no_compiler_messages arm_vfp_ok object {
3322 int dummy;
3323 } "-mfpu=vfp -mfloat-abi=softfp"]
3324 } else {
3325 return 0
3329 # Return 1 if this is an ARM target supporting -mfpu=vfp3
3330 # -mfloat-abi=softfp.
3332 proc check_effective_target_arm_vfp3_ok { } {
3333 if { [check_effective_target_arm32] } {
3334 return [check_no_compiler_messages arm_vfp3_ok object {
3335 int dummy;
3336 } "-mfpu=vfp3 -mfloat-abi=softfp"]
3337 } else {
3338 return 0
3342 # Return 1 if this is an ARM target supporting -mfpu=fp-armv8
3343 # -mfloat-abi=softfp.
3344 proc check_effective_target_arm_v8_vfp_ok {} {
3345 if { [check_effective_target_arm32] } {
3346 return [check_no_compiler_messages arm_v8_vfp_ok object {
3347 int foo (void)
3349 __asm__ volatile ("vrinta.f32.f32 s0, s0");
3350 return 0;
3352 } "-mfpu=fp-armv8 -mfloat-abi=softfp"]
3353 } else {
3354 return 0
3358 # Return 1 if this is an ARM target supporting -mfpu=vfp
3359 # -mfloat-abi=hard. Some multilibs may be incompatible with these
3360 # options.
3362 proc check_effective_target_arm_hard_vfp_ok { } {
3363 if { [check_effective_target_arm32]
3364 && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } {
3365 return [check_no_compiler_messages arm_hard_vfp_ok executable {
3366 int main() { return 0;}
3367 } "-mfpu=vfp -mfloat-abi=hard"]
3368 } else {
3369 return 0
3373 # Return 1 if this is an ARM target defining __ARM_FP. We may need
3374 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
3375 # incompatible with these options. Also set et_arm_fp_flags to the
3376 # best options to add.
3378 proc check_effective_target_arm_fp_ok_nocache { } {
3379 global et_arm_fp_flags
3380 set et_arm_fp_flags ""
3381 if { [check_effective_target_arm32] } {
3382 foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} {
3383 if { [check_no_compiler_messages_nocache arm_fp_ok object {
3384 #ifndef __ARM_FP
3385 #error __ARM_FP not defined
3386 #endif
3387 } "$flags"] } {
3388 set et_arm_fp_flags $flags
3389 return 1
3394 return 0
3397 proc check_effective_target_arm_fp_ok { } {
3398 return [check_cached_effective_target arm_fp_ok \
3399 check_effective_target_arm_fp_ok_nocache]
3402 # Add the options needed to define __ARM_FP. We need either
3403 # -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already
3404 # specified by the multilib, use it.
3406 proc add_options_for_arm_fp { flags } {
3407 if { ! [check_effective_target_arm_fp_ok] } {
3408 return "$flags"
3410 global et_arm_fp_flags
3411 return "$flags $et_arm_fp_flags"
3414 # Return 1 if this is an ARM target that supports DSP multiply with
3415 # current multilib flags.
3417 proc check_effective_target_arm_dsp { } {
3418 return [check_no_compiler_messages arm_dsp assembly {
3419 #ifndef __ARM_FEATURE_DSP
3420 #error not DSP
3421 #endif
3422 int i;
3426 # Return 1 if this is an ARM target that supports unaligned word/halfword
3427 # load/store instructions.
3429 proc check_effective_target_arm_unaligned { } {
3430 return [check_no_compiler_messages arm_unaligned assembly {
3431 #ifndef __ARM_FEATURE_UNALIGNED
3432 #error no unaligned support
3433 #endif
3434 int i;
3438 # Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
3439 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
3440 # incompatible with these options. Also set et_arm_crypto_flags to the
3441 # best options to add.
3443 proc check_effective_target_arm_crypto_ok_nocache { } {
3444 global et_arm_crypto_flags
3445 set et_arm_crypto_flags ""
3446 if { [check_effective_target_arm_v8_neon_ok] } {
3447 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} {
3448 if { [check_no_compiler_messages_nocache arm_crypto_ok object {
3449 #include "arm_neon.h"
3450 uint8x16_t
3451 foo (uint8x16_t a, uint8x16_t b)
3453 return vaeseq_u8 (a, b);
3455 } "$flags"] } {
3456 set et_arm_crypto_flags $flags
3457 return 1
3462 return 0
3465 # Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8
3467 proc check_effective_target_arm_crypto_ok { } {
3468 return [check_cached_effective_target arm_crypto_ok \
3469 check_effective_target_arm_crypto_ok_nocache]
3472 # Add options for crypto extensions.
3473 proc add_options_for_arm_crypto { flags } {
3474 if { ! [check_effective_target_arm_crypto_ok] } {
3475 return "$flags"
3477 global et_arm_crypto_flags
3478 return "$flags $et_arm_crypto_flags"
3481 # Add the options needed for NEON. We need either -mfloat-abi=softfp
3482 # or -mfloat-abi=hard, but if one is already specified by the
3483 # multilib, use it. Similarly, if a -mfpu option already enables
3484 # NEON, do not add -mfpu=neon.
3486 proc add_options_for_arm_neon { flags } {
3487 if { ! [check_effective_target_arm_neon_ok] } {
3488 return "$flags"
3490 global et_arm_neon_flags
3491 return "$flags $et_arm_neon_flags"
3494 proc add_options_for_arm_v8_vfp { flags } {
3495 if { ! [check_effective_target_arm_v8_vfp_ok] } {
3496 return "$flags"
3498 return "$flags -mfpu=fp-armv8 -mfloat-abi=softfp"
3501 proc add_options_for_arm_v8_neon { flags } {
3502 if { ! [check_effective_target_arm_v8_neon_ok] } {
3503 return "$flags"
3505 global et_arm_v8_neon_flags
3506 return "$flags $et_arm_v8_neon_flags -march=armv8-a"
3509 # Add the options needed for ARMv8.1 Adv.SIMD. Also adds the ARMv8 NEON
3510 # options for AArch64 and for ARM.
3512 proc add_options_for_arm_v8_1a_neon { flags } {
3513 if { ! [check_effective_target_arm_v8_1a_neon_ok] } {
3514 return "$flags"
3516 global et_arm_v8_1a_neon_flags
3517 return "$flags $et_arm_v8_1a_neon_flags"
3520 # Add the options needed for ARMv8.2 with the scalar FP16 extension.
3521 # Also adds the ARMv8 FP options for ARM and for AArch64.
3523 proc add_options_for_arm_v8_2a_fp16_scalar { flags } {
3524 if { ! [check_effective_target_arm_v8_2a_fp16_scalar_ok] } {
3525 return "$flags"
3527 global et_arm_v8_2a_fp16_scalar_flags
3528 return "$flags $et_arm_v8_2a_fp16_scalar_flags"
3531 # Add the options needed for ARMv8.2 with the FP16 extension. Also adds
3532 # the ARMv8 NEON options for ARM and for AArch64.
3534 proc add_options_for_arm_v8_2a_fp16_neon { flags } {
3535 if { ! [check_effective_target_arm_v8_2a_fp16_neon_ok] } {
3536 return "$flags"
3538 global et_arm_v8_2a_fp16_neon_flags
3539 return "$flags $et_arm_v8_2a_fp16_neon_flags"
3542 proc add_options_for_arm_crc { flags } {
3543 if { ! [check_effective_target_arm_crc_ok] } {
3544 return "$flags"
3546 global et_arm_crc_flags
3547 return "$flags $et_arm_crc_flags"
3550 # Add the options needed for NEON. We need either -mfloat-abi=softfp
3551 # or -mfloat-abi=hard, but if one is already specified by the
3552 # multilib, use it. Similarly, if a -mfpu option already enables
3553 # NEON, do not add -mfpu=neon.
3555 proc add_options_for_arm_neonv2 { flags } {
3556 if { ! [check_effective_target_arm_neonv2_ok] } {
3557 return "$flags"
3559 global et_arm_neonv2_flags
3560 return "$flags $et_arm_neonv2_flags"
3563 # Add the options needed for vfp3.
3564 proc add_options_for_arm_vfp3 { flags } {
3565 if { ! [check_effective_target_arm_vfp3_ok] } {
3566 return "$flags"
3568 return "$flags -mfpu=vfp3 -mfloat-abi=softfp"
3571 # Return 1 if this is an ARM target supporting -mfpu=neon
3572 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
3573 # incompatible with these options. Also set et_arm_neon_flags to the
3574 # best options to add.
3576 proc check_effective_target_arm_neon_ok_nocache { } {
3577 global et_arm_neon_flags
3578 set et_arm_neon_flags ""
3579 if { [check_effective_target_arm32] } {
3580 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp" "-mfpu=neon -mfloat-abi=softfp -march=armv7-a" "-mfloat-abi=hard" "-mfpu=neon -mfloat-abi=hard" "-mfpu=neon -mfloat-abi=hard -march=armv7-a"} {
3581 if { [check_no_compiler_messages_nocache arm_neon_ok object {
3582 #include <arm_neon.h>
3583 int dummy;
3584 #ifndef __ARM_NEON__
3585 #error not NEON
3586 #endif
3587 /* Avoid the case where a test adds -mfpu=neon, but the toolchain is
3588 configured for -mcpu=arm926ej-s, for example. */
3589 #if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M'
3590 #error Architecture does not support NEON.
3591 #endif
3592 } "$flags"] } {
3593 set et_arm_neon_flags $flags
3594 return 1
3599 return 0
3602 proc check_effective_target_arm_neon_ok { } {
3603 return [check_cached_effective_target arm_neon_ok \
3604 check_effective_target_arm_neon_ok_nocache]
3607 # Return 1 if this is an ARM target supporting -mfpu=neon without any
3608 # -mfloat-abi= option. Useful in tests where add_options is not
3609 # supported (such as lto tests).
3611 proc check_effective_target_arm_neon_ok_no_float_abi_nocache { } {
3612 if { [check_effective_target_arm32] } {
3613 foreach flags {"-mfpu=neon"} {
3614 if { [check_no_compiler_messages_nocache arm_neon_ok_no_float_abi object {
3615 #include <arm_neon.h>
3616 int dummy;
3617 #ifndef __ARM_NEON__
3618 #error not NEON
3619 #endif
3620 /* Avoid the case where a test adds -mfpu=neon, but the toolchain is
3621 configured for -mcpu=arm926ej-s, for example. */
3622 #if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M'
3623 #error Architecture does not support NEON.
3624 #endif
3625 } "$flags"] } {
3626 return 1
3631 return 0
3634 proc check_effective_target_arm_neon_ok_no_float_abi { } {
3635 return [check_cached_effective_target arm_neon_ok_no_float_abi \
3636 check_effective_target_arm_neon_ok_no_float_abi_nocache]
3639 proc check_effective_target_arm_crc_ok_nocache { } {
3640 global et_arm_crc_flags
3641 set et_arm_crc_flags "-march=armv8-a+crc"
3642 return [check_no_compiler_messages_nocache arm_crc_ok object {
3643 #if !defined (__ARM_FEATURE_CRC32)
3644 #error FOO
3645 #endif
3646 } "$et_arm_crc_flags"]
3649 proc check_effective_target_arm_crc_ok { } {
3650 return [check_cached_effective_target arm_crc_ok \
3651 check_effective_target_arm_crc_ok_nocache]
3654 # Return 1 if this is an ARM target supporting -mfpu=neon-fp16
3655 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
3656 # incompatible with these options. Also set et_arm_neon_fp16_flags to
3657 # the best options to add.
3659 proc check_effective_target_arm_neon_fp16_ok_nocache { } {
3660 global et_arm_neon_fp16_flags
3661 global et_arm_neon_flags
3662 set et_arm_neon_fp16_flags ""
3663 if { [check_effective_target_arm32]
3664 && [check_effective_target_arm_neon_ok] } {
3665 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
3666 "-mfpu=neon-fp16 -mfloat-abi=softfp"
3667 "-mfp16-format=ieee"
3668 "-mfloat-abi=softfp -mfp16-format=ieee"
3669 "-mfpu=neon-fp16 -mfp16-format=ieee"
3670 "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} {
3671 if { [check_no_compiler_messages_nocache arm_neon_fp16_ok object {
3672 #include "arm_neon.h"
3673 float16x4_t
3674 foo (float32x4_t arg)
3676 return vcvt_f16_f32 (arg);
3678 } "$et_arm_neon_flags $flags"] } {
3679 set et_arm_neon_fp16_flags [concat $et_arm_neon_flags $flags]
3680 return 1
3685 return 0
3688 proc check_effective_target_arm_neon_fp16_ok { } {
3689 return [check_cached_effective_target arm_neon_fp16_ok \
3690 check_effective_target_arm_neon_fp16_ok_nocache]
3693 proc check_effective_target_arm_neon_fp16_hw { } {
3694 if {! [check_effective_target_arm_neon_fp16_ok] } {
3695 return 0
3697 global et_arm_neon_fp16_flags
3698 check_runtime_nocache arm_neon_fp16_hw {
3700 main (int argc, char **argv)
3702 asm ("vcvt.f32.f16 q1, d0");
3703 return 0;
3705 } $et_arm_neon_fp16_flags
3708 proc add_options_for_arm_neon_fp16 { flags } {
3709 if { ! [check_effective_target_arm_neon_fp16_ok] } {
3710 return "$flags"
3712 global et_arm_neon_fp16_flags
3713 return "$flags $et_arm_neon_fp16_flags"
3716 # Return 1 if this is an ARM target supporting the FP16 alternative
3717 # format. Some multilibs may be incompatible with the options needed. Also
3718 # set et_arm_neon_fp16_flags to the best options to add.
3720 proc check_effective_target_arm_fp16_alternative_ok_nocache { } {
3721 global et_arm_neon_fp16_flags
3722 set et_arm_neon_fp16_flags ""
3723 if { [check_effective_target_arm32] } {
3724 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
3725 "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
3726 if { [check_no_compiler_messages_nocache \
3727 arm_fp16_alternative_ok object {
3728 #if !defined (__ARM_FP16_FORMAT_ALTERNATIVE)
3729 #error __ARM_FP16_FORMAT_ALTERNATIVE not defined
3730 #endif
3731 } "$flags -mfp16-format=alternative"] } {
3732 set et_arm_neon_fp16_flags "$flags -mfp16-format=alternative"
3733 return 1
3738 return 0
3741 proc check_effective_target_arm_fp16_alternative_ok { } {
3742 return [check_cached_effective_target arm_fp16_alternative_ok \
3743 check_effective_target_arm_fp16_alternative_ok_nocache]
3746 # Return 1 if this is an ARM target supports specifying the FP16 none
3747 # format. Some multilibs may be incompatible with the options needed.
3749 proc check_effective_target_arm_fp16_none_ok_nocache { } {
3750 if { [check_effective_target_arm32] } {
3751 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16"
3752 "-mfpu=neon-fp16 -mfloat-abi=softfp"} {
3753 if { [check_no_compiler_messages_nocache \
3754 arm_fp16_none_ok object {
3755 #if defined (__ARM_FP16_FORMAT_ALTERNATIVE)
3756 #error __ARM_FP16_FORMAT_ALTERNATIVE defined
3757 #endif
3758 #if defined (__ARM_FP16_FORMAT_IEEE)
3759 #error __ARM_FP16_FORMAT_IEEE defined
3760 #endif
3761 } "$flags -mfp16-format=none"] } {
3762 return 1
3767 return 0
3770 proc check_effective_target_arm_fp16_none_ok { } {
3771 return [check_cached_effective_target arm_fp16_none_ok \
3772 check_effective_target_arm_fp16_none_ok_nocache]
3775 # Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8
3776 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
3777 # incompatible with these options. Also set et_arm_v8_neon_flags to the
3778 # best options to add.
3780 proc check_effective_target_arm_v8_neon_ok_nocache { } {
3781 global et_arm_v8_neon_flags
3782 set et_arm_v8_neon_flags ""
3783 if { [check_effective_target_arm32] } {
3784 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
3785 if { [check_no_compiler_messages_nocache arm_v8_neon_ok object {
3786 #if __ARM_ARCH < 8
3787 #error not armv8 or later
3788 #endif
3789 #include "arm_neon.h"
3790 void
3791 foo ()
3793 __asm__ volatile ("vrintn.f32 q0, q0");
3795 } "$flags -march=armv8-a"] } {
3796 set et_arm_v8_neon_flags $flags
3797 return 1
3802 return 0
3805 proc check_effective_target_arm_v8_neon_ok { } {
3806 return [check_cached_effective_target arm_v8_neon_ok \
3807 check_effective_target_arm_v8_neon_ok_nocache]
3810 # Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4
3811 # -mfloat-abi=softfp or equivalent options. Some multilibs may be
3812 # incompatible with these options. Also set et_arm_neonv2_flags to the
3813 # best options to add.
3815 proc check_effective_target_arm_neonv2_ok_nocache { } {
3816 global et_arm_neonv2_flags
3817 global et_arm_neon_flags
3818 set et_arm_neonv2_flags ""
3819 if { [check_effective_target_arm32]
3820 && [check_effective_target_arm_neon_ok] } {
3821 foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-vfpv4" "-mfpu=neon-vfpv4 -mfloat-abi=softfp"} {
3822 if { [check_no_compiler_messages_nocache arm_neonv2_ok object {
3823 #include "arm_neon.h"
3824 float32x2_t
3825 foo (float32x2_t a, float32x2_t b, float32x2_t c)
3827 return vfma_f32 (a, b, c);
3829 } "$et_arm_neon_flags $flags"] } {
3830 set et_arm_neonv2_flags [concat $et_arm_neon_flags $flags]
3831 return 1
3836 return 0
3839 proc check_effective_target_arm_neonv2_ok { } {
3840 return [check_cached_effective_target arm_neonv2_ok \
3841 check_effective_target_arm_neonv2_ok_nocache]
3844 # Add the options needed for VFP FP16 support. We need either
3845 # -mfloat-abi=softfp or -mfloat-abi=hard. If one is already specified by
3846 # the multilib, use it.
3848 proc add_options_for_arm_fp16 { flags } {
3849 if { ! [check_effective_target_arm_fp16_ok] } {
3850 return "$flags"
3852 global et_arm_fp16_flags
3853 return "$flags $et_arm_fp16_flags"
3856 # Add the options needed to enable support for IEEE format
3857 # half-precision support. This is valid for ARM targets.
3859 proc add_options_for_arm_fp16_ieee { flags } {
3860 if { ! [check_effective_target_arm_fp16_ok] } {
3861 return "$flags"
3863 global et_arm_fp16_flags
3864 return "$flags $et_arm_fp16_flags -mfp16-format=ieee"
3867 # Add the options needed to enable support for ARM Alternative format
3868 # half-precision support. This is valid for ARM targets.
3870 proc add_options_for_arm_fp16_alternative { flags } {
3871 if { ! [check_effective_target_arm_fp16_ok] } {
3872 return "$flags"
3874 global et_arm_fp16_flags
3875 return "$flags $et_arm_fp16_flags -mfp16-format=alternative"
3878 # Return 1 if this is an ARM target that can support a VFP fp16 variant.
3879 # Skip multilibs that are incompatible with these options and set
3880 # et_arm_fp16_flags to the best options to add. This test is valid for
3881 # ARM only.
3883 proc check_effective_target_arm_fp16_ok_nocache { } {
3884 global et_arm_fp16_flags
3885 set et_arm_fp16_flags ""
3886 if { ! [check_effective_target_arm32] } {
3887 return 0;
3889 if [check-flags \
3890 [list "" { *-*-* } { "-mfpu=*" } \
3891 { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" \
3892 "-mfpu=*fpv[1-9][0-9]*" "-mfpu=*fp-armv8*" } ]] {
3893 # Multilib flags would override -mfpu.
3894 return 0
3896 if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] {
3897 # Must generate floating-point instructions.
3898 return 0
3900 if [check_effective_target_arm_hf_eabi] {
3901 # Use existing float-abi and force an fpu which supports fp16
3902 set et_arm_fp16_flags "-mfpu=vfpv4"
3903 return 1;
3905 if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] {
3906 # The existing -mfpu value is OK; use it, but add softfp.
3907 set et_arm_fp16_flags "-mfloat-abi=softfp"
3908 return 1;
3910 # Add -mfpu for a VFP fp16 variant since there is no preprocessor
3911 # macro to check for this support.
3912 set flags "-mfpu=vfpv4 -mfloat-abi=softfp"
3913 if { [check_no_compiler_messages_nocache arm_fp16_ok assembly {
3914 int dummy;
3915 } "$flags"] } {
3916 set et_arm_fp16_flags "$flags"
3917 return 1
3920 return 0
3923 proc check_effective_target_arm_fp16_ok { } {
3924 return [check_cached_effective_target arm_fp16_ok \
3925 check_effective_target_arm_fp16_ok_nocache]
3928 # Return 1 if the target supports executing VFP FP16 instructions, 0
3929 # otherwise. This test is valid for ARM only.
3931 proc check_effective_target_arm_fp16_hw { } {
3932 if {! [check_effective_target_arm_fp16_ok] } {
3933 return 0
3935 global et_arm_fp16_flags
3936 check_runtime_nocache arm_fp16_hw {
3938 main (int argc, char **argv)
3940 __fp16 a = 1.0;
3941 float r;
3942 asm ("vcvtb.f32.f16 %0, %1"
3943 : "=w" (r) : "w" (a)
3944 : /* No clobbers. */);
3945 return (r == 1.0) ? 0 : 1;
3947 } "$et_arm_fp16_flags -mfp16-format=ieee"
3950 # Creates a series of routines that return 1 if the given architecture
3951 # can be selected and a routine to give the flags to select that architecture
3952 # Note: Extra flags may be added to disable options from newer compilers
3953 # (Thumb in particular - but others may be added in the future).
3954 # Warning: Do not use check_effective_target_arm_arch_*_ok for architecture
3955 # extension (eg. ARMv8.1-A) since there is no macro defined for them. See
3956 # how only __ARM_ARCH_8A__ is checked for ARMv8.1-A.
3957 # Usage: /* { dg-require-effective-target arm_arch_v5_ok } */
3958 # /* { dg-add-options arm_arch_v5 } */
3959 # /* { dg-require-effective-target arm_arch_v5_multilib } */
3960 foreach { armfunc armflag armdefs } {
3961 v4 "-march=armv4 -marm" __ARM_ARCH_4__
3962 v4t "-march=armv4t" __ARM_ARCH_4T__
3963 v5 "-march=armv5 -marm" __ARM_ARCH_5__
3964 v5t "-march=armv5t" __ARM_ARCH_5T__
3965 v5te "-march=armv5te" __ARM_ARCH_5TE__
3966 v6 "-march=armv6" __ARM_ARCH_6__
3967 v6k "-march=armv6k" __ARM_ARCH_6K__
3968 v6t2 "-march=armv6t2" __ARM_ARCH_6T2__
3969 v6z "-march=armv6z" __ARM_ARCH_6Z__
3970 v6m "-march=armv6-m -mthumb -mfloat-abi=soft" __ARM_ARCH_6M__
3971 v7a "-march=armv7-a" __ARM_ARCH_7A__
3972 v7r "-march=armv7-r" __ARM_ARCH_7R__
3973 v7m "-march=armv7-m -mthumb" __ARM_ARCH_7M__
3974 v7em "-march=armv7e-m -mthumb" __ARM_ARCH_7EM__
3975 v7ve "-march=armv7ve -marm"
3976 "__ARM_ARCH_7A__ && __ARM_FEATURE_IDIV"
3977 v8a "-march=armv8-a" __ARM_ARCH_8A__
3978 v8_1a "-march=armv8.1a" __ARM_ARCH_8A__
3979 v8_2a "-march=armv8.2a" __ARM_ARCH_8A__
3980 v8m_base "-march=armv8-m.base -mthumb -mfloat-abi=soft"
3981 __ARM_ARCH_8M_BASE__
3982 v8m_main "-march=armv8-m.main -mthumb" __ARM_ARCH_8M_MAIN__
3983 v8r "-march=armv8-r" __ARM_ARCH_8R__ } {
3984 eval [string map [list FUNC $armfunc FLAG $armflag DEFS $armdefs ] {
3985 proc check_effective_target_arm_arch_FUNC_ok { } {
3986 if { [ string match "*-marm*" "FLAG" ] &&
3987 ![check_effective_target_arm_arm_ok] } {
3988 return 0
3990 return [check_no_compiler_messages arm_arch_FUNC_ok assembly {
3991 #if !(DEFS)
3992 #error !(DEFS)
3993 #endif
3994 } "FLAG" ]
3997 proc add_options_for_arm_arch_FUNC { flags } {
3998 return "$flags FLAG"
4001 proc check_effective_target_arm_arch_FUNC_multilib { } {
4002 return [check_runtime arm_arch_FUNC_multilib {
4004 main (void)
4006 return 0;
4008 } [add_options_for_arm_arch_FUNC ""]]
4013 # Return 1 if GCC was configured with --with-mode=
4014 proc check_effective_target_default_mode { } {
4016 return [check_configured_with "with-mode="]
4019 # Return 1 if this is an ARM target where -marm causes ARM to be
4020 # used (not Thumb)
4022 proc check_effective_target_arm_arm_ok { } {
4023 return [check_no_compiler_messages arm_arm_ok assembly {
4024 #if !defined (__arm__) || defined (__thumb__) || defined (__thumb2__)
4025 #error !__arm__ || __thumb__ || __thumb2__
4026 #endif
4027 } "-marm"]
4031 # Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
4032 # used.
4034 proc check_effective_target_arm_thumb1_ok { } {
4035 return [check_no_compiler_messages arm_thumb1_ok assembly {
4036 #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
4037 #error !__arm__ || !__thumb__ || __thumb2__
4038 #endif
4039 int foo (int i) { return i; }
4040 } "-mthumb"]
4043 # Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
4044 # used.
4046 proc check_effective_target_arm_thumb2_ok { } {
4047 return [check_no_compiler_messages arm_thumb2_ok assembly {
4048 #if !defined(__thumb2__)
4049 #error !__thumb2__
4050 #endif
4051 int foo (int i) { return i; }
4052 } "-mthumb"]
4055 # Return 1 if this is an ARM target where Thumb-1 is used without options
4056 # added by the test.
4058 proc check_effective_target_arm_thumb1 { } {
4059 return [check_no_compiler_messages arm_thumb1 assembly {
4060 #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
4061 #error !__arm__ || !__thumb__ || __thumb2__
4062 #endif
4063 int i;
4064 } ""]
4067 # Return 1 if this is an ARM target where Thumb-2 is used without options
4068 # added by the test.
4070 proc check_effective_target_arm_thumb2 { } {
4071 return [check_no_compiler_messages arm_thumb2 assembly {
4072 #if !defined(__thumb2__)
4073 #error !__thumb2__
4074 #endif
4075 int i;
4076 } ""]
4079 # Return 1 if this is an ARM target where conditional execution is available.
4081 proc check_effective_target_arm_cond_exec { } {
4082 return [check_no_compiler_messages arm_cond_exec assembly {
4083 #if defined(__arm__) && defined(__thumb__) && !defined(__thumb2__)
4084 #error FOO
4085 #endif
4086 int i;
4087 } ""]
4090 # Return 1 if this is an ARM cortex-M profile cpu
4092 proc check_effective_target_arm_cortex_m { } {
4093 if { ![istarget arm*-*-*] } {
4094 return 0
4096 return [check_no_compiler_messages arm_cortex_m assembly {
4097 #if defined(__ARM_ARCH_ISA_ARM)
4098 #error __ARM_ARCH_ISA_ARM is defined
4099 #endif
4100 int i;
4101 } "-mthumb"]
4104 # Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be
4105 # used and MOVT/MOVW instructions to be available.
4107 proc check_effective_target_arm_thumb1_movt_ok {} {
4108 if [check_effective_target_arm_thumb1_ok] {
4109 return [check_no_compiler_messages arm_movt object {
4111 foo (void)
4113 asm ("movt r0, #42");
4115 } "-mthumb"]
4116 } else {
4117 return 0
4121 # Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be
4122 # used and CBZ and CBNZ instructions are available.
4124 proc check_effective_target_arm_thumb1_cbz_ok {} {
4125 if [check_effective_target_arm_thumb1_ok] {
4126 return [check_no_compiler_messages arm_movt object {
4128 foo (void)
4130 asm ("cbz r0, 2f\n2:");
4132 } "-mthumb"]
4133 } else {
4134 return 0
4138 # Return 1 if this is an ARM target where ARMv8-M Security Extensions is
4139 # available.
4141 proc check_effective_target_arm_cmse_ok {} {
4142 return [check_no_compiler_messages arm_cmse object {
4144 foo (void)
4146 asm ("bxns r0");
4148 } "-mcmse"];
4151 # Return 1 if this compilation turns on string_ops_prefer_neon on.
4153 proc check_effective_target_arm_tune_string_ops_prefer_neon { } {
4154 return [check_no_messages_and_pattern arm_tune_string_ops_prefer_neon "@string_ops_prefer_neon:\t1" assembly {
4155 int foo (void) { return 0; }
4156 } "-O2 -mprint-tune-info" ]
4159 # Return 1 if the target supports executing NEON instructions, 0
4160 # otherwise. Cache the result.
4162 proc check_effective_target_arm_neon_hw { } {
4163 return [check_runtime arm_neon_hw_available {
4165 main (void)
4167 long long a = 0, b = 1;
4168 asm ("vorr %P0, %P1, %P2"
4169 : "=w" (a)
4170 : "0" (a), "w" (b));
4171 return (a != 1);
4173 } [add_options_for_arm_neon ""]]
4176 proc check_effective_target_arm_neonv2_hw { } {
4177 return [check_runtime arm_neon_hwv2_available {
4178 #include "arm_neon.h"
4180 main (void)
4182 float32x2_t a, b, c;
4183 asm ("vfma.f32 %P0, %P1, %P2"
4184 : "=w" (a)
4185 : "w" (b), "w" (c));
4186 return 0;
4188 } [add_options_for_arm_neonv2 ""]]
4191 # Return 1 if the target supports the ARMv8.1 Adv.SIMD extension, 0
4192 # otherwise. The test is valid for AArch64 and ARM. Record the command
4193 # line options needed.
4195 proc check_effective_target_arm_v8_1a_neon_ok_nocache { } {
4196 global et_arm_v8_1a_neon_flags
4197 set et_arm_v8_1a_neon_flags ""
4199 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
4200 return 0;
4203 # Iterate through sets of options to find the compiler flags that
4204 # need to be added to the -march option. Start with the empty set
4205 # since AArch64 only needs the -march setting.
4206 foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \
4207 "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
4208 foreach arches { "-march=armv8-a+rdma" "-march=armv8.1-a" } {
4209 if { [check_no_compiler_messages_nocache arm_v8_1a_neon_ok object {
4210 #if !defined (__ARM_FEATURE_QRDMX)
4211 #error "__ARM_FEATURE_QRDMX not defined"
4212 #endif
4213 } "$flags $arches"] } {
4214 set et_arm_v8_1a_neon_flags "$flags $arches"
4215 return 1
4220 return 0;
4223 proc check_effective_target_arm_v8_1a_neon_ok { } {
4224 return [check_cached_effective_target arm_v8_1a_neon_ok \
4225 check_effective_target_arm_v8_1a_neon_ok_nocache]
4228 # Return 1 if the target supports ARMv8.2 scalar FP16 arithmetic
4229 # instructions, 0 otherwise. The test is valid for ARM and for AArch64.
4230 # Record the command line options needed.
4232 proc check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache { } {
4233 global et_arm_v8_2a_fp16_scalar_flags
4234 set et_arm_v8_2a_fp16_scalar_flags ""
4236 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
4237 return 0;
4240 # Iterate through sets of options to find the compiler flags that
4241 # need to be added to the -march option.
4242 foreach flags {"" "-mfpu=fp-armv8" "-mfloat-abi=softfp" \
4243 "-mfpu=fp-armv8 -mfloat-abi=softfp"} {
4244 if { [check_no_compiler_messages_nocache \
4245 arm_v8_2a_fp16_scalar_ok object {
4246 #if !defined (__ARM_FEATURE_FP16_SCALAR_ARITHMETIC)
4247 #error "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC not defined"
4248 #endif
4249 } "$flags -march=armv8.2-a+fp16"] } {
4250 set et_arm_v8_2a_fp16_scalar_flags "$flags -march=armv8.2-a+fp16"
4251 return 1
4255 return 0;
4258 proc check_effective_target_arm_v8_2a_fp16_scalar_ok { } {
4259 return [check_cached_effective_target arm_v8_2a_fp16_scalar_ok \
4260 check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache]
4263 # Return 1 if the target supports ARMv8.2 Adv.SIMD FP16 arithmetic
4264 # instructions, 0 otherwise. The test is valid for ARM and for AArch64.
4265 # Record the command line options needed.
4267 proc check_effective_target_arm_v8_2a_fp16_neon_ok_nocache { } {
4268 global et_arm_v8_2a_fp16_neon_flags
4269 set et_arm_v8_2a_fp16_neon_flags ""
4271 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
4272 return 0;
4275 # Iterate through sets of options to find the compiler flags that
4276 # need to be added to the -march option.
4277 foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \
4278 "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
4279 if { [check_no_compiler_messages_nocache \
4280 arm_v8_2a_fp16_neon_ok object {
4281 #if !defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
4282 #error "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC not defined"
4283 #endif
4284 } "$flags -march=armv8.2-a+fp16"] } {
4285 set et_arm_v8_2a_fp16_neon_flags "$flags -march=armv8.2-a+fp16"
4286 return 1
4290 return 0;
4293 proc check_effective_target_arm_v8_2a_fp16_neon_ok { } {
4294 return [check_cached_effective_target arm_v8_2a_fp16_neon_ok \
4295 check_effective_target_arm_v8_2a_fp16_neon_ok_nocache]
4298 # Return 1 if the target supports executing ARMv8 NEON instructions, 0
4299 # otherwise.
4301 proc check_effective_target_arm_v8_neon_hw { } {
4302 return [check_runtime arm_v8_neon_hw_available {
4303 #include "arm_neon.h"
4305 main (void)
4307 float32x2_t a = { 1.0f, 2.0f };
4308 #ifdef __ARM_ARCH_ISA_A64
4309 asm ("frinta %0.2s, %1.2s"
4310 : "=w" (a)
4311 : "w" (a));
4312 #else
4313 asm ("vrinta.f32 %P0, %P1"
4314 : "=w" (a)
4315 : "0" (a));
4316 #endif
4317 return a[0] == 2.0f;
4319 } [add_options_for_arm_v8_neon ""]]
4322 # Return 1 if the target supports executing the ARMv8.1 Adv.SIMD extension, 0
4323 # otherwise. The test is valid for AArch64 and ARM.
4325 proc check_effective_target_arm_v8_1a_neon_hw { } {
4326 if { ![check_effective_target_arm_v8_1a_neon_ok] } {
4327 return 0;
4329 return [check_runtime arm_v8_1a_neon_hw_available {
4331 main (void)
4333 #ifdef __ARM_ARCH_ISA_A64
4334 __Int32x2_t a = {0, 1};
4335 __Int32x2_t b = {0, 2};
4336 __Int32x2_t result;
4338 asm ("sqrdmlah %0.2s, %1.2s, %2.2s"
4339 : "=w"(result)
4340 : "w"(a), "w"(b)
4341 : /* No clobbers. */);
4343 #else
4345 __simd64_int32_t a = {0, 1};
4346 __simd64_int32_t b = {0, 2};
4347 __simd64_int32_t result;
4349 asm ("vqrdmlah.s32 %P0, %P1, %P2"
4350 : "=w"(result)
4351 : "w"(a), "w"(b)
4352 : /* No clobbers. */);
4353 #endif
4355 return result[0];
4357 } [add_options_for_arm_v8_1a_neon ""]]
4360 # Return 1 if the target supports executing floating point instructions from
4361 # ARMv8.2 with the FP16 extension, 0 otherwise. The test is valid for ARM and
4362 # for AArch64.
4364 proc check_effective_target_arm_v8_2a_fp16_scalar_hw { } {
4365 if { ![check_effective_target_arm_v8_2a_fp16_scalar_ok] } {
4366 return 0;
4368 return [check_runtime arm_v8_2a_fp16_scalar_hw_available {
4370 main (void)
4372 __fp16 a = 1.0;
4373 __fp16 result;
4375 #ifdef __ARM_ARCH_ISA_A64
4377 asm ("fabs %h0, %h1"
4378 : "=w"(result)
4379 : "w"(a)
4380 : /* No clobbers. */);
4382 #else
4384 asm ("vabs.f16 %0, %1"
4385 : "=w"(result)
4386 : "w"(a)
4387 : /* No clobbers. */);
4389 #endif
4391 return (result == 1.0) ? 0 : 1;
4393 } [add_options_for_arm_v8_2a_fp16_scalar ""]]
4396 # Return 1 if the target supports executing Adv.SIMD instructions from ARMv8.2
4397 # with the FP16 extension, 0 otherwise. The test is valid for ARM and for
4398 # AArch64.
4400 proc check_effective_target_arm_v8_2a_fp16_neon_hw { } {
4401 if { ![check_effective_target_arm_v8_2a_fp16_neon_ok] } {
4402 return 0;
4404 return [check_runtime arm_v8_2a_fp16_neon_hw_available {
4406 main (void)
4408 #ifdef __ARM_ARCH_ISA_A64
4410 __Float16x4_t a = {1.0, -1.0, 1.0, -1.0};
4411 __Float16x4_t result;
4413 asm ("fabs %0.4h, %1.4h"
4414 : "=w"(result)
4415 : "w"(a)
4416 : /* No clobbers. */);
4418 #else
4420 __simd64_float16_t a = {1.0, -1.0, 1.0, -1.0};
4421 __simd64_float16_t result;
4423 asm ("vabs.f16 %P0, %P1"
4424 : "=w"(result)
4425 : "w"(a)
4426 : /* No clobbers. */);
4428 #endif
4430 return (result[0] == 1.0) ? 0 : 1;
4432 } [add_options_for_arm_v8_2a_fp16_neon ""]]
4435 # Return 1 if this is a ARM target with NEON enabled.
4437 proc check_effective_target_arm_neon { } {
4438 if { [check_effective_target_arm32] } {
4439 return [check_no_compiler_messages arm_neon object {
4440 #ifndef __ARM_NEON__
4441 #error not NEON
4442 #else
4443 int dummy;
4444 #endif
4446 } else {
4447 return 0
4451 proc check_effective_target_arm_neonv2 { } {
4452 if { [check_effective_target_arm32] } {
4453 return [check_no_compiler_messages arm_neon object {
4454 #ifndef __ARM_NEON__
4455 #error not NEON
4456 #else
4457 #ifndef __ARM_FEATURE_FMA
4458 #error not NEONv2
4459 #else
4460 int dummy;
4461 #endif
4462 #endif
4464 } else {
4465 return 0
4469 # Return 1 if this is an ARM target with load acquire and store release
4470 # instructions for 8-, 16- and 32-bit types.
4472 proc check_effective_target_arm_acq_rel { } {
4473 return [check_no_compiler_messages arm_acq_rel object {
4474 void
4475 load_acquire_store_release (void)
4477 asm ("lda r0, [r1]\n\t"
4478 "stl r0, [r1]\n\t"
4479 "ldah r0, [r1]\n\t"
4480 "stlh r0, [r1]\n\t"
4481 "ldab r0, [r1]\n\t"
4482 "stlb r0, [r1]"
4483 : : : "r0", "memory");
4488 # Add the options needed for MIPS Paired-Single.
4490 proc add_options_for_mpaired_single { flags } {
4491 if { ! [check_effective_target_mpaired_single] } {
4492 return "$flags"
4494 return "$flags -mpaired-single"
4497 # Add the options needed for MIPS SIMD Architecture.
4499 proc add_options_for_mips_msa { flags } {
4500 if { ! [check_effective_target_mips_msa] } {
4501 return "$flags"
4503 return "$flags -mmsa"
4506 # Return 1 if this a Loongson-2E or -2F target using an ABI that supports
4507 # the Loongson vector modes.
4509 proc check_effective_target_mips_loongson { } {
4510 return [check_no_compiler_messages loongson assembly {
4511 #if !defined(__mips_loongson_vector_rev)
4512 #error !__mips_loongson_vector_rev
4513 #endif
4517 # Return 1 if this is a MIPS target that supports the legacy NAN.
4519 proc check_effective_target_mips_nanlegacy { } {
4520 return [check_no_compiler_messages nanlegacy assembly {
4521 #include <stdlib.h>
4522 int main () { return 0; }
4523 } "-mnan=legacy"]
4526 # Return 1 if an MSA program can be compiled to object
4528 proc check_effective_target_mips_msa { } {
4529 if ![check_effective_target_nomips16] {
4530 return 0
4532 return [check_no_compiler_messages msa object {
4533 #if !defined(__mips_msa)
4534 #error "MSA NOT AVAIL"
4535 #else
4536 #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2))
4537 #error "MSA NOT AVAIL FOR ISA REV < 2"
4538 #endif
4539 #if !defined(__mips_hard_float)
4540 #error "MSA HARD_FLOAT REQUIRED"
4541 #endif
4542 #if __mips_fpr != 64
4543 #error "MSA 64-bit FPR REQUIRED"
4544 #endif
4545 #include <msa.h>
4547 int main()
4549 v8i16 v = __builtin_msa_ldi_h (1);
4551 return v[0];
4553 #endif
4554 } "-mmsa" ]
4557 # Return 1 if this is an ARM target that adheres to the ABI for the ARM
4558 # Architecture.
4560 proc check_effective_target_arm_eabi { } {
4561 return [check_no_compiler_messages arm_eabi object {
4562 #ifndef __ARM_EABI__
4563 #error not EABI
4564 #else
4565 int dummy;
4566 #endif
4570 # Return 1 if this is an ARM target that adheres to the hard-float variant of
4571 # the ABI for the ARM Architecture (e.g. -mfloat-abi=hard).
4573 proc check_effective_target_arm_hf_eabi { } {
4574 return [check_no_compiler_messages arm_hf_eabi object {
4575 #if !defined(__ARM_EABI__) || !defined(__ARM_PCS_VFP)
4576 #error not hard-float EABI
4577 #else
4578 int dummy;
4579 #endif
4583 # Return 1 if this is an ARM target supporting -mcpu=iwmmxt.
4584 # Some multilibs may be incompatible with this option.
4586 proc check_effective_target_arm_iwmmxt_ok { } {
4587 if { [check_effective_target_arm32] } {
4588 return [check_no_compiler_messages arm_iwmmxt_ok object {
4589 int dummy;
4590 } "-mcpu=iwmmxt"]
4591 } else {
4592 return 0
4596 # Return true if LDRD/STRD instructions are prefered over LDM/STM instructions
4597 # for an ARM target.
4598 proc check_effective_target_arm_prefer_ldrd_strd { } {
4599 if { ![check_effective_target_arm32] } {
4600 return 0;
4603 return [check_no_messages_and_pattern arm_prefer_ldrd_strd "strd\tr" assembly {
4604 void foo (void) { __asm__ ("" ::: "r4", "r5"); }
4605 } "-O2 -mthumb" ]
4608 # Return 1 if this is a PowerPC target supporting -meabi.
4610 proc check_effective_target_powerpc_eabi_ok { } {
4611 if { [istarget powerpc*-*-*] } {
4612 return [check_no_compiler_messages powerpc_eabi_ok object {
4613 int dummy;
4614 } "-meabi"]
4615 } else {
4616 return 0
4620 # Return 1 if this is a PowerPC target with floating-point registers.
4622 proc check_effective_target_powerpc_fprs { } {
4623 if { [istarget powerpc*-*-*]
4624 || [istarget rs6000-*-*] } {
4625 return [check_no_compiler_messages powerpc_fprs object {
4626 #ifdef __NO_FPRS__
4627 #error no FPRs
4628 #else
4629 int dummy;
4630 #endif
4632 } else {
4633 return 0
4637 # Return 1 if this is a PowerPC target with hardware double-precision
4638 # floating point.
4640 proc check_effective_target_powerpc_hard_double { } {
4641 if { [istarget powerpc*-*-*]
4642 || [istarget rs6000-*-*] } {
4643 return [check_no_compiler_messages powerpc_hard_double object {
4644 #ifdef _SOFT_DOUBLE
4645 #error soft double
4646 #else
4647 int dummy;
4648 #endif
4650 } else {
4651 return 0
4655 # Return 1 if this is a PowerPC target supporting -maltivec.
4657 proc check_effective_target_powerpc_altivec_ok { } {
4658 if { ([istarget powerpc*-*-*]
4659 && ![istarget powerpc-*-linux*paired*])
4660 || [istarget rs6000-*-*] } {
4661 # AltiVec is not supported on AIX before 5.3.
4662 if { [istarget powerpc*-*-aix4*]
4663 || [istarget powerpc*-*-aix5.1*]
4664 || [istarget powerpc*-*-aix5.2*] } {
4665 return 0
4667 return [check_no_compiler_messages powerpc_altivec_ok object {
4668 int dummy;
4669 } "-maltivec"]
4670 } else {
4671 return 0
4675 # Return 1 if this is a PowerPC target supporting -mpower8-vector
4677 proc check_effective_target_powerpc_p8vector_ok { } {
4678 if { ([istarget powerpc*-*-*]
4679 && ![istarget powerpc-*-linux*paired*])
4680 || [istarget rs6000-*-*] } {
4681 # AltiVec is not supported on AIX before 5.3.
4682 if { [istarget powerpc*-*-aix4*]
4683 || [istarget powerpc*-*-aix5.1*]
4684 || [istarget powerpc*-*-aix5.2*] } {
4685 return 0
4687 return [check_no_compiler_messages powerpc_p8vector_ok object {
4688 int main (void) {
4689 #ifdef __MACH__
4690 asm volatile ("xxlorc vs0,vs0,vs0");
4691 #else
4692 asm volatile ("xxlorc 0,0,0");
4693 #endif
4694 return 0;
4696 } "-mpower8-vector"]
4697 } else {
4698 return 0
4702 # Return 1 if this is a PowerPC target supporting -mpower9-vector
4704 proc check_effective_target_powerpc_p9vector_ok { } {
4705 if { ([istarget powerpc*-*-*]
4706 && ![istarget powerpc-*-linux*paired*])
4707 || [istarget rs6000-*-*] } {
4708 # AltiVec is not supported on AIX before 5.3.
4709 if { [istarget powerpc*-*-aix4*]
4710 || [istarget powerpc*-*-aix5.1*]
4711 || [istarget powerpc*-*-aix5.2*] } {
4712 return 0
4714 return [check_no_compiler_messages powerpc_p9vector_ok object {
4715 int main (void) {
4716 long e = -1;
4717 vector double v = (vector double) { 0.0, 0.0 };
4718 asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v));
4719 return e;
4721 } "-mpower9-vector"]
4722 } else {
4723 return 0
4727 # Return 1 if this is a PowerPC target supporting -mmodulo
4729 proc check_effective_target_powerpc_p9modulo_ok { } {
4730 if { ([istarget powerpc*-*-*]
4731 && ![istarget powerpc-*-linux*paired*])
4732 || [istarget rs6000-*-*] } {
4733 # AltiVec is not supported on AIX before 5.3.
4734 if { [istarget powerpc*-*-aix4*]
4735 || [istarget powerpc*-*-aix5.1*]
4736 || [istarget powerpc*-*-aix5.2*] } {
4737 return 0
4739 return [check_no_compiler_messages powerpc_p9modulo_ok object {
4740 int main (void) {
4741 int i = 5, j = 3, r = -1;
4742 asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j));
4743 return (r == 2);
4745 } "-mmodulo"]
4746 } else {
4747 return 0
4751 # Return 1 if this is a PowerPC target supporting -mfloat128 via either
4752 # software emulation on power7/power8 systems or hardware support on power9.
4754 proc check_effective_target_powerpc_float128_sw_ok { } {
4755 if { ([istarget powerpc*-*-*]
4756 && ![istarget powerpc-*-linux*paired*])
4757 || [istarget rs6000-*-*] } {
4758 # AltiVec is not supported on AIX before 5.3.
4759 if { [istarget powerpc*-*-aix4*]
4760 || [istarget powerpc*-*-aix5.1*]
4761 || [istarget powerpc*-*-aix5.2*] } {
4762 return 0
4764 return [check_no_compiler_messages powerpc_float128_sw_ok object {
4765 volatile __float128 x = 1.0q;
4766 volatile __float128 y = 2.0q;
4767 int main() {
4768 __float128 z = x + y;
4769 return (z == 3.0q);
4771 } "-mfloat128 -mvsx"]
4772 } else {
4773 return 0
4777 # Return 1 if this is a PowerPC target supporting -mfloat128 via hardware
4778 # support on power9.
4780 proc check_effective_target_powerpc_float128_hw_ok { } {
4781 if { ([istarget powerpc*-*-*]
4782 && ![istarget powerpc-*-linux*paired*])
4783 || [istarget rs6000-*-*] } {
4784 # AltiVec is not supported on AIX before 5.3.
4785 if { [istarget powerpc*-*-aix4*]
4786 || [istarget powerpc*-*-aix5.1*]
4787 || [istarget powerpc*-*-aix5.2*] } {
4788 return 0
4790 return [check_no_compiler_messages powerpc_float128_hw_ok object {
4791 volatile __float128 x = 1.0q;
4792 volatile __float128 y = 2.0q;
4793 int main() {
4794 __float128 z;
4795 __asm__ ("xsaddqp %0,%1,%2" : "=v" (z) : "v" (x), "v" (y));
4796 return (z == 3.0q);
4798 } "-mfloat128-hardware"]
4799 } else {
4800 return 0
4804 # Return 1 if this is a PowerPC target supporting -mvsx
4806 proc check_effective_target_powerpc_vsx_ok { } {
4807 if { ([istarget powerpc*-*-*]
4808 && ![istarget powerpc-*-linux*paired*])
4809 || [istarget rs6000-*-*] } {
4810 # VSX is not supported on AIX before 7.1.
4811 if { [istarget powerpc*-*-aix4*]
4812 || [istarget powerpc*-*-aix5*]
4813 || [istarget powerpc*-*-aix6*] } {
4814 return 0
4816 return [check_no_compiler_messages powerpc_vsx_ok object {
4817 int main (void) {
4818 #ifdef __MACH__
4819 asm volatile ("xxlor vs0,vs0,vs0");
4820 #else
4821 asm volatile ("xxlor 0,0,0");
4822 #endif
4823 return 0;
4825 } "-mvsx"]
4826 } else {
4827 return 0
4831 # Return 1 if this is a PowerPC target supporting -mhtm
4833 proc check_effective_target_powerpc_htm_ok { } {
4834 if { ([istarget powerpc*-*-*]
4835 && ![istarget powerpc-*-linux*paired*])
4836 || [istarget rs6000-*-*] } {
4837 # HTM is not supported on AIX yet.
4838 if { [istarget powerpc*-*-aix*] } {
4839 return 0
4841 return [check_no_compiler_messages powerpc_htm_ok object {
4842 int main (void) {
4843 asm volatile ("tbegin. 0");
4844 return 0;
4846 } "-mhtm"]
4847 } else {
4848 return 0
4852 # Return 1 if the target supports executing HTM hardware instructions,
4853 # 0 otherwise. Cache the result.
4855 proc check_htm_hw_available { } {
4856 return [check_cached_effective_target htm_hw_available {
4857 # For now, disable on Darwin
4858 if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
4859 expr 0
4860 } else {
4861 check_runtime_nocache htm_hw_available {
4862 int main()
4864 __builtin_ttest ();
4865 return 0;
4867 } "-mhtm"
4871 # Return 1 if this is a PowerPC target supporting -mcpu=cell.
4873 proc check_effective_target_powerpc_ppu_ok { } {
4874 if [check_effective_target_powerpc_altivec_ok] {
4875 return [check_no_compiler_messages cell_asm_available object {
4876 int main (void) {
4877 #ifdef __MACH__
4878 asm volatile ("lvlx v0,v0,v0");
4879 #else
4880 asm volatile ("lvlx 0,0,0");
4881 #endif
4882 return 0;
4885 } else {
4886 return 0
4890 # Return 1 if this is a PowerPC target that supports SPU.
4892 proc check_effective_target_powerpc_spu { } {
4893 if { [istarget powerpc*-*-linux*] } {
4894 return [check_effective_target_powerpc_altivec_ok]
4895 } else {
4896 return 0
4900 # Return 1 if this is a PowerPC SPE target. The check includes options
4901 # specified by dg-options for this test, so don't cache the result.
4903 proc check_effective_target_powerpc_spe_nocache { } {
4904 if { [istarget powerpc*-*-*] } {
4905 return [check_no_compiler_messages_nocache powerpc_spe object {
4906 #ifndef __SPE__
4907 #error not SPE
4908 #else
4909 int dummy;
4910 #endif
4911 } [current_compiler_flags]]
4912 } else {
4913 return 0
4917 # Return 1 if this is a PowerPC target with SPE enabled.
4919 proc check_effective_target_powerpc_spe { } {
4920 if { [istarget powerpc*-*-*] } {
4921 return [check_no_compiler_messages powerpc_spe object {
4922 #ifndef __SPE__
4923 #error not SPE
4924 #else
4925 int dummy;
4926 #endif
4928 } else {
4929 return 0
4933 # Return 1 if this is a PowerPC target with Altivec enabled.
4935 proc check_effective_target_powerpc_altivec { } {
4936 if { [istarget powerpc*-*-*] } {
4937 return [check_no_compiler_messages powerpc_altivec object {
4938 #ifndef __ALTIVEC__
4939 #error not Altivec
4940 #else
4941 int dummy;
4942 #endif
4944 } else {
4945 return 0
4949 # Return 1 if this is a PowerPC 405 target. The check includes options
4950 # specified by dg-options for this test, so don't cache the result.
4952 proc check_effective_target_powerpc_405_nocache { } {
4953 if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } {
4954 return [check_no_compiler_messages_nocache powerpc_405 object {
4955 #ifdef __PPC405__
4956 int dummy;
4957 #else
4958 #error not a PPC405
4959 #endif
4960 } [current_compiler_flags]]
4961 } else {
4962 return 0
4966 # Return 1 if this is a PowerPC target using the ELFv2 ABI.
4968 proc check_effective_target_powerpc_elfv2 { } {
4969 if { [istarget powerpc*-*-*] } {
4970 return [check_no_compiler_messages powerpc_elfv2 object {
4971 #if _CALL_ELF != 2
4972 #error not ELF v2 ABI
4973 #else
4974 int dummy;
4975 #endif
4977 } else {
4978 return 0
4982 # Return 1 if this is a SPU target with a toolchain that
4983 # supports automatic overlay generation.
4985 proc check_effective_target_spu_auto_overlay { } {
4986 if { [istarget spu*-*-elf*] } {
4987 return [check_no_compiler_messages spu_auto_overlay executable {
4988 int main (void) { }
4989 } "-Wl,--auto-overlay" ]
4990 } else {
4991 return 0
4995 # The VxWorks SPARC simulator accepts only EM_SPARC executables and
4996 # chokes on EM_SPARC32PLUS or EM_SPARCV9 executables. Return 1 if the
4997 # test environment appears to run executables on such a simulator.
4999 proc check_effective_target_ultrasparc_hw { } {
5000 return [check_runtime ultrasparc_hw {
5001 int main() { return 0; }
5002 } "-mcpu=ultrasparc"]
5005 # Return 1 if the test environment supports executing UltraSPARC VIS2
5006 # instructions. We check this by attempting: "bmask %g0, %g0, %g0"
5008 proc check_effective_target_ultrasparc_vis2_hw { } {
5009 return [check_runtime ultrasparc_vis2_hw {
5010 int main() { __asm__(".word 0x81b00320"); return 0; }
5011 } "-mcpu=ultrasparc3"]
5014 # Return 1 if the test environment supports executing UltraSPARC VIS3
5015 # instructions. We check this by attempting: "addxc %g0, %g0, %g0"
5017 proc check_effective_target_ultrasparc_vis3_hw { } {
5018 return [check_runtime ultrasparc_vis3_hw {
5019 int main() { __asm__(".word 0x81b00220"); return 0; }
5020 } "-mcpu=niagara3"]
5023 # Return 1 if this is a SPARC-V9 target.
5025 proc check_effective_target_sparc_v9 { } {
5026 if { [istarget sparc*-*-*] } {
5027 return [check_no_compiler_messages sparc_v9 object {
5028 int main (void) {
5029 asm volatile ("return %i7+8");
5030 return 0;
5033 } else {
5034 return 0
5038 # Return 1 if this is a SPARC target with VIS enabled.
5040 proc check_effective_target_sparc_vis { } {
5041 if { [istarget sparc*-*-*] } {
5042 return [check_no_compiler_messages sparc_vis object {
5043 #ifndef __VIS__
5044 #error not VIS
5045 #else
5046 int dummy;
5047 #endif
5049 } else {
5050 return 0
5054 # Return 1 if the target supports hardware vector shift operation.
5056 proc check_effective_target_vect_shift { } {
5057 global et_vect_shift_saved
5058 global et_index
5060 if [info exists et_vect_shift_saved($et_index)] {
5061 verbose "check_effective_target_vect_shift: using cached result" 2
5062 } else {
5063 set et_vect_shift_saved($et_index) 0
5064 if { ([istarget powerpc*-*-*]
5065 && ![istarget powerpc-*-linux*paired*])
5066 || [istarget ia64-*-*]
5067 || [istarget i?86-*-*] || [istarget x86_64-*-*]
5068 || [istarget aarch64*-*-*]
5069 || [is-effective-target arm_neon]
5070 || ([istarget mips*-*-*]
5071 && ([et-is-effective-target mips_msa]
5072 || [et-is-effective-target mips_loongson])) } {
5073 set et_vect_shift_saved($et_index) 1
5077 verbose "check_effective_target_vect_shift:\
5078 returning $et_vect_shift_saved($et_index)" 2
5079 return $et_vect_shift_saved($et_index)
5082 proc check_effective_target_whole_vector_shift { } {
5083 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
5084 || [istarget ia64-*-*]
5085 || [istarget aarch64*-*-*]
5086 || [istarget powerpc64*-*-*]
5087 || ([is-effective-target arm_neon]
5088 && [check_effective_target_arm_little_endian])
5089 || ([istarget mips*-*-*]
5090 && [et-is-effective-target mips_loongson]) } {
5091 set answer 1
5092 } else {
5093 set answer 0
5096 verbose "check_effective_target_vect_long: returning $answer" 2
5097 return $answer
5100 # Return 1 if the target supports vector bswap operations.
5102 proc check_effective_target_vect_bswap { } {
5103 global et_vect_bswap_saved
5104 global et_index
5106 if [info exists et_vect_bswap_saved($et_index)] {
5107 verbose "check_effective_target_vect_bswap: using cached result" 2
5108 } else {
5109 set et_vect_bswap_saved($et_index) 0
5110 if { [istarget aarch64*-*-*]
5111 || [is-effective-target arm_neon]
5113 set et_vect_bswap_saved($et_index) 1
5117 verbose "check_effective_target_vect_bswap:\
5118 returning $et_vect_bswap_saved($et_index)" 2
5119 return $et_vect_bswap_saved($et_index)
5122 # Return 1 if the target supports hardware vector shift operation for char.
5124 proc check_effective_target_vect_shift_char { } {
5125 global et_vect_shift_char_saved
5126 global et_index
5128 if [info exists et_vect_shift_char_saved($et_index)] {
5129 verbose "check_effective_target_vect_shift_char: using cached result" 2
5130 } else {
5131 set et_vect_shift_char_saved($et_index) 0
5132 if { ([istarget powerpc*-*-*]
5133 && ![istarget powerpc-*-linux*paired*])
5134 || [is-effective-target arm_neon]
5135 || ([istarget mips*-*-*]
5136 && [et-is-effective-target mips_msa]) } {
5137 set et_vect_shift_char_saved($et_index) 1
5141 verbose "check_effective_target_vect_shift_char:\
5142 returning $et_vect_shift_char_saved($et_index)" 2
5143 return $et_vect_shift_char_saved($et_index)
5146 # Return 1 if the target supports hardware vectors of long, 0 otherwise.
5148 # This can change for different subtargets so do not cache the result.
5150 proc check_effective_target_vect_long { } {
5151 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
5152 || (([istarget powerpc*-*-*]
5153 && ![istarget powerpc-*-linux*paired*])
5154 && [check_effective_target_ilp32])
5155 || [is-effective-target arm_neon]
5156 || ([istarget sparc*-*-*] && [check_effective_target_ilp32])
5157 || [istarget aarch64*-*-*]
5158 || ([istarget mips*-*-*]
5159 && [et-is-effective-target mips_msa]) } {
5160 set answer 1
5161 } else {
5162 set answer 0
5165 verbose "check_effective_target_vect_long: returning $answer" 2
5166 return $answer
5169 # Return 1 if the target supports hardware vectors of float, 0 otherwise.
5171 # This won't change for different subtargets so cache the result.
5173 proc check_effective_target_vect_float { } {
5174 global et_vect_float_saved
5175 global et_index
5177 if [info exists et_vect_float_saved($et_index)] {
5178 verbose "check_effective_target_vect_float: using cached result" 2
5179 } else {
5180 set et_vect_float_saved($et_index) 0
5181 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
5182 || [istarget powerpc*-*-*]
5183 || [istarget spu-*-*]
5184 || [istarget mips-sde-elf]
5185 || [istarget mipsisa64*-*-*]
5186 || [istarget ia64-*-*]
5187 || [istarget aarch64*-*-*]
5188 || ([istarget mips*-*-*]
5189 && [et-is-effective-target mips_msa])
5190 || [is-effective-target arm_neon] } {
5191 set et_vect_float_saved($et_index) 1
5195 verbose "check_effective_target_vect_float:\
5196 returning $et_vect_float_saved($et_index)" 2
5197 return $et_vect_float_saved($et_index)
5200 # Return 1 if the target supports hardware vectors of double, 0 otherwise.
5202 # This won't change for different subtargets so cache the result.
5204 proc check_effective_target_vect_double { } {
5205 global et_vect_double_saved
5206 global et_index
5208 if [info exists et_vect_double_saved($et_index)] {
5209 verbose "check_effective_target_vect_double: using cached result" 2
5210 } else {
5211 set et_vect_double_saved($et_index) 0
5212 if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
5213 && [check_no_compiler_messages vect_double assembly {
5214 #ifdef __tune_atom__
5215 # error No double vectorizer support.
5216 #endif
5218 || [istarget aarch64*-*-*]
5219 || [istarget spu-*-*]
5220 || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
5221 || ([istarget mips*-*-*]
5222 && [et-is-effective-target mips_msa]) } {
5223 set et_vect_double_saved($et_index) 1
5227 verbose "check_effective_target_vect_double:\
5228 returning $et_vect_double_saved($et_index)" 2
5229 return $et_vect_double_saved($et_index)
5232 # Return 1 if the target supports hardware vectors of long long, 0 otherwise.
5234 # This won't change for different subtargets so cache the result.
5236 proc check_effective_target_vect_long_long { } {
5237 global et_vect_long_long_saved
5238 global et_index
5240 if [info exists et_vect_long_long_saved($et_index)] {
5241 verbose "check_effective_target_vect_long_long: using cached result" 2
5242 } else {
5243 set et_vect_long_long_saved($et_index) 0
5244 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
5245 || ([istarget mips*-*-*]
5246 && [et-is-effective-target mips_msa]) } {
5247 set et_vect_long_long_saved($et_index) 1
5251 verbose "check_effective_target_vect_long_long:\
5252 returning $et_vect_long_long_saved($et_index)" 2
5253 return $et_vect_long_long_saved($et_index)
5257 # Return 1 if the target plus current options does not support a vector
5258 # max instruction on "int", 0 otherwise.
5260 # This won't change for different subtargets so cache the result.
5262 proc check_effective_target_vect_no_int_min_max { } {
5263 global et_vect_no_int_min_max_saved
5264 global et_index
5266 if [info exists et_vect_no_int_min_max_saved($et_index)] {
5267 verbose "check_effective_target_vect_no_int_min_max:\
5268 using cached result" 2
5269 } else {
5270 set et_vect_no_int_min_max_saved($et_index) 0
5271 if { [istarget sparc*-*-*]
5272 || [istarget spu-*-*]
5273 || [istarget alpha*-*-*]
5274 || ([istarget mips*-*-*]
5275 && [et-is-effective-target mips_loongson]) } {
5276 set et_vect_no_int_min_max_saved($et_index) 1
5279 verbose "check_effective_target_vect_no_int_min_max:\
5280 returning $et_vect_no_int_min_max_saved($et_index)" 2
5281 return $et_vect_no_int_min_max_saved($et_index)
5284 # Return 1 if the target plus current options does not support a vector
5285 # add instruction on "int", 0 otherwise.
5287 # This won't change for different subtargets so cache the result.
5289 proc check_effective_target_vect_no_int_add { } {
5290 global et_vect_no_int_add_saved
5291 global et_index
5293 if [info exists et_vect_no_int_add_saved($et_index)] {
5294 verbose "check_effective_target_vect_no_int_add: using cached result" 2
5295 } else {
5296 set et_vect_no_int_add_saved($et_index) 0
5297 # Alpha only supports vector add on V8QI and V4HI.
5298 if { [istarget alpha*-*-*] } {
5299 set et_vect_no_int_add_saved($et_index) 1
5302 verbose "check_effective_target_vect_no_int_add:\
5303 returning $et_vect_no_int_add_saved($et_index)" 2
5304 return $et_vect_no_int_add_saved($et_index)
5307 # Return 1 if the target plus current options does not support vector
5308 # bitwise instructions, 0 otherwise.
5310 # This won't change for different subtargets so cache the result.
5312 proc check_effective_target_vect_no_bitwise { } {
5313 global et_vect_no_bitwise_saved
5314 global et_index
5316 if [info exists et_vect_no_bitwise_saved($et_index)] {
5317 verbose "check_effective_target_vect_no_bitwise: using cached result" 2
5318 } else {
5319 set et_vect_no_bitwise_saved($et_index) 0
5321 verbose "check_effective_target_vect_no_bitwise:\
5322 returning $et_vect_no_bitwise_saved($et_index)" 2
5323 return $et_vect_no_bitwise_saved($et_index)
5326 # Return 1 if the target plus current options supports vector permutation,
5327 # 0 otherwise.
5329 # This won't change for different subtargets so cache the result.
5331 proc check_effective_target_vect_perm { } {
5332 global et_vect_perm_saved
5333 global et_index
5335 if [info exists et_vect_perm_saved($et_index)] {
5336 verbose "check_effective_target_vect_perm: using cached result" 2
5337 } else {
5338 set et_vect_perm_saved($et_index) 0
5339 if { [is-effective-target arm_neon]
5340 || [istarget aarch64*-*-*]
5341 || [istarget powerpc*-*-*]
5342 || [istarget spu-*-*]
5343 || [istarget i?86-*-*] || [istarget x86_64-*-*]
5344 || ([istarget mips*-*-*]
5345 && ([et-is-effective-target mpaired_single]
5346 || [et-is-effective-target mips_msa])) } {
5347 set et_vect_perm_saved($et_index) 1
5350 verbose "check_effective_target_vect_perm:\
5351 returning $et_vect_perm_saved($et_index)" 2
5352 return $et_vect_perm_saved($et_index)
5355 # Return 1 if the target plus current options supports vector permutation
5356 # on byte-sized elements, 0 otherwise.
5358 # This won't change for different subtargets so cache the result.
5360 proc check_effective_target_vect_perm_byte { } {
5361 global et_vect_perm_byte_saved
5362 global et_index
5364 if [info exists et_vect_perm_byte_saved($et_index)] {
5365 verbose "check_effective_target_vect_perm_byte: using cached result" 2
5366 } else {
5367 set et_vect_perm_byte_saved($et_index) 0
5368 if { ([is-effective-target arm_neon]
5369 && [is-effective-target arm_little_endian])
5370 || ([istarget aarch64*-*-*]
5371 && [is-effective-target aarch64_little_endian])
5372 || [istarget powerpc*-*-*]
5373 || [istarget spu-*-*]
5374 || ([istarget mips-*.*]
5375 && [et-is-effective-target mips_msa]) } {
5376 set et_vect_perm_byte_saved($et_index) 1
5379 verbose "check_effective_target_vect_perm_byte:\
5380 returning $et_vect_perm_byte_saved($et_index)" 2
5381 return $et_vect_perm_byte_saved($et_index)
5384 # Return 1 if the target plus current options supports vector permutation
5385 # on short-sized elements, 0 otherwise.
5387 # This won't change for different subtargets so cache the result.
5389 proc check_effective_target_vect_perm_short { } {
5390 global et_vect_perm_short_saved
5391 global et_index
5393 if [info exists et_vect_perm_short_saved($et_index)] {
5394 verbose "check_effective_target_vect_perm_short: using cached result" 2
5395 } else {
5396 set et_vect_perm_short_saved($et_index) 0
5397 if { ([is-effective-target arm_neon]
5398 && [is-effective-target arm_little_endian])
5399 || ([istarget aarch64*-*-*]
5400 && [is-effective-target aarch64_little_endian])
5401 || [istarget powerpc*-*-*]
5402 || [istarget spu-*-*]
5403 || ([istarget mips*-*-*]
5404 && [et-is-effective-target mips_msa]) } {
5405 set et_vect_perm_short_saved($et_index) 1
5408 verbose "check_effective_target_vect_perm_short:\
5409 returning $et_vect_perm_short_saved($et_index)" 2
5410 return $et_vect_perm_short_saved($et_index)
5413 # Return 1 if the target plus current options supports folding of
5414 # copysign into XORSIGN.
5416 # This won't change for different subtargets so cache the result.
5418 proc check_effective_target_xorsign { } {
5419 global et_xorsign_saved
5420 global et_index
5422 if [info exists et_xorsign_saved($et_index)] {
5423 verbose "check_effective_target_xorsign: using cached result" 2
5424 } else {
5425 set et_xorsign_saved($et_index) 0
5426 if { [istarget aarch64*-*-*] || [istarget arm*-*-*] } {
5427 set et_xorsign_saved($et_index) 1
5430 verbose "check_effective_target_xorsign:\
5431 returning $et_xorsign_saved($et_index)" 2
5432 return $et_xorsign_saved($et_index)
5435 # Return 1 if the target plus current options supports a vector
5436 # widening summation of *short* args into *int* result, 0 otherwise.
5438 # This won't change for different subtargets so cache the result.
5440 proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
5441 global et_vect_widen_sum_hi_to_si_pattern_saved
5442 global et_index
5444 if [info exists et_vect_widen_sum_hi_to_si_pattern_saved($et_index)] {
5445 verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern:\
5446 using cached result" 2
5447 } else {
5448 set et_vect_widen_sum_hi_to_si_pattern_saved($et_index) 0
5449 if { [istarget powerpc*-*-*]
5450 || [istarget aarch64*-*-*]
5451 || [is-effective-target arm_neon]
5452 || [istarget ia64-*-*] } {
5453 set et_vect_widen_sum_hi_to_si_pattern_saved($et_index) 1
5456 verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern:\
5457 returning $et_vect_widen_sum_hi_to_si_pattern_saved($et_index)" 2
5458 return $et_vect_widen_sum_hi_to_si_pattern_saved($et_index)
5461 # Return 1 if the target plus current options supports a vector
5462 # widening summation of *short* args into *int* result, 0 otherwise.
5463 # A target can also support this widening summation if it can support
5464 # promotion (unpacking) from shorts to ints.
5466 # This won't change for different subtargets so cache the result.
5468 proc check_effective_target_vect_widen_sum_hi_to_si { } {
5469 global et_vect_widen_sum_hi_to_si_saved
5470 global et_index
5472 if [info exists et_vect_widen_sum_hi_to_si_saved($et_index)] {
5473 verbose "check_effective_target_vect_widen_sum_hi_to_si:\
5474 using cached result" 2
5475 } else {
5476 set et_vect_widen_sum_hi_to_si_saved($et_index) \
5477 [check_effective_target_vect_unpack]
5478 if { [istarget powerpc*-*-*]
5479 || [istarget ia64-*-*] } {
5480 set et_vect_widen_sum_hi_to_si_saved($et_index) 1
5483 verbose "check_effective_target_vect_widen_sum_hi_to_si:\
5484 returning $et_vect_widen_sum_hi_to_si_saved($et_index)" 2
5485 return $et_vect_widen_sum_hi_to_si_saved($et_index)
5488 # Return 1 if the target plus current options supports a vector
5489 # widening summation of *char* args into *short* result, 0 otherwise.
5490 # A target can also support this widening summation if it can support
5491 # promotion (unpacking) from chars to shorts.
5493 # This won't change for different subtargets so cache the result.
5495 proc check_effective_target_vect_widen_sum_qi_to_hi { } {
5496 global et_vect_widen_sum_qi_to_hi_saved
5497 global et_index
5499 if [info exists et_vect_widen_sum_qi_to_hi_saved($et_index)] {
5500 verbose "check_effective_target_vect_widen_sum_qi_to_hi:\
5501 using cached result" 2
5502 } else {
5503 set et_vect_widen_sum_qi_to_hi_saved($et_index) 0
5504 if { [check_effective_target_vect_unpack]
5505 || [is-effective-target arm_neon]
5506 || [istarget ia64-*-*] } {
5507 set et_vect_widen_sum_qi_to_hi_saved($et_index) 1
5510 verbose "check_effective_target_vect_widen_sum_qi_to_hi:\
5511 returning $et_vect_widen_sum_qi_to_hi_saved($et_index)" 2
5512 return $et_vect_widen_sum_qi_to_hi_saved($et_index)
5515 # Return 1 if the target plus current options supports a vector
5516 # widening summation of *char* args into *int* result, 0 otherwise.
5518 # This won't change for different subtargets so cache the result.
5520 proc check_effective_target_vect_widen_sum_qi_to_si { } {
5521 global et_vect_widen_sum_qi_to_si_saved
5522 global et_index
5524 if [info exists et_vect_widen_sum_qi_to_si_saved($et_index)] {
5525 verbose "check_effective_target_vect_widen_sum_qi_to_si:\
5526 using cached result" 2
5527 } else {
5528 set et_vect_widen_sum_qi_to_si_saved($et_index) 0
5529 if { [istarget powerpc*-*-*] } {
5530 set et_vect_widen_sum_qi_to_si_saved($et_index) 1
5533 verbose "check_effective_target_vect_widen_sum_qi_to_si:\
5534 returning $et_vect_widen_sum_qi_to_si_saved($et_index)" 2
5535 return $et_vect_widen_sum_qi_to_si_saved($et_index)
5538 # Return 1 if the target plus current options supports a vector
5539 # widening multiplication of *char* args into *short* result, 0 otherwise.
5540 # A target can also support this widening multplication if it can support
5541 # promotion (unpacking) from chars to shorts, and vect_short_mult (non-widening
5542 # multiplication of shorts).
5544 # This won't change for different subtargets so cache the result.
5547 proc check_effective_target_vect_widen_mult_qi_to_hi { } {
5548 global et_vect_widen_mult_qi_to_hi_saved
5549 global et_index
5551 if [info exists et_vect_widen_mult_qi_to_hi_saved($et_index)] {
5552 verbose "check_effective_target_vect_widen_mult_qi_to_hi:\
5553 using cached result" 2
5554 } else {
5555 if { [check_effective_target_vect_unpack]
5556 && [check_effective_target_vect_short_mult] } {
5557 set et_vect_widen_mult_qi_to_hi_saved($et_index) 1
5558 } else {
5559 set et_vect_widen_mult_qi_to_hi_saved($et_index) 0
5561 if { [istarget powerpc*-*-*]
5562 || [istarget aarch64*-*-*]
5563 || [is-effective-target arm_neon] } {
5564 set et_vect_widen_mult_qi_to_hi_saved($et_index) 1
5567 verbose "check_effective_target_vect_widen_mult_qi_to_hi:\
5568 returning $et_vect_widen_mult_qi_to_hi_saved($et_index)" 2
5569 return $et_vect_widen_mult_qi_to_hi_saved($et_index)
5572 # Return 1 if the target plus current options supports a vector
5573 # widening multiplication of *short* args into *int* result, 0 otherwise.
5574 # A target can also support this widening multplication if it can support
5575 # promotion (unpacking) from shorts to ints, and vect_int_mult (non-widening
5576 # multiplication of ints).
5578 # This won't change for different subtargets so cache the result.
5581 proc check_effective_target_vect_widen_mult_hi_to_si { } {
5582 global et_vect_widen_mult_hi_to_si_saved
5583 global et_index
5585 if [info exists et_vect_widen_mult_hi_to_si_saved($et_index)] {
5586 verbose "check_effective_target_vect_widen_mult_hi_to_si:\
5587 using cached result" 2
5588 } else {
5589 if { [check_effective_target_vect_unpack]
5590 && [check_effective_target_vect_int_mult] } {
5591 set et_vect_widen_mult_hi_to_si_saved($et_index) 1
5592 } else {
5593 set et_vect_widen_mult_hi_to_si_saved($et_index) 0
5595 if { [istarget powerpc*-*-*]
5596 || [istarget spu-*-*]
5597 || [istarget ia64-*-*]
5598 || [istarget aarch64*-*-*]
5599 || [istarget i?86-*-*] || [istarget x86_64-*-*]
5600 || [is-effective-target arm_neon] } {
5601 set et_vect_widen_mult_hi_to_si_saved($et_index) 1
5604 verbose "check_effective_target_vect_widen_mult_hi_to_si:\
5605 returning $et_vect_widen_mult_hi_to_si_saved($et_index)" 2
5606 return $et_vect_widen_mult_hi_to_si_saved($et_index)
5609 # Return 1 if the target plus current options supports a vector
5610 # widening multiplication of *char* args into *short* result, 0 otherwise.
5612 # This won't change for different subtargets so cache the result.
5614 proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
5615 global et_vect_widen_mult_qi_to_hi_pattern_saved
5616 global et_index
5618 if [info exists et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)] {
5619 verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern:\
5620 using cached result" 2
5621 } else {
5622 set et_vect_widen_mult_qi_to_hi_pattern_saved($et_index) 0
5623 if { [istarget powerpc*-*-*]
5624 || ([is-effective-target arm_neon]
5625 && [check_effective_target_arm_little_endian]) } {
5626 set et_vect_widen_mult_qi_to_hi_pattern_saved($et_index) 1
5629 verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern:\
5630 returning $et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)" 2
5631 return $et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)
5634 # Return 1 if the target plus current options supports a vector
5635 # widening multiplication of *short* args into *int* result, 0 otherwise.
5637 # This won't change for different subtargets so cache the result.
5639 proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
5640 global et_vect_widen_mult_hi_to_si_pattern_saved
5641 global et_index
5643 if [info exists et_vect_widen_mult_hi_to_si_pattern_saved($et_index)] {
5644 verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern:\
5645 using cached result" 2
5646 } else {
5647 set et_vect_widen_mult_hi_to_si_pattern_saved($et_index) 0
5648 if { [istarget powerpc*-*-*]
5649 || [istarget spu-*-*]
5650 || [istarget ia64-*-*]
5651 || [istarget i?86-*-*] || [istarget x86_64-*-*]
5652 || ([is-effective-target arm_neon]
5653 && [check_effective_target_arm_little_endian]) } {
5654 set et_vect_widen_mult_hi_to_si_pattern_saved($et_index) 1
5657 verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern:\
5658 returning $et_vect_widen_mult_hi_to_si_pattern_saved($et_index)" 2
5659 return $et_vect_widen_mult_hi_to_si_pattern_saved($et_index)
5662 # Return 1 if the target plus current options supports a vector
5663 # widening multiplication of *int* args into *long* result, 0 otherwise.
5665 # This won't change for different subtargets so cache the result.
5667 proc check_effective_target_vect_widen_mult_si_to_di_pattern { } {
5668 global et_vect_widen_mult_si_to_di_pattern_saved
5669 global et_index
5671 if [info exists et_vect_widen_mult_si_to_di_pattern_saved($et_index)] {
5672 verbose "check_effective_target_vect_widen_mult_si_to_di_pattern:\
5673 using cached result" 2
5674 } else {
5675 set et_vect_widen_mult_si_to_di_pattern_saved($et_index) 0
5676 if {[istarget ia64-*-*]
5677 || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
5678 set et_vect_widen_mult_si_to_di_pattern_saved($et_index) 1
5681 verbose "check_effective_target_vect_widen_mult_si_to_di_pattern:\
5682 returning $et_vect_widen_mult_si_to_di_pattern_saved($et_index)" 2
5683 return $et_vect_widen_mult_si_to_di_pattern_saved($et_index)
5686 # Return 1 if the target plus current options supports a vector
5687 # widening shift, 0 otherwise.
5689 # This won't change for different subtargets so cache the result.
5691 proc check_effective_target_vect_widen_shift { } {
5692 global et_vect_widen_shift_saved
5693 global et_index
5695 if [info exists et_vect_shift_saved($et_index)] {
5696 verbose "check_effective_target_vect_widen_shift: using cached result" 2
5697 } else {
5698 set et_vect_widen_shift_saved($et_index) 0
5699 if { [is-effective-target arm_neon] } {
5700 set et_vect_widen_shift_saved($et_index) 1
5703 verbose "check_effective_target_vect_widen_shift:\
5704 returning $et_vect_widen_shift_saved($et_index)" 2
5705 return $et_vect_widen_shift_saved($et_index)
5708 # Return 1 if the target plus current options supports a vector
5709 # dot-product of signed chars, 0 otherwise.
5711 # This won't change for different subtargets so cache the result.
5713 proc check_effective_target_vect_sdot_qi { } {
5714 global et_vect_sdot_qi_saved
5715 global et_index
5717 if [info exists et_vect_sdot_qi_saved($et_index)] {
5718 verbose "check_effective_target_vect_sdot_qi: using cached result" 2
5719 } else {
5720 set et_vect_sdot_qi_saved($et_index) 0
5721 if { [istarget ia64-*-*]
5722 || ([istarget mips*-*-*]
5723 && [et-is-effective-target mips_msa]) } {
5724 set et_vect_udot_qi_saved 1
5727 verbose "check_effective_target_vect_sdot_qi:\
5728 returning $et_vect_sdot_qi_saved($et_index)" 2
5729 return $et_vect_sdot_qi_saved($et_index)
5732 # Return 1 if the target plus current options supports a vector
5733 # dot-product of unsigned chars, 0 otherwise.
5735 # This won't change for different subtargets so cache the result.
5737 proc check_effective_target_vect_udot_qi { } {
5738 global et_vect_udot_qi_saved
5739 global et_index
5741 if [info exists et_vect_udot_qi_saved($et_index)] {
5742 verbose "check_effective_target_vect_udot_qi: using cached result" 2
5743 } else {
5744 set et_vect_udot_qi_saved($et_index) 0
5745 if { [istarget powerpc*-*-*]
5746 || [istarget ia64-*-*]
5747 || ([istarget mips*-*-*]
5748 && [et-is-effective-target mips_msa]) } {
5749 set et_vect_udot_qi_saved($et_index) 1
5752 verbose "check_effective_target_vect_udot_qi:\
5753 returning $et_vect_udot_qi_saved($et_index)" 2
5754 return $et_vect_udot_qi_saved($et_index)
5757 # Return 1 if the target plus current options supports a vector
5758 # dot-product of signed shorts, 0 otherwise.
5760 # This won't change for different subtargets so cache the result.
5762 proc check_effective_target_vect_sdot_hi { } {
5763 global et_vect_sdot_hi_saved
5764 global et_index
5766 if [info exists et_vect_sdot_hi_saved($et_index)] {
5767 verbose "check_effective_target_vect_sdot_hi: using cached result" 2
5768 } else {
5769 set et_vect_sdot_hi_saved($et_index) 0
5770 if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
5771 || [istarget ia64-*-*]
5772 || [istarget i?86-*-*] || [istarget x86_64-*-*]
5773 || ([istarget mips*-*-*]
5774 && [et-is-effective-target mips_msa]) } {
5775 set et_vect_sdot_hi_saved($et_index) 1
5778 verbose "check_effective_target_vect_sdot_hi:\
5779 returning $et_vect_sdot_hi_saved($et_index)" 2
5780 return $et_vect_sdot_hi_saved($et_index)
5783 # Return 1 if the target plus current options supports a vector
5784 # dot-product of unsigned shorts, 0 otherwise.
5786 # This won't change for different subtargets so cache the result.
5788 proc check_effective_target_vect_udot_hi { } {
5789 global et_vect_udot_hi_saved
5790 global et_index
5792 if [info exists et_vect_udot_hi_saved($et_index)] {
5793 verbose "check_effective_target_vect_udot_hi: using cached result" 2
5794 } else {
5795 set et_vect_udot_hi_saved($et_index) 0
5796 if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
5797 || ([istarget mips*-*-*]
5798 && [et-is-effective-target mips_msa]) } {
5799 set et_vect_udot_hi_saved($et_index) 1
5802 verbose "check_effective_target_vect_udot_hi:\
5803 returning $et_vect_udot_hi_saved($et_index)" 2
5804 return $et_vect_udot_hi_saved($et_index)
5807 # Return 1 if the target plus current options supports a vector
5808 # sad operation of unsigned chars, 0 otherwise.
5810 # This won't change for different subtargets so cache the result.
5812 proc check_effective_target_vect_usad_char { } {
5813 global et_vect_usad_char_saved
5814 global et_index
5816 if [info exists et_vect_usad_char_saved($et_index)] {
5817 verbose "check_effective_target_vect_usad_char: using cached result" 2
5818 } else {
5819 set et_vect_usad_char_saved($et_index) 0
5820 if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
5821 set et_vect_usad_char_saved($et_index) 1
5824 verbose "check_effective_target_vect_usad_char:\
5825 returning $et_vect_usad_char_saved($et_index)" 2
5826 return $et_vect_usad_char_saved($et_index)
5829 # Return 1 if the target plus current options supports a vector
5830 # demotion (packing) of shorts (to chars) and ints (to shorts)
5831 # using modulo arithmetic, 0 otherwise.
5833 # This won't change for different subtargets so cache the result.
5835 proc check_effective_target_vect_pack_trunc { } {
5836 global et_vect_pack_trunc_saved
5837 global et_index
5839 if [info exists et_vect_pack_trunc_saved($et_index)] {
5840 verbose "check_effective_target_vect_pack_trunc: using cached result" 2
5841 } else {
5842 set et_vect_pack_trunc_saved($et_index) 0
5843 if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
5844 || [istarget i?86-*-*] || [istarget x86_64-*-*]
5845 || [istarget aarch64*-*-*]
5846 || [istarget spu-*-*]
5847 || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
5848 && [check_effective_target_arm_little_endian])
5849 || ([istarget mips*-*-*]
5850 && [et-is-effective-target mips_msa]) } {
5851 set et_vect_pack_trunc_saved($et_index) 1
5854 verbose "check_effective_target_vect_pack_trunc:\
5855 returning $et_vect_pack_trunc_saved($et_index)" 2
5856 return $et_vect_pack_trunc_saved($et_index)
5859 # Return 1 if the target plus current options supports a vector
5860 # promotion (unpacking) of chars (to shorts) and shorts (to ints), 0 otherwise.
5862 # This won't change for different subtargets so cache the result.
5864 proc check_effective_target_vect_unpack { } {
5865 global et_vect_unpack_saved
5866 global et_index
5868 if [info exists et_vect_unpack_saved($et_index)] {
5869 verbose "check_effective_target_vect_unpack: using cached result" 2
5870 } else {
5871 set et_vect_unpack_saved($et_index) 0
5872 if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
5873 || [istarget i?86-*-*] || [istarget x86_64-*-*]
5874 || [istarget spu-*-*]
5875 || [istarget ia64-*-*]
5876 || [istarget aarch64*-*-*]
5877 || ([istarget mips*-*-*]
5878 && [et-is-effective-target mips_msa])
5879 || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
5880 && [check_effective_target_arm_little_endian]) } {
5881 set et_vect_unpack_saved($et_index) 1
5884 verbose "check_effective_target_vect_unpack:\
5885 returning $et_vect_unpack_saved($et_index)" 2
5886 return $et_vect_unpack_saved($et_index)
5889 # Return 1 if the target plus current options does not guarantee
5890 # that its STACK_BOUNDARY is >= the reguired vector alignment.
5892 # This won't change for different subtargets so cache the result.
5894 proc check_effective_target_unaligned_stack { } {
5895 global et_unaligned_stack_saved
5897 if [info exists et_unaligned_stack_saved] {
5898 verbose "check_effective_target_unaligned_stack: using cached result" 2
5899 } else {
5900 set et_unaligned_stack_saved 0
5902 verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2
5903 return $et_unaligned_stack_saved
5906 # Return 1 if the target plus current options does not support a vector
5907 # alignment mechanism, 0 otherwise.
5909 # This won't change for different subtargets so cache the result.
5911 proc check_effective_target_vect_no_align { } {
5912 global et_vect_no_align_saved
5913 global et_index
5915 if [info exists et_vect_no_align_saved($et_index)] {
5916 verbose "check_effective_target_vect_no_align: using cached result" 2
5917 } else {
5918 set et_vect_no_align_saved($et_index) 0
5919 if { [istarget mipsisa64*-*-*]
5920 || [istarget mips-sde-elf]
5921 || [istarget sparc*-*-*]
5922 || [istarget ia64-*-*]
5923 || [check_effective_target_arm_vect_no_misalign]
5924 || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
5925 || ([istarget mips*-*-*]
5926 && [et-is-effective-target mips_loongson]) } {
5927 set et_vect_no_align_saved($et_index) 1
5930 verbose "check_effective_target_vect_no_align:\
5931 returning $et_vect_no_align_saved($et_index)" 2
5932 return $et_vect_no_align_saved($et_index)
5935 # Return 1 if the target supports a vector misalign access, 0 otherwise.
5937 # This won't change for different subtargets so cache the result.
5939 proc check_effective_target_vect_hw_misalign { } {
5940 global et_vect_hw_misalign_saved
5941 global et_index
5943 if [info exists et_vect_hw_misalign_saved($et_index)] {
5944 verbose "check_effective_target_vect_hw_misalign: using cached result" 2
5945 } else {
5946 set et_vect_hw_misalign_saved($et_index) 0
5947 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
5948 || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
5949 || [istarget aarch64*-*-*]
5950 || ([istarget mips*-*-*] && [et-is-effective-target mips_msa]) } {
5951 set et_vect_hw_misalign_saved($et_index) 1
5953 if { [istarget arm*-*-*] } {
5954 set et_vect_hw_misalign_saved($et_index) ![check_effective_target_arm_vect_no_misalign]
5957 verbose "check_effective_target_vect_hw_misalign:\
5958 returning $et_vect_hw_misalign_saved($et_index)" 2
5959 return $et_vect_hw_misalign_saved($et_index)
5963 # Return 1 if arrays are aligned to the vector alignment
5964 # boundary, 0 otherwise.
5966 proc check_effective_target_vect_aligned_arrays { } {
5967 set et_vect_aligned_arrays 0
5968 if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
5969 && !([is-effective-target ia32]
5970 || ([check_avx_available] && ![check_prefer_avx128])))
5971 || [istarget spu-*-*] } {
5972 set et_vect_aligned_arrays 1
5975 verbose "check_effective_target_vect_aligned_arrays:\
5976 returning $et_vect_aligned_arrays" 2
5977 return $et_vect_aligned_arrays
5980 # Return 1 if types of size 32 bit or less are naturally aligned
5981 # (aligned to their type-size), 0 otherwise.
5983 # This won't change for different subtargets so cache the result.
5985 proc check_effective_target_natural_alignment_32 { } {
5986 global et_natural_alignment_32
5988 if [info exists et_natural_alignment_32_saved] {
5989 verbose "check_effective_target_natural_alignment_32: using cached result" 2
5990 } else {
5991 # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
5992 set et_natural_alignment_32_saved 1
5993 if { ([istarget *-*-darwin*] && [is-effective-target lp64])
5994 || [istarget avr-*-*] } {
5995 set et_natural_alignment_32_saved 0
5998 verbose "check_effective_target_natural_alignment_32: returning $et_natural_alignment_32_saved" 2
5999 return $et_natural_alignment_32_saved
6002 # Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
6003 # type-size), 0 otherwise.
6005 # This won't change for different subtargets so cache the result.
6007 proc check_effective_target_natural_alignment_64 { } {
6008 global et_natural_alignment_64
6010 if [info exists et_natural_alignment_64_saved] {
6011 verbose "check_effective_target_natural_alignment_64: using cached result" 2
6012 } else {
6013 set et_natural_alignment_64_saved 0
6014 if { ([is-effective-target lp64] && ![istarget *-*-darwin*])
6015 || [istarget spu-*-*] } {
6016 set et_natural_alignment_64_saved 1
6019 verbose "check_effective_target_natural_alignment_64: returning $et_natural_alignment_64_saved" 2
6020 return $et_natural_alignment_64_saved
6023 # Return 1 if all vector types are naturally aligned (aligned to their
6024 # type-size), 0 otherwise.
6026 proc check_effective_target_vect_natural_alignment { } {
6027 set et_vect_natural_alignment 1
6028 if { [check_effective_target_arm_eabi]
6029 || [istarget nvptx-*-*]
6030 || [istarget s390*-*-*] } {
6031 set et_vect_natural_alignment 0
6033 verbose "check_effective_target_vect_natural_alignment:\
6034 returning $et_vect_natural_alignment" 2
6035 return $et_vect_natural_alignment
6038 # Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise.
6040 proc check_effective_target_vector_alignment_reachable { } {
6041 set et_vector_alignment_reachable 0
6042 if { [check_effective_target_vect_aligned_arrays]
6043 || [check_effective_target_natural_alignment_32] } {
6044 set et_vector_alignment_reachable 1
6046 verbose "check_effective_target_vector_alignment_reachable:\
6047 returning $et_vector_alignment_reachable" 2
6048 return $et_vector_alignment_reachable
6051 # Return 1 if vector alignment for 64 bit is reachable, 0 otherwise.
6053 proc check_effective_target_vector_alignment_reachable_for_64bit { } {
6054 set et_vector_alignment_reachable_for_64bit 0
6055 if { [check_effective_target_vect_aligned_arrays]
6056 || [check_effective_target_natural_alignment_64] } {
6057 set et_vector_alignment_reachable_for_64bit 1
6059 verbose "check_effective_target_vector_alignment_reachable_for_64bit:\
6060 returning $et_vector_alignment_reachable_for_64bit" 2
6061 return $et_vector_alignment_reachable_for_64bit
6064 # Return 1 if the target only requires element alignment for vector accesses
6066 proc check_effective_target_vect_element_align { } {
6067 global et_vect_element_align
6068 global et_index
6070 if [info exists et_vect_element_align($et_index)] {
6071 verbose "check_effective_target_vect_element_align:\
6072 using cached result" 2
6073 } else {
6074 set et_vect_element_align($et_index) 0
6075 if { ([istarget arm*-*-*]
6076 && ![check_effective_target_arm_vect_no_misalign])
6077 || [check_effective_target_vect_hw_misalign] } {
6078 set et_vect_element_align($et_index) 1
6082 verbose "check_effective_target_vect_element_align:\
6083 returning $et_vect_element_align($et_index)" 2
6084 return $et_vect_element_align($et_index)
6087 # Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise.
6089 proc check_effective_target_vect_load_lanes { } {
6090 global et_vect_load_lanes
6092 if [info exists et_vect_load_lanes] {
6093 verbose "check_effective_target_vect_load_lanes: using cached result" 2
6094 } else {
6095 set et_vect_load_lanes 0
6096 if { ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok])
6097 || [istarget aarch64*-*-*] } {
6098 set et_vect_load_lanes 1
6102 verbose "check_effective_target_vect_load_lanes: returning $et_vect_load_lanes" 2
6103 return $et_vect_load_lanes
6106 # Return 1 if the target supports vector conditional operations, 0 otherwise.
6108 proc check_effective_target_vect_condition { } {
6109 global et_vect_cond_saved
6110 global et_index
6112 if [info exists et_vect_cond_saved($et_index)] {
6113 verbose "check_effective_target_vect_cond: using cached result" 2
6114 } else {
6115 set et_vect_cond_saved($et_index) 0
6116 if { [istarget aarch64*-*-*]
6117 || [istarget powerpc*-*-*]
6118 || [istarget ia64-*-*]
6119 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6120 || [istarget spu-*-*]
6121 || ([istarget mips*-*-*]
6122 && [et-is-effective-target mips_msa])
6123 || ([istarget arm*-*-*]
6124 && [check_effective_target_arm_neon_ok]) } {
6125 set et_vect_cond_saved($et_index) 1
6129 verbose "check_effective_target_vect_cond:\
6130 returning $et_vect_cond_saved($et_index)" 2
6131 return $et_vect_cond_saved($et_index)
6134 # Return 1 if the target supports vector conditional operations where
6135 # the comparison has different type from the lhs, 0 otherwise.
6137 proc check_effective_target_vect_cond_mixed { } {
6138 global et_vect_cond_mixed_saved
6139 global et_index
6141 if [info exists et_vect_cond_mixed_saved($et_index)] {
6142 verbose "check_effective_target_vect_cond_mixed: using cached result" 2
6143 } else {
6144 set et_vect_cond_mixed_saved($et_index) 0
6145 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
6146 || [istarget aarch64*-*-*]
6147 || [istarget powerpc*-*-*]
6148 || ([istarget mips*-*-*]
6149 && [et-is-effective-target mips_msa]) } {
6150 set et_vect_cond_mixed_saved($et_index) 1
6154 verbose "check_effective_target_vect_cond_mixed:\
6155 returning $et_vect_cond_mixed_saved($et_index)" 2
6156 return $et_vect_cond_mixed_saved($et_index)
6159 # Return 1 if the target supports vector char multiplication, 0 otherwise.
6161 proc check_effective_target_vect_char_mult { } {
6162 global et_vect_char_mult_saved
6163 global et_index
6165 if [info exists et_vect_char_mult_saved($et_index)] {
6166 verbose "check_effective_target_vect_char_mult: using cached result" 2
6167 } else {
6168 set et_vect_char_mult_saved($et_index) 0
6169 if { [istarget aarch64*-*-*]
6170 || [istarget ia64-*-*]
6171 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6172 || [check_effective_target_arm32]
6173 || [check_effective_target_powerpc_altivec]
6174 || ([istarget mips*-*-*]
6175 && [et-is-effective-target mips_msa]) } {
6176 set et_vect_char_mult_saved($et_index) 1
6180 verbose "check_effective_target_vect_char_mult:\
6181 returning $et_vect_char_mult_saved($et_index)" 2
6182 return $et_vect_char_mult_saved($et_index)
6185 # Return 1 if the target supports vector short multiplication, 0 otherwise.
6187 proc check_effective_target_vect_short_mult { } {
6188 global et_vect_short_mult_saved
6189 global et_index
6191 if [info exists et_vect_short_mult_saved($et_index)] {
6192 verbose "check_effective_target_vect_short_mult: using cached result" 2
6193 } else {
6194 set et_vect_short_mult_saved($et_index) 0
6195 if { [istarget ia64-*-*]
6196 || [istarget spu-*-*]
6197 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6198 || [istarget powerpc*-*-*]
6199 || [istarget aarch64*-*-*]
6200 || [check_effective_target_arm32]
6201 || ([istarget mips*-*-*]
6202 && ([et-is-effective-target mips_msa]
6203 || [et-is-effective-target mips_loongson])) } {
6204 set et_vect_short_mult_saved($et_index) 1
6208 verbose "check_effective_target_vect_short_mult:\
6209 returning $et_vect_short_mult_saved($et_index)" 2
6210 return $et_vect_short_mult_saved($et_index)
6213 # Return 1 if the target supports vector int multiplication, 0 otherwise.
6215 proc check_effective_target_vect_int_mult { } {
6216 global et_vect_int_mult_saved
6217 global et_index
6219 if [info exists et_vect_int_mult_saved($et_index)] {
6220 verbose "check_effective_target_vect_int_mult: using cached result" 2
6221 } else {
6222 set et_vect_int_mult_saved($et_index) 0
6223 if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
6224 || [istarget spu-*-*]
6225 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6226 || [istarget ia64-*-*]
6227 || [istarget aarch64*-*-*]
6228 || ([istarget mips*-*-*]
6229 && [et-is-effective-target mips_msa])
6230 || [check_effective_target_arm32] } {
6231 set et_vect_int_mult_saved($et_index) 1
6235 verbose "check_effective_target_vect_int_mult:\
6236 returning $et_vect_int_mult_saved($et_index)" 2
6237 return $et_vect_int_mult_saved($et_index)
6240 # Return 1 if the target supports vector even/odd elements extraction, 0 otherwise.
6242 proc check_effective_target_vect_extract_even_odd { } {
6243 global et_vect_extract_even_odd_saved
6244 global et_index
6246 if [info exists et_vect_extract_even_odd_saved($et_index)] {
6247 verbose "check_effective_target_vect_extract_even_odd:\
6248 using cached result" 2
6249 } else {
6250 set et_vect_extract_even_odd_saved($et_index) 0
6251 if { [istarget aarch64*-*-*]
6252 || [istarget powerpc*-*-*]
6253 || [is-effective-target arm_neon]
6254 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6255 || [istarget ia64-*-*]
6256 || [istarget spu-*-*]
6257 || ([istarget mips*-*-*]
6258 && ([et-is-effective-target mips_msa]
6259 || [et-is-effective-target mpaired_single])) } {
6260 set et_vect_extract_even_odd_saved($et_index) 1
6264 verbose "check_effective_target_vect_extract_even_odd:\
6265 returning $et_vect_extract_even_odd_saved($et_index)" 2
6266 return $et_vect_extract_even_odd_saved($et_index)
6269 # Return 1 if the target supports vector interleaving, 0 otherwise.
6271 proc check_effective_target_vect_interleave { } {
6272 global et_vect_interleave_saved
6273 global et_index
6275 if [info exists et_vect_interleave_saved($et_index)] {
6276 verbose "check_effective_target_vect_interleave: using cached result" 2
6277 } else {
6278 set et_vect_interleave_saved($et_index) 0
6279 if { [istarget aarch64*-*-*]
6280 || [istarget powerpc*-*-*]
6281 || [is-effective-target arm_neon]
6282 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6283 || [istarget ia64-*-*]
6284 || [istarget spu-*-*]
6285 || ([istarget mips*-*-*]
6286 && ([et-is-effective-target mpaired_single]
6287 || [et-is-effective-target mips_msa])) } {
6288 set et_vect_interleave_saved($et_index) 1
6292 verbose "check_effective_target_vect_interleave:\
6293 returning $et_vect_interleave_saved($et_index)" 2
6294 return $et_vect_interleave_saved($et_index)
6297 foreach N {2 3 4 8} {
6298 eval [string map [list N $N] {
6299 # Return 1 if the target supports 2-vector interleaving
6300 proc check_effective_target_vect_stridedN { } {
6301 global et_vect_stridedN_saved
6302 global et_index
6304 if [info exists et_vect_stridedN_saved($et_index)] {
6305 verbose "check_effective_target_vect_stridedN:\
6306 using cached result" 2
6307 } else {
6308 set et_vect_stridedN_saved($et_index) 0
6309 if { (N & -N) == N
6310 && [check_effective_target_vect_interleave]
6311 && [check_effective_target_vect_extract_even_odd] } {
6312 set et_vect_stridedN_saved($et_index) 1
6314 if { ([istarget arm*-*-*]
6315 || [istarget aarch64*-*-*]) && N >= 2 && N <= 4 } {
6316 set et_vect_stridedN_saved($et_index) 1
6320 verbose "check_effective_target_vect_stridedN:\
6321 returning $et_vect_stridedN_saved($et_index)" 2
6322 return $et_vect_stridedN_saved($et_index)
6327 # Return 1 if the target supports multiple vector sizes
6329 proc check_effective_target_vect_multiple_sizes { } {
6330 global et_vect_multiple_sizes_saved
6331 global et_index
6333 set et_vect_multiple_sizes_saved($et_index) 0
6334 if { [istarget aarch64*-*-*]
6335 || [is-effective-target arm_neon]
6336 || (([istarget i?86-*-*] || [istarget x86_64-*-*])
6337 && ([check_avx_available] && ![check_prefer_avx128])) } {
6338 set et_vect_multiple_sizes_saved($et_index) 1
6341 verbose "check_effective_target_vect_multiple_sizes:\
6342 returning $et_vect_multiple_sizes_saved($et_index)" 2
6343 return $et_vect_multiple_sizes_saved($et_index)
6346 # Return 1 if the target supports vectors of 64 bits.
6348 proc check_effective_target_vect64 { } {
6349 global et_vect64_saved
6350 global et_index
6352 if [info exists et_vect64_saved($et_index)] {
6353 verbose "check_effective_target_vect64: using cached result" 2
6354 } else {
6355 set et_vect64_saved($et_index) 0
6356 if { ([is-effective-target arm_neon]
6357 && [check_effective_target_arm_little_endian])
6358 || [istarget aarch64*-*-*]
6359 || [istarget sparc*-*-*] } {
6360 set et_vect64_saved($et_index) 1
6364 verbose "check_effective_target_vect64:\
6365 returning $et_vect64_saved($et_index)" 2
6366 return $et_vect64_saved($et_index)
6369 # Return 1 if the target supports vector copysignf calls.
6371 proc check_effective_target_vect_call_copysignf { } {
6372 global et_vect_call_copysignf_saved
6373 global et_index
6375 if [info exists et_vect_call_copysignf_saved($et_index)] {
6376 verbose "check_effective_target_vect_call_copysignf:\
6377 using cached result" 2
6378 } else {
6379 set et_vect_call_copysignf_saved($et_index) 0
6380 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
6381 || [istarget powerpc*-*-*]
6382 || [istarget aarch64*-*-*] } {
6383 set et_vect_call_copysignf_saved($et_index) 1
6387 verbose "check_effective_target_vect_call_copysignf:\
6388 returning $et_vect_call_copysignf_saved($et_index)" 2
6389 return $et_vect_call_copysignf_saved($et_index)
6392 # Return 1 if the target supports hardware square root instructions.
6394 proc check_effective_target_sqrt_insn { } {
6395 global et_sqrt_insn_saved
6397 if [info exists et_sqrt_insn_saved] {
6398 verbose "check_effective_target_hw_sqrt: using cached result" 2
6399 } else {
6400 set et_sqrt_insn_saved 0
6401 if { [istarget i?86-*-*] || [istarget x86_64-*-*]
6402 || [istarget powerpc*-*-*]
6403 || [istarget aarch64*-*-*]
6404 || ([istarget arm*-*-*] && [check_effective_target_arm_vfp_ok]) } {
6405 set et_sqrt_insn_saved 1
6409 verbose "check_effective_target_hw_sqrt: returning et_sqrt_insn_saved" 2
6410 return $et_sqrt_insn_saved
6413 # Return 1 if the target supports vector sqrtf calls.
6415 proc check_effective_target_vect_call_sqrtf { } {
6416 global et_vect_call_sqrtf_saved
6417 global et_index
6419 if [info exists et_vect_call_sqrtf_saved($et_index)] {
6420 verbose "check_effective_target_vect_call_sqrtf: using cached result" 2
6421 } else {
6422 set et_vect_call_sqrtf_saved($et_index) 0
6423 if { [istarget aarch64*-*-*]
6424 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6425 || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) } {
6426 set et_vect_call_sqrtf_saved($et_index) 1
6430 verbose "check_effective_target_vect_call_sqrtf:\
6431 returning $et_vect_call_sqrtf_saved($et_index)" 2
6432 return $et_vect_call_sqrtf_saved($et_index)
6435 # Return 1 if the target supports vector lrint calls.
6437 proc check_effective_target_vect_call_lrint { } {
6438 set et_vect_call_lrint 0
6439 if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
6440 && [check_effective_target_ilp32]) } {
6441 set et_vect_call_lrint 1
6444 verbose "check_effective_target_vect_call_lrint: returning $et_vect_call_lrint" 2
6445 return $et_vect_call_lrint
6448 # Return 1 if the target supports vector btrunc calls.
6450 proc check_effective_target_vect_call_btrunc { } {
6451 global et_vect_call_btrunc_saved
6452 global et_index
6454 if [info exists et_vect_call_btrunc_saved($et_index)] {
6455 verbose "check_effective_target_vect_call_btrunc:\
6456 using cached result" 2
6457 } else {
6458 set et_vect_call_btrunc_saved($et_index) 0
6459 if { [istarget aarch64*-*-*] } {
6460 set et_vect_call_btrunc_saved($et_index) 1
6464 verbose "check_effective_target_vect_call_btrunc:\
6465 returning $et_vect_call_btrunc_saved($et_index)" 2
6466 return $et_vect_call_btrunc_saved($et_index)
6469 # Return 1 if the target supports vector btruncf calls.
6471 proc check_effective_target_vect_call_btruncf { } {
6472 global et_vect_call_btruncf_saved
6473 global et_index
6475 if [info exists et_vect_call_btruncf_saved($et_index)] {
6476 verbose "check_effective_target_vect_call_btruncf:\
6477 using cached result" 2
6478 } else {
6479 set et_vect_call_btruncf_saved($et_index) 0
6480 if { [istarget aarch64*-*-*] } {
6481 set et_vect_call_btruncf_saved($et_index) 1
6485 verbose "check_effective_target_vect_call_btruncf:\
6486 returning $et_vect_call_btruncf_saved($et_index)" 2
6487 return $et_vect_call_btruncf_saved($et_index)
6490 # Return 1 if the target supports vector ceil calls.
6492 proc check_effective_target_vect_call_ceil { } {
6493 global et_vect_call_ceil_saved
6494 global et_index
6496 if [info exists et_vect_call_ceil_saved($et_index)] {
6497 verbose "check_effective_target_vect_call_ceil: using cached result" 2
6498 } else {
6499 set et_vect_call_ceil_saved($et_index) 0
6500 if { [istarget aarch64*-*-*] } {
6501 set et_vect_call_ceil_saved($et_index) 1
6505 verbose "check_effective_target_vect_call_ceil:\
6506 returning $et_vect_call_ceil_saved($et_index)" 2
6507 return $et_vect_call_ceil_saved($et_index)
6510 # Return 1 if the target supports vector ceilf calls.
6512 proc check_effective_target_vect_call_ceilf { } {
6513 global et_vect_call_ceilf_saved
6514 global et_index
6516 if [info exists et_vect_call_ceilf_saved($et_index)] {
6517 verbose "check_effective_target_vect_call_ceilf: using cached result" 2
6518 } else {
6519 set et_vect_call_ceilf_saved($et_index) 0
6520 if { [istarget aarch64*-*-*] } {
6521 set et_vect_call_ceilf_saved($et_index) 1
6525 verbose "check_effective_target_vect_call_ceilf:\
6526 returning $et_vect_call_ceilf_saved($et_index)" 2
6527 return $et_vect_call_ceilf_saved($et_index)
6530 # Return 1 if the target supports vector floor calls.
6532 proc check_effective_target_vect_call_floor { } {
6533 global et_vect_call_floor_saved
6534 global et_index
6536 if [info exists et_vect_call_floor_saved($et_index)] {
6537 verbose "check_effective_target_vect_call_floor: using cached result" 2
6538 } else {
6539 set et_vect_call_floor_saved($et_index) 0
6540 if { [istarget aarch64*-*-*] } {
6541 set et_vect_call_floor_saved($et_index) 1
6545 verbose "check_effective_target_vect_call_floor:\
6546 returning $et_vect_call_floor_saved($et_index)" 2
6547 return $et_vect_call_floor_saved($et_index)
6550 # Return 1 if the target supports vector floorf calls.
6552 proc check_effective_target_vect_call_floorf { } {
6553 global et_vect_call_floorf_saved
6554 global et_index
6556 if [info exists et_vect_call_floorf_saved($et_index)] {
6557 verbose "check_effective_target_vect_call_floorf: using cached result" 2
6558 } else {
6559 set et_vect_call_floorf_saved($et_index) 0
6560 if { [istarget aarch64*-*-*] } {
6561 set et_vect_call_floorf_saved($et_index) 1
6565 verbose "check_effective_target_vect_call_floorf:\
6566 returning $et_vect_call_floorf_saved($et_index)" 2
6567 return $et_vect_call_floorf_saved($et_index)
6570 # Return 1 if the target supports vector lceil calls.
6572 proc check_effective_target_vect_call_lceil { } {
6573 global et_vect_call_lceil_saved
6574 global et_index
6576 if [info exists et_vect_call_lceil_saved($et_index)] {
6577 verbose "check_effective_target_vect_call_lceil: using cached result" 2
6578 } else {
6579 set et_vect_call_lceil_saved($et_index) 0
6580 if { [istarget aarch64*-*-*] } {
6581 set et_vect_call_lceil_saved($et_index) 1
6585 verbose "check_effective_target_vect_call_lceil:\
6586 returning $et_vect_call_lceil_saved($et_index)" 2
6587 return $et_vect_call_lceil_saved($et_index)
6590 # Return 1 if the target supports vector lfloor calls.
6592 proc check_effective_target_vect_call_lfloor { } {
6593 global et_vect_call_lfloor_saved
6594 global et_index
6596 if [info exists et_vect_call_lfloor_saved($et_index)] {
6597 verbose "check_effective_target_vect_call_lfloor: using cached result" 2
6598 } else {
6599 set et_vect_call_lfloor_saved($et_index) 0
6600 if { [istarget aarch64*-*-*] } {
6601 set et_vect_call_lfloor_saved($et_index) 1
6605 verbose "check_effective_target_vect_call_lfloor:\
6606 returning $et_vect_call_lfloor_saved($et_index)" 2
6607 return $et_vect_call_lfloor_saved($et_index)
6610 # Return 1 if the target supports vector nearbyint calls.
6612 proc check_effective_target_vect_call_nearbyint { } {
6613 global et_vect_call_nearbyint_saved
6614 global et_index
6616 if [info exists et_vect_call_nearbyint_saved($et_index)] {
6617 verbose "check_effective_target_vect_call_nearbyint: using cached result" 2
6618 } else {
6619 set et_vect_call_nearbyint_saved($et_index) 0
6620 if { [istarget aarch64*-*-*] } {
6621 set et_vect_call_nearbyint_saved($et_index) 1
6625 verbose "check_effective_target_vect_call_nearbyint:\
6626 returning $et_vect_call_nearbyint_saved($et_index)" 2
6627 return $et_vect_call_nearbyint_saved($et_index)
6630 # Return 1 if the target supports vector nearbyintf calls.
6632 proc check_effective_target_vect_call_nearbyintf { } {
6633 global et_vect_call_nearbyintf_saved
6634 global et_index
6636 if [info exists et_vect_call_nearbyintf_saved($et_index)] {
6637 verbose "check_effective_target_vect_call_nearbyintf:\
6638 using cached result" 2
6639 } else {
6640 set et_vect_call_nearbyintf_saved($et_index) 0
6641 if { [istarget aarch64*-*-*] } {
6642 set et_vect_call_nearbyintf_saved($et_index) 1
6646 verbose "check_effective_target_vect_call_nearbyintf:\
6647 returning $et_vect_call_nearbyintf_saved($et_index)" 2
6648 return $et_vect_call_nearbyintf_saved($et_index)
6651 # Return 1 if the target supports vector round calls.
6653 proc check_effective_target_vect_call_round { } {
6654 global et_vect_call_round_saved
6655 global et_index
6657 if [info exists et_vect_call_round_saved($et_index)] {
6658 verbose "check_effective_target_vect_call_round: using cached result" 2
6659 } else {
6660 set et_vect_call_round_saved($et_index) 0
6661 if { [istarget aarch64*-*-*] } {
6662 set et_vect_call_round_saved($et_index) 1
6666 verbose "check_effective_target_vect_call_round:\
6667 returning $et_vect_call_round_saved($et_index)" 2
6668 return $et_vect_call_round_saved($et_index)
6671 # Return 1 if the target supports vector roundf calls.
6673 proc check_effective_target_vect_call_roundf { } {
6674 global et_vect_call_roundf_saved
6675 global et_index
6677 if [info exists et_vect_call_roundf_saved($et_index)] {
6678 verbose "check_effective_target_vect_call_roundf: using cached result" 2
6679 } else {
6680 set et_vect_call_roundf_saved($et_index) 0
6681 if { [istarget aarch64*-*-*] } {
6682 set et_vect_call_roundf_saved($et_index) 1
6686 verbose "check_effective_target_vect_call_roundf:\
6687 returning $et_vect_call_roundf_saved($et_index)" 2
6688 return $et_vect_call_roundf_saved($et_index)
6691 # Return 1 if the target supports section-anchors
6693 proc check_effective_target_section_anchors { } {
6694 global et_section_anchors_saved
6696 if [info exists et_section_anchors_saved] {
6697 verbose "check_effective_target_section_anchors: using cached result" 2
6698 } else {
6699 set et_section_anchors_saved 0
6700 if { [istarget powerpc*-*-*]
6701 || [istarget arm*-*-*]
6702 || [istarget aarch64*-*-*] } {
6703 set et_section_anchors_saved 1
6707 verbose "check_effective_target_section_anchors: returning $et_section_anchors_saved" 2
6708 return $et_section_anchors_saved
6711 # Return 1 if the target supports atomic operations on "int_128" values.
6713 proc check_effective_target_sync_int_128 { } {
6714 if { [istarget spu-*-*] } {
6715 return 1
6716 } else {
6717 return 0
6721 # Return 1 if the target supports atomic operations on "int_128" values
6722 # and can execute them.
6723 # This requires support for both compare-and-swap and true atomic loads.
6725 proc check_effective_target_sync_int_128_runtime { } {
6726 if { [istarget spu-*-*] } {
6727 return 1
6728 } else {
6729 return 0
6733 # Return 1 if the target supports atomic operations on "long long".
6735 # Note: 32bit x86 targets require -march=pentium in dg-options.
6736 # Note: 32bit s390 targets require -mzarch in dg-options.
6738 proc check_effective_target_sync_long_long { } {
6739 if { [istarget i?86-*-*] || [istarget x86_64-*-*])
6740 || [istarget aarch64*-*-*]
6741 || [istarget arm*-*-*]
6742 || [istarget alpha*-*-*]
6743 || ([istarget sparc*-*-*] && [check_effective_target_lp64])
6744 || [istarget s390*-*-*]
6745 || [istarget spu-*-*] } {
6746 return 1
6747 } else {
6748 return 0
6752 # Return 1 if the target supports atomic operations on "long long"
6753 # and can execute them.
6755 # Note: 32bit x86 targets require -march=pentium in dg-options.
6757 proc check_effective_target_sync_long_long_runtime { } {
6758 if { (([istarget x86_64-*-*] || [istarget i?86-*-*])
6759 && [check_cached_effective_target sync_long_long_available {
6760 check_runtime_nocache sync_long_long_available {
6761 #include "cpuid.h"
6762 int main ()
6764 unsigned int eax, ebx, ecx, edx;
6765 if (__get_cpuid (1, &eax, &ebx, &ecx, &edx))
6766 return !(edx & bit_CMPXCHG8B);
6767 return 1;
6769 } ""
6771 || [istarget aarch64*-*-*]
6772 || ([istarget arm*-*-linux-*]
6773 && [check_runtime sync_longlong_runtime {
6774 #include <stdlib.h>
6775 int main ()
6777 long long l1;
6779 if (sizeof (long long) != 8)
6780 exit (1);
6782 /* Just check for native;
6783 checking for kernel fallback is tricky. */
6784 asm volatile ("ldrexd r0,r1, [%0]"
6785 : : "r" (&l1) : "r0", "r1");
6786 exit (0);
6788 } "" ])
6789 || [istarget alpha*-*-*]
6790 || ([istarget sparc*-*-*]
6791 && [check_effective_target_lp64]
6792 && [check_effective_target_ultrasparc_hw])
6793 || [istarget spu-*-*]
6794 || ([istarget powerpc*-*-*] && [check_effective_target_lp64]) } {
6795 return 1
6796 } else {
6797 return 0
6801 # Return 1 if the target supports byte swap instructions.
6803 proc check_effective_target_bswap { } {
6804 global et_bswap_saved
6806 if [info exists et_bswap_saved] {
6807 verbose "check_effective_target_bswap: using cached result" 2
6808 } else {
6809 set et_bswap_saved 0
6810 if { [istarget aarch64*-*-*]
6811 || [istarget alpha*-*-*]
6812 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6813 || [istarget m68k-*-*]
6814 || [istarget powerpc*-*-*]
6815 || [istarget rs6000-*-*]
6816 || [istarget s390*-*-*]
6817 || ([istarget arm*-*-*]
6818 && [check_no_compiler_messages_nocache arm_v6_or_later object {
6819 #if __ARM_ARCH < 6
6820 #error not armv6 or later
6821 #endif
6822 int i;
6823 } ""]) } {
6824 set et_bswap_saved 1
6828 verbose "check_effective_target_bswap: returning $et_bswap_saved" 2
6829 return $et_bswap_saved
6832 # Return 1 if the target supports 16-bit byte swap instructions.
6834 proc check_effective_target_bswap16 { } {
6835 global et_bswap16_saved
6837 if [info exists et_bswap16_saved] {
6838 verbose "check_effective_target_bswap16: using cached result" 2
6839 } else {
6840 set et_bswap16_saved 0
6841 if { [is-effective-target bswap]
6842 && ![istarget alpha*-*-*]
6843 && !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
6844 set et_bswap16_saved 1
6848 verbose "check_effective_target_bswap16: returning $et_bswap16_saved" 2
6849 return $et_bswap16_saved
6852 # Return 1 if the target supports 32-bit byte swap instructions.
6854 proc check_effective_target_bswap32 { } {
6855 global et_bswap32_saved
6857 if [info exists et_bswap32_saved] {
6858 verbose "check_effective_target_bswap32: using cached result" 2
6859 } else {
6860 set et_bswap32_saved 0
6861 if { [is-effective-target bswap] } {
6862 set et_bswap32_saved 1
6866 verbose "check_effective_target_bswap32: returning $et_bswap32_saved" 2
6867 return $et_bswap32_saved
6870 # Return 1 if the target supports 64-bit byte swap instructions.
6872 # Note: 32bit s390 targets require -mzarch in dg-options.
6874 proc check_effective_target_bswap64 { } {
6875 global et_bswap64_saved
6877 # expand_unop can expand 64-bit byte swap on 32-bit targets
6878 if { [is-effective-target bswap] && [is-effective-target int32plus] } {
6879 return 1
6881 return 0
6884 # Return 1 if the target supports atomic operations on "int" and "long".
6886 proc check_effective_target_sync_int_long { } {
6887 global et_sync_int_long_saved
6889 if [info exists et_sync_int_long_saved] {
6890 verbose "check_effective_target_sync_int_long: using cached result" 2
6891 } else {
6892 set et_sync_int_long_saved 0
6893 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
6894 # load-reserved/store-conditional instructions.
6895 if { [istarget ia64-*-*]
6896 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6897 || [istarget aarch64*-*-*]
6898 || [istarget alpha*-*-*]
6899 || [istarget arm*-*-linux-*]
6900 || ([istarget arm*-*-*]
6901 && [check_effective_target_arm_acq_rel])
6902 || [istarget bfin*-*linux*]
6903 || [istarget hppa*-*linux*]
6904 || [istarget s390*-*-*]
6905 || [istarget powerpc*-*-*]
6906 || [istarget crisv32-*-*] || [istarget cris-*-*]
6907 || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
6908 || [istarget spu-*-*]
6909 || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
6910 || [check_effective_target_mips_llsc] } {
6911 set et_sync_int_long_saved 1
6915 verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
6916 return $et_sync_int_long_saved
6919 # Return 1 if the target supports atomic operations on "char" and "short".
6921 proc check_effective_target_sync_char_short { } {
6922 global et_sync_char_short_saved
6924 if [info exists et_sync_char_short_saved] {
6925 verbose "check_effective_target_sync_char_short: using cached result" 2
6926 } else {
6927 set et_sync_char_short_saved 0
6928 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
6929 # load-reserved/store-conditional instructions.
6930 if { [istarget aarch64*-*-*]
6931 || [istarget ia64-*-*]
6932 || [istarget i?86-*-*] || [istarget x86_64-*-*]
6933 || [istarget alpha*-*-*]
6934 || [istarget arm*-*-linux-*]
6935 || ([istarget arm*-*-*]
6936 && [check_effective_target_arm_acq_rel])
6937 || [istarget hppa*-*linux*]
6938 || [istarget s390*-*-*]
6939 || [istarget powerpc*-*-*]
6940 || [istarget crisv32-*-*] || [istarget cris-*-*]
6941 || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
6942 || [istarget spu-*-*]
6943 || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
6944 || [check_effective_target_mips_llsc] } {
6945 set et_sync_char_short_saved 1
6949 verbose "check_effective_target_sync_char_short: returning $et_sync_char_short_saved" 2
6950 return $et_sync_char_short_saved
6953 # Return 1 if the target uses a ColdFire FPU.
6955 proc check_effective_target_coldfire_fpu { } {
6956 return [check_no_compiler_messages coldfire_fpu assembly {
6957 #ifndef __mcffpu__
6958 #error !__mcffpu__
6959 #endif
6963 # Return true if this is a uClibc target.
6965 proc check_effective_target_uclibc {} {
6966 return [check_no_compiler_messages uclibc object {
6967 #include <features.h>
6968 #if !defined (__UCLIBC__)
6969 #error !__UCLIBC__
6970 #endif
6974 # Return true if this is a uclibc target and if the uclibc feature
6975 # described by __$feature__ is not present.
6977 proc check_missing_uclibc_feature {feature} {
6978 return [check_no_compiler_messages $feature object "
6979 #include <features.h>
6980 #if !defined (__UCLIBC) || defined (__${feature}__)
6981 #error FOO
6982 #endif
6986 # Return true if this is a Newlib target.
6988 proc check_effective_target_newlib {} {
6989 return [check_no_compiler_messages newlib object {
6990 #include <newlib.h>
6994 # Some newlib versions don't provide a frexpl and instead depend
6995 # on frexp to implement long double conversions in their printf-like
6996 # functions. This leads to broken results. Detect such versions here.
6998 proc check_effective_target_newlib_broken_long_double_io {} {
6999 if { [is-effective-target newlib] && ![is-effective-target frexpl] } {
7000 return 1
7002 return 0
7005 # Return true if this is NOT a Bionic target.
7007 proc check_effective_target_non_bionic {} {
7008 return [check_no_compiler_messages non_bionic object {
7009 #include <ctype.h>
7010 #if defined (__BIONIC__)
7011 #error FOO
7012 #endif
7016 # Return true if this target has error.h header.
7018 proc check_effective_target_error_h {} {
7019 return [check_no_compiler_messages error_h object {
7020 #include <error.h>
7024 # Return true if this target has tgmath.h header.
7026 proc check_effective_target_tgmath_h {} {
7027 return [check_no_compiler_messages tgmath_h object {
7028 #include <tgmath.h>
7032 # Return true if target's libc supports complex functions.
7034 proc check_effective_target_libc_has_complex_functions {} {
7035 return [check_no_compiler_messages libc_has_complex_functions object {
7036 #include <complex.h>
7040 # Return 1 if
7041 # (a) an error of a few ULP is expected in string to floating-point
7042 # conversion functions; and
7043 # (b) overflow is not always detected correctly by those functions.
7045 proc check_effective_target_lax_strtofp {} {
7046 # By default, assume that all uClibc targets suffer from this.
7047 return [check_effective_target_uclibc]
7050 # Return 1 if this is a target for which wcsftime is a dummy
7051 # function that always returns 0.
7053 proc check_effective_target_dummy_wcsftime {} {
7054 # By default, assume that all uClibc targets suffer from this.
7055 return [check_effective_target_uclibc]
7058 # Return 1 if constructors with initialization priority arguments are
7059 # supposed on this target.
7061 proc check_effective_target_init_priority {} {
7062 return [check_no_compiler_messages init_priority assembly "
7063 void f() __attribute__((constructor (1000)));
7064 void f() \{\}
7068 # Return 1 if the target matches the effective target 'arg', 0 otherwise.
7069 # This can be used with any check_* proc that takes no argument and
7070 # returns only 1 or 0. It could be used with check_* procs that take
7071 # arguments with keywords that pass particular arguments.
7073 proc is-effective-target { arg } {
7074 global et_index
7075 set selected 0
7076 if { ![info exists et_index] } {
7077 # Initialize the effective target index that is used in some
7078 # check_effective_target_* procs.
7079 set et_index 0
7081 if { [info procs check_effective_target_${arg}] != [list] } {
7082 set selected [check_effective_target_${arg}]
7083 } else {
7084 switch $arg {
7085 "vmx_hw" { set selected [check_vmx_hw_available] }
7086 "vsx_hw" { set selected [check_vsx_hw_available] }
7087 "p8vector_hw" { set selected [check_p8vector_hw_available] }
7088 "p9vector_hw" { set selected [check_p9vector_hw_available] }
7089 "p9modulo_hw" { set selected [check_p9modulo_hw_available] }
7090 "ppc_float128_sw" { set selected [check_ppc_float128_sw_available] }
7091 "ppc_float128_hw" { set selected [check_ppc_float128_hw_available] }
7092 "ppc_recip_hw" { set selected [check_ppc_recip_hw_available] }
7093 "ppc_cpu_supports_hw" { set selected [check_ppc_cpu_supports_hw_available] }
7094 "dfp_hw" { set selected [check_dfp_hw_available] }
7095 "htm_hw" { set selected [check_htm_hw_available] }
7096 "named_sections" { set selected [check_named_sections_available] }
7097 "gc_sections" { set selected [check_gc_sections_available] }
7098 "cxa_atexit" { set selected [check_cxa_atexit_available] }
7099 default { error "unknown effective target keyword `$arg'" }
7102 verbose "is-effective-target: $arg $selected" 2
7103 return $selected
7106 # Return 1 if the argument is an effective-target keyword, 0 otherwise.
7108 proc is-effective-target-keyword { arg } {
7109 if { [info procs check_effective_target_${arg}] != [list] } {
7110 return 1
7111 } else {
7112 # These have different names for their check_* procs.
7113 switch $arg {
7114 "vmx_hw" { return 1 }
7115 "vsx_hw" { return 1 }
7116 "p8vector_hw" { return 1 }
7117 "p9vector_hw" { return 1 }
7118 "p9modulo_hw" { return 1 }
7119 "ppc_float128_sw" { return 1 }
7120 "ppc_float128_hw" { return 1 }
7121 "ppc_recip_hw" { return 1 }
7122 "dfp_hw" { return 1 }
7123 "htm_hw" { return 1 }
7124 "named_sections" { return 1 }
7125 "gc_sections" { return 1 }
7126 "cxa_atexit" { return 1 }
7127 default { return 0 }
7132 # Execute tests for all targets in EFFECTIVE_TARGETS list. Set et_index to
7133 # indicate what target is currently being processed. This is for
7134 # the vectorizer tests, e.g. vect_int, to keep track what target supports
7135 # a given feature.
7137 proc et-dg-runtest { runtest testcases flags default-extra-flags } {
7138 global dg-do-what-default
7139 global EFFECTIVE_TARGETS
7140 global et_index
7142 if { [llength $EFFECTIVE_TARGETS] > 0 } {
7143 foreach target $EFFECTIVE_TARGETS {
7144 set target_flags $flags
7145 set dg-do-what-default compile
7146 set et_index [lsearch -exact $EFFECTIVE_TARGETS $target]
7147 if { [info procs add_options_for_${target}] != [list] } {
7148 set target_flags [add_options_for_${target} "$flags"]
7150 if { [info procs check_effective_target_${target}_runtime]
7151 != [list] && [check_effective_target_${target}_runtime] } {
7152 set dg-do-what-default run
7154 $runtest $testcases $target_flags ${default-extra-flags}
7156 } else {
7157 set et_index 0
7158 $runtest $testcases $flags ${default-extra-flags}
7162 # Return 1 if a target matches the target in EFFECTIVE_TARGETS at index
7163 # et_index, 0 otherwise.
7165 proc et-is-effective-target { target } {
7166 global EFFECTIVE_TARGETS
7167 global et_index
7169 if { [llength $EFFECTIVE_TARGETS] > $et_index
7170 && [lindex $EFFECTIVE_TARGETS $et_index] == $target } {
7171 return 1
7173 return 0
7176 # Return 1 if target default to short enums
7178 proc check_effective_target_short_enums { } {
7179 return [check_no_compiler_messages short_enums assembly {
7180 enum foo { bar };
7181 int s[sizeof (enum foo) == 1 ? 1 : -1];
7185 # Return 1 if target supports merging string constants at link time.
7187 proc check_effective_target_string_merging { } {
7188 return [check_no_messages_and_pattern string_merging \
7189 "rodata\\.str" assembly {
7190 const char *var = "String";
7191 } {-O2}]
7194 # Return 1 if target has the basic signed and unsigned types in
7195 # <stdint.h>, 0 otherwise. This will be obsolete when GCC ensures a
7196 # working <stdint.h> for all targets.
7198 proc check_effective_target_stdint_types { } {
7199 return [check_no_compiler_messages stdint_types assembly {
7200 #include <stdint.h>
7201 int8_t a; int16_t b; int32_t c; int64_t d;
7202 uint8_t e; uint16_t f; uint32_t g; uint64_t h;
7206 # Return 1 if target has the basic signed and unsigned types in
7207 # <inttypes.h>, 0 otherwise. This is for tests that GCC's notions of
7208 # these types agree with those in the header, as some systems have
7209 # only <inttypes.h>.
7211 proc check_effective_target_inttypes_types { } {
7212 return [check_no_compiler_messages inttypes_types assembly {
7213 #include <inttypes.h>
7214 int8_t a; int16_t b; int32_t c; int64_t d;
7215 uint8_t e; uint16_t f; uint32_t g; uint64_t h;
7219 # Return 1 if programs are intended to be run on a simulator
7220 # (i.e. slowly) rather than hardware (i.e. fast).
7222 proc check_effective_target_simulator { } {
7224 # All "src/sim" simulators set this one.
7225 if [board_info target exists is_simulator] {
7226 return [board_info target is_simulator]
7229 # The "sid" simulators don't set that one, but at least they set
7230 # this one.
7231 if [board_info target exists slow_simulator] {
7232 return [board_info target slow_simulator]
7235 return 0
7238 # Return 1 if programs are intended to be run on hardware rather than
7239 # on a simulator
7241 proc check_effective_target_hw { } {
7243 # All "src/sim" simulators set this one.
7244 if [board_info target exists is_simulator] {
7245 if [board_info target is_simulator] {
7246 return 0
7247 } else {
7248 return 1
7252 # The "sid" simulators don't set that one, but at least they set
7253 # this one.
7254 if [board_info target exists slow_simulator] {
7255 if [board_info target slow_simulator] {
7256 return 0
7257 } else {
7258 return 1
7262 return 1
7265 # Return 1 if the target is a VxWorks kernel.
7267 proc check_effective_target_vxworks_kernel { } {
7268 return [check_no_compiler_messages vxworks_kernel assembly {
7269 #if !defined __vxworks || defined __RTP__
7270 #error NO
7271 #endif
7275 # Return 1 if the target is a VxWorks RTP.
7277 proc check_effective_target_vxworks_rtp { } {
7278 return [check_no_compiler_messages vxworks_rtp assembly {
7279 #if !defined __vxworks || !defined __RTP__
7280 #error NO
7281 #endif
7285 # Return 1 if the target is expected to provide wide character support.
7287 proc check_effective_target_wchar { } {
7288 if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} {
7289 return 0
7291 return [check_no_compiler_messages wchar assembly {
7292 #include <wchar.h>
7296 # Return 1 if the target has <pthread.h>.
7298 proc check_effective_target_pthread_h { } {
7299 return [check_no_compiler_messages pthread_h assembly {
7300 #include <pthread.h>
7304 # Return 1 if the target can truncate a file from a file-descriptor,
7305 # as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or
7306 # chsize. We test for a trivially functional truncation; no stubs.
7307 # As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a
7308 # different function to be used.
7310 proc check_effective_target_fd_truncate { } {
7311 set prog {
7312 #define _FILE_OFFSET_BITS 64
7313 #include <unistd.h>
7314 #include <stdio.h>
7315 #include <stdlib.h>
7316 #include <string.h>
7317 int main ()
7319 FILE *f = fopen ("tst.tmp", "wb");
7320 int fd;
7321 const char t[] = "test writing more than ten characters";
7322 char s[11];
7323 int status = 0;
7324 fd = fileno (f);
7325 write (fd, t, sizeof (t) - 1);
7326 lseek (fd, 0, 0);
7327 if (ftruncate (fd, 10) != 0)
7328 status = 1;
7329 close (fd);
7330 fclose (f);
7331 if (status)
7333 unlink ("tst.tmp");
7334 exit (status);
7336 f = fopen ("tst.tmp", "rb");
7337 if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0)
7338 status = 1;
7339 fclose (f);
7340 unlink ("tst.tmp");
7341 exit (status);
7345 if { [check_runtime ftruncate $prog] } {
7346 return 1;
7349 regsub "ftruncate" $prog "chsize" prog
7350 return [check_runtime chsize $prog]
7353 # Add to FLAGS all the target-specific flags needed to access the c99 runtime.
7355 proc add_options_for_c99_runtime { flags } {
7356 if { [istarget *-*-solaris2*] } {
7357 return "$flags -std=c99"
7359 if { [istarget powerpc-*-darwin*] } {
7360 return "$flags -mmacosx-version-min=10.3"
7362 return $flags
7365 # Add to FLAGS all the target-specific flags needed to enable
7366 # full IEEE compliance mode.
7368 proc add_options_for_ieee { flags } {
7369 if { [istarget alpha*-*-*]
7370 || [istarget sh*-*-*] } {
7371 return "$flags -mieee"
7373 if { [istarget rx-*-*] } {
7374 return "$flags -mnofpu"
7376 return $flags
7379 if {![info exists flags_to_postpone]} {
7380 set flags_to_postpone ""
7383 # Add to FLAGS the flags needed to enable functions to bind locally
7384 # when using pic/PIC passes in the testsuite.
7385 proc add_options_for_bind_pic_locally { flags } {
7386 global flags_to_postpone
7388 # Instead of returning 'flags' with the -fPIE or -fpie appended, we save it
7389 # in 'flags_to_postpone' and append it later in gcc_target_compile procedure in
7390 # order to make sure that the multilib_flags doesn't override this.
7392 if {[check_no_compiler_messages using_pic2 assembly {
7393 #if __PIC__ != 2
7394 #error __PIC__ != 2
7395 #endif
7396 }]} {
7397 set flags_to_postpone "-fPIE"
7398 return $flags
7400 if {[check_no_compiler_messages using_pic1 assembly {
7401 #if __PIC__ != 1
7402 #error __PIC__ != 1
7403 #endif
7404 }]} {
7405 set flags_to_postpone "-fpie"
7406 return $flags
7408 return $flags
7411 # Add to FLAGS the flags needed to enable 64-bit vectors.
7413 proc add_options_for_double_vectors { flags } {
7414 if [is-effective-target arm_neon_ok] {
7415 return "$flags -mvectorize-with-neon-double"
7418 return $flags
7421 # Add to FLAGS the flags needed to define the STACK_SIZE macro.
7423 proc add_options_for_stack_size { flags } {
7424 if [is-effective-target stack_size] {
7425 set stack_size [dg-effective-target-value stack_size]
7426 return "$flags -DSTACK_SIZE=$stack_size"
7429 return $flags
7432 # Return 1 if the target provides a full C99 runtime.
7434 proc check_effective_target_c99_runtime { } {
7435 return [check_cached_effective_target c99_runtime {
7436 global srcdir
7438 set file [open "$srcdir/gcc.dg/builtins-config.h"]
7439 set contents [read $file]
7440 close $file
7441 append contents {
7442 #ifndef HAVE_C99_RUNTIME
7443 #error !HAVE_C99_RUNTIME
7444 #endif
7446 check_no_compiler_messages_nocache c99_runtime assembly \
7447 $contents [add_options_for_c99_runtime ""]
7451 # Return 1 if target wchar_t is at least 4 bytes.
7453 proc check_effective_target_4byte_wchar_t { } {
7454 return [check_no_compiler_messages 4byte_wchar_t object {
7455 int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1];
7459 # Return 1 if the target supports automatic stack alignment.
7461 proc check_effective_target_automatic_stack_alignment { } {
7462 # Ordinarily x86 supports automatic stack alignment ...
7463 if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then {
7464 if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
7465 # ... except Win64 SEH doesn't. Succeed for Win32 though.
7466 return [check_effective_target_ilp32];
7468 return 1;
7470 return 0;
7473 # Return true if we are compiling for AVX target.
7475 proc check_avx_available { } {
7476 if { [check_no_compiler_messages avx_available assembly {
7477 #ifndef __AVX__
7478 #error unsupported
7479 #endif
7480 } ""] } {
7481 return 1;
7483 return 0;
7486 # Return true if 32- and 16-bytes vectors are available.
7488 proc check_effective_target_vect_sizes_32B_16B { } {
7489 if { [check_avx_available] && ![check_prefer_avx128] } {
7490 return 1;
7491 } else {
7492 return 0;
7496 # Return true if 128-bits vectors are preferred even if 256-bits vectors
7497 # are available.
7499 proc check_prefer_avx128 { } {
7500 if ![check_avx_available] {
7501 return 0;
7503 return [check_no_messages_and_pattern avx_explicit "xmm" assembly {
7504 float a[1024],b[1024],c[1024];
7505 void foo (void) { int i; for (i = 0; i < 1024; i++) a[i]=b[i]+c[i];}
7506 } "-O2 -ftree-vectorize"]
7510 # Return 1 if avx512f instructions can be compiled.
7512 proc check_effective_target_avx512f { } {
7513 return [check_no_compiler_messages avx512f object {
7514 typedef double __m512d __attribute__ ((__vector_size__ (64)));
7516 __m512d _mm512_add (__m512d a)
7518 return __builtin_ia32_addpd512_mask (a, a, a, 1, 4);
7520 } "-O2 -mavx512f" ]
7523 # Return 1 if avx instructions can be compiled.
7525 proc check_effective_target_avx { } {
7526 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
7527 return 0
7529 return [check_no_compiler_messages avx object {
7530 void _mm256_zeroall (void)
7532 __builtin_ia32_vzeroall ();
7534 } "-O2 -mavx" ]
7537 # Return 1 if avx2 instructions can be compiled.
7538 proc check_effective_target_avx2 { } {
7539 return [check_no_compiler_messages avx2 object {
7540 typedef long long __v4di __attribute__ ((__vector_size__ (32)));
7541 __v4di
7542 mm256_is32_andnotsi256 (__v4di __X, __v4di __Y)
7544 return __builtin_ia32_andnotsi256 (__X, __Y);
7546 } "-O0 -mavx2" ]
7549 # Return 1 if sse instructions can be compiled.
7550 proc check_effective_target_sse { } {
7551 return [check_no_compiler_messages sse object {
7552 int main ()
7554 __builtin_ia32_stmxcsr ();
7555 return 0;
7557 } "-O2 -msse" ]
7560 # Return 1 if sse2 instructions can be compiled.
7561 proc check_effective_target_sse2 { } {
7562 return [check_no_compiler_messages sse2 object {
7563 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
7565 __m128i _mm_srli_si128 (__m128i __A, int __N)
7567 return (__m128i)__builtin_ia32_psrldqi128 (__A, 8);
7569 } "-O2 -msse2" ]
7572 # Return 1 if sse4.1 instructions can be compiled.
7573 proc check_effective_target_sse4 { } {
7574 return [check_no_compiler_messages sse4.1 object {
7575 typedef long long __m128i __attribute__ ((__vector_size__ (16)));
7576 typedef int __v4si __attribute__ ((__vector_size__ (16)));
7578 __m128i _mm_mullo_epi32 (__m128i __X, __m128i __Y)
7580 return (__m128i) __builtin_ia32_pmulld128 ((__v4si)__X,
7581 (__v4si)__Y);
7583 } "-O2 -msse4.1" ]
7586 # Return 1 if F16C instructions can be compiled.
7588 proc check_effective_target_f16c { } {
7589 return [check_no_compiler_messages f16c object {
7590 #include "immintrin.h"
7591 float
7592 foo (unsigned short val)
7594 return _cvtsh_ss (val);
7596 } "-O2 -mf16c" ]
7599 # Return 1 if C wchar_t type is compatible with char16_t.
7601 proc check_effective_target_wchar_t_char16_t_compatible { } {
7602 return [check_no_compiler_messages wchar_t_char16_t object {
7603 __WCHAR_TYPE__ wc;
7604 __CHAR16_TYPE__ *p16 = &wc;
7605 char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
7609 # Return 1 if C wchar_t type is compatible with char32_t.
7611 proc check_effective_target_wchar_t_char32_t_compatible { } {
7612 return [check_no_compiler_messages wchar_t_char32_t object {
7613 __WCHAR_TYPE__ wc;
7614 __CHAR32_TYPE__ *p32 = &wc;
7615 char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1];
7619 # Return 1 if pow10 function exists.
7621 proc check_effective_target_pow10 { } {
7622 return [check_runtime pow10 {
7623 #include <math.h>
7624 int main () {
7625 double x;
7626 x = pow10 (1);
7627 return 0;
7629 } "-lm" ]
7632 # Return 1 if frexpl function exists.
7634 proc check_effective_target_frexpl { } {
7635 return [check_runtime frexpl {
7636 #include <math.h>
7637 int main () {
7638 long double x;
7639 int y;
7640 x = frexpl (5.0, &y);
7641 return 0;
7643 } "-lm" ]
7647 # Return 1 if issignaling function exists.
7648 proc check_effective_target_issignaling {} {
7649 return [check_runtime issignaling {
7650 #define _GNU_SOURCE
7651 #include <math.h>
7652 int main ()
7654 return issignaling (0.0);
7656 } "-lm" ]
7659 # Return 1 if current options generate DFP instructions, 0 otherwise.
7660 proc check_effective_target_hard_dfp {} {
7661 return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly {
7662 typedef float d64 __attribute__((mode(DD)));
7663 d64 x, y, z;
7664 void foo (void) { z = x + y; }
7668 # Return 1 if string.h and wchar.h headers provide C++ requires overloads
7669 # for strchr etc. functions.
7671 proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
7672 return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly {
7673 #include <string.h>
7674 #include <wchar.h>
7675 #if !defined(__cplusplus) \
7676 || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \
7677 || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO)
7678 ISO C++ correct string.h and wchar.h protos not supported.
7679 #else
7680 int i;
7681 #endif
7685 # Return 1 if GNU as is used.
7687 proc check_effective_target_gas { } {
7688 global use_gas_saved
7689 global tool
7691 if {![info exists use_gas_saved]} {
7692 # Check if the as used by gcc is GNU as.
7693 set gcc_as [lindex [${tool}_target_compile "-print-prog-name=as" "" "none" ""] 0]
7694 # Provide /dev/null as input, otherwise gas times out reading from
7695 # stdin.
7696 set status [remote_exec host "$gcc_as" "-v /dev/null"]
7697 set as_output [lindex $status 1]
7698 if { [ string first "GNU" $as_output ] >= 0 } {
7699 set use_gas_saved 1
7700 } else {
7701 set use_gas_saved 0
7704 return $use_gas_saved
7707 # Return 1 if GNU ld is used.
7709 proc check_effective_target_gld { } {
7710 global use_gld_saved
7711 global tool
7713 if {![info exists use_gld_saved]} {
7714 # Check if the ld used by gcc is GNU ld.
7715 set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=ld" "" "none" ""] 0]
7716 set status [remote_exec host "$gcc_ld" "--version"]
7717 set ld_output [lindex $status 1]
7718 if { [ string first "GNU" $ld_output ] >= 0 } {
7719 set use_gld_saved 1
7720 } else {
7721 set use_gld_saved 0
7724 return $use_gld_saved
7727 # Return 1 if the compiler has been configure with link-time optimization
7728 # (LTO) support.
7730 proc check_effective_target_lto { } {
7731 if { [istarget nvptx-*-*] } {
7732 return 0;
7734 return [check_no_compiler_messages lto object {
7735 void foo (void) { }
7736 } "-flto"]
7739 # Return 1 if -mx32 -maddress-mode=short can compile, 0 otherwise.
7741 proc check_effective_target_maybe_x32 { } {
7742 return [check_no_compiler_messages maybe_x32 object {
7743 void foo (void) {}
7744 } "-mx32 -maddress-mode=short"]
7747 # Return 1 if this target supports the -fsplit-stack option, 0
7748 # otherwise.
7750 proc check_effective_target_split_stack {} {
7751 return [check_no_compiler_messages split_stack object {
7752 void foo (void) { }
7753 } "-fsplit-stack"]
7756 # Return 1 if this target supports the -masm=intel option, 0
7757 # otherwise
7759 proc check_effective_target_masm_intel {} {
7760 return [check_no_compiler_messages masm_intel object {
7761 extern void abort (void);
7762 } "-masm=intel"]
7765 # Return 1 if the language for the compiler under test is C.
7767 proc check_effective_target_c { } {
7768 global tool
7769 if [string match $tool "gcc"] {
7770 return 1
7772 return 0
7775 # Return 1 if the language for the compiler under test is C++.
7777 proc check_effective_target_c++ { } {
7778 global tool
7779 if { [string match $tool "g++"] || [string match $tool "libstdc++"] } {
7780 return 1
7782 return 0
7785 set cxx_default "c++14"
7786 # Check whether the current active language standard supports the features
7787 # of C++11/C++14 by checking for the presence of one of the -std flags.
7788 # This assumes that the default for the compiler is $cxx_default, and that
7789 # there will never be multiple -std= arguments on the command line.
7790 proc check_effective_target_c++11_only { } {
7791 global cxx_default
7792 if ![check_effective_target_c++] {
7793 return 0
7795 if [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }] {
7796 return 1
7798 if { $cxx_default == "c++11" && [check-flags { { } { } { } { -std=* } }] } {
7799 return 1
7801 return 0
7803 proc check_effective_target_c++11 { } {
7804 if [check_effective_target_c++11_only] {
7805 return 1
7807 return [check_effective_target_c++14]
7809 proc check_effective_target_c++11_down { } {
7810 if ![check_effective_target_c++] {
7811 return 0
7813 return [expr ![check_effective_target_c++14] ]
7816 proc check_effective_target_c++14_only { } {
7817 global cxx_default
7818 if ![check_effective_target_c++] {
7819 return 0
7821 if [check-flags { { } { } { -std=c++14 -std=gnu++14 -std=c++14 -std=gnu++14 } }] {
7822 return 1
7824 if { $cxx_default == "c++14" && [check-flags { { } { } { } { -std=* } }] } {
7825 return 1
7827 return 0
7830 proc check_effective_target_c++14 { } {
7831 if [check_effective_target_c++14_only] {
7832 return 1
7834 return [check_effective_target_c++17]
7836 proc check_effective_target_c++14_down { } {
7837 if ![check_effective_target_c++] {
7838 return 0
7840 return [expr ![check_effective_target_c++17] ]
7843 proc check_effective_target_c++98_only { } {
7844 global cxx_default
7845 if ![check_effective_target_c++] {
7846 return 0
7848 if [check-flags { { } { } { -std=c++98 -std=gnu++98 -std=c++03 -std=gnu++03 } }] {
7849 return 1
7851 if { $cxx_default == "c++98" && [check-flags { { } { } { } { -std=* } }] } {
7852 return 1
7854 return 0
7857 proc check_effective_target_c++17_only { } {
7858 global cxx_default
7859 if ![check_effective_target_c++] {
7860 return 0
7862 if [check-flags { { } { } { -std=c++17 -std=gnu++17 -std=c++1z -std=gnu++1z } }] {
7863 return 1
7865 if { $cxx_default == "c++17" && [check-flags { { } { } { } { -std=* } }] } {
7866 return 1
7868 return 0
7871 proc check_effective_target_c++17 { } {
7872 if [check_effective_target_c++17_only] {
7873 return 1
7875 return [check_effective_target_c++2a]
7877 proc check_effective_target_c++17_down { } {
7878 if ![check_effective_target_c++] {
7879 return 0
7881 return [expr ![check_effective_target_c++2a] ]
7884 proc check_effective_target_c++2a_only { } {
7885 global cxx_default
7886 if ![check_effective_target_c++] {
7887 return 0
7889 if [check-flags { { } { } { -std=c++2a -std=gnu++2a } }] {
7890 return 1
7892 if { $cxx_default == "c++20" && [check-flags { { } { } { } { -std=* } }] } {
7893 return 1
7895 return 0
7897 proc check_effective_target_c++2a { } {
7898 return [check_effective_target_c++2a_only]
7901 # Check for C++ Concepts TS support, i.e. -fconcepts flag.
7902 proc check_effective_target_concepts { } {
7903 return [check-flags { "" { } { -fconcepts } }]
7906 # Return 1 if expensive testcases should be run.
7908 proc check_effective_target_run_expensive_tests { } {
7909 if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } {
7910 return 1
7912 return 0
7915 # Returns 1 if "mempcpy" is available on the target system.
7917 proc check_effective_target_mempcpy {} {
7918 return [check_function_available "mempcpy"]
7921 # Returns 1 if "stpcpy" is available on the target system.
7923 proc check_effective_target_stpcpy {} {
7924 return [check_function_available "stpcpy"]
7927 # Check whether the vectorizer tests are supported by the target and
7928 # append additional target-dependent compile flags to DEFAULT_VECTCFLAGS.
7929 # If a port wants to execute the tests more than once it should append
7930 # the supported target to EFFECTIVE_TARGETS instead, and the compile flags
7931 # will be added by a call to add_options_for_<target>.
7932 # Set dg-do-what-default to either compile or run, depending on target
7933 # capabilities. Do not set this if the supported target is appended to
7934 # EFFECTIVE_TARGETS. Flags and this variable will be set by et-dg-runtest
7935 # automatically. Return the number of effective targets if vectorizer tests
7936 # are supported, 0 otherwise.
7938 proc check_vect_support_and_set_flags { } {
7939 global DEFAULT_VECTCFLAGS
7940 global dg-do-what-default
7941 global EFFECTIVE_TARGETS
7943 if [istarget powerpc-*paired*] {
7944 lappend DEFAULT_VECTCFLAGS "-mpaired"
7945 if [check_750cl_hw_available] {
7946 set dg-do-what-default run
7947 } else {
7948 set dg-do-what-default compile
7950 } elseif [istarget powerpc*-*-*] {
7951 # Skip targets not supporting -maltivec.
7952 if ![is-effective-target powerpc_altivec_ok] {
7953 return 0
7956 lappend DEFAULT_VECTCFLAGS "-maltivec"
7957 if [check_p9vector_hw_available] {
7958 lappend DEFAULT_VECTCFLAGS "-mpower9-vector"
7959 } elseif [check_p8vector_hw_available] {
7960 lappend DEFAULT_VECTCFLAGS "-mpower8-vector"
7961 } elseif [check_vsx_hw_available] {
7962 lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
7965 if [check_vmx_hw_available] {
7966 set dg-do-what-default run
7967 } else {
7968 if [is-effective-target ilp32] {
7969 # Specify a cpu that supports VMX for compile-only tests.
7970 lappend DEFAULT_VECTCFLAGS "-mcpu=970"
7972 set dg-do-what-default compile
7974 } elseif { [istarget spu-*-*] } {
7975 set dg-do-what-default run
7976 } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
7977 lappend DEFAULT_VECTCFLAGS "-msse2"
7978 if { [check_effective_target_sse2_runtime] } {
7979 set dg-do-what-default run
7980 } else {
7981 set dg-do-what-default compile
7983 } elseif { [istarget mips*-*-*]
7984 && [check_effective_target_nomips16] } {
7985 if { [check_effective_target_mpaired_single] } {
7986 lappend EFFECTIVE_TARGETS mpaired_single
7988 if { [check_effective_target_mips_loongson] } {
7989 lappend EFFECTIVE_TARGETS mips_loongson
7991 if { [check_effective_target_mips_msa] } {
7992 lappend EFFECTIVE_TARGETS mips_msa
7994 return [llength $EFFECTIVE_TARGETS]
7995 } elseif [istarget sparc*-*-*] {
7996 lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
7997 if [check_effective_target_ultrasparc_hw] {
7998 set dg-do-what-default run
7999 } else {
8000 set dg-do-what-default compile
8002 } elseif [istarget alpha*-*-*] {
8003 # Alpha's vectorization capabilities are extremely limited.
8004 # It's more effort than its worth disabling all of the tests
8005 # that it cannot pass. But if you actually want to see what
8006 # does work, command out the return.
8007 return 0
8009 lappend DEFAULT_VECTCFLAGS "-mmax"
8010 if [check_alpha_max_hw_available] {
8011 set dg-do-what-default run
8012 } else {
8013 set dg-do-what-default compile
8015 } elseif [istarget ia64-*-*] {
8016 set dg-do-what-default run
8017 } elseif [is-effective-target arm_neon_ok] {
8018 eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""]
8019 # NEON does not support denormals, so is not used for vectorization by
8020 # default to avoid loss of precision. We must pass -ffast-math to test
8021 # vectorization of float operations.
8022 lappend DEFAULT_VECTCFLAGS "-ffast-math"
8023 if [is-effective-target arm_neon_hw] {
8024 set dg-do-what-default run
8025 } else {
8026 set dg-do-what-default compile
8028 } elseif [istarget "aarch64*-*-*"] {
8029 set dg-do-what-default run
8030 } else {
8031 return 0
8034 return 1
8037 # Return 1 if the target does *not* require strict alignment.
8039 proc check_effective_target_non_strict_align {} {
8041 # On ARM, the default is to use STRICT_ALIGNMENT, but there
8042 # are interfaces defined for misaligned access and thus
8043 # depending on the architecture levels unaligned access is
8044 # available.
8045 if [istarget "arm*-*-*"] {
8046 return [check_effective_target_arm_unaligned]
8049 return [check_no_compiler_messages non_strict_align assembly {
8050 char *y;
8051 typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c;
8052 c *z;
8053 void foo(void) { z = (c *) y; }
8054 } "-Wcast-align"]
8057 # Return 1 if the target has <ucontext.h>.
8059 proc check_effective_target_ucontext_h { } {
8060 return [check_no_compiler_messages ucontext_h assembly {
8061 #include <ucontext.h>
8065 proc check_effective_target_aarch64_tiny { } {
8066 if { [istarget aarch64*-*-*] } {
8067 return [check_no_compiler_messages aarch64_tiny object {
8068 #ifdef __AARCH64_CMODEL_TINY__
8069 int dummy;
8070 #else
8071 #error target not AArch64 tiny code model
8072 #endif
8074 } else {
8075 return 0
8079 # Create functions to check that the AArch64 assembler supports the
8080 # various architecture extensions via the .arch_extension pseudo-op.
8082 foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse"} {
8083 eval [string map [list FUNC $aarch64_ext] {
8084 proc check_effective_target_aarch64_asm_FUNC_ok { } {
8085 if { [istarget aarch64*-*-*] } {
8086 return [check_no_compiler_messages aarch64_FUNC_assembler object {
8087 __asm__ (".arch_extension FUNC");
8088 } "-march=armv8-a+FUNC"]
8089 } else {
8090 return 0
8096 proc check_effective_target_aarch64_small { } {
8097 if { [istarget aarch64*-*-*] } {
8098 return [check_no_compiler_messages aarch64_small object {
8099 #ifdef __AARCH64_CMODEL_SMALL__
8100 int dummy;
8101 #else
8102 #error target not AArch64 small code model
8103 #endif
8105 } else {
8106 return 0
8110 proc check_effective_target_aarch64_large { } {
8111 if { [istarget aarch64*-*-*] } {
8112 return [check_no_compiler_messages aarch64_large object {
8113 #ifdef __AARCH64_CMODEL_LARGE__
8114 int dummy;
8115 #else
8116 #error target not AArch64 large code model
8117 #endif
8119 } else {
8120 return 0
8125 # Return 1 if this is a reduced AVR Tiny core. Such cores have different
8126 # register set, instruction set, addressing capabilities and ABI.
8128 proc check_effective_target_avr_tiny { } {
8129 if { [istarget avr*-*-*] } {
8130 return [check_no_compiler_messages avr_tiny object {
8131 #ifdef __AVR_TINY__
8132 int dummy;
8133 #else
8134 #error target not a reduced AVR Tiny core
8135 #endif
8137 } else {
8138 return 0
8142 # Return 1 if <fenv.h> is available with all the standard IEEE
8143 # exceptions and floating-point exceptions are raised by arithmetic
8144 # operations. (If the target requires special options for "inexact"
8145 # exceptions, those need to be specified in the testcases.)
8147 proc check_effective_target_fenv_exceptions {} {
8148 return [check_runtime fenv_exceptions {
8149 #include <fenv.h>
8150 #include <stdlib.h>
8151 #ifndef FE_DIVBYZERO
8152 # error Missing FE_DIVBYZERO
8153 #endif
8154 #ifndef FE_INEXACT
8155 # error Missing FE_INEXACT
8156 #endif
8157 #ifndef FE_INVALID
8158 # error Missing FE_INVALID
8159 #endif
8160 #ifndef FE_OVERFLOW
8161 # error Missing FE_OVERFLOW
8162 #endif
8163 #ifndef FE_UNDERFLOW
8164 # error Missing FE_UNDERFLOW
8165 #endif
8166 volatile float a = 0.0f, r;
8168 main (void)
8170 r = a / a;
8171 if (fetestexcept (FE_INVALID))
8172 exit (0);
8173 else
8174 abort ();
8176 } [add_options_for_ieee "-std=gnu99"]]
8179 proc check_effective_target_tiny {} {
8180 global et_target_tiny_saved
8182 if [info exists et_target_tiny_saved] {
8183 verbose "check_effective_target_tiny: using cached result" 2
8184 } else {
8185 set et_target_tiny_saved 0
8186 if { [istarget aarch64*-*-*]
8187 && [check_effective_target_aarch64_tiny] } {
8188 set et_target_tiny_saved 1
8190 if { [istarget avr-*-*]
8191 && [check_effective_target_avr_tiny] } {
8192 set et_target_tiny_saved 1
8196 return $et_target_tiny_saved
8199 # Return 1 if LOGICAL_OP_NON_SHORT_CIRCUIT is set to 0 for the current target.
8201 proc check_effective_target_logical_op_short_circuit {} {
8202 if { [istarget mips*-*-*]
8203 || [istarget arc*-*-*]
8204 || [istarget avr*-*-*]
8205 || [istarget crisv32-*-*] || [istarget cris-*-*]
8206 || [istarget mmix-*-*]
8207 || [istarget s390*-*-*]
8208 || [istarget powerpc*-*-*]
8209 || [istarget nios2*-*-*]
8210 || [istarget riscv*-*-*]
8211 || [istarget visium-*-*]
8212 || [check_effective_target_arm_cortex_m] } {
8213 return 1
8215 return 0
8218 # Record that dg-final test TEST requires convential compilation.
8220 proc force_conventional_output_for { test } {
8221 if { [info proc $test] == "" } {
8222 perror "$test does not exist"
8223 exit 1
8225 proc ${test}_required_options {} {
8226 global gcc_force_conventional_output
8227 return $gcc_force_conventional_output
8231 # Return 1 if the x86-64 target supports PIE with copy reloc, 0
8232 # otherwise. Cache the result.
8234 proc check_effective_target_pie_copyreloc { } {
8235 global pie_copyreloc_available_saved
8236 global tool
8237 global GCC_UNDER_TEST
8239 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
8240 return 0
8243 # Need auto-host.h to check linker support.
8244 if { ![file exists ../../auto-host.h ] } {
8245 return 0
8248 if [info exists pie_copyreloc_available_saved] {
8249 verbose "check_effective_target_pie_copyreloc returning saved $pie_copyreloc_available_saved" 2
8250 } else {
8251 # Set up and compile to see if linker supports PIE with copy
8252 # reloc. Include the current process ID in the file names to
8253 # prevent conflicts with invocations for multiple testsuites.
8255 set src pie[pid].c
8256 set obj pie[pid].o
8258 set f [open $src "w"]
8259 puts $f "#include \"../../auto-host.h\""
8260 puts $f "#if HAVE_LD_PIE_COPYRELOC == 0"
8261 puts $f "# error Linker does not support PIE with copy reloc."
8262 puts $f "#endif"
8263 close $f
8265 verbose "check_effective_target_pie_copyreloc compiling testfile $src" 2
8266 set lines [${tool}_target_compile $src $obj object ""]
8268 file delete $src
8269 file delete $obj
8271 if [string match "" $lines] then {
8272 verbose "check_effective_target_pie_copyreloc testfile compilation passed" 2
8273 set pie_copyreloc_available_saved 1
8274 } else {
8275 verbose "check_effective_target_pie_copyreloc testfile compilation failed" 2
8276 set pie_copyreloc_available_saved 0
8280 return $pie_copyreloc_available_saved
8283 # Return 1 if the x86 target supports R_386_GOT32X relocation, 0
8284 # otherwise. Cache the result.
8286 proc check_effective_target_got32x_reloc { } {
8287 global got32x_reloc_available_saved
8288 global tool
8289 global GCC_UNDER_TEST
8291 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
8292 return 0
8295 # Need auto-host.h to check linker support.
8296 if { ![file exists ../../auto-host.h ] } {
8297 return 0
8300 if [info exists got32x_reloc_available_saved] {
8301 verbose "check_effective_target_got32x_reloc returning saved $got32x_reloc_available_saved" 2
8302 } else {
8303 # Include the current process ID in the file names to prevent
8304 # conflicts with invocations for multiple testsuites.
8306 set src got32x[pid].c
8307 set obj got32x[pid].o
8309 set f [open $src "w"]
8310 puts $f "#include \"../../auto-host.h\""
8311 puts $f "#if HAVE_AS_IX86_GOT32X == 0"
8312 puts $f "# error Assembler does not support R_386_GOT32X."
8313 puts $f "#endif"
8314 close $f
8316 verbose "check_effective_target_got32x_reloc compiling testfile $src" 2
8317 set lines [${tool}_target_compile $src $obj object ""]
8319 file delete $src
8320 file delete $obj
8322 if [string match "" $lines] then {
8323 verbose "check_effective_target_got32x_reloc testfile compilation passed" 2
8324 set got32x_reloc_available_saved 1
8325 } else {
8326 verbose "check_effective_target_got32x_reloc testfile compilation failed" 2
8327 set got32x_reloc_available_saved 0
8331 return $got32x_reloc_available_saved
8334 # Return 1 if the x86 target supports calling ___tls_get_addr via GOT,
8335 # 0 otherwise. Cache the result.
8337 proc check_effective_target_tls_get_addr_via_got { } {
8338 global tls_get_addr_via_got_available_saved
8339 global tool
8340 global GCC_UNDER_TEST
8342 if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
8343 return 0
8346 # Need auto-host.h to check linker support.
8347 if { ![file exists ../../auto-host.h ] } {
8348 return 0
8351 if [info exists tls_get_addr_via_got_available_saved] {
8352 verbose "check_effective_target_tls_get_addr_via_got returning saved $tls_get_addr_via_got_available_saved" 2
8353 } else {
8354 # Include the current process ID in the file names to prevent
8355 # conflicts with invocations for multiple testsuites.
8357 set src tls_get_addr_via_got[pid].c
8358 set obj tls_get_addr_via_got[pid].o
8360 set f [open $src "w"]
8361 puts $f "#include \"../../auto-host.h\""
8362 puts $f "#if HAVE_AS_IX86_TLS_GET_ADDR_GOT == 0"
8363 puts $f "# error Assembler/linker do not support calling ___tls_get_addr via GOT."
8364 puts $f "#endif"
8365 close $f
8367 verbose "check_effective_target_tls_get_addr_via_got compiling testfile $src" 2
8368 set lines [${tool}_target_compile $src $obj object ""]
8370 file delete $src
8371 file delete $obj
8373 if [string match "" $lines] then {
8374 verbose "check_effective_target_tls_get_addr_via_got testfile compilation passed" 2
8375 set tls_get_addr_via_got_available_saved 1
8376 } else {
8377 verbose "check_effective_target_tls_get_addr_via_got testfile compilation failed" 2
8378 set tls_get_addr_via_got_available_saved 0
8382 return $tls_get_addr_via_got_available_saved
8385 # Return 1 if the target uses comdat groups.
8387 proc check_effective_target_comdat_group {} {
8388 return [check_no_messages_and_pattern comdat_group "\.section\[^\n\r]*,comdat" assembly {
8389 // C++
8390 inline int foo () { return 1; }
8391 int (*fn) () = foo;
8395 # Return 1 if target supports __builtin_eh_return
8396 proc check_effective_target_builtin_eh_return { } {
8397 return [check_no_compiler_messages builtin_eh_return object {
8398 void test (long l, void *p)
8400 __builtin_eh_return (l, p);
8402 } "" ]
8405 # Return 1 if the target supports max reduction for vectors.
8407 proc check_effective_target_vect_max_reduc { } {
8408 if { [istarget aarch64*-*-*] || [is-effective-target arm_neon] } {
8409 return 1
8411 return 0
8414 # Return 1 if there is an nvptx offload compiler.
8416 proc check_effective_target_offload_nvptx { } {
8417 return [check_no_compiler_messages offload_nvptx object {
8418 int main () {return 0;}
8419 } "-foffload=nvptx-none" ]
8422 # Return 1 if the compiler has been configured with hsa offloading.
8424 proc check_effective_target_offload_hsa { } {
8425 return [check_no_compiler_messages offload_hsa assembly {
8426 int main () {return 0;}
8427 } "-foffload=hsa" ]
8430 # Return 1 if the target support -fprofile-update=atomic
8431 proc check_effective_target_profile_update_atomic {} {
8432 return [check_no_compiler_messages profile_update_atomic assembly {
8433 int main (void) { return 0; }
8434 } "-fprofile-update=atomic -fprofile-generate"]
8437 # Return 1 if vector (va - vector add) instructions are understood by
8438 # the assembler and can be executed. This also covers checking for
8439 # the VX kernel feature. A kernel without that feature does not
8440 # enable the vector facility and the following check will die with a
8441 # signal.
8442 proc check_effective_target_s390_vx { } {
8443 if ![istarget s390*-*-*] then {
8444 return 0;
8447 return [check_runtime s390_check_vx {
8448 int main (void)
8450 asm ("va %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28");
8451 return 0;
8453 } "-march=z13 -mzarch" ]
8456 # Same as above but for the arch12 vector enhancement facility. Test
8457 # is performed with the vector nand instruction.
8458 proc check_effective_target_s390_vxe { } {
8459 if ![istarget s390*-*-*] then {
8460 return 0;
8463 return [check_runtime s390_check_vxe {
8464 int main (void)
8466 asm ("vnn %%v24, %%v26, %%v28" : : : "v24", "v26", "v28");
8467 return 0;
8469 } "-march=arch12 -mzarch" ]
8472 #For versions of ARM architectures that have hardware div insn,
8473 #disable the divmod transform
8475 proc check_effective_target_arm_divmod_simode { } {
8476 return [check_no_compiler_messages arm_divmod assembly {
8477 #ifdef __ARM_ARCH_EXT_IDIV__
8478 #error has div insn
8479 #endif
8480 int i;
8484 # Return 1 if target supports divmod hardware insn or divmod libcall.
8486 proc check_effective_target_divmod { } {
8487 #TODO: Add checks for all targets that have either hardware divmod insn
8488 # or define libfunc for divmod.
8489 if { [istarget arm*-*-*]
8490 || [istarget i?86-*-*] || [istarget x86_64-*-*] } {
8491 return 1
8493 return 0
8496 # Return 1 if target supports divmod for SImode. The reason for
8497 # separating this from check_effective_target_divmod is that
8498 # some versions of ARM architecture define div instruction
8499 # only for simode, and for these archs, we do not want to enable
8500 # divmod transform for simode.
8502 proc check_effective_target_divmod_simode { } {
8503 if { [istarget arm*-*-*] } {
8504 return [check_effective_target_arm_divmod_simode]
8507 return [check_effective_target_divmod]
8510 # Return 1 if store merging optimization is applicable for target.
8511 # Store merging is not profitable for targets like the avr which
8512 # can load/store only one byte at a time. Use int size as a proxy
8513 # for the number of bytes the target can write, and skip for targets
8514 # with a smallish (< 32) size.
8516 proc check_effective_target_store_merge { } {
8517 if { [is-effective-target non_strict_align ] && [is-effective-target int32plus] } {
8518 return 1
8521 return 0
8524 # Return 1 if we're able to assemble rdrand
8526 proc check_effective_target_rdrand { } {
8527 return [check_no_compiler_messages_nocache rdrand object {
8528 unsigned int
8529 __foo(void)
8531 unsigned int val;
8532 __builtin_ia32_rdrand32_step(&val);
8533 return val;
8535 } "-mrdrnd" ]
8538 # Return 1 if the target supports coprocessor instructions: cdp, ldc, ldcl,
8539 # stc, stcl, mcr and mrc.
8540 proc check_effective_target_arm_coproc1_ok_nocache { } {
8541 if { ![istarget arm*-*-*] } {
8542 return 0
8544 return [check_no_compiler_messages_nocache arm_coproc1_ok assembly {
8545 #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 4
8546 #error FOO
8547 #endif
8551 proc check_effective_target_arm_coproc1_ok { } {
8552 return [check_cached_effective_target arm_coproc1_ok \
8553 check_effective_target_arm_coproc1_ok_nocache]
8556 # Return 1 if the target supports all coprocessor instructions checked by
8557 # check_effective_target_arm_coproc1_ok in addition to the following: cdp2,
8558 # ldc2, ldc2l, stc2, stc2l, mcr2 and mrc2.
8559 proc check_effective_target_arm_coproc2_ok_nocache { } {
8560 if { ![check_effective_target_arm_coproc1_ok] } {
8561 return 0
8563 return [check_no_compiler_messages_nocache arm_coproc2_ok assembly {
8564 #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 5
8565 #error FOO
8566 #endif
8570 proc check_effective_target_arm_coproc2_ok { } {
8571 return [check_cached_effective_target arm_coproc2_ok \
8572 check_effective_target_arm_coproc2_ok_nocache]
8575 # Return 1 if the target supports all coprocessor instructions checked by
8576 # check_effective_target_arm_coproc2_ok in addition the following: mcrr and
8577 # mrrc.
8578 proc check_effective_target_arm_coproc3_ok_nocache { } {
8579 if { ![check_effective_target_arm_coproc2_ok] } {
8580 return 0
8582 return [check_no_compiler_messages_nocache arm_coproc3_ok assembly {
8583 #if (__thumb__ && !__thumb2__) \
8584 || (__ARM_ARCH < 6 && !defined (__ARM_ARCH_5TE__))
8585 #error FOO
8586 #endif
8590 proc check_effective_target_arm_coproc3_ok { } {
8591 return [check_cached_effective_target arm_coproc3_ok \
8592 check_effective_target_arm_coproc3_ok_nocache]
8595 # Return 1 if the target supports all coprocessor instructions checked by
8596 # check_effective_target_arm_coproc3_ok in addition the following: mcrr2 and
8597 # mrcc2.
8598 proc check_effective_target_arm_coproc4_ok_nocache { } {
8599 if { ![check_effective_target_arm_coproc3_ok] } {
8600 return 0
8602 return [check_no_compiler_messages_nocache arm_coproc4_ok assembly {
8603 #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 6
8604 #error FOO
8605 #endif
8609 proc check_effective_target_arm_coproc4_ok { } {
8610 return [check_cached_effective_target arm_coproc4_ok \
8611 check_effective_target_arm_coproc4_ok_nocache]
8614 # Return 1 if the target supports the auto_inc_dec optimization pass.
8615 proc check_effective_target_autoincdec { } {
8616 if { ![check_no_compiler_messages auto_incdec assembly { void f () { }
8617 } "-O2 -fdump-rtl-auto_inc_dec" ] } {
8618 return 0
8621 set dumpfile [glob -nocomplain "auto_incdec[pid].c.\[0-9\]\[0-9\]\[0-9\]r.auto_inc_dec"]
8622 if { [file exists $dumpfile ] } {
8623 file delete $dumpfile
8624 return 1
8626 return 0
8629 # Return 1 if the target has support for stack probing designed
8630 # to avoid stack-clash style attacks.
8632 # This is used to restrict the stack-clash mitigation tests to
8633 # just those targets that have been explicitly supported.
8635 # In addition to the prologue work on those targets, each target's
8636 # properties should be described in the functions below so that
8637 # tests do not become a mess of unreadable target conditions.
8639 proc check_effective_target_supports_stack_clash_protection { } {
8641 # Temporary until the target bits are fully ACK'd.
8642 # if { [istarget aarch*-*-*] } {
8643 # return 1
8646 if { [istarget x86_64-*-*] || [istarget i?86-*-*]
8647 || [istarget powerpc*-*-*] || [istarget rs6000*-*-*]
8648 || [istarget s390*-*-*] } {
8649 return 1
8651 return 0
8654 # Return 1 if the target creates a frame pointer for non-leaf functions
8655 # Note we ignore cases where we apply tail call optimization here.
8656 proc check_effective_target_frame_pointer_for_non_leaf { } {
8657 if { [istarget aarch*-*-*] } {
8658 return 1
8661 # Solaris/x86 defaults to -fno-omit-frame-pointer.
8662 if { [istarget i?86-*-solaris*] || [istarget x86_64-*-solaris*] } {
8663 return 1
8666 return 0
8669 # Return 1 if the target's calling sequence or its ABI
8670 # create implicit stack probes at or prior to function entry.
8671 proc check_effective_target_caller_implicit_probes { } {
8673 # On x86/x86_64 the call instruction itself pushes the return
8674 # address onto the stack. That is an implicit probe of *sp.
8675 if { [istarget x86_64-*-*] || [istarget i?86-*-*] } {
8676 return 1
8679 # On PPC, the ABI mandates that the address of the outer
8680 # frame be stored at *sp. Thus each allocation of stack
8681 # space is itself an implicit probe of *sp.
8682 if { [istarget powerpc*-*-*] || [istarget rs6000*-*-*] } {
8683 return 1
8686 # s390's ABI has a register save area allocated by the
8687 # caller for use by the callee. The mere existence does
8688 # not constitute a probe by the caller, but when the slots
8689 # used by the callee those stores are implicit probes.
8690 if { [istarget s390*-*-*] } {
8691 return 1
8694 # Not strictly true on aarch64, but we have agreed that we will
8695 # consider any function that pushes SP more than 3kbytes into
8696 # the guard page as broken. This essentially means that we can
8697 # consider the aarch64 as having a caller implicit probe at
8698 # *(sp + 1k).
8699 if { [istarget aarch64*-*-*] } {
8700 return 1;
8703 return 0
8706 # Targets that potentially realign the stack pointer often cause residual
8707 # stack allocations and make it difficult to elimination loops or residual
8708 # allocations for dynamic stack allocations
8709 proc check_effective_target_callee_realigns_stack { } {
8710 if { [istarget x86_64-*-*] || [istarget i?86-*-*] } {
8711 return 1
8713 return 0