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